Giter Site home page Giter Site logo

wms's Introduction

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

wms's People

Contributors

calvinmetcalf avatar dependabot[bot] avatar ismyrnow avatar kamataryo avatar knownasilya avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

wms's Issues

Unable to npm install

Getting an error when I try to npm install wms using node v11.6.0:

npm WARN deprecated [email protected]: protozero should no longer be used via npm, install instead via https://github.com/mapbox/mason

> [email protected] install /Users/user/Desktop/projects/reviz/server/node_modules/mapnik
> node-pre-gyp install --fallback-to-build

node-pre-gyp ERR! Tried to download(403): https://mapbox-node-binary.s3.amazonaws.com/mapnik/v3.7.2/node-v67-darwin-x64-Release.tar.gz 
node-pre-gyp ERR! Pre-built binaries not found for [email protected] and [email protected] (node-v67 ABI, unknown) (falling back to source compile with node-gyp) 
node-pre-gyp ERR! Tried to download(undefined): https://mapbox-node-binary.s3.amazonaws.com/mapnik/v3.7.2/node-v67-darwin-x64-Release.tar.gz 
node-pre-gyp ERR! Pre-built binaries not found for [email protected] and [email protected] (node-v67 ABI, unknown) (falling back to source compile with node-gyp) 
/bin/sh: mapnik-config: command not found
/bin/sh: mapnik-config: command not found
gyp: Call to 'mapnik-config --cflags' returned exit status 127 while in binding.gyp. while trying to load binding.gyp
gyp: Call to 'mapnik-config --cflags' returned exit status 127 while in binding.gyp. while trying to load binding.gyp
gypgyp  ERR! configure error 
ERR! configure error 
gyp ERR! stack Error: `gyp` failed with exit code: 1
gyp ERR! stack     at ChildProcess.onCpExit (/Users/user/.nvm/versions/node/v11.6.0/lib/node_modules/npm/node_modules/node-gyp/lib/configure.js:345:16)
gypgyp  ERR!ERR!  stackstack     at ChildProcess.emit (events.js:188:13)
 Error: `gyp` failed with exit code: 1
gyp gypERR!  stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:254:12)
ERR! stack     at ChildProcess.onCpExit (/Users/user/.nvm/versions/node/v11.6.0/lib/node_modules/npm/node_modules/node-gyp/lib/configure.js:345:16)
gyp gypERR!  ERR! stackSystem     at ChildProcess.emit (events.js:188:13)
 Darwin 17.7.0
gyp ERR!gyp  ERR!stack      at Process.ChildProcess._handle.onexit (internal/child_process.js:254:12)
command "/Users/user/.nvm/versions/node/v11.6.0/bin/node" "/Users/user/.nvm/versions/node/v11.6.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "configure" "--fallback-to-build" "--module=/Users/user/Desktop/projects/reviz/server/node_modules/mapnik/lib/binding/mapnik.node" "--module_name=mapnik" "--module_path=/Users/user/Desktop/projects/reviz/server/node_modules/mapnik/lib/binding"
gyp ERR! cwd /Users/user/Desktop/projects/reviz/server/node_modules/mapnik
gyp ERR!gyp node -v  v11.6.0
ERR!gyp  ERR!System node-gyp -v Darwin 17.7.0
 v3.8.0
gyp ERR! not okgyp 
 ERR! command "/Users/user/.nvm/versions/node/v11.6.0/bin/node" "/Users/user/.nvm/versions/node/v11.6.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "configure" "--fallback-to-build" "--module=/Users/user/Desktop/projects/reviz/server/node_modules/mapnik/lib/binding/mapnik.node" "--module_name=mapnik" "--module_path=/Users/user/Desktop/projects/reviz/server/node_modules/mapnik/lib/binding"
