Merge pull request #61 from openmaptiles/feature/changed-place-layer

New Place Layer Schema
pull/89/head
Lukas Martinelli 2016-12-01 11:01:01 +01:00 zatwierdzone przez GitHub
commit 86049b7362
10 zmienionych plików z 154 dodań i 84 usunięć

Wyświetl plik

@ -1,11 +1,11 @@
-- etldoc: layer_city[shape=record fillcolor=lightpink, style="rounded,filled", -- etldoc: layer_city[shape=record fillcolor=lightpink, style="rounded,filled",
-- etldoc: label="layer_city | <z2_7> z2-z7 | <z8_14_> z8_z14_ " ] ; -- etldoc: label="layer_city | <z2_14> z2-z14" ] ;
-- etldoc: osm_city_point -> layer_city:z2_14
CREATE OR REPLACE FUNCTION layer_city(bbox geometry, zoom_level int, pixel_width numeric) 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, "rank", normalize_capital_level(capital) AS capital
SELECT osm_id, geometry, name, COALESCE(NULLIF(name_en, ''), name) AS name_en, place AS class, "rank"
FROM osm_city_point FROM osm_city_point
WHERE geometry && bbox WHERE geometry && bbox
AND ((zoom_level = 2 AND "rank" = 1) 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 UNION ALL
SELECT osm_id, geometry, name, SELECT osm_id, geometry, name,
COALESCE(NULLIF(name_en, ''), name) AS name_en, COALESCE(NULLIF(name_en, ''), name) AS name_en,
place AS class, place,
COALESCE("rank", gridrank + 10) COALESCE("rank", gridrank + 10),
normalize_capital_level(capital) AS capital
FROM ( FROM (
SELECT osm_id, geometry, name, name_en, place, "rank", SELECT osm_id, geometry, name, name_en, place, "rank", capital,
row_number() OVER ( row_number() OVER (
PARTITION BY LabelGrid(geometry, 128 * pixel_width) PARTITION BY LabelGrid(geometry, 128 * pixel_width)
ORDER BY "rank" ASC NULLS LAST, ORDER BY "rank" ASC NULLS LAST,
@ -25,19 +26,18 @@ RETURNS TABLE(osm_id bigint, geometry geometry, name text, name_en text, class c
population DESC NULLS LAST, population DESC NULLS LAST,
length(name) ASC length(name) ASC
)::int AS gridrank )::int AS gridrank
-- etldoc: osm_city_point -> layer_city:z8_14_
FROM osm_city_point FROM osm_city_point
WHERE geometry && bbox WHERE geometry && bbox
AND ((zoom_level = 8 AND place <= 'town'::city_class) AND ((zoom_level = 8 AND place <= 'town'::city_place
OR (zoom_level BETWEEN 9 AND 10 AND place <= 'village'::city_class) OR (zoom_level BETWEEN 9 AND 10 AND place <= 'village'::city_place)
OR (zoom_level BETWEEN 11 AND 13 AND place <= 'suburb'::city_class)
OR (zoom_level BETWEEN 11 AND 13 AND place <= 'suburb'::city_place)
OR (zoom_level >= 14) OR (zoom_level >= 14)
) ))
) AS ranked_places ) AS ranked_places
WHERE (zoom_level = 8 AND (gridrank <= 4 OR "rank" IS NOT NULL)) WHERE (zoom_level = 8 AND (gridrank <= 4 OR "rank" IS NOT NULL))
OR (zoom_level = 9 AND (gridrank <= 8 OR "rank" IS NOT NULL)) 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 = 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 BETWEEN 11 AND 12 AND (gridrank <= 14 OR "rank" IS NOT NULL))
OR (zoom_level >= 13) OR (zoom_level >= 13);
ORDER BY "rank" ASC;
$$ LANGUAGE SQL IMMUTABLE; $$ LANGUAGE SQL IMMUTABLE;

Wyświetl plik

@ -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;

Wyświetl plik

@ -1,11 +0,0 @@
-- etldoc: layer_country[shape=record fillcolor=lightpink, style="rounded,filled",
-- etldoc: label="layer_country | <zall> 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;

Wyświetl plik

@ -0,0 +1,40 @@
-- etldoc: layer_place[shape=record fillcolor=lightpink, style="rounded,filled",
-- etldoc: label="layer_place | <zall> z0-z14_ " ] ;
-- 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 $$
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, COALESCE(NULLIF(name_en, ''), name) AS name_en,
'country' AS class, 'country' AS subclass,"rank", NULL::int AS capital
FROM osm_country_point
WHERE geometry && bbox AND "rank" <= zoom_level AND name <> ''
UNION ALL
SELECT
osm_id, geometry, name, COALESCE(NULLIF(name_en, ''), name) AS name_en,
'state' AS class, 'state' AS subclass, "rank", NULL::int AS capital
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;

Wyświetl plik

@ -45,6 +45,23 @@ rank_field: &rank
tables: 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 # etldoc: imposm3 -> osm_country_point
country_point: country_point:
type: point type: point
@ -156,6 +173,9 @@ tables:
- key: population - key: population
name: population name: population
type: integer type: integer
- key: capital
name: capital
type: string
- *rank - *rank
filters: filters:
exclude_tags: exclude_tags:

Wyświetl plik

@ -18,7 +18,7 @@ WITH important_city_point AS (
ne.nameascii ILIKE osm.name OR ne.nameascii ILIKE osm.name OR
ne.nameascii ILIKE osm.name_en 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) AND ST_DWithin(ne.geom, osm.geometry, 50000)
) )
UPDATE osm_city_point AS osm UPDATE osm_city_point AS osm

