npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

wms

v4.2.1

Published

WMS/WMTS services for node.js

Downloads

27

Readme

wms

Build Status

WMS and WMTS web service for Node.js.

Only works in spherical web mercator, expects a tiled source, requires Graphics Magic to be available, and a version of node that has support for ES6 features (specifically template literals, generators, and WeakMaps).

API

The module is a function which takes 2 required parameters and 2 optional ones. The first is service config, the full config is below, but is only mandatory for getCapabilities, getMap and getTile may pass just the layers array or just the layer object (for getTile and getMap with only one layer requested).

  • title: title for the service
  • abstract: short description
  • host: the host where the service lives
  • wmshost: if you want the wms to be on a different host populate this, otherwise will default to host
  • layerLimit: if you want to specify a limit on the number layers in wms requests, do so here
  • layers: array of layer objects with the following keys
    • viewable: if set to false then the layer won't be included
    • title: title of the layer
    • name: identifier for the layer
    • bbox: bounding box for the layer in, array in [minx, miny, minx, miny] format
    • range: array containing the min and max zooms in terms of tile zooms in [minZoom, maxZoom] format.
    • image: Array with the image types the layer should support, defaults to ['png', 'jpeg'] which are also the only two options, mainly relevant because arcgis offers no ability to select image format (defaulting to 'jpeg' making it impossible to pick png if jpeg is available).
    • getTile: function called to get tiles, not needed for getCapabilities.

The second argument is the query string. These are the arguments being sent to the server via query string e.g. in Express it's req.query.

A cache object may also be supplied as the 3rd argument (detailed bellow).

Either a callback can be supplied or if not it returns a promise (this is the half a parameter).

The callback is called with (or the promise resolves with) an object with the following properties:

  • data: a buffer with the data to return
  • headers: headers
  • code: status code

So with Express you can just call

var wms = require('wms');
app.get('/something', function (req, res){
  wms(layerInfo, req.query).then(function (wmsResponse) {
    res.set(wmsResponse.headers);
    res.status(wmsResponse.code);
    res.send(wmsResponse.data);
  });
});

getTile function

Both WMS and WMTS require a getTile function which is called with zoom, level, and row of a tile and a callback. The callback needs to be called with the time or an error or the tile and buffer. For example:

function(z, x, y, callback){
  // do something
  return callback(null, buffer, headers);
}

This will not be called if the tile is outside of the bounding box or zoom range.

Cache Object

The cache object which may be supplied as the 3rd argument is an object with get and set, get takes a string and a callback, set takes a string, a buffer, and a callback.

Get returns either the object from the key, or it calls the callback with an error.

If this object is omitted then a simple lru memory cache is used, currently is only used to cache the image transforms in the WMTS service.

Should you use a WMS or a WMTS?

Always use a WMTS over a WMS if given a choice. Only ever use a WMS if you don't have a choice. WMS is very slow. This is not a bug; this is a consequence of how it works.

Even better then a WMTS server - use a TMS as it allows the server to make and send tiles in arbitrary and mixed formats.

Spec Compliance

This implementation of a WMS/WMTS server is written with a sensibility more akin to JSON then XML. In other words, mandatory parameters that can be inferred from context do not cause an exception to be throw. For instance: since only WMTS supports GetTile, and only WMS supports GetMap, and the only request they both support is GetCapabilities, omitting the service parameter will only throw an error on a GetCapabilities request.

~~Despite the incredible detail paid to certain areas of the spec, there are situations that are are not covered. For instance, with a WMTS service, the only way to communicate that a tile was not found in the cache is to tell the client that it was out of range. In other words, it does not cover the case where the data behind the cache might not be a perfect square as might be the case for, say, state-level imagery outside of the great plains. In cases like this, I've tried to be the least surprising as I can, and when conventions collide, I err on the side of the more widely used convention. So in this case, I return a NoApplicableCode exception report with a 404 status code. This uses the convention of issuing 404 status codes to indicate missing resources, in favor of the OGC specific convention of responding to requests for non existent resources with 400.~~

QGIS retries 404's because it is too dumb to live so I just am sending back blank tiles in the case of 404s.

The OGC spec fundamentally believes that any request for data that doesn't exist is malformed by definition, because well formed requests would get data. A strict reading of the spec (specifically table 24 of the WMTS spec) would imply I should use a 500 status code for uses of NoApplicableCode because, from what I can tell, the OGC feels that for a server to get into the situation where there is no applicable OGC exception code would by necessity be a server error, because if the server was constructed properly it would never be in this situation.

It is currently not possible to specify additional SRS codes for WMS requests, but should in theory be possible via GDAL. This faces the road block of GDAL hating you and not supporting stdin/stdout, and the fact it would cause the already slow WMS to be even slower.

The chances of adding in additional tile pyramids are approximately 0, as the massive increase in complexity would likely not bring in much useful benefits as it is rare to see the same custom tile pyramid used by 2 different groups, and almost unheard of to see the same custom tile pyramid used across state lines.

License

MIT