Fix landcover generalization. (#1042)

This PR brings few modification which make it possible to generalize landcover on larger areas. Tested on Europe.

- Use ST_SnapToGrid to avoid ERROR:  GEOSUnaryUnion: TopologyException: found non-noded intersection between LINESTRING.
- Cluster only landcover subclasses: wood and forest.
- Use less generalized tables as a starting point for next step generalization.
This commit is contained in:
Adam Laža 2020-11-24 09:33:06 +01:00 committed by GitHub
parent 0776cd3eed
commit da689f9e42
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -5,19 +5,324 @@ DROP TABLE IF EXISTS osm_landcover_gen_z10;
DROP TABLE IF EXISTS osm_landcover_gen_z11;
DROP TABLE IF EXISTS osm_landcover_gen_z12;
DROP TABLE IF EXISTS osm_landcover_gen_z13;
DROP TABLE IF EXISTS simplify_vw_z7 CASCADE;
DROP TABLE IF EXISTS simplify_vw_z8 CASCADE;
DROP TABLE IF EXISTS simplify_vw_z9 CASCADE;
DROP TABLE IF EXISTS simplify_vw_z10 CASCADE;
DROP TABLE IF EXISTS simplify_vw_z11 CASCADE;
DROP TABLE IF EXISTS simplify_vw_z12 CASCADE;
DROP TABLE IF EXISTS simplify_vw_z13 CASCADE;
-- etldoc: osm_landcover_polygon -> osm_landcover_gen_z7
CREATE TABLE osm_landcover_gen_z7 AS
-- etldoc: osm_landcover_polygon -> osm_landcover_gen_z13
CREATE TABLE simplify_vw_z13 AS
(
WITH simplify_vw_z7 AS
(
SELECT subclass,
ST_MakeValid(
ST_SimplifyVW(geometry, zres(7)*zres(7))) AS geometry
ST_SnapToGrid(
ST_SimplifyVW(geometry, power(zres(13),2)),
0.001)) AS geometry
FROM osm_landcover_polygon
WHERE ST_Area(geometry) > power(zres(5),2)
)
WHERE ST_Area(geometry) > power(zres(10),2)
);
CREATE INDEX ON simplify_vw_z13 USING GIST (geometry);
CREATE TABLE osm_landcover_gen_z13 AS
(
SELECT subclass,
ST_MakeValid(
(ST_dump(
ST_Union(geometry))).geom) AS geometry
FROM (
SELECT subclass,
ST_ClusterDBSCAN(geometry, eps := 0, minpoints := 1) over () AS cid, geometry
FROM simplify_vw_z13
WHERE ST_NPoints(geometry) < 50
AND subclass IN ('wood', 'forest')) union_geom50
GROUP BY subclass,
cid
UNION ALL
SELECT subclass, ST_MakeValid((ST_dump(ST_Union(geometry))).geom) AS geometry
FROM (
SELECT subclass,
ST_ClusterDBSCAN(geometry, eps := 0, minpoints := 1) over () AS cid, geometry
FROM simplify_vw_z13
WHERE ST_NPoints(geometry) >= 50
AND ST_NPoints(geometry) < 300
AND subclass IN ('wood', 'forest')) union_geom300
GROUP BY subclass,
cid
UNION ALL
SELECT subclass,
geometry
FROM simplify_vw_z13
WHERE (ST_NPoints(geometry) >= 300 AND subclass IN ('wood', 'forest'))
OR (subclass NOT IN ('wood', 'forest'))
);
CREATE INDEX ON osm_landcover_gen_z13 USING GIST (geometry);
-- etldoc: osm_landcover_polygon -> osm_landcover_gen_z12
CREATE TABLE simplify_vw_z12 AS
(
SELECT subclass,
ST_MakeValid(
ST_SnapToGrid(
ST_SimplifyVW(geometry, power(zres(12),2)),
0.001)) AS geometry
FROM simplify_vw_z13
WHERE ST_Area(geometry) > power(zres(9),2)
);
CREATE INDEX ON simplify_vw_z12 USING GIST (geometry);
CREATE TABLE osm_landcover_gen_z12 AS
(
SELECT subclass,
ST_MakeValid(
(ST_dump(
ST_Union(geometry))).geom) AS geometry
FROM (
SELECT subclass,
ST_ClusterDBSCAN(geometry, eps := 0, minpoints := 1) over () AS cid, geometry
FROM simplify_vw_z12
WHERE ST_NPoints(geometry) < 50
AND subclass IN ('wood', 'forest')) union_geom50
GROUP BY subclass,
cid
UNION ALL
SELECT subclass, ST_MakeValid((ST_dump(ST_Union(geometry))).geom) AS geometry
FROM (
SELECT subclass,
ST_ClusterDBSCAN(geometry, eps := 0, minpoints := 1) over () AS cid, geometry
FROM simplify_vw_z12
WHERE ST_NPoints(geometry) >= 50
AND ST_NPoints(geometry) < 300
AND subclass IN ('wood', 'forest')) union_geom300
GROUP BY subclass,
cid
UNION ALL
SELECT subclass,
geometry
FROM simplify_vw_z12
WHERE (ST_NPoints(geometry) >= 300 AND subclass IN ('wood', 'forest'))
OR (subclass NOT IN ('wood', 'forest'))
);
CREATE INDEX ON osm_landcover_gen_z12 USING GIST (geometry);
-- etldoc: osm_landcover_polygon -> osm_landcover_gen_z11
CREATE TABLE simplify_vw_z11 AS
(
SELECT subclass,
ST_MakeValid(
ST_SnapToGrid(
ST_SimplifyVW(geometry, power(zres(11),2)),
0.001)) AS geometry
FROM simplify_vw_z12
WHERE ST_Area(geometry) > power(zres(8),2)
);
CREATE INDEX ON simplify_vw_z11 USING GIST (geometry);
CREATE TABLE osm_landcover_gen_z11 AS
(
SELECT subclass,
ST_MakeValid(
(ST_dump(
ST_Union(geometry))).geom) AS geometry
FROM (
SELECT subclass,
ST_ClusterDBSCAN(geometry, eps := 0, minpoints := 1) over () AS cid, geometry
FROM simplify_vw_z11
WHERE ST_NPoints(geometry) < 50
AND subclass IN ('wood', 'forest')) union_geom50
GROUP BY subclass,
cid
UNION ALL
SELECT subclass, ST_MakeValid((ST_dump(ST_Union(geometry))).geom) AS geometry
FROM (
SELECT subclass,
ST_ClusterDBSCAN(geometry, eps := 0, minpoints := 1) over () AS cid, geometry
FROM simplify_vw_z11
WHERE ST_NPoints(geometry) >= 50
AND ST_NPoints(geometry) < 300
AND subclass IN ('wood', 'forest')) union_geom300
GROUP BY subclass,
cid
UNION ALL
SELECT subclass,
geometry
FROM simplify_vw_z11
WHERE (ST_NPoints(geometry) >= 300 AND subclass IN ('wood', 'forest'))
OR (subclass NOT IN ('wood', 'forest'))
);
CREATE INDEX ON osm_landcover_gen_z11 USING GIST (geometry);
-- etldoc: osm_landcover_polygon -> osm_landcover_gen_z10
CREATE TABLE simplify_vw_z10 AS
(
SELECT subclass,
ST_MakeValid(
ST_SnapToGrid(
ST_SimplifyVW(geometry, power(zres(10),2)),
0.001)) AS geometry
FROM simplify_vw_z11
WHERE ST_Area(geometry) > power(zres(8),2)
);
CREATE INDEX ON simplify_vw_z10 USING GIST (geometry);
CREATE TABLE osm_landcover_gen_z10 AS
(
SELECT subclass,
ST_MakeValid(
(ST_dump(
ST_Union(geometry))).geom) AS geometry
FROM (
SELECT subclass,
ST_ClusterDBSCAN(geometry, eps := 0, minpoints := 1) over () AS cid, geometry
FROM simplify_vw_z10
WHERE ST_NPoints(geometry) < 50
AND subclass IN ('wood', 'forest')) union_geom50
GROUP BY subclass,
cid
UNION ALL
SELECT subclass, ST_MakeValid((ST_dump(ST_Union(geometry))).geom) AS geometry
FROM (
SELECT subclass,
ST_ClusterDBSCAN(geometry, eps := 0, minpoints := 1) over () AS cid, geometry
FROM simplify_vw_z10
WHERE ST_NPoints(geometry) >= 50
AND ST_NPoints(geometry) < 300
AND subclass IN ('wood', 'forest')) union_geom300
GROUP BY subclass,
cid
UNION ALL
SELECT subclass,
geometry
FROM simplify_vw_z10
WHERE (ST_NPoints(geometry) >= 300 AND subclass IN ('wood', 'forest'))
OR (subclass IN ('wood', 'forest'))
);
CREATE INDEX ON osm_landcover_gen_z10 USING GIST (geometry);
-- etldoc: osm_landcover_polygon -> osm_landcover_gen_z9
CREATE TABLE simplify_vw_z9 AS
(
SELECT subclass,
ST_MakeValid(
ST_SnapToGrid(
ST_SimplifyVW(geometry, power(zres(9),2)),
0.001)) AS geometry
FROM simplify_vw_z10
WHERE ST_Area(geometry) > power(zres(7),2)
);
CREATE INDEX ON simplify_vw_z9 USING GIST (geometry);
CREATE TABLE osm_landcover_gen_z9 AS
(
SELECT subclass,
ST_MakeValid(
(ST_dump(
ST_Union(geometry))).geom) AS geometry
FROM (
SELECT subclass,
ST_ClusterDBSCAN(geometry, eps := 0, minpoints := 1) over () AS cid, geometry
FROM simplify_vw_z9
WHERE ST_NPoints(geometry) < 50
AND subclass IN ('wood', 'forest')) union_geom50
GROUP BY subclass,
cid
UNION ALL
SELECT subclass, ST_MakeValid((ST_dump(ST_Union(geometry))).geom) AS geometry
FROM (
SELECT subclass,
ST_ClusterDBSCAN(geometry, eps := 0, minpoints := 1) over () AS cid, geometry
FROM simplify_vw_z9
WHERE ST_NPoints(geometry) >= 50
AND ST_NPoints(geometry) < 300
AND subclass IN ('wood', 'forest')) union_geom300
GROUP BY subclass,
cid
UNION ALL
SELECT subclass,
ST_MakeValid(
(ST_Dump(
ST_Union(geometry))).geom) AS geometry
FROM (
SELECT subclass,
ST_ClusterDBSCAN(geometry, eps := 0, minpoints := 1) over () AS cid, geometry
FROM simplify_vw_z9
WHERE ST_NPoints(geometry) >= 300
AND subclass IN ('wood', 'forest')) union_geom_rest
GROUP BY subclass,
cid
UNION ALL
SELECT subclass,
geometry
FROM simplify_vw_z9
WHERE subclass NOT IN ('wood', 'forest')
);
CREATE INDEX ON osm_landcover_gen_z9 USING GIST (geometry);
-- etldoc: osm_landcover_polygon -> osm_landcover_gen_z8
CREATE TABLE simplify_vw_z8 AS
(
SELECT subclass,
ST_MakeValid(
ST_SnapToGrid(
ST_SimplifyVW(geometry, power(zres(8),2)),
0.001)) AS geometry
FROM simplify_vw_z9
WHERE ST_Area(geometry) > power(zres(6),2)
);
CREATE INDEX ON simplify_vw_z8 USING GIST (geometry);
CREATE TABLE osm_landcover_gen_z8 AS
(
SELECT subclass,
ST_MakeValid(
(ST_Dump(
ST_Union(geometry))).geom) AS geometry
FROM
(
SELECT subclass,
ST_ClusterDBSCAN(geometry, eps := 0, minpoints := 1) OVER () AS cid,
geometry
FROM simplify_vw_z8
) union_geom
GROUP BY subclass,
cid
UNION ALL
SELECT subclass,
geometry
FROM simplify_vw_z8
WHERE subclass NOT IN ('wood', 'forest')
);
CREATE INDEX ON osm_landcover_gen_z8 USING GIST (geometry);
-- etldoc: osm_landcover_polygon -> osm_landcover_gen_z7
CREATE TABLE simplify_vw_z7 AS
(
SELECT subclass,
ST_MakeValid(
ST_SnapToGrid(
ST_SimplifyVW(geometry, power(zres(7),2)),
0.001)) AS geometry
FROM simplify_vw_z8
WHERE ST_Area(geometry) > power(zres(5),2)
);
CREATE INDEX ON simplify_vw_z7 USING GIST (geometry);
CREATE TABLE osm_landcover_gen_z7 AS
(
SELECT subclass,
ST_MakeValid(
(ST_Dump(
@ -35,243 +340,10 @@ GROUP BY subclass,
CREATE INDEX ON osm_landcover_gen_z7 USING GIST (geometry);
-- etldoc: osm_landcover_polygon -> osm_landcover_gen_z8
CREATE TABLE osm_landcover_gen_z8 AS
(
WITH simplify_vw_z8 AS
(
SELECT subclass,
ST_MakeValid(
ST_SimplifyVW(geometry, zres(8)*zres(8))) AS geometry
FROM osm_landcover_polygon
WHERE ST_Area(geometry) > power(zres(6),2)
)
SELECT subclass,
ST_MakeValid(
(ST_Dump(
ST_Union(geometry))).geom) AS geometry
FROM
(
SELECT subclass,
ST_ClusterDBSCAN(geometry, eps := 0, minpoints := 1) OVER () AS cid,
geometry
FROM simplify_vw_z8
) union_geom
GROUP BY subclass,
cid
);
CREATE INDEX ON osm_landcover_gen_z8 USING GIST (geometry);
-- etldoc: osm_landcover_polygon -> osm_landcover_gen_z9
CREATE TABLE osm_landcover_gen_z9 AS
(
WITH simplify_vw_z9 AS
(
SELECT subclass,
ST_MakeValid(
ST_SimplifyVW(geometry, zres(9)*zres(9))) AS geometry
FROM osm_landcover_polygon
WHERE ST_Area(geometry) > power(zres(7),2)
)
SELECT subclass,
ST_MakeValid(
(ST_dump(
ST_Union(geometry))).geom) AS geometry
FROM (
SELECT subclass,
ST_ClusterDBSCAN(geometry, eps := 0, minpoints := 1) over () AS cid, geometry
FROM simplify_vw_z9
WHERE ST_NPoints(geometry) < 50) union_geom50
GROUP BY subclass,
cid
UNION ALL
SELECT subclass, st_makevalid((ST_dump(ST_Union(geometry))).geom) AS geometry
FROM (
SELECT subclass,
ST_ClusterDBSCAN(geometry, eps := 0, minpoints := 1) over () AS cid, geometry
FROM simplify_vw_z9
WHERE ST_NPoints(geometry) >= 50 AND ST_NPoints(geometry) < 300) union_geom300
GROUP BY subclass,
cid
UNION ALL
SELECT subclass,
ST_MakeValid(
(ST_Dump(
ST_Union(geometry))).geom) AS geometry
FROM (
SELECT subclass,
ST_ClusterDBSCAN(geometry, eps := 0, minpoints := 1) over () AS cid, geometry
FROM simplify_vw_z9
WHERE ST_NPoints(geometry) >= 300) union_geom_rest
GROUP BY subclass,
cid
);
CREATE INDEX ON osm_landcover_gen_z9 USING GIST (geometry);
-- etldoc: osm_landcover_polygon -> osm_landcover_gen_z10
CREATE TABLE osm_landcover_gen_z10 AS
(
WITH simplify_vw_z10 AS
(
SELECT subclass,
ST_MakeValid(
ST_SimplifyVW(geometry, zres(10)*zres(10))) AS geometry
FROM osm_landcover_polygon
WHERE ST_Area(geometry) > power(zres(8),2)
)
SELECT subclass,
ST_MakeValid(
(ST_dump(
ST_Union(geometry))).geom) AS geometry
FROM (
SELECT subclass,
ST_ClusterDBSCAN(geometry, eps := 0, minpoints := 1) over () AS cid, geometry
FROM simplify_vw_z10
WHERE ST_NPoints(geometry) < 50) union_geom50
GROUP BY subclass,
cid
UNION ALL
SELECT subclass, st_makevalid((ST_dump(ST_Union(geometry))).geom) AS geometry
FROM (
SELECT subclass,
ST_ClusterDBSCAN(geometry, eps := 0, minpoints := 1) over () AS cid, geometry
FROM simplify_vw_z10
WHERE ST_NPoints(geometry) >= 50 AND ST_NPoints(geometry) < 300) union_geom300
GROUP BY subclass,
cid
UNION ALL
SELECT subclass,
geometry
FROM simplify_vw_z10
WHERE ST_NPoints(geometry) >= 300
);
CREATE INDEX ON osm_landcover_gen_z10 USING GIST (geometry);
-- etldoc: osm_landcover_polygon -> osm_landcover_gen_z11
CREATE TABLE osm_landcover_gen_z11 AS
(
WITH simplify_vw_z11 AS
(
SELECT subclass,
ST_MakeValid(
ST_SimplifyVW(geometry, zres(11)*zres(11))) AS geometry
FROM osm_landcover_polygon
WHERE ST_Area(geometry) > power(zres(8),2)
)
SELECT subclass,
ST_MakeValid(
(ST_dump(
ST_Union(geometry))).geom) AS geometry
FROM (
SELECT subclass,
ST_ClusterDBSCAN(geometry, eps := 0, minpoints := 1) over () AS cid, geometry
FROM simplify_vw_z11
WHERE ST_NPoints(geometry) < 50) union_geom50
GROUP BY subclass,
cid
UNION ALL
SELECT subclass, st_makevalid((ST_dump(ST_Union(geometry))).geom) AS geometry
FROM (
SELECT subclass,
ST_ClusterDBSCAN(geometry, eps := 0, minpoints := 1) over () AS cid, geometry
FROM simplify_vw_z11
WHERE ST_NPoints(geometry) >= 50 AND ST_NPoints(geometry) < 300) union_geom300
GROUP BY subclass,
cid
UNION ALL
SELECT subclass,
geometry
FROM simplify_vw_z11
WHERE ST_NPoints(geometry) >= 300
);
CREATE INDEX ON osm_landcover_gen_z11 USING GIST (geometry);
-- etldoc: osm_landcover_polygon -> osm_landcover_gen_z12
CREATE TABLE osm_landcover_gen_z12 AS
(
WITH simplify_vw_z12 AS
(
SELECT subclass,
ST_MakeValid(
ST_SimplifyVW(geometry, zres(12)*zres(12))) AS geometry
FROM osm_landcover_polygon
WHERE ST_Area(geometry) > power(zres(9),2)
)
SELECT subclass,
ST_MakeValid(
(ST_dump(
ST_Union(geometry))).geom) AS geometry
FROM (
SELECT subclass,
ST_ClusterDBSCAN(geometry, eps := 0, minpoints := 1) over () AS cid, geometry
FROM simplify_vw_z12
WHERE ST_NPoints(geometry) < 50) union_geom50
GROUP BY subclass,
cid
UNION ALL
SELECT subclass, st_makevalid((ST_dump(ST_Union(geometry))).geom) AS geometry
FROM (
SELECT subclass,
ST_ClusterDBSCAN(geometry, eps := 0, minpoints := 1) over () AS cid, geometry
FROM simplify_vw_z12
WHERE ST_NPoints(geometry) >= 50 AND ST_NPoints(geometry) < 300) union_geom300
GROUP BY subclass,
cid
UNION ALL
SELECT subclass,
geometry
FROM simplify_vw_z12
WHERE ST_NPoints(geometry) >= 300
);
CREATE INDEX ON osm_landcover_gen_z12 USING GIST (geometry);
-- etldoc: osm_landcover_polygon -> osm_landcover_gen_z13
CREATE TABLE osm_landcover_gen_z13 AS
(
WITH simplify_vw_z13 AS
(
SELECT subclass,
ST_MakeValid(
ST_SimplifyVW(geometry, zres(13)*zres(13))) AS geometry
FROM osm_landcover_polygon
WHERE ST_Area(geometry) > power(zres(10),2)
)
SELECT subclass,
ST_MakeValid(
(ST_dump(
ST_Union(geometry))).geom) AS geometry
FROM (
SELECT subclass,
ST_ClusterDBSCAN(geometry, eps := 0, minpoints := 1) over () AS cid, geometry
FROM simplify_vw_z13
WHERE ST_NPoints(geometry) < 50) union_geom50
GROUP BY subclass,
cid
UNION ALL
SELECT subclass, st_makevalid((ST_dump(ST_Union(geometry))).geom) AS geometry
FROM (
SELECT subclass,
ST_ClusterDBSCAN(geometry, eps := 0, minpoints := 1) over () AS cid, geometry
FROM simplify_vw_z13
WHERE ST_NPoints(geometry) >= 50 AND ST_NPoints(geometry) < 300) union_geom300
GROUP BY subclass,
cid
UNION ALL
SELECT subclass,
geometry
FROM simplify_vw_z13
WHERE ST_NPoints(geometry) >= 300
);
CREATE INDEX ON osm_landcover_gen_z13 USING GIST (geometry);
DROP TABLE IF EXISTS simplify_vw_z7 CASCADE;
DROP TABLE IF EXISTS simplify_vw_z8 CASCADE;
DROP TABLE IF EXISTS simplify_vw_z9 CASCADE;
DROP TABLE IF EXISTS simplify_vw_z10 CASCADE;
DROP TABLE IF EXISTS simplify_vw_z11 CASCADE;
DROP TABLE IF EXISTS simplify_vw_z12 CASCADE;
DROP TABLE IF EXISTS simplify_vw_z13 CASCADE;