Home

Awesome

hastile

A Haskell tile server that produces GeoJSON or MVT (Mapbox Vector Tiles) from a PostGIS database.

Build Status

Getting Started

Running

Building

All

Install Haskell Stack:

Linux

MacOS

Build

Point the server at a PostgreSQL (9.6+) database with the PostGIS extension enabled. It will automatically render tables with a "wkb_geometry" column and serve them as layers.

For example:

Tiles will be available at: http://localhost:8080/table_name/z/x/y.mvt

A configuration file will be created automatically although not used (see running in Server mode below).

RESTful API

GET    /                          (application/json)                   - Returns the current configuration.
POST   /                          (application/json)                   - Add/overwite many layer configurations.
POST   /layername                 (application/json)                   - Add/overwrite a single layer configuration.
GET    /layername[.json]          (application/json)                   - Return TileJSON for a tile layer.
GET    /layername/Z/X/Y.<mvt|pbf> (application/vnd.mapbox-vector-tile) - Return Mapnik Vector Tile for given layername, Zoom, (X,Y).
GET    /layername/Z/X/Y.json      (application/json)                   - Return GeoJSON for given layername, Zoom, (X,Y).
GET    /token                     (application/json)                   - Returns tokens and authorised layers.
GET    /token/tokenid             (application/json)                   - Returns the authorised layers for the given token.
POST   /token                     (application/json)                   - A token and authorised layers to upsert the token database.
DELETE /token/tokenid             (application/json)                   - Delete the given token from the token database.

Layer API

The POST / with multiple layer configuration or POST /layername with a layer configuration allows you to change the layers that Hastile serves up and will save the configuration file to disk.

To create a new layer:

To modify an existing layer:

Payload

Example:

    "rail_network": {
      "security": "public",
      "table-name": "suburbanrail_hastile",
      "format": "wkb-properties",
      "minzoom": 0,
      "maxzoom": 20,
      "bounds": [ 144.94932174682617, -37.82449737924566, 144.97901916503906, -37.84788365473107 ],
      "format": "wkb-properties",
      "last-modified": "2018-10-31 09:09:39 +1000",
      "quantize": 4,
      "simplify": {
        "12": "douglas-peucker"
      }
    }
Attributes
layer-name<br/>stringThe unique key to the layer configuration

Layer Configuration

Attributes
security<br/>string"public" - allow anyone to request<br/>"private" - require a valid token (using ?token=xxxx).
table-name<br/>stringThe unique key to the layer.
format<br/>string"source" - a normal table<br/>"wkb-properties" - combination of JSON hash and wkb_geometry columns<br/>"geojson" - combination of GeoJSON, JSON hash of properties and wkb geomtry columns.
last-modified<br/>dateLast time the layer has been update, used to return the Last-Modified HTTP header.
quantize<br/>integerPositive integer, amount to round and remove duplicates (10 is probably the most, 1 is typical).
simplify<br/>mapA map of zoom levels to simplification settings.
minzoom<br/>int0..30 Minimum zoom level to render, otherwise returns 404. Adds setting to TileJSON.
maxzoom<br/>int0..30 Maximum zoom level to render, otherwise returns 404. Adds setting to TileJSON.
bounds<br/>array floatBounds are represented in WGS:84 latitude and longitude values. Adds settings to TileJSON.

Layer Simplification Settings

Attributes
zoom-level<br/>stringThe zoom level (>=) to apply the layer simplification algorithm.

Layer Simplification Algorithm

Attributes
algorithm-name<br/>string"douglas-peucker" - apply the Ramer-Douglas-Peucker algorithm (epsilon of 1.0).

Building

Building:

Server Mode

Server mode makes more features available:

Token Based Security

A token table is required for token security. This is required for "private" layers.

Setup the Token Database

Token API

To insert or update a token:

To delete a token:

Running in Server Mode

To run Hastile in server mode you must use a configuration file:

Configuration

The file contains settings for the database connection and layer configuration, for example:

{
  "db-connection": "host=example.com port=5432 user=tiler password=123abc dbname=notoracle"
  "layers": {
    "layer1": { 
      "table_name": "layer1_table",
      "format": "wkb-properties",
      "last-modified": "2017-01-15T23:49:36Z"
    },
    "layer2": {
      "table_name": "layer2_table",
      "format": "geojson",
      "last-modified": "2017-01-15T23:49:36Z"
    }
  }
}

Where, db-connection is a PostgreSQL connection string.

To construct a table with a GeoJSON feature with all properties containing arbitrary columns from a table, create a materialized view like:

CREATE MATERIALIZED VIEW layer1_table as SELECT jsonb_build_object(
    'type',      'Feature',
    'id',         ogc_fid,
    'geometry',   ST_AsGeoJSON(wkb_geometry)::jsonb,
    'properties', to_jsonb(row) - 'ogc_fid' - 'wkb_geometry'
)::json as geojson, (to_jsonb(row) - 'wkb_geometry') :: JSON as properties,row.wkb_geometry as wkb_geometry FROM (SELECT * FROM source_layer1_table) row;

This will create the two columns required: geojson (a GeoJSON feature in JSON format) and the geometry column.

You can configure other database, mapnik and HTTP port settings too:

{
  "db-pool-size": 10,
  "db-timeout": 5,
  "port": 8080
}

If you want to combine multiple tables into a single layer you can use UNION and MATERIALIZED VIEWS and then query it directly:

CREATE MATERIALIZED VIEW layers AS
  SELECT geojson FROM layer1_table
  UNION
  SELECT geojson FROM layer2_table

Changing the configuration to:

  "layers": {
    "layer": {
      ...
    }  
  }

Running

To start the server: ./hastile server --configFile FILEPATH

To run with GHC Metrics: ./hastile server --configFile FILEPATH +RTS -T

Documentation

Hastile docs are generated using mkdocs.

Preview docs locally by using mkdocs serve or mkdocs build. Then deploy to https://indicatrix.github.io/hastile using mkdocs gh-deploy. This command will deploy to the gh-pages branch as outlined here.

Projections

We assume tiles are requested in the spherical mercator (EPSG 3857 AKA EPSG 900913 AKA Webby McWebcator). Furthermore, map data is assumed to be stored in EPSG 4326.

Helpful links