Refactor place layer

pull/24/head
lukasmartinelli 2016-10-28 12:05:18 +02:00
rodzic 52c7306563
commit 38dcc030b0
5 zmienionych plików z 52 dodań i 119 usunięć

Wyświetl plik

@ -0,0 +1,29 @@
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 text, scalerank int) AS $$
SELECT osm_id, geometry, name, name_en, place, scalerank
FROM osm_important_place_point
WHERE geometry && bbox
AND ((zoom_level = 2 AND scalerank = 0)
OR (zoom_level BETWEEN 3 AND 7 AND scalerank < zoom_level)
)
UNION ALL
SELECT osm_id, geometry, name, name_en, place, NULL AS scalerank FROM (
SELECT osm_id, geometry, name, name_en, place,
row_number() OVER (
PARTITION BY LabelGrid(geometry, 150 * pixel_width)
ORDER BY place::place_subclass ASC NULLS LAST,
population DESC NULLS LAST,
length(name) DESC
) AS gridrank
FROM osm_place_point
WHERE geometry && bbox
AND ((zoom_level BETWEEN 8 AND 9 AND place::place_subclass <= 'town'::place_subclass)
OR (zoom_level = 10 AND place::place_subclass <= 'village'::place_subclass)
OR (zoom_level BETWEEN 11 AND 13 AND place::place_subclass <= 'suburb'::place_subclass)
OR (zoom_level >= 14)
)
) AS ranked_places
WHERE (zoom_level = 8 AND gridrank <= 4)
OR (zoom_level BETWEEN 9 AND 12 AND gridrank <= 9)
OR (zoom_level >= 13);
$$ LANGUAGE SQL IMMUTABLE;

Wyświetl plik

@ -1,112 +1,8 @@
CREATE OR REPLACE VIEW place_z2 AS (
SELECT osm_id, geometry, name, name_en, place, scalerank, population
FROM osm_important_place_point
WHERE scalerank <= 0
);
CREATE OR REPLACE VIEW place_z3 AS (
SELECT osm_id, geometry, name, name_en, place, scalerank, population
FROM osm_important_place_point
WHERE scalerank <= 2
);
CREATE OR REPLACE VIEW place_z4 AS (
SELECT osm_id, geometry, name, name_en, place, scalerank, population
FROM osm_important_place_point
WHERE scalerank <= 5
);
CREATE OR REPLACE VIEW place_z5 AS (
SELECT osm_id, geometry, name, name_en, place, scalerank, population
FROM osm_important_place_point
WHERE scalerank <= 6
);
CREATE OR REPLACE VIEW place_z6 AS (
SELECT osm_id, geometry, name, name_en, place, scalerank, population
FROM osm_important_place_point
WHERE scalerank <= 7
);
CREATE OR REPLACE VIEW place_z7 AS (
SELECT osm_id, geometry, name, name_en, place, scalerank, population
FROM osm_important_place_point
);
CREATE OR REPLACE VIEW place_z8 AS (
SELECT osm_id, geometry, name, name_en, place, NULL::integer AS scalerank, population FROM osm_place_point
WHERE place IN ('city', 'town')
);
CREATE OR REPLACE VIEW place_z10 AS (
SELECT osm_id, geometry, name, name_en, place, NULL::integer AS scalerank, population FROM osm_place_point
WHERE place IN ('city', 'town', 'village') OR place='subregion'
);
CREATE OR REPLACE VIEW place_z11 AS (
SELECT osm_id, geometry, name, name_en, place, NULL::integer AS scalerank, population FROM osm_place_point
WHERE place IN ('city', 'town', 'village', 'suburb')
);
CREATE OR REPLACE VIEW place_z13 AS (
SELECT osm_id, geometry, name, name_en, place, NULL::integer AS scalerank, population FROM osm_place_point
WHERE place IN ('city', 'town', 'village', 'suburb')
);
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, place text, abbrev text, postal text, scalerank int) AS $$
SELECT osm_id, geometry, name, name AS name_en, 'country' AS place, abbrev, postal, scalerank FROM layer_country(bbox, zoom_level)
UNION ALL
SELECT osm_id, geometry, name, name_en, 'state' AS place, abbrev, postal, scalerank FROM layer_state(bbox, zoom_level)
UNION ALL
SELECT osm_id, geometry, name, name_en, place, NULL AS abbrev, NULL AS postal, scalerank FROM (
SELECT osm_id, geometry, name, name_en, place, scalerank,
row_number() OVER (
PARTITION BY LabelGrid(geometry, 150 * pixel_width)
ORDER BY scalerank ASC NULLS LAST,
population DESC NULLS LAST,
length(name) DESC
) AS gridrank
FROM (
--Cities
SELECT * FROM place_z2
WHERE zoom_level = 2
UNION ALL
SELECT * FROM place_z3
WHERE zoom_level = 3
UNION ALL
SELECT * FROM place_z4
WHERE zoom_level = 4
UNION ALL
SELECT * FROM place_z5
WHERE zoom_level = 5
UNION ALL
SELECT * FROM place_z6
WHERE zoom_level = 6
UNION ALL
SELECT * FROM place_z7
WHERE zoom_level = 7
UNION ALL
SELECT * FROM place_z8
WHERE zoom_level BETWEEN 8 AND 9
UNION ALL
SELECT * FROM place_z10
WHERE zoom_level = 10
UNION ALL
SELECT * FROM place_z11
WHERE zoom_level BETWEEN 11 AND 12
UNION ALL
SELECT * FROM place_z13
WHERE zoom_level >= 13
) AS zoom_levels
WHERE geometry && bbox
) AS ranked_places
WHERE
zoom_level <= 7 OR
(zoom_level = 8 AND gridrank <= 4) OR
(zoom_level = 9 AND gridrank <= 9) OR
(zoom_level = 10 AND gridrank <= 9) OR
(zoom_level = 11 AND gridrank <= 9) OR
(zoom_level = 12 AND gridrank <= 9) OR
zoom_level >= 13;
SELECT osm_id, geometry, name, name_en, place, NULL AS abbrev, NULL AS postal, scalerank FROM layer_city(bbox, zoom_level, pixel_width)
$$ LANGUAGE SQL IMMUTABLE;

