openmaptiles/layers/landcover/landcover.sql
Tomas Pohanka 4a1b0afa26
reworked landcover layer (#1035)
Instead of using [Douglas-Peucker algorithm](https://postgis.net/docs/ST_SimplifyPreserveTopology.html) which is using for generalized tables [imposm](https://imposm.org/docs/imposm3/latest/mapping.html#generalized-tables) it is used [Visvalingam-Whyatt algorithm](https://postgis.net/docs/ST_SimplifyVW.html).

Solution:
remove imposm generalized tables (during `import-osm`) and create generalization in `import-sql` step for zooms 7-14. Zooms 0-6 are from Natural Earth data.

Upper zoom levels (7 and 8) are ok to merge with no big impact on creation speed. In Canada from z9 it took too long. Between zoom levels 10 - 13 there can be union polygons with less than 300 edge points (empirical number based on a test on Canada forest, can be discussed). Polygons with more than 300 edge points are just simplified. Zoom 14 is from the original dataset `osm_landcover_polygon`.

There is also removed `osm_id` which is never used and not passed into vector tiles.
2020-11-11 15:11:48 +02:00

145 lines
4.7 KiB
PL/PgSQL

--TODO: Find a way to nicely generalize landcover
--CREATE TABLE IF NOT EXISTS landcover_grouped_gen2 AS (
-- SELECT osm_id, ST_Simplify((ST_Dump(geometry)).geom, 600) AS geometry, landuse, "natural", wetland
-- FROM (
-- SELECT max(osm_id) AS osm_id, ST_Union(ST_Buffer(geometry, 600)) AS geometry, landuse, "natural", wetland
-- FROM osm_landcover_polygon_gen1
-- GROUP BY LabelGrid(geometry, 15000000), landuse, "natural", wetland
-- ) AS grouped_measurements
--);
--CREATE INDEX IF NOT EXISTS landcover_grouped_gen2_geometry_idx ON landcover_grouped_gen2 USING gist(geometry);
CREATE OR REPLACE FUNCTION landcover_class(subclass varchar) RETURNS text AS
$$
SELECT CASE
%%FIELD_MAPPING: class %%
END;
$$ LANGUAGE SQL IMMUTABLE
-- STRICT
PARALLEL SAFE;
-- etldoc: ne_110m_glaciated_areas -> landcover_z0
CREATE OR REPLACE VIEW landcover_z0 AS
(
SELECT geometry, 'glacier'::text AS subclass
FROM ne_110m_glaciated_areas
);
CREATE OR REPLACE VIEW landcover_z2 AS
(
-- etldoc: ne_50m_glaciated_areas -> landcover_z2
SELECT geometry, 'glacier'::text AS subclass
FROM ne_50m_glaciated_areas
UNION ALL
-- etldoc: ne_50m_antarctic_ice_shelves_polys -> landcover_z2
SELECT geometry, 'ice_shelf'::text AS subclass
FROM ne_50m_antarctic_ice_shelves_polys
);
CREATE OR REPLACE VIEW landcover_z5 AS
(
-- etldoc: ne_10m_glaciated_areas -> landcover_z5
SELECT geometry, 'glacier'::text AS subclass
FROM ne_10m_glaciated_areas
UNION ALL
-- etldoc: ne_10m_antarctic_ice_shelves_polys -> landcover_z5
SELECT geometry, 'ice_shelf'::text AS subclass
FROM ne_10m_antarctic_ice_shelves_polys
);
-- etldoc: layer_landcover[shape=record fillcolor=lightpink, style="rounded, filled", label="layer_landcover | <z0_1> z0-z1 | <z2_4> z2-z4 | <z5_6> z5-z6 |<z7> z7 |<z8> z8 |<z9> z9 |<z10> z10 |<z11> z11 |<z12> z12|<z13> z13|<z14_> z14+" ] ;
CREATE OR REPLACE FUNCTION layer_landcover(bbox geometry, zoom_level int)
RETURNS TABLE
(
geometry geometry,
class text,
subclass text
)
AS
$$
SELECT geometry,
landcover_class(subclass) AS class,
subclass
FROM (
-- etldoc: landcover_z0 -> layer_landcover:z0_1
SELECT geometry,
subclass
FROM landcover_z0
WHERE zoom_level BETWEEN 0 AND 1
AND geometry && bbox
UNION ALL
-- etldoc: landcover_z2 -> layer_landcover:z2_4
SELECT geometry,
subclass
FROM landcover_z2
WHERE zoom_level BETWEEN 2 AND 4
AND geometry && bbox
UNION ALL
-- etldoc: landcover_z5 -> layer_landcover:z5_6
SELECT geometry,
subclass
FROM landcover_z5
WHERE zoom_level BETWEEN 5 AND 6
AND geometry && bbox
UNION ALL
-- etldoc: osm_landcover_gen_z7 -> layer_landcover:z7
SELECT geometry,
subclass
FROM osm_landcover_gen_z7
WHERE zoom_level = 7
AND geometry && bbox
UNION ALL
-- etldoc: osm_landcover_gen_z8 -> layer_landcover:z8
SELECT geometry,
subclass
FROM osm_landcover_gen_z8
WHERE zoom_level = 8
AND geometry && bbox
UNION ALL
-- etldoc: osm_landcover_gen_z9 -> layer_landcover:z9
SELECT geometry,
subclass
FROM osm_landcover_gen_z9
WHERE zoom_level = 9
AND geometry && bbox
UNION ALL
-- etldoc: osm_landcover_gen_z10 -> layer_landcover:z10
SELECT geometry,
subclass
FROM osm_landcover_gen_z10
WHERE zoom_level = 10
AND geometry && bbox
UNION ALL
-- etldoc: osm_landcover_gen_z11 -> layer_landcover:z11
SELECT geometry,
subclass
FROM osm_landcover_gen_z11
WHERE zoom_level = 11
AND geometry && bbox
UNION ALL
-- etldoc: osm_landcover_gen_z12 -> layer_landcover:z12
SELECT geometry,
subclass
FROM osm_landcover_gen_z12
WHERE zoom_level = 12
AND geometry && bbox
UNION ALL
-- etldoc: osm_landcover_gen_z13 -> layer_landcover:z13
SELECT geometry,
subclass
FROM osm_landcover_gen_z13
WHERE zoom_level = 13
AND geometry && bbox
UNION ALL
-- etldoc: osm_landcover_polygon -> layer_landcover:z14_
SELECT geometry,
subclass
FROM osm_landcover_polygon
WHERE zoom_level >= 14
AND geometry && bbox
) AS zoom_levels;
$$ LANGUAGE SQL STABLE
-- STRICT
PARALLEL SAFE;