├── tests
├── __init__.py
├── python
│ ├── __init__.py
│ ├── README.md
│ ├── test_import_wikidata.py
│ ├── test_helpers.py
│ └── test_utils.py
├── expected
│ ├── monaco2.bbox
│ ├── monaco.bbox
│ ├── parallel_sql
│ │ ├── run_last.sql
│ │ ├── run_first.sql
│ │ └── parallel
│ │ │ ├── mountain_peak.sql
│ │ │ ├── housenumber.sql
│ │ │ └── enumfield.sql
│ ├── parallel_sql2
│ │ ├── run_last.sql
│ │ ├── run_first.sql
│ │ └── parallel
│ │ │ ├── mountain_peak.sql
│ │ │ ├── housenumber.sql
│ │ │ └── enumfield.sql
│ ├── devdoc
│ │ ├── enumfield
│ │ │ ├── etl_diagram
│ │ │ ├── mapping_diagram
│ │ │ ├── etl_diagram.png
│ │ │ ├── mapping_diagram.png
│ │ │ ├── etl_diagram.svg
│ │ │ └── mapping_diagram.svg
│ │ ├── mountain_peak
│ │ │ ├── etl_diagram
│ │ │ ├── etl_diagram.png
│ │ │ ├── mapping_diagram.png
│ │ │ ├── mapping_diagram
│ │ │ ├── etl_diagram.svg
│ │ │ └── mapping_diagram.svg
│ │ ├── etl_housenumber.png
│ │ ├── mapping_diagram.png
│ │ ├── housenumber
│ │ │ ├── etl_diagram.png
│ │ │ ├── mapping_diagram.png
│ │ │ ├── etl_diagram
│ │ │ ├── mapping_diagram
│ │ │ ├── mapping_diagram.svg
│ │ │ └── etl_diagram.svg
│ │ ├── etl_housenumber
│ │ ├── mapping_diagram
│ │ ├── mapping_diagram.svg
│ │ └── etl_housenumber.svg
│ ├── monaco-cfg.json
│ ├── LabelGrid.sql.out
│ ├── LineLabel.sql.out
│ ├── ZRes.sql.out
│ ├── Z.sql.out
│ ├── sqlquery.sql
│ ├── doc.md
│ ├── omt_is_latin.sql.out
│ ├── delete_empty_keys.sql.out
│ ├── omt_as_numeric.sql.out
│ ├── debug_mvt_STDIN_dump_summary.out
│ ├── debug_mvt_dump_summary.out
│ ├── debug_mvt_URL_dump_summary.out
│ ├── debug_mvt_dump_summary_show_names.out
│ ├── ToPoint.sql.out
│ ├── TileBBox.sql.out
│ ├── mvttile_query_v2.5.sql
│ ├── imposm3.yaml
│ ├── mvttile_query_no_feat_ids.sql
│ ├── mvttile_query.sql
│ ├── mvttile_query_v3.0.sql
│ ├── mvttile_query_gzip.sql
│ ├── mvttile_query_gzip9.sql
│ ├── mvttile_query_v2.4.8.sql
│ ├── mvttile_query_v2.4.0dev-a.sql
│ ├── mvttile_query_v2.4.0dev.sql
│ ├── mvttile_query_v2.4.8-a.sql
│ ├── mvttile_psql.sql
│ ├── mvttile_func.sql
│ ├── mvttile_func_key.sql
│ ├── mvttile_prep.sql
│ ├── mvttile_query_test_geom.sql
│ ├── mvttile_query_test_geom_key.sql
│ ├── CleanNumeric.sql.out
│ ├── debug_mvt_dump.out
│ ├── debug_mvt_dump_show_names.out
│ ├── debug_mvt_dump_show_names_sorted.out
│ ├── tm2source.yml
│ ├── tm2source2.yml
│ └── tm2source3.yml
├── http
│ ├── monaco-20150428.osm.pbf.md5
│ ├── empty.mbtiles
│ ├── osm_13_4388_2568.mvt
│ └── monaco-20150428.osm.pbf
├── sql
│ ├── test.env
│ ├── LabelGrid.sql
│ ├── Z.sql
│ ├── ZRes.sql
│ ├── README.md
│ ├── LineLabel.sql
│ ├── TileBBox.sql
│ ├── docker-compose.yml
│ ├── omt_as_numeric.sql
│ ├── delete_empty_keys.sql
│ ├── omt_is_latin.sql
│ ├── ToPoint.sql
│ └── CleanNumeric.sql
├── testlayers
│ ├── housenumber
│ │ ├── housenumber_centroid.sql
│ │ ├── mapping.yaml
│ │ ├── layer.sql
│ │ └── housenumber.yaml
│ ├── enumfield
│ │ ├── enumfield.sql
│ │ └── enumfield.yaml
│ ├── mountain_peak
│ │ ├── mapping.yaml
│ │ └── mountain_peak.yaml
│ └── testmaptiles.yaml
└── cache
│ ├── Bbbike.json
│ └── Geofabrik.json
├── openmaptiles
├── __init__.py
├── sqlite_utils.py
├── tmsource.py
├── vector_tile.py
├── imposm.py
├── styleutils.py
└── vector_tile.proto
├── .flake8
├── docs
├── test-perf.png
├── README.md
├── LocalDocker.md
└── gcp_test_startup.sh
├── bin
├── config
│ └── repl_config.json
├── generate-imposm3
├── psql.sh
├── pgwait
├── import-update
├── import-diff
├── generate-doc
├── generate-sqlquery
├── generate-mapping-graph
├── style-tools
├── generate-etlgraph
├── tile_multiplier
├── generate-tm2source
├── generate-sql
├── import-osm
├── import-sql
├── postserve
└── generate-sqltomvt
├── sql
├── Makefile
├── zzz_omt_as_numeric.sql
├── CleanNumeric.sql
├── Z.sql
├── LineLabel.sql
├── ZRes.sql
├── TileBBox.sql
├── ToPoint.sql
├── LabelGrid.sql
└── LICENSE.md
├── docker
├── generate-vectortiles
│ ├── Dockerfile
│ ├── export-list.sh
│ ├── README.md
│ ├── export-local.sh
│ ├── LICENSE
│ └── utils.sh
├── postgis-preloaded
│ ├── README.md
│ ├── preload-database.sh
│ ├── LICENSE
│ └── Dockerfile
├── import-data
│ ├── LICENSE
│ ├── README.md
│ ├── Dockerfile
│ ├── clean-natural-earth.sh
│ └── import_data.sh
└── postgis
│ ├── README.md
│ ├── initdb-postgis.sh
│ └── Dockerfile
├── requirements.txt
├── docker-run.sh
├── .github
└── workflows
│ └── pull_request.yml
├── LICENSE
├── setup.py
├── .gitignore
└── .dockerignore
/tests/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/python/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/openmaptiles/__init__.py:
--------------------------------------------------------------------------------
1 | __version__ = '0.0.0'
2 |
--------------------------------------------------------------------------------
/tests/expected/monaco2.bbox:
--------------------------------------------------------------------------------
1 | 7.409205,43.72335,7.448637,43.75169
2 |
--------------------------------------------------------------------------------
/tests/expected/monaco.bbox:
--------------------------------------------------------------------------------
1 | 7.3830115,43.516333,7.500333,43.7543525
2 |
--------------------------------------------------------------------------------
/.flake8:
--------------------------------------------------------------------------------
1 | [flake8]
2 | # do not warn for line length > 80
3 | ignore = E501,W503
4 |
--------------------------------------------------------------------------------
/tests/expected/parallel_sql/run_last.sql:
--------------------------------------------------------------------------------
1 | -- This SQL code should be executed last
2 |
--------------------------------------------------------------------------------
/tests/expected/parallel_sql2/run_last.sql:
--------------------------------------------------------------------------------
1 | -- This SQL code should be executed last
2 |
--------------------------------------------------------------------------------
/tests/expected/devdoc/enumfield/etl_diagram:
--------------------------------------------------------------------------------
1 | digraph G {
2 | graph [rankdir=LR]
3 | }
4 |
--------------------------------------------------------------------------------
/docs/test-perf.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openmaptiles/openmaptiles-tools/HEAD/docs/test-perf.png
--------------------------------------------------------------------------------
/tests/http/monaco-20150428.osm.pbf.md5:
--------------------------------------------------------------------------------
1 | caf8ad16c7c3a0bdfa78780832745457 monaco-20150428.osm.pbf
2 |
--------------------------------------------------------------------------------
/tests/expected/devdoc/enumfield/mapping_diagram:
--------------------------------------------------------------------------------
1 | digraph "Imposm Mapping" {
2 | graph [rankdir=LR ranksep=3]
3 | }
4 |
--------------------------------------------------------------------------------
/tests/http/empty.mbtiles:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openmaptiles/openmaptiles-tools/HEAD/tests/http/empty.mbtiles
--------------------------------------------------------------------------------
/tests/expected/devdoc/mountain_peak/etl_diagram:
--------------------------------------------------------------------------------
1 | digraph G {
2 | graph [rankdir=LR]
3 | imposm3 -> osm_peak_point
4 | }
5 |
--------------------------------------------------------------------------------
/tests/http/osm_13_4388_2568.mvt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openmaptiles/openmaptiles-tools/HEAD/tests/http/osm_13_4388_2568.mvt
--------------------------------------------------------------------------------
/tests/http/monaco-20150428.osm.pbf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openmaptiles/openmaptiles-tools/HEAD/tests/http/monaco-20150428.osm.pbf
--------------------------------------------------------------------------------
/tests/expected/devdoc/etl_housenumber.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openmaptiles/openmaptiles-tools/HEAD/tests/expected/devdoc/etl_housenumber.png
--------------------------------------------------------------------------------
/tests/expected/devdoc/mapping_diagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openmaptiles/openmaptiles-tools/HEAD/tests/expected/devdoc/mapping_diagram.png
--------------------------------------------------------------------------------
/bin/config/repl_config.json:
--------------------------------------------------------------------------------
1 | {
2 | "replication_url": "http://planet.openstreetmap.org/replication/day/",
3 | "replication_interval": "24h"
4 | }
5 |
--------------------------------------------------------------------------------
/tests/expected/devdoc/enumfield/etl_diagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openmaptiles/openmaptiles-tools/HEAD/tests/expected/devdoc/enumfield/etl_diagram.png
--------------------------------------------------------------------------------
/tests/expected/monaco-cfg.json:
--------------------------------------------------------------------------------
1 | {
2 | "foo": "bar",
3 | "replication_interval": "4h",
4 | "replication_url": "http://localhost:8555/fake-updates/"
5 | }
6 |
--------------------------------------------------------------------------------
/tests/sql/test.env:
--------------------------------------------------------------------------------
1 | POSTGRES_DB=openmaptiles
2 | POSTGRES_USER=openmaptiles
3 | POSTGRES_PASSWORD=openmaptiles
4 | POSTGRES_HOST=postgres
5 | POSTGRES_PORT=5432
6 |
--------------------------------------------------------------------------------
/tests/expected/devdoc/housenumber/etl_diagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openmaptiles/openmaptiles-tools/HEAD/tests/expected/devdoc/housenumber/etl_diagram.png
--------------------------------------------------------------------------------
/tests/expected/devdoc/enumfield/mapping_diagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openmaptiles/openmaptiles-tools/HEAD/tests/expected/devdoc/enumfield/mapping_diagram.png
--------------------------------------------------------------------------------
/tests/expected/devdoc/housenumber/mapping_diagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openmaptiles/openmaptiles-tools/HEAD/tests/expected/devdoc/housenumber/mapping_diagram.png
--------------------------------------------------------------------------------
/tests/expected/devdoc/mountain_peak/etl_diagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openmaptiles/openmaptiles-tools/HEAD/tests/expected/devdoc/mountain_peak/etl_diagram.png
--------------------------------------------------------------------------------
/tests/sql/LabelGrid.sql:
--------------------------------------------------------------------------------
1 | -- LabelGrid
2 | SELECT LabelGrid(ST_GeomFromText('POINT(100 -100)',900913), 64*9.5546285343) AS v1; -- POINT(305.7481130976 -305.7481130976)
3 |
--------------------------------------------------------------------------------
/tests/expected/devdoc/mountain_peak/mapping_diagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openmaptiles/openmaptiles-tools/HEAD/tests/expected/devdoc/mountain_peak/mapping_diagram.png
--------------------------------------------------------------------------------
/tests/expected/LabelGrid.sql.out:
--------------------------------------------------------------------------------
1 | v1
2 | ---------------------------------------
3 | POINT(305.7481130976 -305.7481130976)
4 | (1 row)
5 |
6 |
--------------------------------------------------------------------------------
/tests/expected/LineLabel.sql.out:
--------------------------------------------------------------------------------
1 | t_v1
2 | ------
3 | t
4 | (1 row)
5 |
6 | f_v2
7 | ------
8 | f
9 | (1 row)
10 |
11 | t_v3
12 | ------
13 | t
14 | (1 row)
15 |
16 |
--------------------------------------------------------------------------------
/sql/Makefile:
--------------------------------------------------------------------------------
1 | .PHONY: README.md
2 | README.md:
3 | sed -n -i'' -e '1,/
6 |
7 |
14 |
--------------------------------------------------------------------------------
/sql/CleanNumeric.sql:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | ### CleanNumeric ###
3 |
4 | Returns the input text as an numeric if possible, otherwise null.
5 |
6 | __Parameters:__
7 |
8 | - `text` i - Text that you would like as an numeric.
9 |
10 | __Returns:__ `numeric`
11 | ******************************************************************************/
12 | create or replace function CleanNumeric (i text) returns numeric as
13 | $body$
14 | SELECT substring(i from '^\s*([-+]?(?=\d|\.\d)\d*(?:\.\d*)?(?:[Ee][-+]?\d+)?)\s*$')::numeric;
15 | $body$
16 | language sql
17 | strict immutable cost 20
18 | parallel safe;
19 |
--------------------------------------------------------------------------------
/tests/expected/devdoc/enumfield/mapping_diagram.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
14 |
--------------------------------------------------------------------------------
/tests/sql/delete_empty_keys.sql:
--------------------------------------------------------------------------------
1 | -- delete_empty_keys
2 | SELECT delete_empty_keys(NULL) AS v1_null;
3 | SELECT delete_empty_keys(''::hstore) AS v2_null;
4 | SELECT delete_empty_keys('"empty"=>""'::hstore) AS v3_null;
5 | SELECT delete_empty_keys('"foo"=>"bar"'::hstore) AS v4;
6 | SELECT delete_empty_keys('"foo"=>"bar", "empty"=>""'::hstore) AS v5;
7 | SELECT delete_empty_keys('"foo"=>"bar", "empty"=>"", "xx"=>"zz"'::hstore) AS v6;
8 | SELECT delete_empty_keys('"empty"=>"", "foo"=>"bar"'::hstore) AS v7;
9 | SELECT delete_empty_keys('""=>"empty_key"'::hstore) AS v8;
10 | SELECT delete_empty_keys('"nil"=>NULL, "foo"=>"bar"'::hstore) AS v9;
11 | SELECT delete_empty_keys('"nil"=>NULL'::hstore) AS v10_null;
12 |
--------------------------------------------------------------------------------
/tests/testlayers/housenumber/mapping.yaml:
--------------------------------------------------------------------------------
1 | tags:
2 | include:
3 | - access
4 |
5 | tables:
6 |
7 | # --- test that duplicate items are removed
8 | # etldoc: imposm3 -> osm_housenumber_point
9 | # etldoc: imposm3 -> osm_housenumber_point
10 | housenumber_point:
11 | type: geometry
12 | fields:
13 | - name: osm_id
14 | type: id
15 | - name: geometry
16 | type: geometry
17 | - name: housenumber
18 | key: addr:housenumber
19 | type: string
20 | - name: tags
21 | type: hstore_tags
22 | type_mappings:
23 | points:
24 | addr:housenumber:
25 | - __any__
26 | polygons:
27 | addr:housenumber:
28 | - __any__
29 |
--------------------------------------------------------------------------------
/tests/testlayers/mountain_peak/mapping.yaml:
--------------------------------------------------------------------------------
1 | tables:
2 |
3 | # etldoc: imposm3 -> osm_peak_point
4 | peak_point:
5 | type: point
6 | columns:
7 | - name: osm_id
8 | type: id
9 | - name: geometry
10 | type: geometry
11 | - name: name
12 | key: name
13 | type: string
14 | - name: name_en
15 | key: name:en
16 | type: string
17 | - name: name_de
18 | key: name:de
19 | type: string
20 | - name: tags
21 | type: hstore_tags
22 | - name: ele
23 | key: ele
24 | type: string
25 | - name: wikipedia
26 | key: wikipedia
27 | type: string
28 | mapping:
29 | natural:
30 | - peak
31 | - volcano
32 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | ## This list is also used by setup.py - install_requires
2 | ## But there it removes all version restrictions
3 | ## To upgrade this list, run
4 | ## make build-docker
5 | ## make bash
6 | ## pip install pip-upgrader
7 | ## /home/openmaptiles/.local/bin/pip-upgrade --skip-virtualenv-check
8 | ## choose all if asked
9 | ## this file should now be updated
10 | aiohttp==3.12.14
11 | ascii_graph==1.5.1
12 | asyncpg==0.25.0
13 | beautifulsoup4==4.10.0
14 | betterproto==1.2.5
15 | dataclasses-json==0.5.6
16 | deprecated==1.2.13
17 | docopt-ng==0.7.2
18 | flake8==4.0.1
19 | flake8-quotes==3.3.1
20 | graphviz==0.19.1
21 | psycopg2-binary==2.9.3
22 | pyyaml==6.0
23 | requests==2.32.4
24 | tabulate==0.8.9
25 | tornado==6.5
26 |
--------------------------------------------------------------------------------
/tests/expected/delete_empty_keys.sql.out:
--------------------------------------------------------------------------------
1 | v1_null
2 | ---------
3 |
4 | (1 row)
5 |
6 | v2_null
7 | ---------
8 |
9 | (1 row)
10 |
11 | v3_null
12 | ---------
13 |
14 | (1 row)
15 |
16 | v4
17 | --------------
18 | "foo"=>"bar"
19 | (1 row)
20 |
21 | v5
22 | --------------
23 | "foo"=>"bar"
24 | (1 row)
25 |
26 | v6
27 | --------------------------
28 | "xx"=>"zz", "foo"=>"bar"
29 | (1 row)
30 |
31 | v7
32 | --------------
33 | "foo"=>"bar"
34 | (1 row)
35 |
36 | v8
37 | -----------------
38 | ""=>"empty_key"
39 | (1 row)
40 |
41 | v9
42 | --------------
43 | "foo"=>"bar"
44 | (1 row)
45 |
46 | v10_null
47 | ----------
48 |
49 | (1 row)
50 |
51 |
--------------------------------------------------------------------------------
/tests/sql/omt_is_latin.sql:
--------------------------------------------------------------------------------
1 | SELECT omt_is_latin('') as empty_str;
2 | SELECT omt_is_latin(' ') as space;
3 | SELECT omt_is_latin('abc_xyz') as abc_xyz;
4 | SELECT omt_is_latin('ABC_XYZ') as ABC_XYZ;
5 | SELECT omt_is_latin('0123456789') as digits;
6 |
7 | -- Extended Latin from https://en.wikipedia.org/wiki/Latin_Extended_Additional#Compact_table
8 | SELECT omt_is_latin('ḀḁḂḃḄḅḆḇḈḉḊḋḌḍḎḏḐḑḒḓḔḕḖḗḘḙḚḛḜḝḞḟḠḡḢḣḤḥḦḧḨḩḪḫḬḭḮḯḰḱḲḳḴḵḶḷḸḹḺḻḼḽḾḿṀṁṂṃṄṅṆṇṈṉṊṋṌṍṎṏṐṑṒṓṔṕṖṗṘṙṚṛṜṝṞṟṠṡṢṣṤṥṦṧṨṩṪṫṬṭṮṯṰṱṲṳṴṵṶṷṸṹṺṻṼṽṾṿẀẁẂẃẄẅẆẇẈẉẊẋẌẍẎẏẐẑẒẓẔẕẖẗẘẙẚẛẜẝẞẟẠạẢảẤấẦầẨẩẪẫẬậẮắẰằẲẳẴẵẶặẸẹẺẻẼẽẾếỀềỂểỄễỆệỈỉỊịỌọỎỏỐốỒồỔổỖỗỘộỚớỜờỞởỠỡỢợỤụỦủỨứỪừỬửỮữỰựỲỳỴỵỶỷỸỹỺỻỼỽỾỿ') as ext_latin;
9 |
10 | -- Russian
11 | SELECT omt_is_latin('привет') as russian_lc;
12 | SELECT omt_is_latin('ПРИВЕТ') as russian_uc;
13 |
--------------------------------------------------------------------------------
/docker-run.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | set -e
3 |
4 | # Get package version from the openmaptiles/__init__.py
5 | : "${VERSION:=$(grep '__version__' "$(dirname "$0")/openmaptiles/__init__.py" | sed -E 's/^(.*"([^"]+)".*|.*)$/\2/')}"
6 | : "${IMAGE_NAME:=openmaptiles/openmaptiles-tools}"
7 | : "${DOCKER_IMAGE:=${IMAGE_NAME}:${VERSION}}"
8 | : "${DOCKER_USER:=$(id -u "${USER}"):$(id -g "${USER}")}"
9 |
10 | # Current dir is shared with the docker, allowing scripts to write to the dir as a current user
11 | : "${WORKDIR:="$( pwd -P )"}"
12 |
13 | if [[ -t 1 ]]; then
14 | # Running in a terminal
15 | : "${DOCKER_OPTS:="-it --rm"}"
16 | else
17 | : "${DOCKER_OPTS:="--rm"}"
18 | fi
19 |
20 | set -x
21 | docker run ${DOCKER_OPTS} -u "${DOCKER_USER}" -v "${WORKDIR}:/tileset" "${DOCKER_IMAGE}" "$@"
22 |
--------------------------------------------------------------------------------
/bin/psql.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # Start psql command !
4 |
5 | set -o errexit
6 | set -o pipefail
7 | set -o nounset
8 |
9 | # wait for Postgres. On error, this script will exit too
10 | SOURCE_DIR="$(dirname "$(readlink -f "$0")")"
11 | # shellcheck source=./pgwait
12 | source "$SOURCE_DIR/pgwait"
13 |
14 | # For backward compatibility, allow both PG* and POSTGRES_* forms,
15 | # with the non-standard POSTGRES_* form taking precedence.
16 | # An error will be raised if neither form is given, except for the PGPORT
17 | export PGHOST="${POSTGRES_HOST:-${PGHOST?}}"
18 | export PGDATABASE="${POSTGRES_DB:-${PGDATABASE?}}"
19 | export PGUSER="${POSTGRES_USER:-${PGUSER?}}"
20 | export PGPASSWORD="${POSTGRES_PASSWORD:-${PGPASSWORD?}}"
21 | export PGPORT="${POSTGRES_PORT:-${PGPORT:-5432}}"
22 |
23 | psql "$@"
24 |
--------------------------------------------------------------------------------
/tests/testlayers/testmaptiles.yaml:
--------------------------------------------------------------------------------
1 | tileset:
2 | layers:
3 | - housenumber/housenumber.yaml
4 | - enumfield/enumfield.yaml
5 | - mountain_peak/mountain_peak.yaml
6 | name: TestMapTiles v1.0
7 | version: 1.1.1
8 | id: testmaptiles
9 | description: "Simple tileset for testing."
10 | attribution: "© OpenStreetMap contributors"
11 | center: [-12.2168, 28.6135, 4]
12 | bounds: [-180.0,-85.0511,180.0,85.0511]
13 | maxzoom: 10
14 | minzoom: 0
15 | pixel_scale: 256
16 | languages:
17 | - en
18 | - de
19 | - cs
20 | defaults:
21 | srs: +proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over
22 | datasource:
23 | srid: 900913
24 |
--------------------------------------------------------------------------------
/docker/generate-vectortiles/export-list.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | set -o errexit
3 | set -o pipefail
4 | set -o nounset
5 |
6 | source utils.sh
7 |
8 | readonly LIST_FILE="$EXPORT_DIR/tiles.txt"
9 | readonly TILE_TIMEOUT=${TILE_TIMEOUT:-1800000}
10 |
11 | function export_local_mbtiles() {
12 | local mbtiles_name="tiles.mbtiles"
13 |
14 | if [ ! -f "$LIST_FILE" ]; then
15 | echo "List file "$LIST_FILE" does not exist"
16 | exit 500
17 | fi
18 |
19 | exec tilelive-copy \
20 | --scheme="list" \
21 | --list="$LIST_FILE" \
22 | --timeout="$TILE_TIMEOUT" \
23 | "tmsource://$DEST_PROJECT_DIR" "mbtiles://$EXPORT_DIR/$mbtiles_name"
24 | }
25 |
26 | function main() {
27 | copy_source_project
28 | cleanup_dest_project
29 | replace_db_connection
30 | export_local_mbtiles
31 | }
32 |
33 | main
34 |
--------------------------------------------------------------------------------
/tests/testlayers/housenumber/layer.sql:
--------------------------------------------------------------------------------
1 |
2 | -- etldoc: layer_housenumber[shape=record fillcolor=lightpink, style="rounded,filled",
3 | -- etldoc: label="layer_housenumber | z14_" ] ;
4 |
5 | CREATE OR REPLACE FUNCTION layer_housenumber(bbox geometry, zoom_level integer)
6 | RETURNS TABLE(osm_id bigint, geometry geometry, housenumber text, tags hstore) AS $$
7 | -- etldoc: osm_housenumber_point -> layer_housenumber:z14_
8 | SELECT osm_id, geometry, housenumber, tags FROM osm_housenumber_point
9 | WHERE zoom_level >= 14 AND geometry && bbox;
10 | $$ LANGUAGE SQL IMMUTABLE;
11 |
12 |
13 | DROP MATERIALIZED VIEW IF EXISTS layer_housenumber_gen1 CASCADE;
14 | CREATE MATERIALIZED VIEW layer_housenumber_gen1 AS (
15 | SELECT ST_Simplify(geometry, 10) AS geometry, osm_id, housenumber
16 | FROM osm_housenumber_point
17 | ) /* DELAY_MATERIALIZED_VIEW_CREATION */ ;
18 |
--------------------------------------------------------------------------------
/tests/expected/omt_as_numeric.sql.out:
--------------------------------------------------------------------------------
1 | fail_null
2 | -----------
3 | -1
4 | (1 row)
5 |
6 | fail_dot
7 | ----------
8 | -1
9 | (1 row)
10 |
11 | fail_prefixed_letter
12 | ----------------------
13 | -1
14 | (1 row)
15 |
16 | fail_postfixed_letter
17 | -----------------------
18 | -1
19 | (1 row)
20 |
21 | fail_text
22 | -----------
23 | -1
24 | (1 row)
25 |
26 | ok_big_positive
27 | -----------------
28 | 9999999999
29 | (1 row)
30 |
31 | ok_big_negative
32 | -----------------
33 | -9999999999
34 | (1 row)
35 |
36 | ok_integer
37 | ------------
38 | 123
39 | (1 row)
40 |
41 | ok_float
42 | ----------
43 | 123.456
44 | (1 row)
45 |
46 | ok_float_trim
47 | ---------------
48 | 123.456
49 | (1 row)
50 |
51 | ok_e_notation
52 | ---------------
53 | 45678.9
54 | (1 row)
55 |
56 |
--------------------------------------------------------------------------------
/docker/postgis-preloaded/preload-database.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | set -Eeo pipefail
3 |
4 | # This code was adapted from a postgres issue
5 | # https://github.com/docker-library/postgres/issues/661#issuecomment-573192715
6 |
7 | source "$(command -v docker-entrypoint.sh)"
8 |
9 | docker_setup_env
10 | docker_create_db_directories
11 |
12 | docker_verify_minimum_env
13 | docker_init_database_dir
14 | pg_setup_hba_conf
15 |
16 | # only required for '--auth[-local]=md5' on POSTGRES_INITDB_ARGS
17 | export PGPASSWORD="${PGPASSWORD:-$POSTGRES_PASSWORD}"
18 |
19 | # Support for the import scripts from other docker containers
20 | # Override PGCONN so that ogr2ogr would connect via socket rather than TCP
21 | export PGCONN="dbname=$POSTGRES_DB user=$POSTGRES_USER password=$PGPASSWORD"
22 |
23 | docker_temp_server_start -c autovacuum=off
24 | docker_setup_db
25 | docker_process_init_files /docker-entrypoint-initdb.d/*
26 | docker_temp_server_stop
27 |
--------------------------------------------------------------------------------
/tests/expected/debug_mvt_STDIN_dump_summary.out:
--------------------------------------------------------------------------------
1 | Tile from STDIN size=2,222 bytes, gzipped=1,248 bytes, 3 layers
2 | Layer Extent Ver Features GeoType GeoSize AVG GeoSize Fields (percentage only if not all features have it) name:* fields
3 | ------------------- -------- ----- ---------- ---------------------------- --------- ------------- ---------------------------------------------------------------- ---------------
4 | water 4096 2 1 POLYGON 304 304.0 class
5 | transportation 4096 2 11 LINESTRING(91%), POLYGON(9%) 237 21.5 class, oneway, ramp, brunnel, layer, subclass(55%), surface(36%)
6 | transportation_name 4096 2 2 LINESTRING 72 36.0 name_en, name_de, ref, ref_length, network, class 1 languages
7 |
--------------------------------------------------------------------------------
/bin/pgwait:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # Wait for Postgres to start using pg_isready
4 |
5 | set -o errexit
6 | set -o pipefail
7 | set -o nounset
8 |
9 | # For backward compatibility, allow both PG* and POSTGRES_* forms,
10 | # with the non-standard POSTGRES_* form taking precedence.
11 | # An error will be raised if neither form is given, except for the PGPORT
12 | export PGHOST="${POSTGRES_HOST:-${PGHOST?}}"
13 | export PGDATABASE="${POSTGRES_DB:-${PGDATABASE?}}"
14 | export PGUSER="${POSTGRES_USER:-${PGUSER?}}"
15 | export PGPORT="${POSTGRES_PORT:-${PGPORT:-5432}}"
16 |
17 | : "${MAX_RETRIES:=40}" # Maximum number of pg_isready calls
18 | tries=0
19 | while ! pg_isready -q
20 | do
21 | tries=$((tries + 1))
22 | if (( tries > MAX_RETRIES )); then
23 | echo "... gave up waiting for Postgres: PGHOST=${PGHOST} PGDATABASE=${PGDATABASE} PGUSER=${PGUSER} PGPORT=${PGPORT} pg_isready"
24 | exit 1
25 | fi
26 | sleep 2
27 | done
28 |
--------------------------------------------------------------------------------
/bin/import-update:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | set -o errexit
3 | set -o pipefail
4 | set -o nounset
5 |
6 | # For backward compatibility, allow both PG* and POSTGRES_* forms,
7 | # with the non-standard POSTGRES_* form taking precedence.
8 | # An error will be raised if neither form is given, except for the PGPORT
9 | export PGHOST="${POSTGRES_HOST:-${PGHOST?}}"
10 | export PGDATABASE="${POSTGRES_DB:-${PGDATABASE?}}"
11 | export PGUSER="${POSTGRES_USER:-${PGUSER?}}"
12 | export PGPASSWORD="${POSTGRES_PASSWORD:-${PGPASSWORD?}}"
13 | export PGPORT="${POSTGRES_PORT:-${PGPORT:-5432}}"
14 |
15 | imposm run \
16 | -connection "postgis://$PGUSER:$PGPASSWORD@$PGHOST:$PGPORT/$PGDATABASE" \
17 | -mapping "${IMPOSM_MAPPING_FILE:?}" \
18 | -cachedir "${IMPOSM_CACHE_DIR:?}" \
19 | -diffdir "${IMPOSM_DIFF_DIR:?}" \
20 | -expiretiles-dir "${EXPIRETILES_DIR:?}" \
21 | -expiretiles-zoom "${EXPIRETILES_ZOOM:-14}" \
22 | -config "${IMPOSM_CONFIG_FILE:?}"
23 |
--------------------------------------------------------------------------------
/tests/sql/ToPoint.sql:
--------------------------------------------------------------------------------
1 | -- ToPoint
2 | SELECT ToPoint(ST_GeomFromText('POINT(0 0)',900913)) AS v1; -- 010100002031BF0D0000000000000000000000000000000000
3 | SELECT ToPoint(ST_GeomFromText('POLYGON EMPTY',900913)) AS null_v2; -- \\N
4 | SELECT ToPoint(ST_GeomFromText('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))',900913)) AS v3; -- 010100002031BF0D0000000000000014400000000000001440
5 | SELECT ToPoint(ST_GeomFromText('POLYGON((0 0, 10 0, 0 10, 10 10, 0 0))',900913)) AS v4; -- 010100002031BF0D0000000000000014400000000000000440
6 | SELECT ToPoint(ST_GeomFromText('MULTIPOLYGON(((0 0, 10 0, 10 10, 0 10, 0 0)))',900913)) AS v5; -- 010100002031BF0D0000000000000014400000000000001440
7 | SELECT ToPoint(ST_GeomFromText('MULTIPOLYGON(((0 0, 10 0, 10 10, 0 10, 0 0)), ((20 20, 30 20, 30 30, 20 30, 20 20)))',900913)) AS v6; -- 010100002031BF0D0000000000000014400000000000001440
8 | SELECT ST_AsText(ToPoint(ST_GeomFromText('POLYGON((50 5,10 8,10 10,100 190,150 30,150 10,50 5))',900913))) AS v7; -- POINT(92.5 110)
9 |
--------------------------------------------------------------------------------
/tests/expected/debug_mvt_dump_summary.out:
--------------------------------------------------------------------------------
1 | Uncompressed tile from tests/http/osm_13_4388_2568.mvt size=2,222 bytes, gzipped=1,248 bytes, 3 layers
2 | Layer Extent Ver Features GeoType GeoSize AVG GeoSize Fields (percentage only if not all features have it) name:* fields
3 | ------------------- -------- ----- ---------- ---------------------------- --------- ------------- ---------------------------------------------------------------- ---------------
4 | water 4096 2 1 POLYGON 304 304.0 class
5 | transportation 4096 2 11 LINESTRING(91%), POLYGON(9%) 237 21.5 class, oneway, ramp, brunnel, layer, subclass(55%), surface(36%)
6 | transportation_name 4096 2 2 LINESTRING 72 36.0 name_en, name_de, ref, ref_length, network, class 1 languages
7 |
--------------------------------------------------------------------------------
/tests/expected/debug_mvt_URL_dump_summary.out:
--------------------------------------------------------------------------------
1 | Uncompressed tile from http://localhost:8555/osm_13_4388_2568.mvt size=2,222 bytes, gzipped=1,248 bytes, 3 layers
2 | Layer Extent Ver Features GeoType GeoSize AVG GeoSize Fields (percentage only if not all features have it) name:* fields
3 | ------------------- -------- ----- ---------- ---------------------------- --------- ------------- ---------------------------------------------------------------- ---------------
4 | water 4096 2 1 POLYGON 304 304.0 class
5 | transportation 4096 2 11 LINESTRING(91%), POLYGON(9%) 237 21.5 class, oneway, ramp, brunnel, layer, subclass(55%), surface(36%)
6 | transportation_name 4096 2 2 LINESTRING 72 36.0 name_en, name_de, ref, ref_length, network, class 1 languages
7 |
--------------------------------------------------------------------------------
/.github/workflows/pull_request.yml:
--------------------------------------------------------------------------------
1 | name: Validate PR
2 |
3 | on: [pull_request]
4 |
5 | jobs:
6 |
7 | job:
8 | name: Run integrity test
9 | runs-on: ubuntu-latest
10 | steps:
11 | - name: Checkout the changes
12 | uses: actions/checkout@v4
13 |
14 | - name: Tests
15 | run: |
16 | make test
17 |
18 | - name: Save test results
19 | if: ${{ always() }}
20 | uses: actions/upload-artifact@v4
21 | with:
22 | name: build-result
23 | path: build
24 |
25 | - name: Build postgis docker
26 | run: |
27 | pushd docker/postgis
28 | docker build .
29 | popd
30 |
31 | - name: Build generate-vectortiles docker
32 | continue-on-error: true
33 | run: |
34 | pushd docker/generate-vectortiles
35 | docker build .
36 | popd
37 |
38 | # Do not auto-build import-data and postgis-preload due to high download requirements
39 |
--------------------------------------------------------------------------------
/bin/import-diff:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | set -o errexit
3 | set -o pipefail
4 | set -o nounset
5 |
6 | # For backward compatibility, allow both PG* and POSTGRES_* forms,
7 | # with the non-standard POSTGRES_* form taking precedence.
8 | # An error will be raised if neither form is given, except for the PGPORT
9 | export PGHOST="${POSTGRES_HOST:-${PGHOST?}}"
10 | export PGDATABASE="${POSTGRES_DB:-${PGDATABASE?}}"
11 | export PGUSER="${POSTGRES_USER:-${PGUSER?}}"
12 | export PGPASSWORD="${POSTGRES_PASSWORD:-${PGPASSWORD?}}"
13 | export PGPORT="${POSTGRES_PORT:-${PGPORT:-5432}}"
14 |
15 | imposm diff \
16 | -connection "postgis://$PGUSER:$PGPASSWORD@$PGHOST:$PGPORT/$PGDATABASE" \
17 | -mapping "${IMPOSM_MAPPING_FILE:?}" \
18 | -cachedir "${IMPOSM_CACHE_DIR:?}" \
19 | -diffdir "${IMPOSM_DIFF_DIR:?}" \
20 | -expiretiles-dir "${EXPIRETILES_DIR:?}" \
21 | -expiretiles-zoom "${EXPIRETILES_ZOOM:-14}" \
22 | -config "${IMPOSM_CONFIG_FILE:?}" \
23 | "${PBF_DATA_DIR:?}/changes.osc.gz"
24 |
--------------------------------------------------------------------------------
/bin/generate-doc:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | """
3 | Usage:
4 | generate-doc
5 | generate-doc --help
6 | generate-doc --version
7 | Options:
8 | --help Show this screen.
9 | --version Show version.
10 | """
11 | from docopt import docopt
12 |
13 | import openmaptiles
14 | from openmaptiles.tileset import Layer, Field
15 |
16 |
17 | def generate_field_doc(field: Field):
18 | field_doc = f'### {field.name}\n\n{field.description}\n'
19 | if field.values:
20 | field_doc += '\nPossible values:\n\n'
21 | field_doc += '\n'.join((f'- `{v}`' for v in field.values)) + '\n\n'
22 | return field_doc
23 |
24 |
25 | def main(args):
26 | layer = Layer.parse(args[''])
27 | fields_doc = '\n'.join((generate_field_doc(f) for f in layer.fields))
28 | print(f'{layer.description}\n\n## Fields\n\n{fields_doc}\n\n\n')
29 |
30 |
31 | if __name__ == '__main__':
32 | main(docopt(__doc__, version=openmaptiles.__version__))
33 |
--------------------------------------------------------------------------------
/tests/testlayers/housenumber/housenumber.yaml:
--------------------------------------------------------------------------------
1 | layer:
2 | id: "housenumber"
3 | description: |
4 | Everything in OpenStreetMap which contains a `addr:housenumber` tag useful for labelling housenumbers on a map.
5 | This adds significant size to *z14*. For buildings the centroid of the building is used as housenumber.
6 | buffer_size: 8
7 | srs: +proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over
8 | fields:
9 | housenumber: Value of the [`addr:housenumber`](http://wiki.openstreetmap.org/wiki/Key:addr) tag (Faked from current zoom).
10 | datasource:
11 | geometry_field: geometry
12 | srid: 900913
13 | query: (SELECT !bbox! as geometry, z(!scale_denominator!) AS housenumber, {name_languages} FROM (SELECT 'name:en=>"enname"'::hstore as tags) AS tt) AS t
14 | schema:
15 | - ./housenumber_centroid.sql
16 | - ./layer.sql
17 | datasources:
18 | - type: imposm3
19 | mapping_file: ./mapping.yaml
20 |
--------------------------------------------------------------------------------
/bin/generate-sqlquery:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | """
4 | Usage:
5 | generate-sqlquery
6 | generate-sqlquery --help
7 | generate-sqlquery --version
8 | Options:
9 | --help Show this screen.
10 | --version Show version.
11 | """
12 | import re
13 |
14 | from docopt import docopt
15 |
16 | import openmaptiles
17 | from openmaptiles.tileset import Layer
18 |
19 |
20 | def main(args):
21 | bbox = "ST_SetSRID('BOX3D(-20037508.34 -20037508.34, 20037508.34 20037508.34)'::box3d, 3857)"
22 | zoom = args['']
23 | layer = Layer.parse(args[''])
24 |
25 | sql = (layer.query
26 | .replace('!bbox!', bbox)
27 | .replace('z(!scale_denominator!)', zoom)
28 | .replace('!pixel_width!', '1'))
29 |
30 | match = re.search(r'\((.*)\) AS *', sql)
31 | print(match.group(1))
32 |
33 |
34 | if __name__ == '__main__':
35 | main(docopt(__doc__, version=openmaptiles.__version__))
36 |
--------------------------------------------------------------------------------
/tests/expected/parallel_sql/parallel/mountain_peak.sql:
--------------------------------------------------------------------------------
1 | DO $$ BEGIN RAISE NOTICE 'Processing layer mountain_peak'; END$$;
2 |
3 | DO $$ BEGIN
4 | PERFORM 'my_magic_table'::regclass;
5 | EXCEPTION
6 | WHEN undefined_table THEN
7 | RAISE EXCEPTION '%', SQLERRM
8 | USING DETAIL = 'this table or view is required for layer "mountain_peak"';
9 | END;
10 | $$ LANGUAGE 'plpgsql';
11 |
12 | DO $$ BEGIN
13 | PERFORM 'my_magic_func(TEXT, TEXT)'::regprocedure;
14 | EXCEPTION
15 | WHEN undefined_function THEN
16 | RAISE EXCEPTION '%', SQLERRM
17 | USING DETAIL = 'this function is required for layer "mountain_peak"';
18 | WHEN invalid_text_representation THEN
19 | RAISE EXCEPTION '%', SQLERRM
20 | USING DETAIL = 'Required function "my_magic_func(TEXT, TEXT)" in layer "mountain_peak" is incorrectly declared. Use full function signature with parameter types, e.g. "my_magic_func(TEXT, TEXT)"';
21 | END;
22 | $$ LANGUAGE 'plpgsql';
23 |
24 | DO $$ BEGIN RAISE NOTICE 'Finished layer mountain_peak'; END$$;
25 |
--------------------------------------------------------------------------------
/tests/expected/parallel_sql2/parallel/mountain_peak.sql:
--------------------------------------------------------------------------------
1 | DO $$ BEGIN RAISE NOTICE 'Processing layer mountain_peak'; END$$;
2 |
3 | DO $$ BEGIN
4 | PERFORM 'my_magic_table'::regclass;
5 | EXCEPTION
6 | WHEN undefined_table THEN
7 | RAISE EXCEPTION '%', SQLERRM
8 | USING DETAIL = 'this table or view is required for layer "mountain_peak"';
9 | END;
10 | $$ LANGUAGE 'plpgsql';
11 |
12 | DO $$ BEGIN
13 | PERFORM 'my_magic_func(TEXT, TEXT)'::regprocedure;
14 | EXCEPTION
15 | WHEN undefined_function THEN
16 | RAISE EXCEPTION '%', SQLERRM
17 | USING DETAIL = 'this function is required for layer "mountain_peak"';
18 | WHEN invalid_text_representation THEN
19 | RAISE EXCEPTION '%', SQLERRM
20 | USING DETAIL = 'Required function "my_magic_func(TEXT, TEXT)" in layer "mountain_peak" is incorrectly declared. Use full function signature with parameter types, e.g. "my_magic_func(TEXT, TEXT)"';
21 | END;
22 | $$ LANGUAGE 'plpgsql';
23 |
24 | DO $$ BEGIN RAISE NOTICE 'Finished layer mountain_peak'; END$$;
25 |
--------------------------------------------------------------------------------
/tests/expected/debug_mvt_dump_summary_show_names.out:
--------------------------------------------------------------------------------
1 | Uncompressed tile from tests/http/osm_13_4388_2568.mvt size=2,222 bytes, gzipped=1,248 bytes, 3 layers
2 | Layer Extent Ver Features GeoType GeoSize AVG GeoSize Fields (percentage only if not all features have it) name:* fields (percentage of features with that language)
3 | ------------------- -------- ----- ---------- ---------------------------- --------- ------------- ---------------------------------------------------------------- -----------------------------------------------------------
4 | water 4096 2 1 POLYGON 304 304.0 class
5 | transportation 4096 2 11 LINESTRING(91%), POLYGON(9%) 237 21.5 class, oneway, ramp, brunnel, layer, subclass(55%), surface(36%)
6 | transportation_name 4096 2 2 LINESTRING 72 36.0 name_en, name_de, ref, ref_length, network, class da(100%)
7 |
--------------------------------------------------------------------------------
/sql/Z.sql:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | ### Z ###
3 |
4 | Returns a Web Mercator integer zoom level given a scale denominator.
5 |
6 | Useful with Mapnik's !scale_denominator! token in vector tile source
7 | queries.
8 |
9 | __Parameters:__
10 |
11 | - `numeric` scale_denominator - The denominator of the scale, eg `250000`
12 | for a 1:250,000 scale.
13 |
14 | __Returns:__ `integer`
15 |
16 | __Example Mapbox Studio query:__
17 |
18 | ```sql
19 | ( SELECT * FROM roads
20 | WHERE Z(!scale_denominator!) >= 12
21 | ) AS data
22 | ```
23 | ******************************************************************************/
24 | create or replace function z (numeric)
25 | returns integer
26 | language sql
27 | immutable
28 | parallel safe
29 | returns null on null input
30 | as $func$
31 | select
32 | case
33 | -- Don't bother if the scale is larger than ~zoom level 0
34 | when $1 > 600000000 or $1 = 0 then null
35 | else cast (round(log(2,559082264.028/$1)) as integer)
36 | end;
37 | $func$;
38 |
39 |
40 |
--------------------------------------------------------------------------------
/tests/expected/ToPoint.sql.out:
--------------------------------------------------------------------------------
1 | v1
2 | ----------------------------------------------------
3 | 010100002031BF0D0000000000000000000000000000000000
4 | (1 row)
5 |
6 | null_v2
7 | ---------
8 |
9 | (1 row)
10 |
11 | v3
12 | ----------------------------------------------------
13 | 010100002031BF0D0000000000000014400000000000001440
14 | (1 row)
15 |
16 | v4
17 | ----------------------------------------------------
18 | 010100002031BF0D0000000000000014400000000000001E40
19 | (1 row)
20 |
21 | v5
22 | ----------------------------------------------------
23 | 010100002031BF0D0000000000000014400000000000001440
24 | (1 row)
25 |
26 | v6
27 | ----------------------------------------------------
28 | 010100002031BF0D0000000000000014400000000000001440
29 | (1 row)
30 |
31 | v7
32 | -----------------
33 | POINT(92.5 110)
34 | (1 row)
35 |
36 |
--------------------------------------------------------------------------------
/tests/expected/TileBBox.sql.out:
--------------------------------------------------------------------------------
1 | v1
2 | -----------------------------------------------------------------------------------------------------------------------------------------
3 | POLYGON((-20037508.34 20037508.34,-20037508.34 -20037508.34,20037508.34 -20037508.34,20037508.34 20037508.34,-20037508.34 20037508.34))
4 | (1 row)
5 |
6 | v2
7 | --------------------------------------------------------------------------------------------------------------------------------------------
8 | POLYGON((-8590298.99 4715858.9,-8590298.99 4696291.0200000005,-8570731.11 4696291.0200000005,-8570731.11 4715858.9,-8590298.99 4715858.9))
9 | (1 row)
10 |
11 | v3
12 | -------------------------------------------------------------------
13 | POLYGON((-180 85.05,-180 -85.05,180 -85.05,180 85.05,-180 85.05))
14 | (1 row)
15 |
16 |
--------------------------------------------------------------------------------
/docker/generate-vectortiles/README.md:
--------------------------------------------------------------------------------
1 | # Generate Vector Tiles from TM2Source
2 | []() [](https://microbadger.com/images/openmaptiles/generate-vectortiles)
3 |
4 | A Docker image to export MBTiles (containing gzipped MVT PBF) from a TM2Source project.
5 | The TM2Source project usually references a database you need to link against this container.
6 |
7 | ## Usage
8 |
9 | You need to provide the database credentials and run `generate-vectortiles`.
10 |
11 | ```bash
12 | docker run --rm \
13 | -v $(pwd)/project.tm2source:/tm2source \
14 | -v $(pwd):/export \
15 | -e PGHOST="127.0.0.1" \
16 | -e PGDATABASE="openmaptiles" \
17 | -e PGUSER="openmaptiles" \
18 | -e PGPASSWORD="openmaptiles" \
19 | openmaptiles/generate-vectortiles
20 | ```
21 |
22 | Optional environment variables:
23 | * `PGPORT` (defaults to `5432`)
24 |
25 | Legacy env variables are still supported, but they are not recommended:
26 | `POSTGRES_HOST`,`POSTGRES_DB`, `POSTGRES_USER`, `POSTGRES_PASSWORD`, `POSTGRES_PORT`
27 |
--------------------------------------------------------------------------------
/docker/generate-vectortiles/export-local.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | set -o errexit
3 | set -o pipefail
4 | set -o nounset
5 |
6 | source utils.sh
7 |
8 | readonly RENDER_SCHEME=${RENDER_SCHEME:-pyramid}
9 | readonly MIN_ZOOM=${MIN_ZOOM:-0}
10 | readonly MAX_ZOOM=${MAX_ZOOM:-14}
11 | readonly BBOX=${BBOX:-"-180,-85.0511,180,85.0511"}
12 | readonly COPY_CONCURRENCY=${COPY_CONCURRENCY:-10}
13 | readonly TILE_TIMEOUT=${TILE_TIMEOUT:-1800000}
14 | readonly MBTILES_NAME=${MBTILES_NAME:-tiles.mbtiles}
15 |
16 | function export_local_mbtiles() {
17 | echo "Generating tiles into $EXPORT_DIR/$MBTILES_NAME for zooms $MIN_ZOOM..$MAX_ZOOM inside ($BBOX) using $COPY_CONCURRENCY concurrent I/O operations"
18 |
19 | exec tilelive-copy \
20 | --scheme="$RENDER_SCHEME" \
21 | --bounds="$BBOX" \
22 | --timeout="$TILE_TIMEOUT" \
23 | --concurrency="$COPY_CONCURRENCY" \
24 | --minzoom="$MIN_ZOOM" \
25 | --maxzoom="$MAX_ZOOM" \
26 | "tmsource://$DEST_PROJECT_DIR" "mbtiles://$EXPORT_DIR/$MBTILES_NAME"
27 | }
28 |
29 | function main() {
30 | copy_source_project
31 | cleanup_dest_project
32 | replace_db_connection
33 | export_local_mbtiles
34 | }
35 |
36 | main
37 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2024, MapTiler.com & OpenMapTiles/OSM2VectorTiles contributors.
4 | All rights reserved.
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | SOFTWARE.
23 |
24 |
--------------------------------------------------------------------------------
/docker/import-data/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2020, Yuri Astrakhan (YuriAstrakhan@gmail.com)
4 | All rights reserved.
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | SOFTWARE.
23 |
24 |
--------------------------------------------------------------------------------
/docker/postgis-preloaded/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2020, Yuri Astrakhan (YuriAstrakhan@gmail.com)
4 | All rights reserved.
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | SOFTWARE.
23 |
24 |
--------------------------------------------------------------------------------
/sql/LineLabel.sql:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | ### LineLabel ###
3 |
4 | This function tries to estimate whether a line geometry would be long enough to
5 | have the given text placed along it at the specified scale.
6 |
7 | It is useful in vector tile queries to filter short lines from zoom levels
8 | where they would be unlikely to have text places on them anyway.
9 |
10 | __Parameters:__
11 |
12 | - `numeric` zoom - The Web Mercator zoom level you are considering.
13 | - `text` label - The label text that you will be placing along the line.
14 | - `geometry(linestring)` g - A line geometry.
15 |
16 | __Returns:__ `boolean`
17 | ******************************************************************************/
18 | create or replace function LineLabel (
19 | zoom numeric,
20 | label text,
21 | g geometry
22 | )
23 | returns boolean
24 | language sql immutable
25 | parallel safe as
26 | $func$
27 | SELECT CASE
28 | -- if length is 0 geom is (probably) a point; keep it
29 | WHEN zoom > 20 or ST_Length(g) = 0 THEN true
30 | ELSE length(label) between 1 and ST_Length(g)/(2^(20-zoom))
31 | END;
32 | $func$;
33 |
34 |
35 |
--------------------------------------------------------------------------------
/docker/generate-vectortiles/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2024, MapTiler.com & OpenMapTiles/OSM2VectorTiles contributors.
4 | All rights reserved.
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | SOFTWARE.
23 |
24 |
--------------------------------------------------------------------------------
/sql/ZRes.sql:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | ### ZRES ###
3 |
4 | Takes a web mercator zoom level and returns the pixel resolution for that
5 | scale, assuming 256x256 pixel tiles. Non-integer zoom levels are accepted.
6 |
7 | __Parameters:__
8 |
9 | - `integer` or `float` z - A Web Mercator zoom level.
10 |
11 | __Returns:__ `float`
12 |
13 | __Examples:__
14 |
15 | ```sql
16 | -- Delete all polygons smaller than 1px square at zoom level 10
17 | DELETE FROM water_polygons WHERE sqrt(ST_Area(geom)) < ZRes(10);
18 |
19 | -- Simplify geometries to a resolution appropriate for zoom level 10
20 | UPDATE water_polygons SET geom = ST_Simplify(geom, ZRes(10));
21 | ```
22 | ******************************************************************************/
23 | create or replace function ZRes (z integer)
24 | returns float
25 | returns null on null input
26 | language sql immutable
27 | parallel safe as
28 | $func$
29 | select (40075016.6855785/(256*2^z));
30 | $func$;
31 |
32 | create or replace function ZRes (z float)
33 | returns float
34 | returns null on null input
35 | language sql immutable
36 | parallel safe as
37 | $func$
38 | select (40075016.6855785/(256*2^z));
39 | $func$;
40 |
41 |
42 |
--------------------------------------------------------------------------------
/sql/TileBBox.sql:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | ### TileBBox ###
3 |
4 | Given a Web Mercator tile ID as (z, x, y), returns a bounding-box
5 | geometry of the area covered by that tile.
6 |
7 | __Parameters:__
8 |
9 | - `integer` z - A tile zoom level.
10 | - `integer` x - A tile x-position.
11 | - `integer` y - A tile y-position.
12 | - `integer` srid - SRID of the desired target projection of the bounding
13 | box. Defaults to 3857 (Web Mercator).
14 |
15 | __Returns:__ `geometry(polygon)`
16 | ******************************************************************************/
17 | create or replace function TileBBox (z int, x int, y int, srid int = 3857)
18 | returns geometry
19 | language plpgsql immutable
20 | parallel safe as
21 | $func$
22 | declare
23 | max numeric := 20037508.34;
24 | res numeric := (max*2)/(2^z);
25 | bbox geometry;
26 | begin
27 | bbox := ST_MakeEnvelope(
28 | -max + (x * res),
29 | max - (y * res),
30 | -max + (x * res) + res,
31 | max - (y * res) - res,
32 | 3857
33 | );
34 | if srid = 3857 then
35 | return bbox;
36 | else
37 | return ST_Transform(bbox, srid);
38 | end if;
39 | end;
40 | $func$;
41 |
42 |
43 |
--------------------------------------------------------------------------------
/tests/expected/mvttile_query_v2.5.sql:
--------------------------------------------------------------------------------
1 | SELECT STRING_AGG(mvtl, '') AS mvt FROM (
2 | SELECT COALESCE(ST_AsMVT(t, 'housenumber', 4096, 'mvtgeometry'), '') as mvtl FROM (SELECT ST_Expand(TileBBox($1, $2, $3), 1252344.2714243282/2^$1) as ST_AsMVTGeom(geometry, TileBBox($1, $2, $3), 4096, 128, true) AS mvtgeometry, $1 AS housenumber, NULLIF(tags->'name:en', '') AS "name:en", NULLIF(tags->'name:de', '') AS "name:de", NULLIF(tags->'name:cs', '') AS "name:cs", NULLIF(tags->'name_int', '') AS "name_int", NULLIF(tags->'name:latin', '') AS "name:latin", NULLIF(tags->'name:nonlatin', '') AS "name:nonlatin" FROM (SELECT 'name:en=>"enname"'::hstore as tags) AS tt) AS t
3 | UNION ALL
4 | SELECT COALESCE(ST_AsMVT(t, 'enumfield', 4096, 'mvtgeometry'), '') as mvtl FROM (SELECT TileBBox($1, $2, $3) as ST_AsMVTGeom(geometry, TileBBox($1, $2, $3), 4096, 0, true) AS mvtgeometry, $1 AS osm_id, 'foo' AS class) AS t
5 | UNION ALL
6 | SELECT COALESCE(ST_AsMVT(t, 'mountain_peak', 4096, 'mvtgeometry'), '') as mvtl FROM (SELECT ST_Expand(TileBBox($1, $2, $3), 10018754.171394626/2^$1) AS ST_AsMVTGeom(geometry, TileBBox($1, $2, $3), 4096, 1024, true) AS mvtgeometry, $1 AS osm_id, 'foo_name' AS name, 'foo_name_en' AS name_en, 'foo_name_de' AS name_de, 'foo_class' AS class, $1 AS ele, $1 AS ele_ft, $1 AS rank) AS t
7 | ) AS all_layers
8 |
9 |
--------------------------------------------------------------------------------
/tests/expected/parallel_sql2/parallel/housenumber.sql:
--------------------------------------------------------------------------------
1 | DO $$ BEGIN RAISE NOTICE 'Processing layer housenumber'; END$$;
2 |
3 | -- Layer housenumber - ./housenumber_centroid.sql
4 |
5 |
6 | -- etldoc: osm_housenumber_point -> osm_housenumber_point
7 | UPDATE osm_housenumber_point SET geometry=topoint(geometry)
8 | WHERE ST_GeometryType(geometry) <> 'ST_Point';
9 |
10 | -- Layer housenumber - ./layer.sql
11 |
12 |
13 | -- etldoc: layer_housenumber[shape=record fillcolor=lightpink, style="rounded,filled",
14 | -- etldoc: label="layer_housenumber | z14_" ] ;
15 |
16 | CREATE OR REPLACE FUNCTION layer_housenumber(bbox geometry, zoom_level integer)
17 | RETURNS TABLE(osm_id bigint, geometry geometry, housenumber text, tags hstore) AS $$
18 | -- etldoc: osm_housenumber_point -> layer_housenumber:z14_
19 | SELECT osm_id, geometry, housenumber, tags FROM osm_housenumber_point
20 | WHERE zoom_level >= 14 AND geometry && bbox;
21 | $$ LANGUAGE SQL IMMUTABLE;
22 |
23 |
24 | DROP MATERIALIZED VIEW IF EXISTS layer_housenumber_gen1 CASCADE;
25 | CREATE MATERIALIZED VIEW layer_housenumber_gen1 AS (
26 | SELECT ST_Simplify(geometry, 10) AS geometry, osm_id, housenumber
27 | FROM osm_housenumber_point
28 | ) WITH NO DATA ;
29 |
30 | DO $$ BEGIN RAISE NOTICE 'Finished layer housenumber'; END$$;
31 |
--------------------------------------------------------------------------------
/docker/postgis/README.md:
--------------------------------------------------------------------------------
1 | # PostGIS + OSM-specific extensions Docker image
2 | []()
3 |
4 | This images is based on PostgreSQL 14 and PostGIS 3.2 [Docker image](https://hub.docker.com/r/postgis/postgis/) and includes [osml10n extension](https://github.com/openmaptiles/mapnik-german-l10n.git) - OSM-specific label manipulation support.
5 |
6 | ## Usage
7 |
8 | Run a PostgreSQL container and mount it to a persistent data directory outside.
9 |
10 | In this example we start up the container and create a database `openmaptiles` with the owner `openmaptiles` and password `openmaptiles`
11 | and mount our local directory `./data` as storage.
12 |
13 | ```bash
14 | docker run \
15 | -v $(pwd)/data:/var/lib/postgresql/data \
16 | -e POSTGRES_DB="openmaptiles" \
17 | -e POSTGRES_USER="openmaptiles" \
18 | -e POSTGRES_PASSWORD="openmaptiles" \
19 | -d openmaptiles/postgis
20 | ```
21 |
22 | ### Environment Variables
23 | Unlike all other OpenMapTiles repositories, this repo uses a different set of environment variables to initialize the database - `POSTGRES_*`. See (full documentation](https://hub.docker.com/_/postgres/).
24 |
25 | ## Build
26 |
27 | ```bash
28 | docker build -t openmaptiles/postgis .
29 | ```
30 |
--------------------------------------------------------------------------------
/tests/expected/imposm3.yaml:
--------------------------------------------------------------------------------
1 | tags:
2 | include:
3 | - access
4 | - int_name
5 | - loc_name
6 | - name
7 | - name:cs
8 | - name:de
9 | - name:en
10 | - wikidata
11 | - wikipedia
12 | generalized_tables: {}
13 | tables:
14 | housenumber_point:
15 | type: geometry
16 | fields:
17 | - name: osm_id
18 | type: id
19 | - name: geometry
20 | type: geometry
21 | - name: housenumber
22 | key: addr:housenumber
23 | type: string
24 | - name: tags
25 | type: hstore_tags
26 | type_mappings:
27 | points:
28 | addr:housenumber:
29 | - __any__
30 | polygons:
31 | addr:housenumber:
32 | - __any__
33 | peak_point:
34 | type: point
35 | columns:
36 | - name: osm_id
37 | type: id
38 | - name: geometry
39 | type: geometry
40 | - name: name
41 | key: name
42 | type: string
43 | - name: name_en
44 | key: name:en
45 | type: string
46 | - name: name_de
47 | key: name:de
48 | type: string
49 | - name: tags
50 | type: hstore_tags
51 | - name: ele
52 | key: ele
53 | type: string
54 | - name: wikipedia
55 | key: wikipedia
56 | type: string
57 | mapping:
58 | natural:
59 | - peak
60 | - volcano
61 |
62 |
--------------------------------------------------------------------------------
/tests/expected/parallel_sql/parallel/housenumber.sql:
--------------------------------------------------------------------------------
1 | DO $$ BEGIN RAISE NOTICE 'Processing layer housenumber'; END$$;
2 |
3 | -- Layer housenumber - ./housenumber_centroid.sql
4 |
5 |
6 | -- etldoc: osm_housenumber_point -> osm_housenumber_point
7 | UPDATE osm_housenumber_point SET geometry=topoint(geometry)
8 | WHERE ST_GeometryType(geometry) <> 'ST_Point';
9 |
10 | -- Layer housenumber - ./layer.sql
11 |
12 |
13 | -- etldoc: layer_housenumber[shape=record fillcolor=lightpink, style="rounded,filled",
14 | -- etldoc: label="layer_housenumber | z14_" ] ;
15 |
16 | CREATE OR REPLACE FUNCTION layer_housenumber(bbox geometry, zoom_level integer)
17 | RETURNS TABLE(osm_id bigint, geometry geometry, housenumber text, tags hstore) AS $$
18 | -- etldoc: osm_housenumber_point -> layer_housenumber:z14_
19 | SELECT osm_id, geometry, housenumber, tags FROM osm_housenumber_point
20 | WHERE zoom_level >= 14 AND geometry && bbox;
21 | $$ LANGUAGE SQL IMMUTABLE;
22 |
23 |
24 | DROP MATERIALIZED VIEW IF EXISTS layer_housenumber_gen1 CASCADE;
25 | CREATE MATERIALIZED VIEW layer_housenumber_gen1 AS (
26 | SELECT ST_Simplify(geometry, 10) AS geometry, osm_id, housenumber
27 | FROM osm_housenumber_point
28 | ) /* DELAY_MATERIALIZED_VIEW_CREATION */ ;
29 |
30 | DO $$ BEGIN RAISE NOTICE 'Finished layer housenumber'; END$$;
31 |
--------------------------------------------------------------------------------
/tests/expected/mvttile_query_no_feat_ids.sql:
--------------------------------------------------------------------------------
1 | SELECT STRING_AGG(mvtl, '') AS mvt FROM (
2 | SELECT COALESCE(ST_AsMVT(t, 'housenumber', 4096, 'mvtgeometry'), '') as mvtl FROM (SELECT ST_Expand(ST_TileEnvelope($1, $2, $3), 1252344.2714243282/2^$1) as ST_AsMVTGeom(geometry, ST_TileEnvelope($1, $2, $3), 4096, 128, true) AS mvtgeometry, $1 AS housenumber, NULLIF(tags->'name:en', '') AS "name:en", NULLIF(tags->'name:de', '') AS "name:de", NULLIF(tags->'name:cs', '') AS "name:cs", NULLIF(tags->'name_int', '') AS "name_int", NULLIF(tags->'name:latin', '') AS "name:latin", NULLIF(tags->'name:nonlatin', '') AS "name:nonlatin" FROM (SELECT 'name:en=>"enname"'::hstore as tags) AS tt) AS t
3 | UNION ALL
4 | SELECT COALESCE(ST_AsMVT(t, 'enumfield', 4096, 'mvtgeometry'), '') as mvtl FROM (SELECT ST_TileEnvelope($1, $2, $3) as ST_AsMVTGeom(geometry, ST_TileEnvelope($1, $2, $3), 4096, 0, true) AS mvtgeometry, $1 AS osm_id, 'foo' AS class) AS t
5 | UNION ALL
6 | SELECT COALESCE(ST_AsMVT(t, 'mountain_peak', 4096, 'mvtgeometry'), '') as mvtl FROM (SELECT ST_Expand(ST_TileEnvelope($1, $2, $3), 10018754.171394626/2^$1) AS ST_AsMVTGeom(geometry, ST_TileEnvelope($1, $2, $3), 4096, 1024, true) AS mvtgeometry, $1 AS osm_id, 'foo_name' AS name, 'foo_name_en' AS name_en, 'foo_name_de' AS name_de, 'foo_class' AS class, $1 AS ele, $1 AS ele_ft, $1 AS rank) AS t
7 | ) AS all_layers
8 |
9 |
--------------------------------------------------------------------------------
/tests/expected/mvttile_query.sql:
--------------------------------------------------------------------------------
1 | SELECT STRING_AGG(mvtl, '') AS mvt FROM (
2 | SELECT COALESCE(ST_AsMVT(t, 'housenumber', 4096, 'mvtgeometry'), '') as mvtl FROM (SELECT ST_Expand(ST_TileEnvelope($1, $2, $3), 1252344.2714243282/2^$1) as ST_AsMVTGeom(geometry, ST_TileEnvelope($1, $2, $3), 4096, 128, true) AS mvtgeometry, $1 AS housenumber, NULLIF(tags->'name:en', '') AS "name:en", NULLIF(tags->'name:de', '') AS "name:de", NULLIF(tags->'name:cs', '') AS "name:cs", NULLIF(tags->'name_int', '') AS "name_int", NULLIF(tags->'name:latin', '') AS "name:latin", NULLIF(tags->'name:nonlatin', '') AS "name:nonlatin" FROM (SELECT 'name:en=>"enname"'::hstore as tags) AS tt) AS t
3 | UNION ALL
4 | SELECT COALESCE(ST_AsMVT(t, 'enumfield', 4096, 'mvtgeometry', 'osm_id'), '') as mvtl FROM (SELECT ST_TileEnvelope($1, $2, $3) as ST_AsMVTGeom(geometry, ST_TileEnvelope($1, $2, $3), 4096, 0, true) AS mvtgeometry, $1 AS osm_id, 'foo' AS class) AS t
5 | UNION ALL
6 | SELECT COALESCE(ST_AsMVT(t, 'mountain_peak', 4096, 'mvtgeometry', 'osm_id'), '') as mvtl FROM (SELECT ST_Expand(ST_TileEnvelope($1, $2, $3), 10018754.171394626/2^$1) AS ST_AsMVTGeom(geometry, ST_TileEnvelope($1, $2, $3), 4096, 1024, true) AS mvtgeometry, $1 AS osm_id, 'foo_name' AS name, 'foo_name_en' AS name_en, 'foo_name_de' AS name_de, 'foo_class' AS class, $1 AS ele, $1 AS ele_ft, $1 AS rank) AS t
7 | ) AS all_layers
8 |
9 |
--------------------------------------------------------------------------------
/tests/expected/mvttile_query_v3.0.sql:
--------------------------------------------------------------------------------
1 | SELECT STRING_AGG(mvtl, '') AS mvt FROM (
2 | SELECT COALESCE(ST_AsMVT(t, 'housenumber', 4096, 'mvtgeometry'), '') as mvtl FROM (SELECT ST_Expand(ST_TileEnvelope($1, $2, $3), 1252344.2714243282/2^$1) as ST_AsMVTGeom(geometry, ST_TileEnvelope($1, $2, $3), 4096, 128, true) AS mvtgeometry, $1 AS housenumber, NULLIF(tags->'name:en', '') AS "name:en", NULLIF(tags->'name:de', '') AS "name:de", NULLIF(tags->'name:cs', '') AS "name:cs", NULLIF(tags->'name_int', '') AS "name_int", NULLIF(tags->'name:latin', '') AS "name:latin", NULLIF(tags->'name:nonlatin', '') AS "name:nonlatin" FROM (SELECT 'name:en=>"enname"'::hstore as tags) AS tt) AS t
3 | UNION ALL
4 | SELECT COALESCE(ST_AsMVT(t, 'enumfield', 4096, 'mvtgeometry', 'osm_id'), '') as mvtl FROM (SELECT ST_TileEnvelope($1, $2, $3) as ST_AsMVTGeom(geometry, ST_TileEnvelope($1, $2, $3), 4096, 0, true) AS mvtgeometry, $1 AS osm_id, 'foo' AS class) AS t
5 | UNION ALL
6 | SELECT COALESCE(ST_AsMVT(t, 'mountain_peak', 4096, 'mvtgeometry', 'osm_id'), '') as mvtl FROM (SELECT ST_Expand(ST_TileEnvelope($1, $2, $3), 10018754.171394626/2^$1) AS ST_AsMVTGeom(geometry, ST_TileEnvelope($1, $2, $3), 4096, 1024, true) AS mvtgeometry, $1 AS osm_id, 'foo_name' AS name, 'foo_name_en' AS name_en, 'foo_name_de' AS name_de, 'foo_class' AS class, $1 AS ele, $1 AS ele_ft, $1 AS rank) AS t
7 | ) AS all_layers
8 |
9 |
--------------------------------------------------------------------------------
/tests/expected/mvttile_query_gzip.sql:
--------------------------------------------------------------------------------
1 | SELECT GZIP(STRING_AGG(mvtl, '')) AS mvt FROM (
2 | SELECT COALESCE(ST_AsMVT(t, 'housenumber', 4096, 'mvtgeometry'), '') as mvtl FROM (SELECT ST_Expand(ST_TileEnvelope($1, $2, $3), 1252344.2714243282/2^$1) as ST_AsMVTGeom(geometry, ST_TileEnvelope($1, $2, $3), 4096, 128, true) AS mvtgeometry, $1 AS housenumber, NULLIF(tags->'name:en', '') AS "name:en", NULLIF(tags->'name:de', '') AS "name:de", NULLIF(tags->'name:cs', '') AS "name:cs", NULLIF(tags->'name_int', '') AS "name_int", NULLIF(tags->'name:latin', '') AS "name:latin", NULLIF(tags->'name:nonlatin', '') AS "name:nonlatin" FROM (SELECT 'name:en=>"enname"'::hstore as tags) AS tt) AS t
3 | UNION ALL
4 | SELECT COALESCE(ST_AsMVT(t, 'enumfield', 4096, 'mvtgeometry', 'osm_id'), '') as mvtl FROM (SELECT ST_TileEnvelope($1, $2, $3) as ST_AsMVTGeom(geometry, ST_TileEnvelope($1, $2, $3), 4096, 0, true) AS mvtgeometry, $1 AS osm_id, 'foo' AS class) AS t
5 | UNION ALL
6 | SELECT COALESCE(ST_AsMVT(t, 'mountain_peak', 4096, 'mvtgeometry', 'osm_id'), '') as mvtl FROM (SELECT ST_Expand(ST_TileEnvelope($1, $2, $3), 10018754.171394626/2^$1) AS ST_AsMVTGeom(geometry, ST_TileEnvelope($1, $2, $3), 4096, 1024, true) AS mvtgeometry, $1 AS osm_id, 'foo_name' AS name, 'foo_name_en' AS name_en, 'foo_name_de' AS name_de, 'foo_class' AS class, $1 AS ele, $1 AS ele_ft, $1 AS rank) AS t
7 | ) AS all_layers
8 |
9 |
--------------------------------------------------------------------------------
/tests/expected/mvttile_query_gzip9.sql:
--------------------------------------------------------------------------------
1 | SELECT GZIP(STRING_AGG(mvtl, ''), 9) AS mvt FROM (
2 | SELECT COALESCE(ST_AsMVT(t, 'housenumber', 4096, 'mvtgeometry'), '') as mvtl FROM (SELECT ST_Expand(ST_TileEnvelope($1, $2, $3), 1252344.2714243282/2^$1) as ST_AsMVTGeom(geometry, ST_TileEnvelope($1, $2, $3), 4096, 128, true) AS mvtgeometry, $1 AS housenumber, NULLIF(tags->'name:en', '') AS "name:en", NULLIF(tags->'name:de', '') AS "name:de", NULLIF(tags->'name:cs', '') AS "name:cs", NULLIF(tags->'name_int', '') AS "name_int", NULLIF(tags->'name:latin', '') AS "name:latin", NULLIF(tags->'name:nonlatin', '') AS "name:nonlatin" FROM (SELECT 'name:en=>"enname"'::hstore as tags) AS tt) AS t
3 | UNION ALL
4 | SELECT COALESCE(ST_AsMVT(t, 'enumfield', 4096, 'mvtgeometry', 'osm_id'), '') as mvtl FROM (SELECT ST_TileEnvelope($1, $2, $3) as ST_AsMVTGeom(geometry, ST_TileEnvelope($1, $2, $3), 4096, 0, true) AS mvtgeometry, $1 AS osm_id, 'foo' AS class) AS t
5 | UNION ALL
6 | SELECT COALESCE(ST_AsMVT(t, 'mountain_peak', 4096, 'mvtgeometry', 'osm_id'), '') as mvtl FROM (SELECT ST_Expand(ST_TileEnvelope($1, $2, $3), 10018754.171394626/2^$1) AS ST_AsMVTGeom(geometry, ST_TileEnvelope($1, $2, $3), 4096, 1024, true) AS mvtgeometry, $1 AS osm_id, 'foo_name' AS name, 'foo_name_en' AS name_en, 'foo_name_de' AS name_de, 'foo_class' AS class, $1 AS ele, $1 AS ele_ft, $1 AS rank) AS t
7 | ) AS all_layers
8 |
9 |
--------------------------------------------------------------------------------
/tests/expected/mvttile_query_v2.4.8.sql:
--------------------------------------------------------------------------------
1 | SELECT STRING_AGG(mvtl, '') AS mvt FROM (
2 | SELECT COALESCE(ST_AsMVT(t, 'housenumber', 4096, 'mvtgeometry'), '') as mvtl FROM (SELECT ST_Expand(TileBBox($1, $2, $3), 1252344.2714243282/2^$1) as ST_AsMVTGeom(geometry, TileBBox($1, $2, $3), 4096, 128, true) AS mvtgeometry, $1 AS housenumber, NULLIF(tags->'name:en', '') AS "name:en", NULLIF(tags->'name:de', '') AS "name:de", NULLIF(tags->'name:cs', '') AS "name:cs", NULLIF(tags->'name_int', '') AS "name_int", NULLIF(tags->'name:latin', '') AS "name:latin", NULLIF(tags->'name:nonlatin', '') AS "name:nonlatin" FROM (SELECT 'name:en=>"enname"'::hstore as tags) AS tt) AS t WHERE mvtgeometry IS NOT NULL
3 | UNION ALL
4 | SELECT COALESCE(ST_AsMVT(t, 'enumfield', 4096, 'mvtgeometry'), '') as mvtl FROM (SELECT TileBBox($1, $2, $3) as ST_AsMVTGeom(geometry, TileBBox($1, $2, $3), 4096, 0, true) AS mvtgeometry, $1 AS osm_id, 'foo' AS class) AS t WHERE mvtgeometry IS NOT NULL
5 | UNION ALL
6 | SELECT COALESCE(ST_AsMVT(t, 'mountain_peak', 4096, 'mvtgeometry'), '') as mvtl FROM (SELECT ST_Expand(TileBBox($1, $2, $3), 10018754.171394626/2^$1) AS ST_AsMVTGeom(geometry, TileBBox($1, $2, $3), 4096, 1024, true) AS mvtgeometry, $1 AS osm_id, 'foo_name' AS name, 'foo_name_en' AS name_en, 'foo_name_de' AS name_de, 'foo_class' AS class, $1 AS ele, $1 AS ele_ft, $1 AS rank) AS t WHERE mvtgeometry IS NOT NULL
7 | ) AS all_layers
8 |
9 |
--------------------------------------------------------------------------------
/tests/expected/mvttile_query_v2.4.0dev-a.sql:
--------------------------------------------------------------------------------
1 | SELECT STRING_AGG(mvtl, '') AS mvt FROM (
2 | SELECT COALESCE(ST_AsMVT('housenumber', 4096, 'mvtgeometry', t), '') as mvtl FROM (SELECT ST_Expand(TileBBox($1, $2, $3), 1252344.2714243282/2^$1) as ST_AsMVTGeom(geometry, TileBBox($1, $2, $3), 4096, 128, true) AS mvtgeometry, $1 AS housenumber, NULLIF(tags->'name:en', '') AS "name:en", NULLIF(tags->'name:de', '') AS "name:de", NULLIF(tags->'name:cs', '') AS "name:cs", NULLIF(tags->'name_int', '') AS "name_int", NULLIF(tags->'name:latin', '') AS "name:latin", NULLIF(tags->'name:nonlatin', '') AS "name:nonlatin" FROM (SELECT 'name:en=>"enname"'::hstore as tags) AS tt) AS t WHERE mvtgeometry IS NOT NULL
3 | UNION ALL
4 | SELECT COALESCE(ST_AsMVT('enumfield', 4096, 'mvtgeometry', t), '') as mvtl FROM (SELECT TileBBox($1, $2, $3) as ST_AsMVTGeom(geometry, TileBBox($1, $2, $3), 4096, 0, true) AS mvtgeometry, $1 AS osm_id, 'foo' AS class) AS t WHERE mvtgeometry IS NOT NULL
5 | UNION ALL
6 | SELECT COALESCE(ST_AsMVT('mountain_peak', 4096, 'mvtgeometry', t), '') as mvtl FROM (SELECT ST_Expand(TileBBox($1, $2, $3), 10018754.171394626/2^$1) AS ST_AsMVTGeom(geometry, TileBBox($1, $2, $3), 4096, 1024, true) AS mvtgeometry, $1 AS osm_id, 'foo_name' AS name, 'foo_name_en' AS name_en, 'foo_name_de' AS name_de, 'foo_class' AS class, $1 AS ele, $1 AS ele_ft, $1 AS rank) AS t WHERE mvtgeometry IS NOT NULL
7 | ) AS all_layers
8 |
9 |
--------------------------------------------------------------------------------
/tests/expected/mvttile_query_v2.4.0dev.sql:
--------------------------------------------------------------------------------
1 | SELECT STRING_AGG(mvtl, '') AS mvt FROM (
2 | SELECT COALESCE(ST_AsMVT('housenumber', 4096, 'mvtgeometry', t), '') as mvtl FROM (SELECT ST_Expand(TileBBox($1, $2, $3), 1252344.2714243282/2^$1) as ST_AsMVTGeom(geometry, TileBBox($1, $2, $3), 4096, 128, true) AS mvtgeometry, $1 AS housenumber, NULLIF(tags->'name:en', '') AS "name:en", NULLIF(tags->'name:de', '') AS "name:de", NULLIF(tags->'name:cs', '') AS "name:cs", NULLIF(tags->'name_int', '') AS "name_int", NULLIF(tags->'name:latin', '') AS "name:latin", NULLIF(tags->'name:nonlatin', '') AS "name:nonlatin" FROM (SELECT 'name:en=>"enname"'::hstore as tags) AS tt) AS t WHERE mvtgeometry IS NOT NULL
3 | UNION ALL
4 | SELECT COALESCE(ST_AsMVT('enumfield', 4096, 'mvtgeometry', t), '') as mvtl FROM (SELECT TileBBox($1, $2, $3) as ST_AsMVTGeom(geometry, TileBBox($1, $2, $3), 4096, 0, true) AS mvtgeometry, $1 AS osm_id, 'foo' AS class) AS t WHERE mvtgeometry IS NOT NULL
5 | UNION ALL
6 | SELECT COALESCE(ST_AsMVT('mountain_peak', 4096, 'mvtgeometry', t), '') as mvtl FROM (SELECT ST_Expand(TileBBox($1, $2, $3), 10018754.171394626/2^$1) AS ST_AsMVTGeom(geometry, TileBBox($1, $2, $3), 4096, 1024, true) AS mvtgeometry, $1 AS osm_id, 'foo_name' AS name, 'foo_name_en' AS name_en, 'foo_name_de' AS name_de, 'foo_class' AS class, $1 AS ele, $1 AS ele_ft, $1 AS rank) AS t WHERE mvtgeometry IS NOT NULL
7 | ) AS all_layers
8 |
9 |
--------------------------------------------------------------------------------
/tests/expected/mvttile_query_v2.4.8-a.sql:
--------------------------------------------------------------------------------
1 | SELECT STRING_AGG(mvtl, '') AS mvt FROM (
2 | SELECT COALESCE(ST_AsMVT(t, 'housenumber', 4096, 'mvtgeometry'), '') as mvtl FROM (SELECT ST_Expand(TileBBox($1, $2, $3), 1252344.2714243282/2^$1) as ST_AsMVTGeom(geometry, TileBBox($1, $2, $3), 4096, 128, true) AS mvtgeometry, $1 AS housenumber, NULLIF(tags->'name:en', '') AS "name:en", NULLIF(tags->'name:de', '') AS "name:de", NULLIF(tags->'name:cs', '') AS "name:cs", NULLIF(tags->'name_int', '') AS "name_int", NULLIF(tags->'name:latin', '') AS "name:latin", NULLIF(tags->'name:nonlatin', '') AS "name:nonlatin" FROM (SELECT 'name:en=>"enname"'::hstore as tags) AS tt) AS t WHERE mvtgeometry IS NOT NULL
3 | UNION ALL
4 | SELECT COALESCE(ST_AsMVT(t, 'enumfield', 4096, 'mvtgeometry'), '') as mvtl FROM (SELECT TileBBox($1, $2, $3) as ST_AsMVTGeom(geometry, TileBBox($1, $2, $3), 4096, 0, true) AS mvtgeometry, $1 AS osm_id, 'foo' AS class) AS t WHERE mvtgeometry IS NOT NULL
5 | UNION ALL
6 | SELECT COALESCE(ST_AsMVT(t, 'mountain_peak', 4096, 'mvtgeometry'), '') as mvtl FROM (SELECT ST_Expand(TileBBox($1, $2, $3), 10018754.171394626/2^$1) AS ST_AsMVTGeom(geometry, TileBBox($1, $2, $3), 4096, 1024, true) AS mvtgeometry, $1 AS osm_id, 'foo_name' AS name, 'foo_name_en' AS name_en, 'foo_name_de' AS name_de, 'foo_class' AS class, $1 AS ele, $1 AS ele_ft, $1 AS rank) AS t WHERE mvtgeometry IS NOT NULL
7 | ) AS all_layers
8 |
9 |
--------------------------------------------------------------------------------
/bin/generate-mapping-graph:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | """
3 | Usage:
4 | generate-mapping-graph [] [--keep]
5 | [--format ]...
6 | generate-mapping-graph --help
7 | generate-mapping-graph --version
8 |
9 | If tileset file is given, will create one dir per layer
10 | in the output directory.
11 | If set, compares generated graphs with graphs that already
12 | exist at this location, and exit with non-zero code
13 | if they are not the same.
14 |
15 | Options:
16 | -k --keep If set, do not delete generated .dot file
17 | -f --format Specify which format(s) to output. [default: png]
18 | --help Show this screen.
19 | --version Show version.
20 | """
21 |
22 | from docopt import docopt
23 |
24 | import openmaptiles
25 | from openmaptiles.diagram import MappingGraph
26 |
27 |
28 | def main(args):
29 | exit(MappingGraph(
30 | args[''],
31 | args[''],
32 | args[''],
33 | not args['--keep'],
34 | args['--format'],
35 | ).run())
36 |
37 |
38 | if __name__ == '__main__':
39 | main(docopt(__doc__, version=openmaptiles.__version__))
40 |
--------------------------------------------------------------------------------
/tests/expected/mvttile_psql.sql:
--------------------------------------------------------------------------------
1 | SELECT STRING_AGG(mvtl, '') AS mvt FROM (
2 | SELECT COALESCE(ST_AsMVT(t, 'housenumber', 4096, 'mvtgeometry'), '') as mvtl FROM (SELECT ST_Expand(ST_TileEnvelope(:zoom, :x, :y), 1252344.2714243282/2^:zoom) as ST_AsMVTGeom(geometry, ST_TileEnvelope(:zoom, :x, :y), 4096, 128, true) AS mvtgeometry, :zoom AS housenumber, NULLIF(tags->'name:en', '') AS "name:en", NULLIF(tags->'name:de', '') AS "name:de", NULLIF(tags->'name:cs', '') AS "name:cs", NULLIF(tags->'name_int', '') AS "name_int", NULLIF(tags->'name:latin', '') AS "name:latin", NULLIF(tags->'name:nonlatin', '') AS "name:nonlatin" FROM (SELECT 'name:en=>"enname"'::hstore as tags) AS tt) AS t
3 | UNION ALL
4 | SELECT COALESCE(ST_AsMVT(t, 'enumfield', 4096, 'mvtgeometry', 'osm_id'), '') as mvtl FROM (SELECT ST_TileEnvelope(:zoom, :x, :y) as ST_AsMVTGeom(geometry, ST_TileEnvelope(:zoom, :x, :y), 4096, 0, true) AS mvtgeometry, :zoom AS osm_id, 'foo' AS class) AS t
5 | UNION ALL
6 | SELECT COALESCE(ST_AsMVT(t, 'mountain_peak', 4096, 'mvtgeometry', 'osm_id'), '') as mvtl FROM (SELECT ST_Expand(ST_TileEnvelope(:zoom, :x, :y), 10018754.171394626/2^:zoom) AS ST_AsMVTGeom(geometry, ST_TileEnvelope(:zoom, :x, :y), 4096, 1024, true) AS mvtgeometry, :zoom AS osm_id, 'foo_name' AS name, 'foo_name_en' AS name_en, 'foo_name_de' AS name_de, 'foo_class' AS class, :zoom AS ele, :zoom AS ele_ft, :zoom AS rank) AS t
7 | ) AS all_layers
8 |
9 |
--------------------------------------------------------------------------------
/bin/style-tools:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | """
3 | Usage:
4 | style-tools split