]> granicus.if.org Git - postgis/commitdiff
Check edge disposition around endnodes (#1571)
authorSandro Santilli <strk@keybit.net>
Fri, 17 Feb 2012 18:29:50 +0000 (18:29 +0000)
committerSandro Santilli <strk@keybit.net>
Fri, 17 Feb 2012 18:29:50 +0000 (18:29 +0000)
Includes a couple new testcases, for closed and non-closed edges
changing disposition around their end nodes.

git-svn-id: http://svn.osgeo.org/postgis/trunk@9228 b70326c6-7e19-0410-871a-916f4a2858ee

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

index f78143e3e2129fe8bb2ba0d7508dfb7844d09dbc..de4e86084b5ed4a8a746e84be198351474887466 100644 (file)
@@ -2520,6 +2520,42 @@ $$
 LANGUAGE 'plpgsql' VOLATILE;
 --} ST_AddIsoEdge
 
+-- Internal function used by ST_ChangeEdgeGeom to compare
+-- adjacent edges of an edge endpoint
+--
+-- @param anode the node to use edge end star of
+-- @param anedge the directed edge to get adjacents from
+--        if positive `anode' is assumed to be its start node
+--        if negative `anode' is assumed to be its end node
+--      
+-- {
+CREATE OR REPLACE FUNCTION topology._ST_AdjacentEdges(atopology varchar, anode integer, anedge integer)
+RETURNS integer[] AS
+$$
+DECLARE
+  ret integer[];
+BEGIN
+  WITH edgestar AS (
+    SELECT *, count(*) over () AS cnt
+    FROM GetNodeEdges(atopology, anode)
+  )
+  SELECT ARRAY[ (
+      SELECT p.edge AS prev FROM edgestar p
+      WHERE p.sequence = CASE WHEN m.sequence-1 < 1 THEN cnt
+                         ELSE m.sequence-1 END
+    ), (
+      SELECT p.edge AS prev FROM edgestar p                                           WHERE p.sequence = ((m.sequence)%cnt)+1
+    ) ]
+  FROM edgestar m
+  WHERE edge = anedge
+  INTO ret;
+
+  RETURN ret;
+END
+$$
+LANGUAGE 'plpgsql' STABLE;
+--}
+
 --{
 -- Topo-Geo and Topo-Net 3: Routine Details
 -- X.3.6
@@ -2540,6 +2576,8 @@ DECLARE
   range GEOMETRY; -- movement range
   tmp1 GEOMETRY;
   tmp2 GEOMETRY;
+  snode_info RECORD;
+  enode_info RECORD;
   sql TEXT;
   iscw BOOLEAN;
 BEGIN
@@ -2674,6 +2712,10 @@ BEGIN
   -- Not in the specs:
   -- Check topological isomorphism 
   --
+
+  -- Check that the "motion range" doesn't include any node 
+  --{
+
   tmp1 := ST_MakeLine(ST_EndPoint(oldedge.geom), ST_StartPoint(oldedge.geom));
   RAISE DEBUG 'end-to-start: %', ST_AsText(tmp1);
 
@@ -2706,7 +2748,25 @@ BEGIN
     RAISE EXCEPTION 'Edge motion collision at %', ST_AsText(rec.geom);
   END LOOP; -- }
 
-  --RAISE EXCEPTION 'Not doing it';
+  --} motion range checking end
+
+  -- 
+  -- Check edge adjacency before
+  --{
+
+  SELECT topology._ST_AdjacentEdges(
+      atopology, oldedge.start_node, anedge
+    ) as pre, NULL::integer[] as post
+  INTO STRICT snode_info;
+  RAISE DEBUG 'Bs:%', snode_info.pre;
+
+  SELECT topology._ST_AdjacentEdges(
+      atopology, oldedge.end_node, -anedge
+    ) as pre, NULL::integer[] as post
+  INTO STRICT enode_info;
+  RAISE DEBUG 'Be:%', enode_info.pre;
+
+  --}
 
   --
   -- Update edge geometry
@@ -2715,6 +2775,35 @@ BEGIN
     || ' SET geom = ' || quote_literal(acurve::text) 
     || ' WHERE edge_id = ' || anedge;
 
+  -- 
+  -- Check edge adjacency after
+  --{
+
+  snode_info.post := topology._ST_AdjacentEdges(
+      atopology, oldedge.start_node, anedge
+    );
+  RAISE DEBUG 'As:%', snode_info.post;
+
+  enode_info.post := topology._ST_AdjacentEdges(
+      atopology, oldedge.end_node, -anedge
+    );
+  RAISE DEBUG 'Ae:%', enode_info.post;
+
+  IF snode_info.pre != snode_info.post THEN
+    RAISE EXCEPTION 'Edge changed disposition around start node %',
+      oldedge.start_node;
+  END IF;
+
+  IF enode_info.pre != enode_info.post THEN
+    RAISE EXCEPTION 'Edge changed disposition around end node %',
+      oldedge.end_node;
+  END IF;
+
+  --}
+
+  --RAISE EXCEPTION 'Not doing it';
+
+
   RETURN 'Edge ' || anedge || ' changed';
 
 END
index f6cefdc2fc78ca52717798059ef4b4962b8d5f5f..a9d68a74b430859dc738865efe6e699dee5de087 100644 (file)
@@ -78,8 +78,18 @@ SELECT 'T8', topology.ST_ChangeEdgeGeom('city_data', 26,
 SELECT topology.ST_ChangeEdgeGeom('city_data', 13,
  'LINESTRING(21 6, 21 2, 6 2, 6 25, 50 25, 50 2, 35 2, 35 6)');
 
+-- test moving closed edge into another face
+SELECT 'T9', ST_AddEdgeModFace('city_data', 20, 20,
+ 'LINESTRING(4 31, 7 31, 4 34, 4 31)');
+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
+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 moving closed edge into another face
 -- TODO: test face mbr update
 
 SELECT topology.DropTopology('city_data');
index 74e1ce560475bc465293c46e812072914a54e9f5..62c3007687b4d3ac85b100913f06b2b37343ef18 100644 (file)
@@ -23,4 +23,8 @@ T7.1|Edge 2 changed
 ERROR:  Edge twist at node POINT(4 31)
 T8|Edge 26 changed
 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
 Topology 'city_data' dropped