-- 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, name_de text, tags hstore, place city_place, "rank" int, capital int) AS $$ SELECT * FROM ( SELECT osm_id, geometry, name, COALESCE(NULLIF(name_en, ''), name) AS name_en, COALESCE(NULLIF(name_de, ''), name, name_en) AS name_de, tags, place, "rank", normalize_capital_level(capital) AS capital FROM osm_city_point WHERE geometry && bbox AND ((zoom_level = 2 AND "rank" = 1) OR (zoom_level BETWEEN 3 AND 7 AND "rank" <= zoom_level + 1) ) UNION ALL SELECT osm_id, geometry, name, COALESCE(NULLIF(name_en, ''), name) AS name_en, COALESCE(NULLIF(name_de, ''), name, name_en) AS name_de, tags, place, COALESCE("rank", gridrank + 10), normalize_capital_level(capital) AS capital FROM ( SELECT osm_id, geometry, name, COALESCE(NULLIF(name_en, ''), name) AS name_en, COALESCE(NULLIF(name_de, ''), name, name_en) AS name_de, tags, place, "rank", capital, row_number() OVER ( PARTITION BY LabelGrid(geometry, 128 * pixel_width) ORDER BY "rank" ASC NULLS LAST, place ASC NULLS LAST, population DESC NULLS LAST, length(name) ASC )::int AS gridrank FROM osm_city_point WHERE geometry && bbox AND ((zoom_level = 7 AND place <= 'town'::city_place OR (zoom_level BETWEEN 8 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 BETWEEN 7 AND 8 AND (gridrank <= 4 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 BETWEEN 11 AND 12 AND (gridrank <= 14 OR "rank" IS NOT NULL)) OR (zoom_level >= 13) ) as city_all; $$ LANGUAGE SQL IMMUTABLE;