2018-01-16 15:55:05 +03:00
# Martin
2017-10-09 14:29:03 +03:00
2018-10-05 17:58:06 +03:00
![CircleCI ](https://img.shields.io/circleci/project/github/urbica/martin.svg?style=popout )
2017-10-15 14:48:23 +03:00
2018-10-17 11:49:02 +03:00
Martin is a [PostGIS ](https://github.com/postgis/postgis ) [Mapbox Vector Tiles ](https://github.com/mapbox/vector-tile-spec ) server suitable for large databases. Martin is written in [Rust ](https://github.com/rust-lang/rust ) using [Actix ](https://github.com/actix/actix-web ) web framework.
2017-10-09 14:29:03 +03:00
2018-10-19 19:11:44 +03:00
![Martin ](https://raw.githubusercontent.com/urbica/martin/master/mart.png )
2017-10-09 14:29:03 +03:00
## Installation
2018-10-17 11:49:02 +03:00
You can download martin from [Github releases page ](https://github.com/urbica/martin/releases ).
2018-10-10 16:32:24 +03:00
2018-10-17 11:49:02 +03:00
If you are using macOS and [Homebrew ](https://brew.sh/ ) you can install martin using Homebrew tap.
2018-10-10 16:32:24 +03:00
```shell
2018-10-10 17:23:41 +03:00
brew tap urbica/tap
2018-10-10 16:32:24 +03:00
brew install martin
```
2017-10-09 14:29:03 +03:00
## Usage
2018-10-10 19:27:21 +03:00
Martin requires a database connection string. It can be passed as a command-line argument or as a `DATABASE_URL` environment variable.
2018-10-10 16:32:24 +03:00
```shell
martin postgres://postgres@localhost/db
```
2017-10-09 14:29:03 +03:00
2018-10-12 18:18:34 +03:00
## Table Sources
2018-10-17 11:49:02 +03:00
Table Source is a database table which can be used to query [vector tiles ](https://github.com/mapbox/vector-tile-spec ). When started, martin will go through all spatial tables in the database and build a list of table sources. A table should have at least one geometry column with non-zero SRID. All other table columns will be represented as properties of a vector tile feature.
2018-10-12 18:18:34 +03:00
2018-10-11 15:01:47 +03:00
### Table Sources List
Table Sources list endpoint is available at `/index.json`
```shell
curl localhost:3000/index.json
```
### Table Source TileJSON
2018-10-12 18:18:34 +03:00
Table Source [TileJSON ](https://github.com/mapbox/tilejson-spec ) endpoint is available at `/{schema_name}.{table_name}.json` .
2018-10-11 15:01:47 +03:00
For example, `points` table in `public` schema will be available at `/public.points.json`
```shell
curl localhost:3000/public.points.json
```
### Table Source tiles
Table Source tiles endpoint is available at `/{schema_name}.{table_name}/{z}/{x}/{y}.pbf`
For example, `points` table in `public` schema will be available at `/public.points/{z}/{x}/{y}.pbf`
```shell
curl localhost:3000/public.points/0/0/0.pbf
```
2018-10-12 18:18:34 +03:00
## Function Sources
2018-10-17 11:49:02 +03:00
Function Source is a database function which can be used to query [vector tiles ](https://github.com/mapbox/vector-tile-spec ). When started, martin will look for the functions with a suitable signature. A function that takes `z integer` , `x integer` , `y integer` , and `query_params json` and returns `bytea` , can be used as a Function Source.
2018-10-12 18:18:34 +03:00
| Argument | Type | Description |
|--------------|---------|-------------------------|
| z | integer | Tile zoom parameter |
| x | integer | Tile x parameter |
| y | integer | Tile y parameter |
| query_params | json | Query string parameters |
**Hint**: You may want to use [TileBBox ](https://github.com/mapbox/postgis-vt-util#tilebbox ) function to generate bounding-box geometry of the area covered by a tile.
2018-10-17 11:49:02 +03:00
Here is an example of a function that can be used as a Function Source.
2018-10-12 18:18:34 +03:00
```plsql
CREATE OR REPLACE FUNCTION public.function_source(z integer, x integer, y integer, query_params json) RETURNS bytea AS $$
DECLARE
bounds geometry;
mvt bytea;
BEGIN
SELECT INTO bounds TileBBox(z, x, y, 3857);
SELECT INTO mvt ST_AsMVT(tile, 'public.function_source', 4096, 'geom') FROM (
SELECT
ST_AsMVTGeom(geom, bounds, 4096, 64, true) AS geom
FROM public.table_source
WHERE geom & & bounds
) as tile WHERE geom IS NOT NULL;
RETURN mvt;
END
$$ LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE;
```
2018-10-11 15:01:47 +03:00
### Function Sources List
Function Sources list endpoint is available at `/rpc/index.json`
```shell
curl localhost:3000/rpc/index.json
```
### Function Source TileJSON
2018-10-12 18:18:34 +03:00
Function Source [TileJSON ](https://github.com/mapbox/tilejson-spec ) endpoint is available at `/rpc/{schema_name}.{function_name}.json`
2018-10-11 15:01:47 +03:00
For example, `points` function in `public` schema will be available at `/rpc/public.points.json`
```shell
curl localhost:3000/rpc/public.points.json
```
2018-10-17 11:49:02 +03:00
### Function Source Tiles
2018-10-11 15:01:47 +03:00
Function Source tiles endpoint is available at `/rpc/{schema_name}.{function_name}/{z}/{x}/{y}.pbf`
For example, `points` function in `public` schema will be available at `/rpc/public.points/{z}/{x}/{y}.pbf`
```shell
curl localhost:3000/rpc/public.points/0/0/0.pbf
```
2018-10-17 11:49:02 +03:00
## Configuration File
2018-10-12 18:18:34 +03:00
2018-10-17 11:49:02 +03:00
If you don't want to expose all of your tables and functions, you can list your sources in a configuration file. To start martin with a configuration file you need to pass a file name with a `--config` argument.
2018-10-12 18:18:34 +03:00
```shell
martin --config config.yaml
```
2018-10-17 11:49:02 +03:00
You can find an example of a configuration file [here ](https://github.com/urbica/martin/blob/master/tests/config.yaml ).
2018-10-12 18:18:34 +03:00
2018-10-17 11:49:02 +03:00
## Using Martin with Mapbox GL JS
2018-10-11 15:01:47 +03:00
[Mapbox GL JS ](https://github.com/mapbox/mapbox-gl-js ) is a JavaScript library for interactive, customizable vector maps on the web. It takes map styles that conform to the
[Mapbox Style Specification ](https://www.mapbox.com/mapbox-gl-js/style-spec ), applies them to vector tiles that
conform to the [Mapbox Vector Tile Specification ](https://github.com/mapbox/vector-tile-spec ), and renders them using
WebGL.
2018-10-17 11:49:02 +03:00
You can add a layer to the map and specify martin TileJSON endpoint as a vector source URL. You should also specify a `source-layer` property. For Table Sources it is `{schema_name}.{table_name}` by default.
2018-10-11 15:01:47 +03:00
```js
map.addLayer({
"id": "public.points",
"type": "circle",
"source": {
"type": "vector",
"url": "http://localhost:3000/public.points.json",
},
"source-layer": "public.points"
});
```
2018-10-17 11:49:02 +03:00
## Command-line Interface
2018-10-11 15:01:47 +03:00
You can configure martin using command-line interface
2018-10-10 19:27:21 +03:00
```shell
Usage:
martin [options] [< connection > ]
martin -h | --help
martin -v | --version
Options:
-h --help Show this screen.
-v --version Show version.
--workers=< n > Number of web server workers.
--pool_size=< n > Maximum connections pool size [default: 20].
--keep_alive=< n > Connection keep alive timeout [default: 75].
--listen_addresses=< n > The socket address to bind [default: 0.0.0.0:3000].
--config=< path > Path to config file.
```
2018-10-17 11:49:02 +03:00
## Environment Variables
2018-03-27 14:40:33 +03:00
2018-10-11 15:01:47 +03:00
You can also configure martin using environment variables
2018-10-10 16:32:24 +03:00
| Environment variable | Example | Description |
|----------------------|----------------------------------|-------------------------------|
| DATABASE_URL | postgres://postgres@localhost/db | postgres database connection |
| DATABASE_POOL_SIZE | 20 | maximum connections pool size |
| WORKER_PROCESSES | 8 | number of web server workers |
| KEEP_ALIVE | 75 | connection keep alive timeout |
2018-03-27 14:40:33 +03:00
2017-10-09 14:29:03 +03:00
## Using with Docker
2018-10-10 16:32:24 +03:00
You can use official Docker image `urbica/martin`
```shell
docker run \
-p 3000:3000 \
-e DATABASE_URL=postgres://postgres@localhost/db \
urbica/martin
```
2018-10-17 11:49:02 +03:00
## Building from Source
2018-10-10 16:32:24 +03:00
2018-10-17 11:49:02 +03:00
You can clone the repository and build martin using [cargo ](https://doc.rust-lang.org/cargo ) package manager.
2018-10-10 16:32:24 +03:00
```shell
git clone git@github.com:urbica/martin.git
cd martin
cargo build --release
```
2018-10-17 11:49:02 +03:00
The binary will be available at `./target/release/martin` .
2018-10-01 20:10:33 +03:00
2018-10-10 16:32:24 +03:00
```shell
2018-10-10 19:27:21 +03:00
cd ./target/release/
./martin postgres://postgres@localhost/db
2018-10-10 16:32:24 +03:00
```
2017-10-09 14:29:03 +03:00
## Development
2018-10-17 11:49:02 +03:00
Install project dependencies and check if all the tests are running.
2017-10-09 14:29:03 +03:00
2018-10-10 16:32:24 +03:00
```shell
cargo test
cargo run
2018-10-17 11:49:02 +03:00
```