]> granicus.if.org Git - postgis/commitdiff
Update face MBR on edge change (#1587)
authorSandro Santilli <strk@keybit.net>
Mon, 20 Feb 2012 10:52:31 +0000 (10:52 +0000)
committerSandro Santilli <strk@keybit.net>
Mon, 20 Feb 2012 10:52:31 +0000 (10:52 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@9235 b70326c6-7e19-0410-871a-916f4a2858ee

topology/sql/sqlmm.sql.in.c
topology/test/regress/st_changeedgegeom.sql
topology/test/regress/st_changeedgegeom_expected

index de4e86084b5ed4a8a746e84be198351474887466..38a2a16f31d29566a9244e16ecdd2a71d59a6597 100644 (file)
@@ -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';
 
index a9d68a74b430859dc738865efe6e699dee5de087..52f4475f1f96db4ad3c6a605b0768330be7a73c5 100644 (file)
@@ -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');
index 62c3007687b4d3ac85b100913f06b2b37343ef18..290db81f67470631fb17c32328e0890579b0b020 100644 (file)
@@ -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