Wyświetl plik

@ -1,16 +0,0 @@
-- etldoc: layer_place[shape=record fillcolor=lightpink, style="rounded,filled",
-- etldoc: label="layer_place | <zall> 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;

Wyświetl plik

@ -7,34 +7,71 @@ layer:
We suggest you use different font styles and sizes to create a text hierarchy. We suggest you use different font styles and sizes to create a text hierarchy.
fields: fields:
name: The OSM [`name`](http://wiki.openstreetmap.org/wiki/Key:name) value of the POI. 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: | class: |
Distinguish between `country`, `state` and other city classes like description: |
`city`, `town`, `village`, `hamlet`, `suburb`, `neighbourhood` or `isolated_dwelling`. Distinguish between continents, countries, states and
Use this to separately style the different places according to their importance (usually country and state different places like settlements or smaller entities.
than cities). Use this to separately style the different places and build
rank: | a text hierarchy according to their importance.
Countries, states and the most important cities all have a `rank` to boost their importance on the map. than cities).
The `rank` field for counries and states ranges from `1` to `6` while the `rank` field for values:
cities ranges from `1` to `10` for the most important cities and continues from `10` serially based - continent
on the local importance of the city (derived from population and city class). - country
Use the `rank` field to build a text hierarchy. - state
The rank value is a combination of the Natural Earth `scalerank`, `labelrank` and `datarank` values for countries - settlement
and states and for cities consists out of a shifted Natural Earth `scalerank` combined with a local rank - subregion
within a grid for cities that do not have a Natural Earth `scalerank`. - 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 buffer_size: 128
datasource: datasource:
geometry_field: geometry 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: schema:
- ./types.sql - ./types.sql
- ./class.sql
- ./city.sql - ./city.sql
- ./country.sql
- ./state.sql
- ./merge_country_rank.sql - ./merge_country_rank.sql
- ./merge_city_rank.sql - ./merge_city_rank.sql
- ./merge_state_rank.sql - ./merge_state_rank.sql
- ./place.sql - ./layer.sql
datasources: datasources:
- type: imposm3 - type: imposm3
mapping_file: ./mapping.yaml mapping_file: ./mapping.yaml

Wyświetl plik

@ -1,18 +0,0 @@
-- etldoc: layer_state[shape=record fillcolor=lightpink, style="rounded,filled",
-- etldoc: label="layer_state | <zall> 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;

Wyświetl plik

@ -1,9 +1,9 @@
DO $$ DO $$
BEGIN BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'city_class') THEN IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'city_place') THEN
CREATE TYPE city_class AS ENUM ('city', 'town', 'village', 'hamlet', 'suburb', 'neighbourhood', 'isolated_dwelling'); CREATE TYPE city_place AS ENUM ('city', 'town', 'village', 'hamlet', 'suburb', 'neighbourhood', 'isolated_dwelling');
END IF; END IF;
END 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;