From 2f35ab3ee135834036284bc0b39f8fd8eb540d77 Mon Sep 17 00:00:00 2001 From: Lukas Martinelli Date: Mon, 28 Nov 2016 15:42:13 +0000 Subject: [PATCH 1/4] Use classes from ClearTables and add continents --- layers/place/city.sql | 20 +++++++++++--------- layers/place/class.sql | 18 ++++++++++++++++++ layers/place/layer.sql | 32 ++++++++++++++++++++++++++++++++ layers/place/mapping.yaml | 20 ++++++++++++++++++++ layers/place/merge_city_rank.sql | 2 +- layers/place/place.sql | 16 ---------------- layers/place/place.yaml | 5 +++-- layers/place/types.sql | 6 +++--- 8 files changed, 88 insertions(+), 31 deletions(-) create mode 100644 layers/place/class.sql create mode 100644 layers/place/layer.sql delete mode 100644 layers/place/place.sql diff --git a/layers/place/city.sql b/layers/place/city.sql index af23866e..d5304d3d 100644 --- a/layers/place/city.sql +++ b/layers/place/city.sql @@ -3,9 +3,9 @@ -- etldoc: label="layer_city | z2-z7 | z8_z14_ " ] ; CREATE OR REPLACE FUNCTION layer_city(bbox geometry, zoom_level int, pixel_width numeric) -RETURNS TABLE(osm_id bigint, geometry geometry, name text, name_en text, class city_class, "rank" int) AS $$ +RETURNS TABLE(osm_id bigint, geometry geometry, name text, name_en text, place city_place, "rank" int, capital int) AS $$ -- etldoc: osm_city_point -> layer_city:z2_7 - SELECT osm_id, geometry, name, COALESCE(NULLIF(name_en, ''), name) AS name_en, place AS class, "rank" + SELECT osm_id, geometry, name, COALESCE(NULLIF(name_en, ''), name) AS name_en, place, "rank", normalize_capital_level(capital) AS capital FROM osm_city_point WHERE geometry && bbox AND ((zoom_level = 2 AND "rank" = 1) @@ -14,10 +14,11 @@ RETURNS TABLE(osm_id bigint, geometry geometry, name text, name_en text, class c UNION ALL SELECT osm_id, geometry, name, COALESCE(NULLIF(name_en, ''), name) AS name_en, - place AS class, - COALESCE("rank", gridrank + 10) + place, + COALESCE("rank", gridrank + 10), + normalize_capital_level(capital) AS capital FROM ( - SELECT osm_id, geometry, name, name_en, place, "rank", + SELECT osm_id, geometry, name, name_en, place, "rank", capital, row_number() OVER ( PARTITION BY LabelGrid(geometry, 128 * pixel_width) ORDER BY "rank" ASC NULLS LAST, @@ -28,11 +29,12 @@ RETURNS TABLE(osm_id bigint, geometry geometry, name text, name_en text, class c -- etldoc: osm_city_point -> layer_city:z8_14_ FROM osm_city_point WHERE geometry && bbox - AND ((zoom_level = 8 AND place <= 'town'::city_class) - OR (zoom_level BETWEEN 9 AND 10 AND place <= 'village'::city_class) - OR (zoom_level BETWEEN 11 AND 13 AND place <= 'suburb'::city_class) + AND ((zoom_level = 8 AND place <= 'town'::city_place + OR (zoom_level BETWEEN 9 AND 10 AND place <= 'village'::city_place) + + OR (zoom_level BETWEEN 11 AND 13 AND place <= 'suburb'::city_place) OR (zoom_level >= 14) - ) + )) ) AS ranked_places WHERE (zoom_level = 8 AND (gridrank <= 4 OR "rank" IS NOT NULL)) OR (zoom_level = 9 AND (gridrank <= 8 OR "rank" IS NOT NULL)) diff --git a/layers/place/class.sql b/layers/place/class.sql new file mode 100644 index 00000000..fa349217 --- /dev/null +++ b/layers/place/class.sql @@ -0,0 +1,18 @@ +CREATE OR REPLACE FUNCTION place_class(place TEXT) +RETURNS TEXT AS $$ + SELECT CASE + WHEN place IN ('city', 'town', 'village', 'hamlet', 'isolated_dwelling') THEN 'settlement' + WHEN place IN ('suburb', 'neighbourhood') THEN 'subregion' + WHEN place IN ('locality', 'farm') THEN 'other' + ELSE NULL + END; +$$ LANGUAGE SQL IMMUTABLE STRICT; + +CREATE OR REPLACE FUNCTION normalize_capital_level(capital TEXT) +RETURNS INT AS $$ + SELECT CASE + WHEN capital IN ('yes', '2') THEN 2 + WHEN capital = '4' THEN 4 + ELSE NULL + END; +$$ LANGUAGE SQL IMMUTABLE STRICT; diff --git a/layers/place/layer.sql b/layers/place/layer.sql new file mode 100644 index 00000000..a6871940 --- /dev/null +++ b/layers/place/layer.sql @@ -0,0 +1,32 @@ + +-- etldoc: layer_place[shape=record fillcolor=lightpink, style="rounded,filled", +-- etldoc: label="layer_place | z0-z14_ " ] ; + +-- etldoc: layer_continent -> layer_place +-- etldoc: layer_country -> layer_place +-- etldoc: layer_state -> layer_place +-- etldoc: layer_city -> layer_place + +CREATE OR REPLACE FUNCTION layer_place(bbox geometry, zoom_level int, pixel_width numeric) +RETURNS TABLE(osm_id bigint, geometry geometry, name text, name_en text, class text, subclass text, "rank" int, capital INT) AS $$ + SELECT + osm_id, geometry, name, name_en, + 'continent' AS class, 'continent' AS subclass, 1 AS "rank", NULL::int AS capital + FROM osm_continent_point + WHERE geometry && bbox AND zoom_level < 4 + UNION ALL + SELECT + osm_id, geometry, name, name_en, + 'country' AS class, 'country' AS subclass,"rank", NULL::int AS capital + FROM layer_country(bbox, zoom_level) + UNION ALL + SELECT + osm_id, geometry, name, name_en, + 'state' AS class, 'state' AS subclass, "rank", NULL::int AS capital + FROM layer_state(bbox, zoom_level) + UNION ALL + SELECT + osm_id, geometry, name, name_en, + place_class(place::text) AS class, place::text AS subclass, "rank", capital + FROM layer_city(bbox, zoom_level, pixel_width) +$$ LANGUAGE SQL IMMUTABLE; diff --git a/layers/place/mapping.yaml b/layers/place/mapping.yaml index 2e342325..aa3b1482 100644 --- a/layers/place/mapping.yaml +++ b/layers/place/mapping.yaml @@ -12,6 +12,23 @@ rank_field: &rank type: integer tables: + # etldoc: imposm3 -> osm_continent_point + continent_point: + type: point + fields: + - name: osm_id + type: id + - name: geometry + type: geometry + - *name + - *name_en + filters: + exclude_tags: + - [ "name", "__nil__" ] + mapping: + place: + - continent + # etldoc: imposm3 -> osm_country_point country_point: type: point @@ -73,6 +90,9 @@ tables: - key: population name: population type: integer + - key: capital + name: capital + type: string - *rank filters: exclude_tags: diff --git a/layers/place/merge_city_rank.sql b/layers/place/merge_city_rank.sql index 025f0586..66ce265a 100644 --- a/layers/place/merge_city_rank.sql +++ b/layers/place/merge_city_rank.sql @@ -18,7 +18,7 @@ WITH important_city_point AS ( ne.nameascii ILIKE osm.name OR ne.nameascii ILIKE osm.name_en ) - AND (osm.place = 'city'::city_class OR osm.place= 'town'::city_class OR osm.place = 'village'::city_class) + AND osm.place IN ('city', 'town', 'village') AND ST_DWithin(ne.geom, osm.geometry, 50000) ) UPDATE osm_city_point AS osm diff --git a/layers/place/place.sql b/layers/place/place.sql deleted file mode 100644 index 8e11d215..00000000 --- a/layers/place/place.sql +++ /dev/null @@ -1,16 +0,0 @@ - --- etldoc: layer_place[shape=record fillcolor=lightpink, style="rounded,filled", --- etldoc: label="layer_place | z0-z14_ " ] ; - --- etldoc: layer_country -> layer_place --- etldoc: layer_state -> layer_place --- etldoc: layer_city -> layer_place - -CREATE OR REPLACE FUNCTION layer_place(bbox geometry, zoom_level int, pixel_width numeric) -RETURNS TABLE(osm_id bigint, geometry geometry, name text, name_en text, class text, "rank" int) AS $$ - SELECT osm_id, geometry, name, name_en, 'country' AS class, "rank" FROM layer_country(bbox, zoom_level) - UNION ALL - SELECT osm_id, geometry, name, name_en, 'state' AS class, "rank" FROM layer_state(bbox, zoom_level) - UNION ALL - SELECT osm_id, geometry, name, name_en, class::text, "rank" FROM layer_city(bbox, zoom_level, pixel_width) -$$ LANGUAGE SQL IMMUTABLE; diff --git a/layers/place/place.yaml b/layers/place/place.yaml index 2ac875d0..02bedd7b 100644 --- a/layers/place/place.yaml +++ b/layers/place/place.yaml @@ -25,16 +25,17 @@ layer: buffer_size: 128 datasource: geometry_field: geometry - query: (SELECT geometry, name, name_en, class, rank FROM layer_place(!bbox!, z(!scale_denominator!), !pixel_width!)) AS t + query: (SELECT geometry, name, name_en, class, subclass, rank, capital FROM layer_place(!bbox!, z(!scale_denominator!), !pixel_width!)) AS t schema: - ./types.sql + - ./class.sql - ./city.sql - ./country.sql - ./state.sql - ./merge_country_rank.sql - ./merge_city_rank.sql - ./merge_state_rank.sql - - ./place.sql + - ./layer.sql datasources: - type: imposm3 mapping_file: ./mapping.yaml diff --git a/layers/place/types.sql b/layers/place/types.sql index 48c575e1..f7fdedfc 100644 --- a/layers/place/types.sql +++ b/layers/place/types.sql @@ -1,9 +1,9 @@ DO $$ BEGIN - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'city_class') THEN - CREATE TYPE city_class AS ENUM ('city', 'town', 'village', 'hamlet', 'suburb', 'neighbourhood', 'isolated_dwelling'); + IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'city_place') THEN + CREATE TYPE city_place AS ENUM ('city', 'town', 'village', 'hamlet', 'suburb', 'neighbourhood', 'isolated_dwelling'); END IF; END $$; -ALTER TABLE osm_city_point ALTER COLUMN place TYPE city_class USING place::city_class; +ALTER TABLE osm_city_point ALTER COLUMN place TYPE city_place USING place::city_place; From 6fb20ab650c244acf688991df9ac4ebc85d862ce Mon Sep 17 00:00:00 2001 From: Lukas Martinelli Date: Mon, 28 Nov 2016 16:03:42 +0000 Subject: [PATCH 2/4] Include country and state select direcdtly in layer func --- layers/place/city.sql | 3 +-- layers/place/country.sql | 11 ----------- layers/place/layer.sql | 24 ++++++++++++++++-------- layers/place/place.yaml | 2 -- layers/place/state.sql | 18 ------------------ 5 files changed, 17 insertions(+), 41 deletions(-) delete mode 100644 layers/place/country.sql delete mode 100644 layers/place/state.sql diff --git a/layers/place/city.sql b/layers/place/city.sql index d5304d3d..1695f312 100644 --- a/layers/place/city.sql +++ b/layers/place/city.sql @@ -40,6 +40,5 @@ RETURNS TABLE(osm_id bigint, geometry geometry, name text, name_en text, place c OR (zoom_level = 9 AND (gridrank <= 8 OR "rank" IS NOT NULL)) OR (zoom_level = 10 AND (gridrank <= 12 OR "rank" IS NOT NULL)) OR (zoom_level BETWEEN 11 AND 12 AND (gridrank <= 14 OR "rank" IS NOT NULL)) - OR (zoom_level >= 13) - ORDER BY "rank" ASC; + OR (zoom_level >= 13); $$ LANGUAGE SQL IMMUTABLE; diff --git a/layers/place/country.sql b/layers/place/country.sql deleted file mode 100644 index 3f276fa2..00000000 --- a/layers/place/country.sql +++ /dev/null @@ -1,11 +0,0 @@ - --- etldoc: layer_country[shape=record fillcolor=lightpink, style="rounded,filled", --- etldoc: label="layer_country | z0-z14_ " ] ; - --- etldoc: osm_country_point -> layer_country -CREATE OR REPLACE FUNCTION layer_country(bbox geometry, zoom_level int) -RETURNS TABLE(osm_id bigint, geometry geometry, name text, name_en text, "rank" int) AS $$ - SELECT osm_id, geometry, name, COALESCE(NULLIF(name_en, ''), name) AS name_en, "rank" FROM osm_country_point - WHERE geometry && bbox AND "rank" <= zoom_level AND name <> '' - ORDER BY "rank" ASC, length(name) ASC; -$$ LANGUAGE SQL IMMUTABLE; diff --git a/layers/place/layer.sql b/layers/place/layer.sql index a6871940..053a2601 100644 --- a/layers/place/layer.sql +++ b/layers/place/layer.sql @@ -2,10 +2,10 @@ -- etldoc: layer_place[shape=record fillcolor=lightpink, style="rounded,filled", -- etldoc: label="layer_place | z0-z14_ " ] ; --- etldoc: layer_continent -> layer_place --- etldoc: layer_country -> layer_place --- etldoc: layer_state -> layer_place --- etldoc: layer_city -> layer_place +-- etldoc: osm_continent_point -> layer_place +-- etldoc: osm_country_point -> layer_place +-- etldoc: osm_state_point -> layer_place +-- etldoc: layer_city -> layer_place CREATE OR REPLACE FUNCTION layer_place(bbox geometry, zoom_level int, pixel_width numeric) RETURNS TABLE(osm_id bigint, geometry geometry, name text, name_en text, class text, subclass text, "rank" int, capital INT) AS $$ @@ -16,17 +16,25 @@ RETURNS TABLE(osm_id bigint, geometry geometry, name text, name_en text, class t WHERE geometry && bbox AND zoom_level < 4 UNION ALL SELECT - osm_id, geometry, name, name_en, + osm_id, geometry, name, COALESCE(NULLIF(name_en, ''), name) AS name_en, 'country' AS class, 'country' AS subclass,"rank", NULL::int AS capital - FROM layer_country(bbox, zoom_level) + FROM osm_country_point + WHERE geometry && bbox AND "rank" <= zoom_level AND name <> '' UNION ALL SELECT - osm_id, geometry, name, name_en, + osm_id, geometry, name, COALESCE(NULLIF(name_en, ''), name) AS name_en, 'state' AS class, 'state' AS subclass, "rank", NULL::int AS capital - FROM layer_state(bbox, zoom_level) + FROM osm_state_point + WHERE geometry && bbox AND + name <> '' AND + ("rank" + 2 <= zoom_level) AND ( + zoom_level >= 5 OR + is_in_country IN ('United Kingdom', 'USA', 'Россия', 'Brasil', 'China', 'India') OR + is_in_country_code IN ('AU', 'CN', 'IN', 'BR', 'US')) UNION ALL SELECT osm_id, geometry, name, name_en, place_class(place::text) AS class, place::text AS subclass, "rank", capital FROM layer_city(bbox, zoom_level, pixel_width) + ORDER BY "rank" ASC $$ LANGUAGE SQL IMMUTABLE; diff --git a/layers/place/place.yaml b/layers/place/place.yaml index 02bedd7b..e1949bed 100644 --- a/layers/place/place.yaml +++ b/layers/place/place.yaml @@ -30,8 +30,6 @@ schema: - ./types.sql - ./class.sql - ./city.sql - - ./country.sql - - ./state.sql - ./merge_country_rank.sql - ./merge_city_rank.sql - ./merge_state_rank.sql diff --git a/layers/place/state.sql b/layers/place/state.sql deleted file mode 100644 index de11478e..00000000 --- a/layers/place/state.sql +++ /dev/null @@ -1,18 +0,0 @@ - --- etldoc: layer_state[shape=record fillcolor=lightpink, style="rounded,filled", --- etldoc: label="layer_state | z0-z14_ " ] ; - --- etldoc: osm_state_point -> layer_state - -CREATE OR REPLACE FUNCTION layer_state(bbox geometry, zoom_level int) -RETURNS TABLE(osm_id bigint, geometry geometry, name text, name_en text, "rank" int) AS $$ - SELECT osm_id, geometry, name, COALESCE(NULLIF(name_en, ''), name) AS name_en, "rank" - FROM osm_state_point - WHERE geometry && bbox AND - name <> '' AND - ("rank" + 2 <= zoom_level) AND ( - zoom_level >= 5 OR - is_in_country IN ('United Kingdom', 'USA', 'Россия', 'Brasil', 'China', 'India') OR - is_in_country_code IN ('AU', 'CN', 'IN', 'BR', 'US')) - ORDER BY "rank" ASC; -$$ LANGUAGE SQL IMMUTABLE; From ee9d4348e05871d62307c2246ddffcbf6e30538f Mon Sep 17 00:00:00 2001 From: Lukas Martinelli Date: Wed, 30 Nov 2016 12:38:47 +0000 Subject: [PATCH 3/4] Add possible values to place layer doc --- layers/place/place.yaml | 66 ++++++++++++++++++++++++++++++++--------- 1 file changed, 52 insertions(+), 14 deletions(-) diff --git a/layers/place/place.yaml b/layers/place/place.yaml index e1949bed..443c268d 100644 --- a/layers/place/place.yaml +++ b/layers/place/place.yaml @@ -7,21 +7,59 @@ layer: We suggest you use different font styles and sizes to create a text hierarchy. fields: name: The OSM [`name`](http://wiki.openstreetmap.org/wiki/Key:name) value of the POI. - name_en: The english `name:en` value if available. + name_en: The English `name:en` value or local `name` if not available. + capital: + description: | + The **capital** field marks the + [`admin_level`](http://wiki.openstreetmap.org/wiki/Tag:boundary%3Dadministrative#admin_level) + of the boundary the place is a capital of. + values: [2, 4] class: | - Distinguish between `country`, `state` and other city classes like - `city`, `town`, `village`, `hamlet`, `suburb`, `neighbourhood` or `isolated_dwelling`. - Use this to separately style the different places according to their importance (usually country and state different - than cities). - rank: | - Countries, states and the most important cities all have a `rank` to boost their importance on the map. - The `rank` field for counries and states ranges from `1` to `6` while the `rank` field for - cities ranges from `1` to `10` for the most important cities and continues from `10` serially based - on the local importance of the city (derived from population and city class). - Use the `rank` field to build a text hierarchy. - The rank value is a combination of the Natural Earth `scalerank`, `labelrank` and `datarank` values for countries - and states and for cities consists out of a shifted Natural Earth `scalerank` combined with a local rank - within a grid for cities that do not have a Natural Earth `scalerank`. + description: | + Distinguish between continents, countries, states and + places like settlements or smaller entities. + Use this to separately style the different places and build + a text hierarchy according to their importance. + than cities). + values: + - continent + - country + - state + - settlement + - subregion + - other + subclass: + description: | + Use **subclass** to do more precise styling. + Original value of the + [`place`](http://wiki.openstreetmap.org/wiki/Key:place) tag. + values: + - continent + - country + - state + - city + - town + - village + - hamlet + - suburb + - neighbourhood + - isolated_dwelling + rank: + description: | + Countries, states and the most important cities all have a + **rank** to boost their importance on the map. + The **rank** field for counries and states ranges from + `1` to `6` while the **rank** field for cities ranges from + `1` to `10` for the most important cities + and continues from `10` serially based on the + local importance of the city (derived from population and city class). + You can use the **rank** to limit density of labels or improve + the text hierarchy. + The rank value is a combination of the Natural Earth + `scalerank`, `labelrank` and `datarank` values for countries + and states and for cities consists out of a shifted + Natural Earth `scalerank` combined with a local rank + within a grid for cities that do not have a Natural Earth `scalerank`. buffer_size: 128 datasource: geometry_field: geometry From 3f5b1371e9611c4eedffeb1ff7805441e5862207 Mon Sep 17 00:00:00 2001 From: Lukas Martinelli Date: Wed, 30 Nov 2016 16:19:49 +0000 Subject: [PATCH 4/4] Clarify etldoc for place layer --- layers/place/city.sql | 7 +++---- layers/place/mapping.yaml | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/layers/place/city.sql b/layers/place/city.sql index 1695f312..5e21bca5 100644 --- a/layers/place/city.sql +++ b/layers/place/city.sql @@ -1,10 +1,10 @@ --- etldoc: layer_city[shape=record fillcolor=lightpink, style="rounded,filled", --- etldoc: label="layer_city | z2-z7 | z8_z14_ " ] ; +-- etldoc: layer_city[shape=record fillcolor=lightpink, style="rounded,filled", +-- etldoc: label="layer_city | z2-z14" ] ; +-- etldoc: osm_city_point -> layer_city:z2_14 CREATE OR REPLACE FUNCTION layer_city(bbox geometry, zoom_level int, pixel_width numeric) RETURNS TABLE(osm_id bigint, geometry geometry, name text, name_en text, place city_place, "rank" int, capital int) AS $$ - -- etldoc: osm_city_point -> layer_city:z2_7 SELECT osm_id, geometry, name, COALESCE(NULLIF(name_en, ''), name) AS name_en, place, "rank", normalize_capital_level(capital) AS capital FROM osm_city_point WHERE geometry && bbox @@ -26,7 +26,6 @@ RETURNS TABLE(osm_id bigint, geometry geometry, name text, name_en text, place c population DESC NULLS LAST, length(name) ASC )::int AS gridrank - -- etldoc: osm_city_point -> layer_city:z8_14_ FROM osm_city_point WHERE geometry && bbox AND ((zoom_level = 8 AND place <= 'town'::city_place diff --git a/layers/place/mapping.yaml b/layers/place/mapping.yaml index aa3b1482..1cd4333d 100644 --- a/layers/place/mapping.yaml +++ b/layers/place/mapping.yaml @@ -47,7 +47,7 @@ tables: place: - country - # etldoc: imposm3 -> osm_state_point + # etldoc: imposm3 -> osm_state_point state_point: type: point fields: @@ -74,7 +74,7 @@ tables: place: - state - # etldoc: imposm3 -> osm_city_point + # etldoc: imposm3 -> osm_city_point city_point: type: point fields: