From 6c472db2c96831704d360c9f1761ec258f605339 Mon Sep 17 00:00:00 2001 From: Sandro Santilli Date: Mon, 20 Feb 2012 10:52:31 +0000 Subject: [PATCH] Update face MBR on edge change (#1587) git-svn-id: http://svn.osgeo.org/postgis/trunk@9235 b70326c6-7e19-0410-871a-916f4a2858ee --- topology/sql/sqlmm.sql.in.c | 25 +++++++++++- topology/test/regress/st_changeedgegeom.sql | 39 ++++++++++++++++--- .../test/regress/st_changeedgegeom_expected | 6 +++ 3 files changed, 62 insertions(+), 8 deletions(-) diff --git a/topology/sql/sqlmm.sql.in.c b/topology/sql/sqlmm.sql.in.c index de4e86084..38a2a16f3 100644 --- a/topology/sql/sqlmm.sql.in.c +++ b/topology/sql/sqlmm.sql.in.c @@ -2801,8 +2801,29 @@ BEGIN --} - --RAISE EXCEPTION 'Not doing it'; - + -- Update faces MBR of left and right faces + -- TODO: think about ways to optimize this part, like see if + -- the old edge geometry partecipated in the definition + -- of the current MBR (for shrinking) or the new edge MBR + -- would be larger than the old face MBR... + -- + IF oldedge.left_face != 0 THEN + sql := 'UPDATE ' || quote_ident(atopology) || '.face ' + || ' SET mbr = ' || quote_literal( + ST_Envelope(ST_GetFaceGeometry(atopology, oldedge.left_face))::text + ) + || '::geometry WHERE face_id = ' || oldedge.left_face; + EXECUTE sql; + END IF; + IF oldedge.right_face != 0 AND oldedge.right_face != oldedge.left_face THEN + sql := 'UPDATE ' || quote_ident(atopology) || '.face ' + || ' SET mbr = ' || quote_literal( + ST_Envelope(ST_GetFaceGeometry(atopology, oldedge.right_face))::text + ) + || '::geometry WHERE face_id = ' || oldedge.right_face; + EXECUTE sql; + END IF; + RETURN 'Edge ' || anedge || ' changed'; diff --git a/topology/test/regress/st_changeedgegeom.sql b/topology/test/regress/st_changeedgegeom.sql index a9d68a74b..52f4475f1 100644 --- a/topology/test/regress/st_changeedgegeom.sql +++ b/topology/test/regress/st_changeedgegeom.sql @@ -33,9 +33,13 @@ SELECT 'T2', topology.ST_ChangeEdgeGeom('city_data', 5, SELECT 'T3', topology.ST_ChangeEdgeGeom('city_data', 5, 'LINESTRING(41 40, 49 40, 49 34, 57 33)'); --- Change a closed edge +-- Change a closed edge (counterclockwise) SELECT 'T4', topology.ST_ChangeEdgeGeom('city_data', 26, - 'LINESTRING(4 31, 7 31, 4 34, 4 31)'); + 'LINESTRING(4 31, 7 31, 4 33, 4 31)'); +-- Check face update +SELECT 'T4F', ST_Equals(f.mbr, ST_Envelope(e.geom)) + FROM city_data.face f, city_data.edge e + WHERE e.edge_id = 26 AND f.face_id = e.left_face; -- Collisions on edge motion path is forbidden: -- get to include a whole isolated edge @@ -54,9 +58,13 @@ SELECT 'T6', topology.ST_ChangeEdgeGeom('city_data', 3, SELECT topology.ST_ChangeEdgeGeom('city_data', 3, 'LINESTRING(25 30, 18 35, 18 39, 23 39, 23 36, 20 35, 25 35)'); --- This movement is legit +-- This movement is legit (counterclockwise closed edge) SELECT 'T7', topology.ST_ChangeEdgeGeom('city_data', 2, 'LINESTRING(25 30, 28 39, 16 39, 25 30)'); +-- Check face update +SELECT 'T7F', ST_Equals(f.mbr, ST_Envelope(e.geom)) + FROM city_data.face f, city_data.edge e + WHERE e.edge_id = 2 AND f.face_id = e.left_face; -- This movement gets to exclude an isolated node: SELECT topology.ST_ChangeEdgeGeom('city_data', 2, @@ -65,14 +73,24 @@ SELECT topology.ST_ChangeEdgeGeom('city_data', 2, -- This movement should be fine SELECT 'T7.1', topology.ST_ChangeEdgeGeom('city_data', 2, 'LINESTRING(25 30, 28 39, 17 39, 25 30)'); +-- Check face update +SELECT 'T7F.1', + ST_Equals(f.mbr, ST_Envelope(ST_GetFaceGeometry('city_data', f.face_id))) + FROM city_data.face f, city_data.edge e + WHERE e.edge_id = 2 AND f.face_id = e.left_face; -- Test changing winding direction of closed edge SELECT topology.ST_ChangeEdgeGeom('city_data', 26, ST_Reverse('LINESTRING(4 31, 7 31, 4 34, 4 31)')); --- Maintain winding of closed edge +-- Maintain winding of closed edge (counterclockwise) SELECT 'T8', topology.ST_ChangeEdgeGeom('city_data', 26, 'LINESTRING(4 31, 4 30.4, 5 30.4, 4 31)'); +-- Check face update +SELECT 'T8F', + ST_Equals(f.mbr, ST_Envelope(ST_GetFaceGeometry('city_data', f.face_id))) + FROM city_data.face f, city_data.edge e + WHERE e.edge_id = 26 AND f.face_id = e.left_face; -- test changing winding of non-closed edge ring SELECT topology.ST_ChangeEdgeGeom('city_data', 13, @@ -84,12 +102,21 @@ SELECT 'T9', ST_AddEdgeModFace('city_data', 20, 20, SELECT ST_ChangeEdgeGeom('city_data', 26, -- should fail! 'LINESTRING(4 31,5 31.5,4.6 32,4 31)'); --- TODO: test moving non-closed edge into another face +-- test moving non-closed edge into another face SELECT 'T10', ST_AddEdgeModFace('city_data', 17, 18, 'LINESTRING(21 22, 28 27, 35 22)'); SELECT ST_ChangeEdgeGeom('city_data', 28, -- should fail! 'LINESTRING(21 22, 28 18, 35 22)'); --- TODO: test face mbr update +-- test enlarging a face MBR by moving an edge +SELECT 'T11', ST_ChangeEdgeGeom('city_data', 16, + 'LINESTRING(47 6, 51 10, 47 14)'); +-- Check face update +SELECT 'T11F', + ST_Equals(f.mbr, ST_Envelope(ST_GetFaceGeometry('city_data', f.face_id))) + FROM city_data.face f, city_data.edge e + WHERE e.edge_id = 16 AND f.face_id = e.left_face; + +-- TODO: test changing some clockwise closed edges.. SELECT topology.DropTopology('city_data'); diff --git a/topology/test/regress/st_changeedgegeom_expected b/topology/test/regress/st_changeedgegeom_expected index 62c300768..290db81f6 100644 --- a/topology/test/regress/st_changeedgegeom_expected +++ b/topology/test/regress/st_changeedgegeom_expected @@ -13,18 +13,24 @@ ERROR: SQL/MM Spatial exception - geometry crosses an edge T2|Edge 5 changed T3|Edge 5 changed T4|Edge 26 changed +T4F|t ERROR: Edge motion collision at POINT(9 35) T5|Edge 3 changed T6|Edge 3 changed ERROR: Edge motion collision at POINT(20 37) T7|Edge 2 changed +T7F|t ERROR: Edge motion collision at POINT(20 37) T7.1|Edge 2 changed +T7F.1|t ERROR: Edge twist at node POINT(4 31) T8|Edge 26 changed +T8F|t ERROR: Edge motion collision at POINT(9 6) T9|27 ERROR: Edge changed disposition around start node 20 T10|28 ERROR: Edge changed disposition around start node 17 +T11|Edge 16 changed +T11F|t Topology 'city_data' dropped -- 2.40.0