Wyświetl plik

@ -1,12 +1,21 @@
layer:
id: "place"
description: |
[OSM Places](http://wiki.openstreetmap.org/wiki/Key:place)
The place layer consists out of [countries](http://wiki.openstreetmap.org/wiki/Tag:place%3Dcountry),
[states](http://wiki.openstreetmap.org/wiki/Tag:place%3Dstate) and [cities](http://wiki.openstreetmap.org/wiki/Key:place).
For countries, states and places at low zoom levels (`z0` to `z7`) the
[Populated Places](http://www.naturalearthdata.com/downloads/10m-cultural-vectors/10m-populated-places/) dataset from NaturalEarth is merged
with OSM data to only show the most relevant places for the given zoom level. All features derived from NaturalEarth have a `scalerank` field.
States and countries additionally contain `postal` and `abbreviation` fields for styles that want to fit a lot of data with small labels on the map.
The `place` layer only contains more important states (or similar entities) from the US, Russia, China and Brazil.
buffer_size: 128
datasource:
geometry_field: geometry
query: (SELECT geometry, name, name_en, place, abbrev, postal, scalerank FROM layer_place(!bbox!, z(!scale_denominator!), !pixel_width!)) AS t
schema:
- ./types.sql
- ./city.sql
- ./country.sql
- ./state.sql
- ./important_place.sql

Wyświetl plik

@ -19,24 +19,16 @@ CREATE TABLE IF NOT EXISTS state_label AS (
);
CREATE INDEX IF NOT EXISTS state_label_geometry_idx ON state_label USING gist(geometry);
CREATE OR REPLACE VIEW state_z3 AS (
SELECT * FROM state_label
WHERE (scalerank <= 2 AND labelrank <= 1) OR type = 'Avtonomnyy Okrug'
);
CREATE OR REPLACE VIEW state_z4 AS (
SELECT * FROM state_label
);
CREATE OR REPLACE FUNCTION layer_state(bbox geometry, zoom_level int)
RETURNS TABLE(osm_id bigint, geometry geometry, name text, name_en text, abbrev text, postal text, scalerank int, labelrank int) AS $$
SELECT osm_id, geometry,
COALESCE(name_local, name_en) AS name_local, name_en,
COALESCE(name_local, name_en) AS name, name_en,
abbrev, postal, scalerank::int, labelrank::int FROM (
SELECT * FROM state_z3
WHERE zoom_level = 3
SELECT * FROM state_label
WHERE (zoom_level = 3)
AND ((scalerank <= 2 AND labelrank <= 1) OR type = 'Avtonomnyy Okrug')
UNION ALL
SELECT * FROM state_z4
SELECT * FROM state_label
WHERE zoom_level >= 4
) AS t
WHERE geometry && bbox

Wyświetl plik

@ -0,0 +1,7 @@
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'place_subclass') THEN
CREATE TYPE place_subclass AS ENUM ('city', 'town', 'village', 'hamlet', 'suburb', 'neighbourhood', 'isolated_dwelling');
END IF;
END
$$;