Merge branch 'master' into imposm3_filter_reject_require

This commit is contained in:
Lukas Martinelli 2017-01-18 15:39:40 +01:00 committed by GitHub
commit a865d6c970
33 changed files with 868 additions and 191 deletions

60
LICENSE.md Normal file
View File

@ -0,0 +1,60 @@
Copyright (c) 2016, KlokanTech.com & OpenMapTiles contributors.
All rights reserved.
The vector tile schema has been developed by Klokan Technologies GmbH and
was initially modelled after the cartography of the CARTO's Positron basemap
with permission from CartoDB Inc.
The vector tile schema has been refined and improved in cooperation with
the Wikimedia Foundation and is heavily influenced by years of
Paul Norman's experience of creating maps from OpenStreetMap data.
# Code license: BSD 3-Clause License
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# Design license: CC-BY 4.0
The cartography and visual design features of the map tile schema (also known as
the "look and feel" of the map) are licensed under the Creative Commons
Attribution 4.0 license.
To view a copy of the license, visit http://creativecommons.org/licenses/by/4.0/.
Products or services using maps derived from OpenMapTiles schema need to visibly
credit "OpenMapTiles.org" or reference "OpenMapTiles" with a link to
http://openmaptiles.org/.
For a browsable electronic map based on OpenMapTiles and OpenStreetMap data, the
credit should appear in the corner of the map. For example:
[© OpenMapTiles](http://openmaptiles.org/) [© OpenStreetMap contributors](http://www.openstreetmap.org/copyright)
For printed and static maps a similar attribution should be made in a textual
description near the image, in the same fashion as if you cite a photograph.
Exceptions to OpenMapTiles attribution requirement can be in a written form granted
by Klokan Technologies GmbH (info@klokantech.com).
The project contributors grant Klokan Technologies GmbH the license to give such
exceptions on a commercial basis.

View File

@ -10,7 +10,7 @@ help:
@echo " "
@echo "Hints for designers:"
@echo " ....TODO.... # start Maputnik "
@echo " ....TODO.... # start Tileserver-gl-light"
@echo " make start-tileserver # start klokantech/tileserver-gl [ see localhost:8080 ] "
@echo " make start-mapbox-studio # start Mapbox Studio"
@echo " "
@echo "Hints for developers:"
@ -61,9 +61,9 @@ refresh-docker-images:
remove-docker-images:
@echo "Deleting all openmaptiles related docker image(s)..."
@docker-compose down
@docker images | grep "<none>" | awk -F" " '{print $$3}' | xargs --no-run-if-empty docker rmi
@docker images | grep "openmaptiles" | awk -F" " '{print $$3}' | xargs --no-run-if-empty docker rmi
@docker images | grep "osm2vectortiles/mapbox-studio" | awk -F" " '{print $$3}' | xargs --no-run-if-empty docker rmi
@docker images | grep "openmaptiles" | awk -F" " '{print $$3}' | xargs --no-run-if-empty docker rmi -f
@docker images | grep "osm2vectortiles/mapbox-studio" | awk -F" " '{print $$3}' | xargs --no-run-if-empty docker rmi -f
@docker images | grep "klokantech/tileserver-gl" | awk -F" " '{print $$3}' | xargs --no-run-if-empty docker rmi -f
docker-unnecessary-clean:
@echo "Deleting unnecessary container(s)..."
@ -117,6 +117,26 @@ list:
download-geofabrik-list:
docker-compose run --rm import-osm ./download-geofabrik-list.sh
start-tileserver:
@echo " "
@echo "***********************************************************"
@echo "* "
@echo "* Download/refresh klokantech/tileserver-gl docker image"
@echo "* see documentation: https://github.com/klokantech/tileserver-gl"
@echo "* "
@echo "***********************************************************"
@echo " "
docker pull klokantech/tileserver-gl
@echo " "
@echo "***********************************************************"
@echo "* "
@echo "* Start klokantech/tileserver-gl "
@echo "* ----------------------------> check localhost:8080 "
@echo "* "
@echo "***********************************************************"
@echo " "
docker run -it --rm -v $$(pwd)/data:/data -p 8080:80 klokantech/tileserver-gl
start-mapbox-studio:
docker-compose up mapbox-studio

View File

@ -272,14 +272,18 @@ This is generating `.mbtiles` for your area : [ MIN_ZOOM: "0" - MAX_ZOOM: "7"
./quickstart.sh yukon
```
### Check other commands
### Check tileserver
`make help`
start:
* ` make start-tileserver`
and the generated maps are going to be available in webbrowser on [localhost:8080](http://localhost:8080/).
This is only a quick preview, because your mbtiles only generated to zoom level 7 !
### Change MIN_ZOOM and MAX_ZOOM
modify the settings in the `.env` file
modify the settings in the `.env` file, the defaults :
* QUICKSTART_MIN_ZOOM=0
* QUICKSTART_MAX_ZOOM=7
@ -292,3 +296,6 @@ Hints:
* Small increments! Never starts with the MAX_ZOOM = 14
* The suggested MAX_ZOOM = 14 - use only with small extracts
### Check other commands
`make help`

View File

@ -1,4 +1,4 @@
## OpenMapTiles
## OpenMapTiles [![Build Status](https://travis-ci.org/openmaptiles/openmaptiles.svg?branch=master)](https://travis-ci.org/openmaptiles/openmaptiles)
OpenMapTiles is an extensible and open vector tile schema for a OpenStreetMap basemap. It is used to generate vector tiles for [openmaptiles.org](http://openmaptiles.org/) and [openmaptiles.com](http://openmaptiles.com/).
@ -116,7 +116,7 @@ Each time you modify layer SQL code run `make` and `docker-compose run import-sq
make clean && make && docker-compose run import-sql
```
Now you are ready to **generate the vector tiles** using a single process (for a full blown distributed workflow of rendering tiles check out [openmaptiles/distributed](https://github.com/openmaptiles/distributed)). Using environment variables
Now you are ready to **generate the vector tiles**. Using environment variables
you can limit the bounding box and zoom levels of what you want to generate (`docker-compose.yml`).
```
@ -125,6 +125,14 @@ docker-compose run generate-vectortiles
## License
*LICENSE HAS NOT BEEN YET DECIDED*
All code in this repository is under the [BSD license](./LICENSE.md) and the cartography decisions encoded in the schema and SQL are licensed under [CC-BY](./LICENSE.md).
All code in this repository is under the [MIT license](./LICENSE) and the cartography decisions encoded in the schema and SQL is licensed under [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
Products or services using maps derived from OpenMapTiles schema need to visibly credit "OpenMapTiles.org" or reference "OpenMapTiles" with a link to http://openmaptiles.org/. Exceptions to attribution requirement can be granted on request.
For a browsable electronic map based on OpenMapTiles and OpenStreetMap data, the
credit should appear in the corner of the map. For example:
[© OpenMapTiles](http://openmaptiles.org/) [© OpenStreetMap contributors](http://www.openstreetmap.org/copyright)
For printed and static maps a similar attribution should be made in a textual
description near the image, in the same fashion as if you cite a photograph.

38
UPDATE.md Normal file
View File

@ -0,0 +1,38 @@
# Keep the vector tiles updated
Once you have imported OpenMapTiles you can also keep it up to date by importing the latest OSM changes and
regenerating the tables.
## Import
You can either keep the database up to date based on the daily OSM change feed
or import specific change files.
### Keep Database Updated
You can use the new imposm3 feature to keep the database updated (thanks to the [work for @stirringhalo](https://github.com/openmaptiles/openmaptiles/pull/131)). This will automatically download
the OSM change feed and import it into the database.
After each run of you should also have a list of tiles that have updated.
```
docker-compose run update-osm
```
### Import Change File
Given you have a file `changes.osc.gz` in your import folder. Once you ran the import command you should also have a list of tiles that have updated.
```
docker-compose run import-osm-diff
```
## Generate Changed Tiles
After the import has finished **imposm3** will store a list of tiles in text format in the `diffdir`.
Copy the as `tiles.txt` to the import folder.
Now run the command to read the tilelist and write the vector tiles for it to a new MBTiles.
```
docker-compose run generate-changed-vectortiles
```

View File

@ -36,6 +36,35 @@ services:
- ./data:/import
- ./build:/mapping
- cache:/cache
import-osmborder:
image: "openmaptiles/import-osmborder:0.2"
env_file: .env
links:
- postgres
import-osm-diff:
image: "openmaptiles/import-osm:latest"
env_file: .env
command: ./import_diff.sh
environment:
DIFF_MODE: ${DIFF_MODE}
links:
- postgres
volumes:
- ./data:/import
- ./build:/mapping
- cache:/cache
update-osm:
image: "openmaptiles/import-osm:latest"
env_file: .env
environment:
DIFF_MODE: ${DIFF_MODE}
command: ./import_update.sh
links:
- postgres
volumes:
- ./data:/import
- ./build:/mapping
- cache:/cache
import-sql:
image: "openmaptiles/import-sql:0.1"
env_file: .env
@ -59,6 +88,15 @@ services:
- postgres:db
ports:
- "3000:3000"
generate-changed-vectortiles:
image: "openmaptiles/generate-vectortiles:0.1"
command: ./export-list.sh
volumes:
- ./data:/export
- ./build/openmaptiles.tm2source:/tm2source
links:
- postgres:postgres
env_file: .env
generate-vectortiles:
image: "openmaptiles/generate-vectortiles:0.1"
volumes:

View File

@ -23,7 +23,7 @@ tables:
key: aeroway
type: string
- name: area
type: pseudoarea
type: webmerc_area
mapping:
aeroway:
- aerodrome

View File

@ -3,7 +3,7 @@
-- etldoc: ne_110m_admin_0_boundary_lines_land -> boundary_z0
CREATE OR REPLACE VIEW boundary_z0 AS (
SELECT geometry, 2 AS admin_level
SELECT geometry, 2 AS admin_level, false AS disputed, false AS maritime
FROM ne_110m_admin_0_boundary_lines_land
);
@ -11,10 +11,10 @@ CREATE OR REPLACE VIEW boundary_z0 AS (
-- etldoc: ne_50m_admin_1_states_provinces_lines -> boundary_z1
CREATE OR REPLACE VIEW boundary_z1 AS (
SELECT geometry, 2 AS admin_level
SELECT geometry, 2 AS admin_level, false AS disputed, false AS maritime
FROM ne_50m_admin_0_boundary_lines_land
UNION ALL
SELECT geometry, 4 AS admin_level
SELECT geometry, 4 AS admin_level, false AS disputed, false AS maritime
FROM ne_50m_admin_1_states_provinces_lines
WHERE scalerank <= 2
);
@ -24,102 +24,108 @@ CREATE OR REPLACE VIEW boundary_z1 AS (
-- etldoc: ne_50m_admin_1_states_provinces_lines -> boundary_z3
CREATE OR REPLACE VIEW boundary_z3 AS (
SELECT geometry, 2 AS admin_level
SELECT geometry, 2 AS admin_level, false AS disputed, false AS maritime
FROM ne_50m_admin_0_boundary_lines_land
UNION ALL
SELECT geometry, 4 AS admin_level
SELECT geometry, 4 AS admin_level, false AS disputed, false AS maritime
FROM ne_50m_admin_1_states_provinces_lines
);
-- etldoc: ne_10m_admin_0_boundary_lines_land -> boundary_z4
-- etldoc: ne_10m_admin_1_states_provinces_lines_shp -> boundary_z4
-- etldoc: osm_border_linestring_gen10 -> boundary_z4
CREATE OR REPLACE VIEW boundary_z4 AS (
SELECT geometry, 2 AS admin_level
SELECT geometry, 2 AS admin_level, false AS disputed, false AS maritime
FROM ne_10m_admin_0_boundary_lines_land
UNION ALL
SELECT geometry, 4 AS admin_level
SELECT geometry, 4 AS admin_level, false AS disputed, false AS maritime
FROM ne_10m_admin_1_states_provinces_lines_shp
WHERE scalerank <= 3 AND featurecla = 'Adm-1 boundary'
UNION ALL
SELECT geometry, admin_level, disputed, maritime
FROM osm_border_linestring_gen10
WHERE maritime=true AND admin_level <= 2
);
-- etldoc: ne_10m_admin_0_boundary_lines_land -> boundary_z5
-- etldoc: ne_10m_admin_1_states_provinces_lines_shp -> boundary_z5
-- etldoc: osm_border_linestring_gen9 -> boundary_z5
CREATE OR REPLACE VIEW boundary_z5 AS (
SELECT geometry, 2 AS admin_level
SELECT geometry, 2 AS admin_level, false AS disputed, false AS maritime
FROM ne_10m_admin_0_boundary_lines_land
UNION ALL
SELECT geometry, 4 AS admin_level
SELECT geometry, 4 AS admin_level, false AS disputed, false AS maritime
FROM ne_10m_admin_1_states_provinces_lines_shp
WHERE scalerank <= 7 AND featurecla = 'Adm-1 boundary'
UNION ALL
SELECT geometry, admin_level, disputed, maritime
FROM osm_border_linestring_gen9
WHERE maritime=true AND admin_level <= 2
);
-- etldoc: ne_10m_admin_0_boundary_lines_land -> boundary_z6
-- etldoc: ne_10m_admin_1_states_provinces_lines_shp -> boundary_z6
-- etldoc: osm_border_linestring_gen8 -> boundary_z6
CREATE OR REPLACE VIEW boundary_z6 AS (
SELECT geometry, 2 AS admin_level
FROM ne_10m_admin_0_boundary_lines_land
UNION ALL
SELECT geometry, 4 AS admin_level
FROM ne_10m_admin_1_states_provinces_lines_shp
WHERE scalerank <= 9 AND featurecla = 'Adm-1 boundary'
SELECT geometry, admin_level, disputed, maritime
FROM osm_border_linestring_gen8
WHERE admin_level <= 4
);
-- etldoc: ne_10m_admin_0_boundary_lines_land -> boundary_z7
-- etldoc: ne_10m_admin_1_states_provinces_lines_shp -> boundary_z7
-- etldoc: osm_border_linestring_gen7 -> boundary_z7
CREATE OR REPLACE VIEW boundary_z7 AS (
SELECT geometry, 2 AS admin_level
FROM ne_10m_admin_0_boundary_lines_land
UNION ALL
SELECT geometry, 4 AS admin_level
FROM ne_10m_admin_1_states_provinces_lines_shp
WHERE featurecla = 'Adm-1 boundary'
SELECT geometry, admin_level, disputed, maritime
FROM osm_border_linestring_gen7
WHERE admin_level <= 4
);
-- etldoc: osm_boundary_linestring_gen5 -> boundary_z8
-- etldoc: osm_border_linestring_gen6 -> boundary_z8
CREATE OR REPLACE VIEW boundary_z8 AS (
SELECT geometry, admin_level
FROM osm_boundary_linestring_gen5
WHERE admin_level <= 4 AND ST_Length(geometry) > 1000
SELECT geometry, admin_level, disputed, maritime
FROM osm_border_linestring_gen6
WHERE admin_level <= 4
);
-- etldoc: osm_boundary_linestring_gen4 -> boundary_z9
-- etldoc: osm_border_linestring_gen5 -> boundary_z9
CREATE OR REPLACE VIEW boundary_z9 AS (
SELECT geometry, admin_level
FROM osm_boundary_linestring_gen4
SELECT geometry, admin_level, disputed, maritime
FROM osm_border_linestring_gen5
WHERE admin_level <= 6
);
-- etldoc: osm_boundary_linestring_gen3 -> boundary_z10
-- etldoc: osm_border_linestring_gen4 -> boundary_z10
CREATE OR REPLACE VIEW boundary_z10 AS (
SELECT geometry, admin_level
FROM osm_boundary_linestring_gen3
SELECT geometry, admin_level, disputed, maritime
FROM osm_border_linestring_gen4
WHERE admin_level <= 6
);
-- etldoc: osm_boundary_linestring_gen2 -> boundary_z11
-- etldoc: osm_border_linestring_gen3 -> boundary_z11
CREATE OR REPLACE VIEW boundary_z11 AS (
SELECT geometry, admin_level
FROM osm_boundary_linestring_gen2
SELECT geometry, admin_level, disputed, maritime
FROM osm_border_linestring_gen3
WHERE admin_level <= 8
);
-- etldoc: osm_boundary_linestring_gen1 -> boundary_z12
-- etldoc: osm_border_linestring_gen2 -> boundary_z12
CREATE OR REPLACE VIEW boundary_z12 AS (
SELECT geometry, admin_level
FROM osm_boundary_linestring_gen1
SELECT geometry, admin_level, disputed, maritime
FROM osm_border_linestring_gen2
);
-- etldoc: osm_border_linestring_gen1 -> boundary_z12
CREATE OR REPLACE VIEW boundary_z13 AS (
SELECT geometry, admin_level, disputed, maritime
FROM osm_border_linestring_gen1
);
-- etldoc: layer_boundary[shape=record fillcolor=lightpink, style="rounded,filled",
-- etldoc: label="<sql> layer_boundary |<z0> z0 |<z1_2> z1_2 | <z3> z3 | <z4> z4 | <z5> z5 | <z6> z6 | <z7> z7 | <z8> z8 | <z9> z9 |<z10> z10 |<z11> z11 |<z12> z12|<z13> z13+"]
CREATE OR REPLACE FUNCTION layer_boundary (bbox geometry, zoom_level int)
RETURNS TABLE(geometry geometry, admin_level int) AS $$
SELECT geometry, admin_level FROM (
RETURNS TABLE(geometry geometry, admin_level int, disputed int, maritime int) AS $$
SELECT geometry, admin_level, disputed::int, maritime::int FROM (
-- etldoc: boundary_z0 -> layer_boundary:z0
SELECT * FROM boundary_z0 WHERE geometry && bbox AND zoom_level = 0
UNION ALL
@ -156,7 +162,7 @@ RETURNS TABLE(geometry geometry, admin_level int) AS $$
-- etldoc: boundary_z12 -> layer_boundary:z12
SELECT * FROM boundary_z12 WHERE geometry && bbox AND zoom_level = 12
UNION ALL
-- etldoc: boundary_z12 -> layer_boundary:z13
SELECT * FROM boundary_z12 WHERE geometry && bbox AND zoom_level >= 13
-- etldoc: boundary_z13 -> layer_boundary:z13
SELECT * FROM boundary_z13 WHERE geometry && bbox AND zoom_level >= 13
) AS zoom_levels;
$$ LANGUAGE SQL IMMUTABLE;

View File

@ -15,12 +15,16 @@ layer:
At low zoom levels the Natural Earth boundaries are mapped to the equivalent admin levels.
disputed:
description: |
Mark with `1` if the boundary is disputed.
Mark with `1` if the border is disputed.
values: [0, 1]
maritime:
description: |
Mark with `1` if it is a maritime border.
values: [0, 1]
buffer_size: 4
datasource:
geometry_field: geometry
query: (SELECT geometry, admin_level FROM layer_boundary(!bbox!, z(!scale_denominator!))) AS t
query: (SELECT geometry, admin_level, disputed, maritime FROM layer_boundary(!bbox!, z(!scale_denominator!))) AS t
schema:
- ./boundary.sql
datasources:

View File

@ -16,7 +16,7 @@ tables:
- name: geometry
type: validated_geometry
- name: area
type: pseudoarea
type: webmerc_area
- name: building
key: building
type: string

View File

@ -1,4 +1,45 @@
DROP TRIGGER IF EXISTS trigger_flag ON osm_housenumber_point;
DROP TRIGGER IF EXISTS trigger_refresh ON housenumber.updates;
-- etldoc: osm_housenumber_point -> osm_housenumber_point
UPDATE osm_housenumber_point SET geometry=topoint(geometry)
WHERE ST_GeometryType(geometry) <> 'ST_Point';
CREATE OR REPLACE FUNCTION convert_housenumber_point() RETURNS VOID AS $$
BEGIN
UPDATE osm_housenumber_point SET geometry=ST_PointOnSurface(geometry) WHERE ST_GeometryType(geometry) <> 'ST_Point';
END;
$$ LANGUAGE plpgsql;
SELECT convert_housenumber_point();
-- Handle updates
CREATE SCHEMA IF NOT EXISTS housenumber;
CREATE TABLE IF NOT EXISTS housenumber.updates(id serial primary key, t text, unique (t));
CREATE OR REPLACE FUNCTION housenumber.flag() RETURNS trigger AS $$
BEGIN
INSERT INTO housenumber.updates(t) VALUES ('y') ON CONFLICT(t) DO NOTHING;
RETURN null;
END;
$$ language plpgsql;
CREATE OR REPLACE FUNCTION housenumber.refresh() RETURNS trigger AS
$BODY$
BEGIN
RAISE LOG 'Refresh housenumber';
PERFORM convert_housenumber_point();
DELETE FROM housenumber.updates;
RETURN null;
END;
$BODY$
language plpgsql;
CREATE TRIGGER trigger_flag
AFTER INSERT OR UPDATE OR DELETE ON osm_housenumber_point
FOR EACH STATEMENT
EXECUTE PROCEDURE housenumber.flag();
CREATE CONSTRAINT TRIGGER trigger_refresh
AFTER INSERT ON housenumber.updates
INITIALLY DEFERRED
FOR EACH ROW
EXECUTE PROCEDURE housenumber.refresh();

View File

@ -58,7 +58,7 @@ tables:
key: wetland
type: string
- name: area
type: pseudoarea
type: webmerc_area
mapping:
landuse:
- allotments

View File

@ -39,7 +39,7 @@ tables:
key: leisure
type: string
- name: area
type: pseudoarea
type: webmerc_area
mapping:
amenity:
- school

View File

@ -67,7 +67,7 @@ tables:
key: boundary
type: string
- name: area
type: pseudoarea
type: webmerc_area
mapping:
leisure:
- nature_reserve

View File

@ -1,5 +1,46 @@
-- etldoc: osm_island_polygon -> osm_island_polygon
UPDATE osm_island_polygon SET geometry=topoint(geometry)
WHERE ST_GeometryType(geometry) <> 'ST_Point';
DROP TRIGGER IF EXISTS trigger_flag ON osm_island_polygon;
DROP TRIGGER IF EXISTS trigger_refresh ON place_island.updates;
ANALYZE osm_island_polygon;
-- etldoc: osm_island_polygon -> osm_island_polygon
CREATE OR REPLACE FUNCTION convert_island_polygon_point() RETURNS VOID AS $$
BEGIN
UPDATE osm_island_polygon SET geometry=ST_PointOnSurface(geometry) WHERE ST_GeometryType(geometry) <> 'ST_Point';
ANALYZE osm_island_polygon;
END;
$$ LANGUAGE plpgsql;
SELECT convert_island_polygon_point();
-- Handle updates
CREATE SCHEMA IF NOT EXISTS place_island;
CREATE TABLE IF NOT EXISTS place_island.updates(id serial primary key, t text, unique (t));
CREATE OR REPLACE FUNCTION place_island.flag() RETURNS trigger AS $$
BEGIN
INSERT INTO place_island.updates(t) VALUES ('y') ON CONFLICT(t) DO NOTHING;
RETURN null;
END;
$$ language plpgsql;
CREATE OR REPLACE FUNCTION place_island.refresh() RETURNS trigger AS
$BODY$
BEGIN
RAISE LOG 'Refresh place_island';
PERFORM convert_island_polygon_point();
DELETE FROM place_island.updates;
RETURN null;
END;
$BODY$
language plpgsql;
CREATE TRIGGER trigger_flag
AFTER INSERT OR UPDATE OR DELETE ON osm_island_polygon
FOR EACH STATEMENT
EXECUTE PROCEDURE place_island.flag();
CREATE CONSTRAINT TRIGGER trigger_refresh
AFTER INSERT ON place_island.updates
INITIALLY DEFERRED
FOR EACH ROW
EXECUTE PROCEDURE place_island.refresh();

View File

@ -21,7 +21,7 @@ RETURNS TABLE(osm_id bigint, geometry geometry, name text, name_en text, class t
osm_id, geometry, name, COALESCE(NULLIF(name_en, ''), name) AS name_en,
'country' AS class, "rank", NULL::int AS capital
FROM osm_country_point
WHERE geometry && bbox AND "rank" <= zoom_level AND name <> ''
WHERE geometry && bbox AND "rank" <= zoom_level + 1 AND name <> ''
UNION ALL
-- etldoc: osm_state_point -> layer_place:z0_3

View File

@ -97,7 +97,7 @@ tables:
- name: geometry
type: geometry
- name: area
type: pseudoarea
type: webmerc_area
- *name
- *name_en
- *name_de

View File

@ -1,38 +1,82 @@
DROP TRIGGER IF EXISTS trigger_flag ON osm_city_point;
DROP TRIGGER IF EXISTS trigger_refresh ON place_city.updates;
CREATE EXTENSION IF NOT EXISTS unaccent;
-- Clear OSM key:rank ( https://github.com/openmaptiles/openmaptiles/issues/108 )
-- etldoc: osm_city_point -> osm_city_point
UPDATE osm_city_point AS osm SET "rank" = NULL WHERE "rank" IS NOT NULL;
CREATE OR REPLACE FUNCTION update_osm_city_point() RETURNS VOID AS $$
BEGIN
-- etldoc: ne_10m_populated_places -> osm_city_point
-- etldoc: osm_city_point -> osm_city_point
-- Clear OSM key:rank ( https://github.com/openmaptiles/openmaptiles/issues/108 )
-- etldoc: osm_city_point -> osm_city_point
UPDATE osm_city_point AS osm SET "rank" = NULL WHERE "rank" IS NOT NULL;
WITH important_city_point AS (
SELECT osm.geometry, osm.osm_id, osm.name, osm.name_en, ne.scalerank, ne.labelrank
FROM ne_10m_populated_places AS ne, osm_city_point AS osm
WHERE
(
ne.name ILIKE osm.name OR
ne.name ILIKE osm.name_en OR
ne.namealt ILIKE osm.name OR
ne.namealt ILIKE osm.name_en OR
ne.meganame ILIKE osm.name OR
ne.meganame ILIKE osm.name_en OR
ne.gn_ascii ILIKE osm.name OR
ne.gn_ascii ILIKE osm.name_en OR
ne.nameascii ILIKE osm.name OR
ne.nameascii ILIKE osm.name_en OR
ne.name = unaccent(osm.name)
)
AND osm.place IN ('city', 'town', 'village')
AND ST_DWithin(ne.geometry, osm.geometry, 50000)
)
UPDATE osm_city_point AS osm
-- Move scalerank to range 1 to 10 and merge scalerank 5 with 6 since not enough cities
-- are in the scalerank 5 bucket
SET "rank" = CASE WHEN scalerank <= 5 THEN scalerank + 1 ELSE scalerank END
FROM important_city_point AS ne
WHERE osm.osm_id = ne.osm_id;
-- etldoc: ne_10m_populated_places -> osm_city_point
-- etldoc: osm_city_point -> osm_city_point
WITH important_city_point AS (
SELECT osm.geometry, osm.osm_id, osm.name, osm.name_en, ne.scalerank, ne.labelrank
FROM ne_10m_populated_places AS ne, osm_city_point AS osm
WHERE
(
ne.name ILIKE osm.name OR
ne.name ILIKE osm.name_en OR
ne.namealt ILIKE osm.name OR
ne.namealt ILIKE osm.name_en OR
ne.meganame ILIKE osm.name OR
ne.meganame ILIKE osm.name_en OR
ne.gn_ascii ILIKE osm.name OR
ne.gn_ascii ILIKE osm.name_en OR
ne.nameascii ILIKE osm.name OR
ne.nameascii ILIKE osm.name_en OR
ne.name = unaccent(osm.name)
)
AND osm.place IN ('city', 'town', 'village')
AND ST_DWithin(ne.geometry, osm.geometry, 50000)
)
UPDATE osm_city_point AS osm
-- Move scalerank to range 1 to 10 and merge scalerank 5 with 6 since not enough cities
-- are in the scalerank 5 bucket
SET "rank" = CASE WHEN scalerank <= 5 THEN scalerank + 1 ELSE scalerank END
FROM important_city_point AS ne
WHERE osm.osm_id = ne.osm_id;
END;
$$ LANGUAGE plpgsql;
SELECT update_osm_city_point();
CREATE INDEX IF NOT EXISTS osm_city_point_rank_idx ON osm_city_point("rank");
-- Handle updates
CREATE SCHEMA IF NOT EXISTS place_city;
CREATE TABLE IF NOT EXISTS place_city.updates(id serial primary key, t text, unique (t));
CREATE OR REPLACE FUNCTION place_city.flag() RETURNS trigger AS $$
BEGIN
INSERT INTO place_city.updates(t) VALUES ('y') ON CONFLICT(t) DO NOTHING;
RETURN null;
END;
$$ language plpgsql;
CREATE OR REPLACE FUNCTION place_city.refresh() RETURNS trigger AS
$BODY$
BEGIN
RAISE LOG 'Refresh place_city rank';
PERFORM update_osm_city_point();
DELETE FROM place_city.updates;
RETURN null;
END;
$BODY$
language plpgsql;
CREATE TRIGGER trigger_flag
AFTER INSERT OR UPDATE OR DELETE ON osm_city_point
FOR EACH STATEMENT
EXECUTE PROCEDURE place_city.flag();
CREATE CONSTRAINT TRIGGER trigger_refresh
AFTER INSERT ON place_city.updates
INITIALLY DEFERRED
FOR EACH ROW
EXECUTE PROCEDURE place_city.refresh();

View File

@ -1,34 +1,79 @@
DROP TRIGGER IF EXISTS trigger_flag ON osm_country_point;
DROP TRIGGER IF EXISTS trigger_refresh ON place_country.updates;
ALTER TABLE osm_country_point DROP CONSTRAINT IF EXISTS osm_country_point_rank_constraint;
-- etldoc: ne_10m_admin_0_countries -> osm_country_point
-- etldoc: osm_country_point -> osm_country_point
WITH important_country_point AS (
SELECT osm.geometry, osm.osm_id, osm.name, COALESCE(NULLIF(osm.name_en, ''), ne.name) AS name_en, ne.scalerank, ne.labelrank
FROM ne_10m_admin_0_countries AS ne, osm_country_point AS osm
WHERE
-- We only match whether the point is within the Natural Earth polygon
-- because name matching is to difficult since OSM does not contain good
-- enough coverage of ISO codesy
ST_Within(osm.geometry, ne.geometry)
-- We leave out tiny countries
AND ne.scalerank <= 1
)
UPDATE osm_country_point AS osm
-- Normalize both scalerank and labelrank into a ranking system from 1 to 6
-- where the ranks are still distributed uniform enough across all countries
SET "rank" = LEAST(6, CEILING((scalerank + labelrank)/2.0))
FROM important_country_point AS ne
WHERE osm.osm_id = ne.osm_id;
CREATE OR REPLACE FUNCTION update_osm_country_point() RETURNS VOID AS $$
BEGIN
UPDATE osm_country_point AS osm
SET "rank" = 6
WHERE "rank" IS NULL;
WITH important_country_point AS (
SELECT osm.geometry, osm.osm_id, osm.name, COALESCE(NULLIF(osm.name_en, ''), ne.name) AS name_en, ne.scalerank, ne.labelrank
FROM ne_10m_admin_0_countries AS ne, osm_country_point AS osm
WHERE
-- We only match whether the point is within the Natural Earth polygon
-- because name matching is to difficult since OSM does not contain good
-- enough coverage of ISO codesy
ST_Within(osm.geometry, ne.geometry)
-- We leave out tiny countries
AND ne.scalerank <= 1
)
UPDATE osm_country_point AS osm
-- Normalize both scalerank and labelrank into a ranking system from 1 to 6
-- where the ranks are still distributed uniform enough across all countries
SET "rank" = LEAST(6, CEILING((scalerank + labelrank)/2.0))
FROM important_country_point AS ne
WHERE osm.osm_id = ne.osm_id;
-- TODO: This shouldn't be necessary? The rank function makes something wrong...
UPDATE osm_country_point AS osm
SET "rank" = 1
WHERE "rank" = 0;
UPDATE osm_country_point AS osm
SET "rank" = 6
WHERE "rank" IS NULL;
ALTER TABLE osm_country_point ADD CONSTRAINT osm_country_point_rank_constraint CHECK("rank" BETWEEN 1 AND 6);
-- TODO: This shouldn't be necessary? The rank function makes something wrong...
UPDATE osm_country_point AS osm
SET "rank" = 1
WHERE "rank" = 0;
END;
$$ LANGUAGE plpgsql;
SELECT update_osm_country_point();
-- ALTER TABLE osm_country_point ADD CONSTRAINT osm_country_point_rank_constraint CHECK("rank" BETWEEN 1 AND 6);
CREATE INDEX IF NOT EXISTS osm_country_point_rank_idx ON osm_country_point("rank");
-- Handle updates
CREATE SCHEMA IF NOT EXISTS place_country;
CREATE TABLE IF NOT EXISTS place_country.updates(id serial primary key, t text, unique (t));
CREATE OR REPLACE FUNCTION place_country.flag() RETURNS trigger AS $$
BEGIN
INSERT INTO place_country.updates(t) VALUES ('y') ON CONFLICT(t) DO NOTHING;
RETURN null;
END;
$$ language plpgsql;
CREATE OR REPLACE FUNCTION place_country.refresh() RETURNS trigger AS
$BODY$
BEGIN
RAISE LOG 'Refresh place_country rank';
PERFORM update_osm_country_point();
DELETE FROM place_country.updates;
RETURN null;
END;
$BODY$
language plpgsql;
CREATE TRIGGER trigger_flag
AFTER INSERT OR UPDATE OR DELETE ON osm_country_point
FOR EACH STATEMENT
EXECUTE PROCEDURE place_country.flag();
CREATE CONSTRAINT TRIGGER trigger_refresh
AFTER INSERT ON place_country.updates
INITIALLY DEFERRED
FOR EACH ROW
EXECUTE PROCEDURE place_country.refresh();

View File

@ -1,30 +1,75 @@
DROP TRIGGER IF EXISTS trigger_flag ON osm_state_point;
DROP TRIGGER IF EXISTS trigger_refresh ON place_state.updates;
ALTER TABLE osm_state_point DROP CONSTRAINT IF EXISTS osm_state_point_rank_constraint;
-- etldoc: ne_10m_admin_1_states_provinces_shp -> osm_state_point
-- etldoc: osm_state_point -> osm_state_point
WITH important_state_point AS (
SELECT osm.geometry, osm.osm_id, osm.name, COALESCE(NULLIF(osm.name_en, ''), ne.name) AS name_en, ne.scalerank, ne.labelrank, ne.datarank
FROM ne_10m_admin_1_states_provinces_shp AS ne, osm_state_point AS osm
WHERE
-- We only match whether the point is within the Natural Earth polygon
-- because name matching is difficult
ST_Within(osm.geometry, ne.geometry)
-- We leave out leess important states
AND ne.scalerank <= 3 AND ne.labelrank <= 2
)
UPDATE osm_state_point AS osm
-- Normalize both scalerank and labelrank into a ranking system from 1 to 6.
SET "rank" = LEAST(6, CEILING((scalerank + labelrank + datarank)/3.0))
FROM important_state_point AS ne
WHERE osm.osm_id = ne.osm_id;
CREATE OR REPLACE FUNCTION update_osm_state_point() RETURNS VOID AS $$
BEGIN
-- TODO: This shouldn't be necessary? The rank function makes something wrong...
UPDATE osm_state_point AS osm
SET "rank" = 1
WHERE "rank" = 0;
WITH important_state_point AS (
SELECT osm.geometry, osm.osm_id, osm.name, COALESCE(NULLIF(osm.name_en, ''), ne.name) AS name_en, ne.scalerank, ne.labelrank, ne.datarank
FROM ne_10m_admin_1_states_provinces_shp AS ne, osm_state_point AS osm
WHERE
-- We only match whether the point is within the Natural Earth polygon
-- because name matching is difficult
ST_Within(osm.geometry, ne.geometry)
-- We leave out leess important states
AND ne.scalerank <= 3 AND ne.labelrank <= 2
)
UPDATE osm_state_point AS osm
-- Normalize both scalerank and labelrank into a ranking system from 1 to 6.
SET "rank" = LEAST(6, CEILING((scalerank + labelrank + datarank)/3.0))
FROM important_state_point AS ne
WHERE osm.osm_id = ne.osm_id;
DELETE FROM osm_state_point WHERE "rank" IS NULL;
-- TODO: This shouldn't be necessary? The rank function makes something wrong...
UPDATE osm_state_point AS osm
SET "rank" = 1
WHERE "rank" = 0;
ALTER TABLE osm_state_point ADD CONSTRAINT osm_state_point_rank_constraint CHECK("rank" BETWEEN 1 AND 6);
DELETE FROM osm_state_point WHERE "rank" IS NULL;
END;
$$ LANGUAGE plpgsql;
SELECT update_osm_state_point();
-- ALTER TABLE osm_state_point ADD CONSTRAINT osm_state_point_rank_constraint CHECK("rank" BETWEEN 1 AND 6);
CREATE INDEX IF NOT EXISTS osm_state_point_rank_idx ON osm_state_point("rank");
-- Handle updates
CREATE SCHEMA IF NOT EXISTS place_state;
CREATE TABLE IF NOT EXISTS place_state.updates(id serial primary key, t text, unique (t));
CREATE OR REPLACE FUNCTION place_state.flag() RETURNS trigger AS $$
BEGIN
INSERT INTO place_state.updates(t) VALUES ('y') ON CONFLICT(t) DO NOTHING;
RETURN null;
END;
$$ language plpgsql;
CREATE OR REPLACE FUNCTION place_state.refresh() RETURNS trigger AS
$BODY$
BEGIN
RAISE LOG 'Refresh place_state rank';
PERFORM update_osm_state_point();
DELETE FROM place_state.updates;
RETURN null;
END;
$BODY$
language plpgsql;
CREATE TRIGGER trigger_flag
AFTER INSERT OR UPDATE OR DELETE ON osm_state_point
FOR EACH STATEMENT
EXECUTE PROCEDURE place_state.flag();
CREATE CONSTRAINT TRIGGER trigger_refresh
AFTER INSERT ON place_state.updates
INITIALLY DEFERRED
FOR EACH ROW
EXECUTE PROCEDURE place_state.refresh();

View File

@ -1,5 +1,47 @@
-- etldoc: osm_poi_polygon -> osm_poi_polygon
UPDATE osm_poi_polygon SET geometry=topoint(geometry)
WHERE ST_GeometryType(geometry) <> 'ST_Point';
DROP TRIGGER IF EXISTS trigger_flag ON osm_poi_polygon;
DROP TRIGGER IF EXISTS trigger_refresh ON poi.updates;
ANALYZE osm_poi_polygon;
-- etldoc: osm_poi_polygon -> osm_poi_polygon
CREATE OR REPLACE FUNCTION convert_poi_point() RETURNS VOID AS $$
BEGIN
UPDATE osm_poi_polygon SET geometry=ST_PointOnSurface(geometry) WHERE ST_GeometryType(geometry) <> 'ST_Point';
ANALYZE osm_poi_polygon;
END;
$$ LANGUAGE plpgsql;
SELECT convert_poi_point();
-- Handle updates
CREATE SCHEMA IF NOT EXISTS poi;
CREATE TABLE IF NOT EXISTS poi.updates(id serial primary key, t text, unique (t));
CREATE OR REPLACE FUNCTION poi.flag() RETURNS trigger AS $$
BEGIN
INSERT INTO poi.updates(t) VALUES ('y') ON CONFLICT(t) DO NOTHING;
RETURN null;
END;
$$ language plpgsql;
CREATE OR REPLACE FUNCTION poi.refresh() RETURNS trigger AS
$BODY$
BEGIN
RAISE LOG 'Refresh poi';
PERFORM convert_poi_point();
DELETE FROM poi.updates;
RETURN null;
END;
$BODY$
language plpgsql;
CREATE TRIGGER trigger_flag
AFTER INSERT OR UPDATE OR DELETE ON osm_poi_polygon
FOR EACH STATEMENT
EXECUTE PROCEDURE poi.flag();
CREATE CONSTRAINT TRIGGER trigger_refresh
AFTER INSERT ON poi.updates
INITIALLY DEFERRED
FOR EACH ROW
EXECUTE PROCEDURE poi.refresh();

View File

@ -96,6 +96,7 @@ RETURNS TABLE(osm_id bigint, geometry geometry, class text, ramp int, oneway int
)
UNION ALL
-- etldoc: osm_railway_linestring -> layer_transportation:z12"
-- etldoc: osm_railway_linestring -> layer_transportation:z13
-- etldoc: osm_railway_linestring -> layer_transportation:z14_
SELECT
@ -103,7 +104,7 @@ RETURNS TABLE(osm_id bigint, geometry geometry, class text, ramp int, oneway int
service_value(service) AS service,
is_bridge, is_tunnel, is_ford, is_ramp, is_oneway, z_order
FROM osm_railway_linestring
WHERE zoom_level = 13 AND (railway='rail' AND service = '')
WHERE zoom_level BETWEEN 12 AND 13 AND (railway='rail' AND service = '')
OR zoom_Level >= 14
UNION ALL

View File

@ -1,16 +1,18 @@
DROP TABLE IF EXISTS osm_transportation_name_linestring CASCADE;
DROP TABLE IF EXISTS osm_transportation_name_linestring_gen1 CASCADE;
DROP TABLE IF EXISTS osm_transportation_name_linestring_gen2 CASCADE;
DROP TABLE IF EXISTS osm_transportation_name_linestring_gen3 CASCADE;
DROP TRIGGER IF EXISTS trigger_flag ON osm_highway_linestring;
DROP TRIGGER IF EXISTS trigger_refresh ON transportation_name.updates;
-- Instead of using relations to find out the road names we
-- stitch together the touching ways with the same name
-- to allow for nice label rendering
-- Because this works well for roads that do not have relations as well
DROP MATERIALIZED VIEW IF EXISTS osm_transportation_name_linestring CASCADE;
DROP MATERIALIZED VIEW IF EXISTS osm_transportation_name_linestring_gen1 CASCADE;
DROP MATERIALIZED VIEW IF EXISTS osm_transportation_name_linestring_gen2 CASCADE;
DROP MATERIALIZED VIEW IF EXISTS osm_transportation_name_linestring_gen3 CASCADE;
-- etldoc: osm_highway_linestring -> osm_transportation_name_linestring
CREATE TABLE IF NOT EXISTS osm_transportation_name_linestring AS (
CREATE MATERIALIZED VIEW osm_transportation_name_linestring AS (
SELECT
(ST_Dump(geometry)).geom AS geometry,
-- NOTE: The osm_id is no longer the original one which can make it difficult
@ -18,14 +20,14 @@ CREATE TABLE IF NOT EXISTS osm_transportation_name_linestring AS (
member_osm_ids[0] AS osm_id,
member_osm_ids,
name,
ref,
ref,
highway,
z_order
FROM (
SELECT
ST_LineMerge(ST_Union(geometry)) AS geometry,
ST_LineMerge(ST_Collect(geometry)) AS geometry,
name,
ref,
ref,
highway,
min(z_order) AS z_order,
array_agg(DISTINCT osm_id) AS member_osm_ids
@ -35,11 +37,10 @@ CREATE TABLE IF NOT EXISTS osm_transportation_name_linestring AS (
GROUP BY name, highway, ref
) AS highway_union
);
CREATE INDEX IF NOT EXISTS osm_transportation_name_linestring_geometry_idx ON osm_transportation_name_linestring USING gist(geometry);
-- etldoc: osm_transportation_name_linestring -> osm_transportation_name_linestring_gen1
CREATE TABLE IF NOT EXISTS osm_transportation_name_linestring_gen1 AS (
CREATE MATERIALIZED VIEW osm_transportation_name_linestring_gen1 AS (
SELECT ST_Simplify(geometry, 50) AS geometry, osm_id, member_osm_ids, name, ref, highway, z_order
FROM osm_transportation_name_linestring
WHERE highway IN ('motorway','trunk') AND ST_Length(geometry) > 8000
@ -47,7 +48,7 @@ CREATE TABLE IF NOT EXISTS osm_transportation_name_linestring_gen1 AS (
CREATE INDEX IF NOT EXISTS osm_transportation_name_linestring_gen1_geometry_idx ON osm_transportation_name_linestring_gen1 USING gist(geometry);
-- etldoc: osm_transportation_name_linestring_gen1 -> osm_transportation_name_linestring_gen2
CREATE TABLE IF NOT EXISTS osm_transportation_name_linestring_gen2 AS (
CREATE MATERIALIZED VIEW osm_transportation_name_linestring_gen2 AS (
SELECT ST_Simplify(geometry, 120) AS geometry, osm_id, member_osm_ids, name, ref, highway, z_order
FROM osm_transportation_name_linestring_gen1
WHERE highway IN ('motorway','trunk') AND ST_Length(geometry) > 14000
@ -55,9 +56,46 @@ CREATE TABLE IF NOT EXISTS osm_transportation_name_linestring_gen2 AS (
CREATE INDEX IF NOT EXISTS osm_transportation_name_linestring_gen2_geometry_idx ON osm_transportation_name_linestring_gen2 USING gist(geometry);
-- etldoc: osm_transportation_name_linestring_gen2 -> osm_transportation_name_linestring_gen3
CREATE TABLE IF NOT EXISTS osm_transportation_name_linestring_gen3 AS (
CREATE MATERIALIZED VIEW osm_transportation_name_linestring_gen3 AS (
SELECT ST_Simplify(geometry, 120) AS geometry, osm_id, member_osm_ids, name, ref, highway, z_order
FROM osm_transportation_name_linestring_gen2
WHERE highway = 'motorway' AND ST_Length(geometry) > 20000
);
CREATE INDEX IF NOT EXISTS osm_transportation_name_linestring_gen3_geometry_idx ON osm_transportation_name_linestring_gen3 USING gist(geometry);
-- Handle updates
CREATE SCHEMA IF NOT EXISTS transportation_name;
CREATE TABLE IF NOT EXISTS transportation_name.updates(id serial primary key, t text, unique (t));
CREATE OR REPLACE FUNCTION transportation_name.flag() RETURNS trigger AS $$
BEGIN
INSERT INTO transportation_name.updates(t) VALUES ('y') ON CONFLICT(t) DO NOTHING;
RETURN null;
END;
$$ language plpgsql;
CREATE OR REPLACE FUNCTION transportation_name.refresh() RETURNS trigger AS
$BODY$
BEGIN
RAISE LOG 'Refresh transportation_name';
REFRESH MATERIALIZED VIEW osm_transportation_name_linestring;
REFRESH MATERIALIZED VIEW osm_transportation_name_linestring_gen1;
REFRESH MATERIALIZED VIEW osm_transportation_name_linestring_gen2;
REFRESH MATERIALIZED VIEW osm_transportation_name_linestring_gen3;
DELETE FROM transportation_name.updates;
RETURN null;
END;
$BODY$
language plpgsql;
CREATE TRIGGER trigger_flag
AFTER INSERT OR UPDATE OR DELETE ON osm_highway_linestring
FOR EACH STATEMENT
EXECUTE PROCEDURE transportation_name.flag();
CREATE CONSTRAINT TRIGGER trigger_refresh
AFTER INSERT ON transportation_name.updates
INITIALLY DEFERRED
FOR EACH ROW
EXECUTE PROCEDURE transportation_name.refresh();

View File

@ -40,7 +40,7 @@ tables:
- name: geometry
type: validated_geometry
- name: area
type: pseudoarea
type: webmerc_area
- key: name
name: name
type: string

View File

@ -19,5 +19,14 @@ RETURNS TABLE(osm_id bigint, geometry geometry, name text, name_en text, class t
WHERE geometry && bbox AND (
(zoom_level BETWEEN 9 AND 13 AND area > 70000*2^(20-zoom_level))
OR (zoom_level >= 14)
)
-- etldoc: osm_marine_point -> layer_water_name:z0_14_
UNION ALL
SELECT osm_id, geometry, name, name_en, place::text AS class
FROM osm_marine_point
WHERE geometry && bbox AND (
place = 'ocean'
OR (zoom_level >= 1 AND zoom_level <= "rank" AND "rank" IS NOT NULL)
OR (zoom_level >= 8)
);
$$ LANGUAGE SQL IMMUTABLE;

View File

@ -16,6 +16,9 @@ tables:
- name: place
key: place
type: string
- name: rank
key: rank
type: integer
filters:
require:
name: ["__any__"]

View File

@ -0,0 +1,61 @@
DROP TRIGGER IF EXISTS trigger_flag ON osm_marine_point;
DROP TRIGGER IF EXISTS trigger_refresh ON water_name_marine.updates;
CREATE EXTENSION IF NOT EXISTS unaccent;
CREATE OR REPLACE FUNCTION update_osm_marine_point() RETURNS VOID AS $$
BEGIN
-- etldoc: osm_marine_point -> osm_marine_point
UPDATE osm_marine_point AS osm SET "rank" = NULL WHERE "rank" IS NOT NULL;
-- etldoc: ne_10m_geography_marine_polys -> osm_marine_point
-- etldoc: osm_marine_point -> osm_marine_point
WITH important_marine_point AS (
SELECT osm.geometry, osm.osm_id, osm.name, osm.name_en, ne.scalerank
FROM ne_10m_geography_marine_polys AS ne, osm_marine_point AS osm
WHERE ne.name ILIKE osm.name
)
UPDATE osm_marine_point AS osm
SET "rank" = scalerank
FROM important_marine_point AS ne
WHERE osm.osm_id = ne.osm_id;
END;
$$ LANGUAGE plpgsql;
SELECT update_osm_marine_point();
CREATE INDEX IF NOT EXISTS osm_marine_point_rank_idx ON osm_marine_point("rank");
-- Handle updates
CREATE SCHEMA IF NOT EXISTS water_name_marine;
CREATE TABLE IF NOT EXISTS water_name_marine.updates(id serial primary key, t text, unique (t));
CREATE OR REPLACE FUNCTION water_name_marine.flag() RETURNS trigger AS $$
BEGIN
INSERT INTO water_name_marine.updates(t) VALUES ('y') ON CONFLICT(t) DO NOTHING;
RETURN null;
END;
$$ language plpgsql;
CREATE OR REPLACE FUNCTION water_name_marine.refresh() RETURNS trigger AS
$BODY$
BEGIN
RAISE LOG 'Refresh water_name_marine rank';
PERFORM update_osm_marine_point();
DELETE FROM water_name_marine.updates;
RETURN null;
END;
$BODY$
language plpgsql;
CREATE TRIGGER trigger_flag
AFTER INSERT OR UPDATE OR DELETE ON osm_marine_point
FOR EACH STATEMENT
EXECUTE PROCEDURE water_name_marine.flag();
CREATE CONSTRAINT TRIGGER trigger_refresh
AFTER INSERT ON water_name_marine.updates
INITIALLY DEFERRED
FOR EACH ROW
EXECUTE PROCEDURE water_name_marine.refresh();

View File

@ -1,9 +1,11 @@
DROP TABLE IF EXISTS osm_water_lakeline CASCADE;
DROP TRIGGER IF EXISTS trigger_flag_line ON osm_water_polygon;
DROP TRIGGER IF EXISTS trigger_refresh ON water_lakeline.updates;
-- etldoc: osm_water_polygon -> osm_water_lakeline
-- etldoc: lake_centerline -> osm_water_lakeline
CREATE TABLE IF NOT EXISTS osm_water_lakeline AS (
DROP MATERIALIZED VIEW IF EXISTS osm_water_lakeline CASCADE;
CREATE MATERIALIZED VIEW osm_water_lakeline AS (
SELECT wp.osm_id,
ll.wkb_geometry AS geometry,
name, name_en, ST_Area(wp.geometry) AS area
@ -11,5 +13,38 @@ CREATE TABLE IF NOT EXISTS osm_water_lakeline AS (
INNER JOIN lake_centerline ll ON wp.osm_id = ll.osm_id
WHERE wp.name <> ''
);
CREATE INDEX IF NOT EXISTS osm_water_lakeline_geometry_idx ON osm_water_lakeline USING gist(geometry);
-- Handle updates
CREATE SCHEMA IF NOT EXISTS water_lakeline;
CREATE TABLE IF NOT EXISTS water_lakeline.updates(id serial primary key, t text, unique (t));
CREATE OR REPLACE FUNCTION water_lakeline.flag() RETURNS trigger AS $$
BEGIN
INSERT INTO water_lakeline.updates(t) VALUES ('y') ON CONFLICT(t) DO NOTHING;
RETURN null;
END;
$$ language plpgsql;
CREATE OR REPLACE FUNCTION water_lakeline.refresh() RETURNS trigger AS
$BODY$
BEGIN
RAISE LOG 'Refresh water_lakeline';
REFRESH MATERIALIZED VIEW osm_water_lakeline;
DELETE FROM water_lakeline.updates;
RETURN null;
END;
$BODY$
language plpgsql;
CREATE TRIGGER trigger_flag_line
AFTER INSERT OR UPDATE OR DELETE ON osm_water_polygon
FOR EACH STATEMENT
EXECUTE PROCEDURE water_lakeline.flag();
CREATE CONSTRAINT TRIGGER trigger_refresh
AFTER INSERT ON water_lakeline.updates
INITIALLY DEFERRED
FOR EACH ROW
EXECUTE PROCEDURE water_lakeline.refresh();

View File

@ -12,13 +12,14 @@ layer:
At the moment only `lake` since no ocean parts are labelled. *Reserved for future use*.
values:
- lake
buffer_size: 8
buffer_size: 64
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
datasource:
geometry_field: geometry
srid: 900913
query: (SELECT geometry, name, name_en, class FROM layer_water_name(!bbox!, z(!scale_denominator!))) AS t
schema:
- ./merge_marine_rank.sql
- ./water_lakeline.sql
- ./water_point.sql
- ./layer.sql

View File

@ -1,15 +1,50 @@
DROP TABLE IF EXISTS osm_water_point CASCADE;
DROP TRIGGER IF EXISTS trigger_flag_point ON osm_water_polygon;
DROP TRIGGER IF EXISTS trigger_refresh ON water_point.updates;
-- etldoc: osm_water_polygon -> osm_water_point
-- etldoc: lake_centerline -> osm_water_point
CREATE TABLE IF NOT EXISTS osm_water_point AS (
DROP MATERIALIZED VIEW IF EXISTS osm_water_point CASCADE;
CREATE MATERIALIZED VIEW osm_water_point AS (
SELECT
wp.osm_id, topoint(wp.geometry) AS geometry,
wp.osm_id, ST_PointOnSurface(wp.geometry) AS geometry,
wp.name, wp.name_en, ST_Area(wp.geometry) AS area
FROM osm_water_polygon AS wp
LEFT JOIN lake_centerline ll ON wp.osm_id = ll.osm_id
WHERE ll.osm_id IS NULL AND wp.name <> ''
);
CREATE INDEX IF NOT EXISTS osm_water_point_geometry_idx ON osm_water_point USING gist (geometry);
-- Handle updates
CREATE SCHEMA IF NOT EXISTS water_point;
CREATE TABLE IF NOT EXISTS water_point.updates(id serial primary key, t text, unique (t));
CREATE OR REPLACE FUNCTION water_point.flag() RETURNS trigger AS $$
BEGIN
INSERT INTO water_point.updates(t) VALUES ('y') ON CONFLICT(t) DO NOTHING;
RETURN null;
END;
$$ language plpgsql;
CREATE OR REPLACE FUNCTION water_point.refresh() RETURNS trigger AS
$BODY$
BEGIN
RAISE LOG 'Refresh water_point';
REFRESH MATERIALIZED VIEW osm_water_point;
DELETE FROM water_point.updates;
RETURN null;
END;
$BODY$
language plpgsql;
CREATE TRIGGER trigger_flag_point
AFTER INSERT OR UPDATE OR DELETE ON osm_water_polygon
FOR EACH STATEMENT
EXECUTE PROCEDURE water_point.flag();
CREATE CONSTRAINT TRIGGER trigger_refresh
AFTER INSERT ON water_point.updates
INITIALLY DEFERRED
FOR EACH ROW
EXECUTE PROCEDURE water_point.refresh();

View File

@ -1,15 +1,17 @@
DROP TABLE IF EXISTS osm_important_waterway_linestring CASCADE;
DROP TABLE IF EXISTS osm_important_waterway_linestring_gen1 CASCADE;
DROP TABLE IF EXISTS osm_important_waterway_linestring_gen2 CASCADE;
DROP TABLE IF EXISTS osm_important_waterway_linestring_gen3 CASCADE;
DROP TRIGGER IF EXISTS trigger_flag ON osm_waterway_linestring;
DROP TRIGGER IF EXISTS trigger_refresh ON waterway.updates;
-- We merge the waterways by name like the highways
-- This helps to drop not important rivers (since they do not have a name)
-- and also makes it possible to filter out too short rivers
-- etldoc: osm_waterway_linestring -> osm_important_waterway_linestring
CREATE TABLE IF NOT EXISTS osm_important_waterway_linestring AS (
DROP MATERIALIZED VIEW IF EXISTS osm_important_waterway_linestring CASCADE;
DROP MATERIALIZED VIEW IF EXISTS osm_important_waterway_linestring_gen1 CASCADE;
DROP MATERIALIZED VIEW IF EXISTS osm_important_waterway_linestring_gen2 CASCADE;
DROP MATERIALIZED VIEW IF EXISTS osm_important_waterway_linestring_gen3 CASCADE;
CREATE MATERIALIZED VIEW osm_important_waterway_linestring AS (
SELECT
(ST_Dump(geometry)).geom AS geometry,
name
@ -22,11 +24,10 @@ CREATE TABLE IF NOT EXISTS osm_important_waterway_linestring AS (
GROUP BY name
) AS waterway_union
);
CREATE INDEX IF NOT EXISTS osm_important_waterway_linestring_geometry_idx ON osm_important_waterway_linestring USING gist(geometry);
-- etldoc: osm_important_waterway_linestring -> osm_important_waterway_linestring_gen1
CREATE TABLE IF NOT EXISTS osm_important_waterway_linestring_gen1 AS (
CREATE MATERIALIZED VIEW osm_important_waterway_linestring_gen1 AS (
SELECT ST_Simplify(geometry, 60) AS geometry, name
FROM osm_important_waterway_linestring
WHERE ST_Length(geometry) > 1000
@ -34,7 +35,7 @@ CREATE TABLE IF NOT EXISTS osm_important_waterway_linestring_gen1 AS (
CREATE INDEX IF NOT EXISTS osm_important_waterway_linestring_gen1_geometry_idx ON osm_important_waterway_linestring_gen1 USING gist(geometry);
-- etldoc: osm_important_waterway_linestring_gen1 -> osm_important_waterway_linestring_gen2
CREATE TABLE IF NOT EXISTS osm_important_waterway_linestring_gen2 AS (
CREATE MATERIALIZED VIEW osm_important_waterway_linestring_gen2 AS (
SELECT ST_Simplify(geometry, 100) AS geometry, name
FROM osm_important_waterway_linestring_gen1
WHERE ST_Length(geometry) > 4000
@ -42,9 +43,49 @@ CREATE TABLE IF NOT EXISTS osm_important_waterway_linestring_gen2 AS (
CREATE INDEX IF NOT EXISTS osm_important_waterway_linestring_gen2_geometry_idx ON osm_important_waterway_linestring_gen2 USING gist(geometry);
-- etldoc: osm_important_waterway_linestring_gen2 -> osm_important_waterway_linestring_gen3
CREATE TABLE IF NOT EXISTS osm_important_waterway_linestring_gen3 AS (
CREATE MATERIALIZED VIEW osm_important_waterway_linestring_gen3 AS (
SELECT ST_Simplify(geometry, 200) AS geometry, name
FROM osm_important_waterway_linestring_gen2
WHERE ST_Length(geometry) > 8000
);
CREATE INDEX IF NOT EXISTS osm_important_waterway_linestring_gen3_geometry_idx ON osm_important_waterway_linestring_gen3 USING gist(geometry);
-- Handle updates
CREATE SCHEMA IF NOT EXISTS waterway;
CREATE TABLE IF NOT EXISTS waterway.updates(id serial primary key, t text, unique (t));
CREATE OR REPLACE FUNCTION waterway.flag() RETURNS trigger AS $$
BEGIN
INSERT INTO waterway.updates(t) VALUES ('y') ON CONFLICT(t) DO NOTHING;
RETURN null;
END;
$$ language plpgsql;
CREATE OR REPLACE FUNCTION waterway.refresh() RETURNS trigger AS
$BODY$
BEGIN
RAISE LOG 'Refresh waterway';
REFRESH MATERIALIZED VIEW osm_important_waterway_linestring;
REFRESH MATERIALIZED VIEW osm_important_waterway_linestring_gen1;
REFRESH MATERIALIZED VIEW osm_important_waterway_linestring_gen2;
REFRESH MATERIALIZED VIEW osm_important_waterway_linestring_gen3;
DELETE FROM waterway.updates;
RETURN null;
END;
$BODY$
language plpgsql;
CREATE TRIGGER trigger_flag
AFTER INSERT OR UPDATE OR DELETE ON osm_waterway_linestring
FOR EACH STATEMENT
EXECUTE PROCEDURE waterway.flag();
CREATE CONSTRAINT TRIGGER trigger_refresh
AFTER INSERT ON waterway.updates
INITIALLY DEFERRED
FOR EACH ROW
EXECUTE PROCEDURE waterway.refresh();

View File

@ -194,6 +194,14 @@ echo " : Data license: http://openstreetmapdata.com/info/license "
echo " : Thank you: http://openstreetmapdata.com/info/supporting "
docker-compose run --rm import-water
echo " "
echo "-------------------------------------------------------------------------------------"
echo "====> : Start importing border data from http://openstreetmap.org into PostgreSQL "
echo " : Source code: https://github.com/openmaptiles/import-osmborder"
echo " : Data license: http://www.openstreetmap.org/copyright"
echo " : Thank you: https://github.com/pnorman/osmborder "
docker-compose run --rm import-osmborder
echo " "
echo "-------------------------------------------------------------------------------------"
echo "====> : Start importing http://www.naturalearthdata.com into PostgreSQL "
@ -241,6 +249,12 @@ echo " : like : Mapnik LOG> ... is deprecated and will be removed in M
docker-compose -f docker-compose.yml -f ./data/docker-compose-config.yml run --rm generate-vectortiles
echo " "
echo "-------------------------------------------------------------------------------------"
echo "====> : Add special metadata to mbtiles! "
docker-compose run --rm openmaptiles-tools generate-metadata ./data/tiles.mbtiles
docker-compose run --rm openmaptiles-tools chmod 666 ./data/tiles.mbtiles
echo " "
echo "-------------------------------------------------------------------------------------"
echo "====> : Stop PostgreSQL service ( but we keep PostgreSQL data volume for debugging )"