diff --git a/layers/place/city.sql b/layers/place/city.sql index f606c90..be7df65 100644 --- a/layers/place/city.sql +++ b/layers/place/city.sql @@ -1,25 +1,25 @@ 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::text, scalerank - FROM osm_place_point +RETURNS TABLE(osm_id bigint, geometry geometry, name text, name_en text, class city_class, scalerank int) AS $$ + SELECT osm_id, geometry, name, name_en, place, scalerank + FROM osm_city_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::text, scalerank FROM ( + SELECT osm_id, geometry, name, name_en, place, scalerank FROM ( SELECT osm_id, geometry, name, name_en, place, scalerank, row_number() OVER ( PARTITION BY LabelGrid(geometry, 150 * pixel_width) - ORDER BY place::place_subclass ASC NULLS LAST, + ORDER BY place ASC NULLS LAST, population DESC NULLS LAST, length(name) DESC ) AS gridrank - FROM osm_place_point + FROM osm_city_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) + AND ((zoom_level BETWEEN 8 AND 9 AND place <= 'town'::city_class) + OR (zoom_level = 10 AND place <= 'village'::city_class) + OR (zoom_level BETWEEN 11 AND 13 AND place <= 'suburb'::city_class) OR (zoom_level >= 14) ) ) AS ranked_places diff --git a/layers/place/important_place.sql b/layers/place/important_place.sql deleted file mode 100644 index 511d4ab..0000000 --- a/layers/place/important_place.sql +++ /dev/null @@ -1,25 +0,0 @@ -WITH important_place_point AS ( - SELECT osm.geometry, osm.osm_id, osm.name, osm.name_en, osm.place, ne.scalerank, COALESCE(osm.population, ne.pop_min) AS population - FROM ne_10m_populated_places AS ne, osm_place_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 - ) - AND (osm.place = 'city' OR osm.place= 'town' OR osm.place = 'village') - AND ST_DWithin(ne.geom, osm.geometry, 50000) -) -UPDATE osm_place_point -SET scalerank = important_place_point.scalerank -FROM important_place_point -WHERE osm_place_point.osm_id = important_place_point.osm_id; - -CREATE INDEX IF NOT EXISTS osm_place_point_scalerank_idx ON osm_place_point (scalerank); diff --git a/layers/place/mapping.yaml b/layers/place/mapping.yaml index c696929..6b4fd3e 100644 --- a/layers/place/mapping.yaml +++ b/layers/place/mapping.yaml @@ -1,26 +1,82 @@ +name_field: &name + name: name + key: name + type: string +name_en_field: &name_en + name: name_en + key: name_en + type: string +scalerank_field: &scalerank + name: scalerank + key: scalerank + type: integer tables: - place_point: + country_point: + type: point + fields: + - name: osm_id + type: id + - name: geometry + type: geometry + - *name + - *name_en + - name: name_int + key: int_name + type: string + - name: country_code_fips + key: country_code_fips + type: string + - *scalerank + filters: + exclude_tags: + - [ "name", "__nil__" ] + mapping: + place: + - country + state_point: + type: point + fields: + - name: osm_id + type: id + - name: geometry + type: geometry + - *name + - *name_en + - name: is_in_country + key: is_in:country + type: string + - name: is_in_country_code + key: is_in:country_code + type: string + - name: name_abbreviation + key: name:abbreviation + type: string + - name: ref + key: ref + type: string + - *scalerank + filters: + exclude_tags: + - [ "name", "__nil__" ] + mapping: + place: + - state + city_point: type: geometry fields: - name: osm_id type: id - name: geometry type: geometry - - key: name - name: name - type: string - - name: name_en - key: name:en - type: string + - *name + - *name_en - name: place key: place type: string - key: population name: population type: integer - - key: scalerank - name: scalerank - type: integer + - *scalerank filters: exclude_tags: - [ "name", "__nil__" ] diff --git a/layers/place/merge_scalerank.sql b/layers/place/merge_scalerank.sql new file mode 100644 index 0000000..44b2309 --- /dev/null +++ b/layers/place/merge_scalerank.sql @@ -0,0 +1,47 @@ +WITH important_country_point AS ( + SELECT osm.geometry, osm.osm_id, osm.name, osm.name_en, ne.scalerank + FROM ne_10m_admin_0_countries AS ne, osm_country_point AS osm + WHERE + ( + ne.name ILIKE osm.name OR + ne.name ILIKE osm.name_en OR + ne.adm0_a3 ILIKE osm.country_code_fips + ) + AND ST_Within(osm.geometry, ne.geom) +) +UPDATE osm_country_point AS osm +SET scalerank = ne.scalerank +FROM important_country_point AS ne +WHERE osm.osm_id = ne.osm_id; + +DELETE FROM osm_state_point +WHERE is_in_country IN ('United Kingdom', 'USA', 'Россия', 'Brasil', 'China', 'India') + OR is_in_country_code IN ('AU', 'CN', 'IN', 'BR', 'US'); + +CREATE INDEX IF NOT EXISTS osm_country_point_scalerank_idx ON osm_country_point(scalerank); + +WITH important_city_point AS ( + SELECT osm.geometry, osm.osm_id, osm.name, osm.name_en, ne.scalerank + 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 + ) + AND (osm.place = 'city'::city_class OR osm.place= 'town'::city_class OR osm.place = 'village'::city_class) + AND ST_DWithin(ne.geom, osm.geometry, 50000) +) +UPDATE osm_city_point AS osm +SET scalerank = ne.scalerank +FROM important_city_point AS ne +WHERE osm.osm_id = ne.osm_id; + +CREATE INDEX IF NOT EXISTS osm_city_point_scalerank_idx ON osm_city_point(scalerank); diff --git a/layers/place/place.sql b/layers/place/place.sql index 5f1c7ad..855d664 100644 --- a/layers/place/place.sql +++ b/layers/place/place.sql @@ -1,8 +1,8 @@ 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) +RETURNS TABLE(osm_id bigint, geometry geometry, name text, name_en text, class text, abbrev text, scalerank int) AS $$ + SELECT osm_id, geometry, name, name AS name_en, 'country' AS class, abbrev, 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) + SELECT osm_id, geometry, name, name_en, 'state' AS class, abbrev, 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 layer_city(bbox, zoom_level, pixel_width) + SELECT osm_id, geometry, name, name_en, class::text, NULL AS abbrev, scalerank FROM layer_city(bbox, zoom_level, pixel_width) $$ LANGUAGE SQL IMMUTABLE; diff --git a/layers/place/place.yaml b/layers/place/place.yaml index 60be69b..e53a9b2 100644 --- a/layers/place/place.yaml +++ b/layers/place/place.yaml @@ -12,13 +12,13 @@ layer: 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 + query: (SELECT geometry, name, name_en, class, abbrev scalerank FROM layer_place(!bbox!, z(!scale_denominator!), !pixel_width!)) AS t schema: - ./types.sql - ./city.sql - ./country.sql - ./state.sql - - ./important_place.sql + - ./merge_scalerank.sql - ./place.sql datasources: - type: imposm3 diff --git a/layers/place/types.sql b/layers/place/types.sql index 846a30a..48c575e 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 = 'place_subclass') THEN - CREATE TYPE place_subclass AS ENUM ('city', 'town', 'village', 'hamlet', 'suburb', 'neighbourhood', 'isolated_dwelling'); + 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'); END IF; END $$; -ALTER TABLE osm_place_point ALTER COLUMN place TYPE place_subclass USING place::place_subclass; +ALTER TABLE osm_city_point ALTER COLUMN place TYPE city_class USING place::city_class;