Geospatial dataset picker via fast Api Rest interface written in NodeJs for GDAL bindings and Fastify
GeoPicker is essentially an advanced elevation service: given one or more lon,lat coordinates, it reads the corresponding pixel values (elevation or any other raster band) from the configured datasets (e.g. GeoTIFF DEMs) through GDAL, and returns them in the same shape the request came in.
It is designed to offer the widest possible range of request methods and input/output formats — coordinates in the URL, JSON objects, arrays of locations, GeoJSON geometries, encoded polylines, GPX — so that any client can integrate it without adapting its own data model. Endpoints and parameters follow the conventions of already existing elevation services, gathered here into a single complete and coherent API.
Beyond value picking, it provides supporting geometry functions: densify, simplify, precision rounding, contour lines and on-the-fly metadata (length, direction, centroid, bbox).
The index.html demo page exercises the whole API browser-side, using LeafletJs as basemap and jQuery.
- Large API Rest: ergonomic endpoints suitable for any type of use case
- Validation: full validation of endpoint and parameters via JSON-Schema which allows output optimization
- Configuration: friendly configs and to help devs in many deployment contexts
- Formats: support for different geospatial input and output formats
- Compression: configurable output compression if client accept encoding: deflate,gzip
and includes some other additional functions:
- Densify: add more interpolated points in input coordinates, this improves the display on an elevation graph, adding intermediate positions at a minimum fixed distance.
- Simplify: unlike densify it removes points that are too close together from coordinates.
- Precision: alter the coordinates precision digits to lossily reduce the size of a geometry.
- Height: add the vertical distance from the ground, if input has elevation add a fourth coordinate with this value.
- Metadata: get on the fly metadata informations for a geometry (ex. length, direction, bbox, centroid, middlepoint)
The API is work in progress.
This basic structure can be extended starting from the environment variable PREFIX which by default /
(✔️ Work ❌ TODO 🚧 Work in Progress)
| Status | Method | Path | Return | Description |
|---|---|---|---|---|
| ✔️ | GET | / | html | default demo map page if enabled by env var DEMO_PAGE=true |
| ✔️ | GET | /status | object | service status, versions, datasets |
| ✔️ | GET | /datasets | array | list available datasets and their attributes |
| ✔️ | GET | /datasets/:datasetId | object | search dataset by id |
| ✔️ | GET | /datasets/:lon/:lat | array | search dataset contains lon,lat |
| ✔️ | GET | /:datasetId | object | show attributes of a certain dataset by id |
| ✔️ | GET | /:datasetId/:lon/:lat | array | get single location value of dataset, densify not supported |
| ✔️ | GET | /:datasetId/:locations | array | locations is a string (format: `lon,lat |
| ✔️ | POST | /:datasetId/lonlat | arrays | accept array or object in body |
| ✔️ | POST | /:datasetId/locations | arrays | accept array or object of locations in body (format is [[lon,lat],[lon,lat],[lon,lat]]) |
| ✔️ | POST | /:datasetId/geometry | object | geojson Point or LineString in body (support feature/geometry/f.collection) |
| ✔️ | GET | /:datasetId/contour/:lon/:lat | object | get geojson LineString of contour line for a given location value |
| ✔️ | GET | /metadata/:locations | object | return info about direction, length, centroid, middlepoint of locations |
| ✔️ | POST | /metadata/geometry | object | return info about direction, length, centroid, middlepoint of geometry |
| Status | Parameter | Default | Description |
|---|---|---|---|
| ✔️ | precision | input |
rounded to digits decimal precision |
| ✔️ | format | input |
output format conversion |
| ✔️ | densify | input |
enable densification of points in the result |
| ✔️ | simplify | input |
enable simplication geometry of the result |
Some behaviors to know about parameters are that:
precisionanddensifyparameters is only supported by endpoints and formats that return coordinatesdatasetIdcan have the valuedefaultto referring the main dataset defined in config- from version v1.6.1
/<datasetId>/...is the same of/datasets/<datasetId>/.../datasets/is implicit.
If the format parameter is not specified the default behavior is to output the same format as the input
- input format can be specified by
Content-type:header in request - output format can be specified by
formatparameter
the support for various input and output formats is summarized in the table
| Value | In | Out | Description |
|---|---|---|---|
input |
✔️ | ✔️ | means the same format as the input data |
array |
✔️ | 🚧 | each location is Array and a Z dimension as value [lon,lat,val] |
json |
✔️ | 🚧 | each location is Object having lon,lat and val attributes |
geojson |
✔️ | 🚧 | standard GeoJSON objects Feature, Geometry with a Z dimension in coordinates as value |
polyline |
🚧 | ✔️ | Encoded Polyline Algorithm |
gpx |
🚧 | ✔️ | GPS eXchange Format is an XML textual format |
csv |
❌ | ❌ | Comma-separated values is an textual format |
kml |
❌ | ❌ | Keyhole Markup Language is an XML format for Google Earth |
each endpoint has its own default format, for example endpoint /dataset/lon/lat return a simple array of one value.
The repository has 4 npm packages, linked as npm workspaces from the root package.json:
lib/core logic defining utils and GDAL bindingscli/standalone CLI (cli/bin/geopicker) for dataset get/set, config validation and other side operations; declared as a dependency ofserver/and installed by npm as thegeopickercommandserver/a standard Fastify HTTP server defining routes, plugins and schemas for the API Rest endpointsbenchmark/HTTP benchmark script based on autocannon (not published), declaresserver/andcli/as its own dependencies; it generates its config and spawns the server by itself, run withnpm run benchmarkindex.htmldemo page with LeafletJs map that demostrates the usage of the API Rest endpoints
Other folders: docs/ extended documentation, tests/ sample datasets
Running by official Docker image:
docker run -v "/$(pwd)/tests/data:/data" -e DEMO_PAGE=true -p 8080:8080 stefcud/geopickerthen browse the demo page: http://localhost:8080/ (in production the server listens on port 8080, see prod: section in server/config.yml)
More details about the Docker image structure, docker-compose and custom deployments in docs docker
Running from source code in development mode, requirements: nodejs 18.x > , npm 8.x > and glibc 2.28 (Ubuntu 20.x > ):
npm install
npm run devnpm install at the repository root installs server/, cli/ and benchmark/ too, via npm workspaces.
Then browse the demo page (in dev mode the server listens on port 9090): http://localhost:9090/
Full configuration options can be found in docs config
A new config.yml file can be generated interactively with the CLI command geopicker config-generate [file], printing to stdout if file is omitted.
It can also run unattended with --yes (keep every default) and -p <dir> (dataset files directory), scanning that directory to fill the datasets section.
Command Line interface is useful for side management operations, for example inside docker container, and its config validation tool.
The geopicker command is installed by npm as bin of the cli/ workspace.
$ geopicker --help
$ geopicker config-validate custom.config.ymlThe geopicker command is also available inside the Docker container, for example:
docker exec <container> geopicker config-validate ./my/custom.config.yml
docker exec <container> geopicker -d /data/trentino-altoadige_dem_90m.tif -g "11.123,46.123"Full CLI options can be found in docs cli
Get single location exchanging a few bytes:
$ curl "http://localhost:9090/default/11.123/46.123"
[195]More request examples (POST body, locations, GeoJSON geometry, densify) are documented in docs/examples.md
To run from source in development mode: npm install then npm run dev (see Usage for requirements).
Contributor scripts and the release/publishing flow are documented in docs development
Benchmarks metrics, methodology and results are documented in docs/benchmarks.md
for details see the descriptions in the Roadmap issues
| Status | Goal |
|---|---|
| ✔️ | Swagger Documentation Interface |
| ✔️ | manage multiple datasets |
| ✔️ | command line interface |
| ✔️ | enable densify function |
| ✔️ | enable simply function |
| 🚧 | extend benchmarks for any endpoints |
| 🚧 | ES6 modules |
| ❌ | OGC API Features endpoint |
| ❌ | unit testing |
| ❌ | support vector format in datasets, such as shapefile |
| ❌ | limit access by api key |
| ❌ | caching responses |
| ❌ | interfaces: websocket, jsonrpc |
Created by Stefano Cudini @zakis Distributed under the BSD 2-Clause license.