gyp ERR! cwd /Users/user/Desktop/projects/reviz/server/node_modules/mapnik
gyp ERR! node -v v11.6.0
gyp ERR! node-gyp -v v3.8.0
gyp ERR! not ok 
node-pre-gyp ERR! build error 
node-pre-gyp ERR! stack Error: Failed to execute '/Users/user/.nvm/versions/node/v11.6.0/bin/node /Users/user/.nvm/versions/node/v11.6.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js configure --fallback-to-build --module=/Users/user/Desktop/projects/reviz/server/node_modules/mapnik/lib/binding/mapnik.node --module_name=mapnik --module_path=/Users/user/Desktop/projects/reviz/server/node_modules/mapnik/lib/binding' (1)
node-pre-gyp ERR! stack     at ChildProcess.<anonymous> (/Users/user/Desktop/projects/reviz/server/node_modules/mapnik/node_modules/node-pre-gyp/lib/util/compile.js:83:29)
node-pre-gyp ERR! stack     at ChildProcess.emit (events.js:188:13)
node-pre-gyp ERR! stack     at maybeClose (internal/child_process.js:978:16)
node-pre-gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:265:5)
node-pre-gyp ERR! System Darwin 17.7.0
node-pre-gyp ERR! command "/Users/user/.nvm/versions/node/v11.6.0/bin/node" "/Users/user/Desktop/projects/reviz/server/node_modules/mapnik/node_modules/.bin/node-pre-gyp" "install" "--fallback-to-build"
node-pre-gyp ERR! cwd /Users/user/Desktop/projects/reviz/server/node_modules/mapnik
node-pre-gyp ERR! node -v v11.6.0
node-pre-gyp ERR! node-pre-gyp -v v0.6.39
node-pre-gyp ERR! not ok 
Failed to execute '/Users/user/.nvm/versions/node/v11.6.0/bin/node /Users/user/.nvm/versions/node/v11.6.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js configure --fallback-to-build --module=/Users/user/Desktop/projects/reviz/server/node_modules/mapnik/lib/binding/mapnik.node --module_name=mapnik --module_path=/Users/user/Desktop/projects/reviz/server/node_modules/mapnik/lib/binding' (1)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] install: `node-pre-gyp install --fallback-to-build`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the [email protected] install script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/user/.npm/_logs/2019-01-13T00_23_22_777Z-debug.log

Thanks!

GetFeatureInfo !

Hi @calvinmetcalf,

This is great work. I managed to implement a fully working custom wms/wmts server with it in a few hours. The responsiveness is awesome.

However, I still want little bit more! The only thing stopping me from throwing out GeoServer is the GetFeatureInfo capability. I've had a brief look over the source code and it looks like it would not be that hard to add. Is this something you were planning to implement to soonish anyway? Do you accept pull requests?

Many Thanks,
Nahid

Node v12 Support

So, the good news is, that, at least for my use case, this package works great on node v12. However, I have to install with --ignore-engines since the engine specifier specifies a maximum version of v10.

Maybe only set the minimum version, and if it breaks on newer node wait for reports? (AFAIK, there's no good way for a user to say "for this one package, I know it works on my version of node", and ignoring engine versions for all installs clearly isn't desirable.)

Adding Email - Breaks Login?

Email from TNRIS with potential bug.

"Gayla and I both noticed what may be a bug. This morning, each of us logged into the appliance. The message on the login page said to add our email address to our user profile. So, being the ever obedient people that we are, we complied and we each entered our email address.

The appliance reset to the login page and prompted us to login again. Upon doing so, our passwords no longer worked. So, we had to hit the "Forgot Password" link to reset our passwords.

We will refrain from adding emails to the system until we know what might be causing this issue."

is it working on windows ?

I can't npm install the wms package due to this error:

node-pre-gyp WARN Using request for node-pre-gyp https download
node-pre-gyp WARN Tried to download(403): https://mapbox-node-binary.s3.amazonaws.com/mapnik/v4.2.1/node-v57-win32-x64-Release.tar.gz
node-pre-gyp WARN Pre-built binaries not found for [email protected] and [email protected] (node-v57 ABI, unknown) (falling back to source compile with node-gyp)

I am using node v 8.15.0 cause I saw in another issue than the lts version of node is not supported yet.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.