]> granicus.if.org Git - postgis/commitdiff
Fix missing edge from toTopoGeom return (#1968)
authorSandro Santilli <strk@keybit.net>
Wed, 6 Mar 2013 18:11:27 +0000 (18:11 +0000)
committerSandro Santilli <strk@keybit.net>
Wed, 6 Mar 2013 18:11:27 +0000 (18:11 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@11152 b70326c6-7e19-0410-871a-916f4a2858ee

topology/sql/topogeometry/totopogeom.sql.in.c
topology/test/regress/totopogeom.sql
topology/test/regress/totopogeom_expected

index 74525a8d26c337840930a273230bba51610032fa..9c2821ac89c7a97459747aa622130f1f94c411a7 100644 (file)
@@ -24,8 +24,10 @@ DECLARE
   layer_info RECORD;
   topology_info RECORD;
   rec RECORD;
+  rec2 RECORD;
   tg topology.TopoGeometry;
-  elems topology.TopoElementArray = '{{0,0}}';
+  elems INT[][];
+  elem INT[];
   sql TEXT;
   typ TEXT;
 BEGIN
@@ -132,7 +134,9 @@ DECLARE
   layer_info RECORD;
   topology_info RECORD;
   rec RECORD;
-  elems topology.TopoElementArray = '{{0,0}}';
+  rec2 RECORD;
+  elem INT[];
+  elems INT[][];
   sql TEXT;
   typ TEXT;
   tolerance FLOAT8;
@@ -231,36 +235,47 @@ BEGIN
   -- and add them to the definition of it. We add them as soon
   -- as possible so that each element can further edit the
   -- definition by splitting
-  FOR rec IN SELECT DISTINCT id(tg), alayer as lyr,
-    CASE WHEN ST_Dimension(geom) = 0 THEN 1
-         WHEN ST_Dimension(geom) = 1 THEN 2
-         WHEN ST_Dimension(geom) = 2 THEN 3
-    END as type,
-    CASE WHEN ST_Dimension(geom) = 0 THEN
-           topology.topogeo_addPoint(topology_info.name, geom, tolerance)
-         WHEN ST_Dimension(geom) = 1 THEN
-           topology.topogeo_addLineString(topology_info.name, geom, tolerance)
-         WHEN ST_Dimension(geom) = 2 THEN
-           topology.topogeo_addPolygon(topology_info.name, geom, tolerance)
-    END as primitive
+  FOR rec IN SELECT id(tg), alayer as lyr,
+    geom, ST_Dimension(geom) as dims
     FROM (SELECT (ST_Dump(ageom)).geom) as f
     WHERE NOT ST_IsEmpty(geom)
   LOOP
-    -- TODO: consider use a single INSERT statement for the whole thing
-    sql := 'INSERT INTO ' || quote_ident(topology_info.name)
-        || '.relation(topogeo_id, layer_id, element_type, element_id) SELECT '
-        || rec.id || ',' || rec.lyr || ',' || rec.type
-        || ',' || rec.primitive
-        -- NOTE: we're avoiding duplicated rows here
-        || ' EXCEPT SELECT ' || rec.id || ', ' || rec.lyr
-        || ', element_type, element_id FROM '
-        || quote_ident(topology_info.name)
-        || '.relation WHERE layer_id = ' || rec.lyr
-        || ' AND topogeo_id = ' || rec.id; 
+    FOR rec2 IN SELECT CASE
+       WHEN rec.dims = 0 THEN
+         topology.topogeo_addPoint(atopology, rec.geom, tolerance)
+       WHEN rec.dims = 1 THEN
+         topology.topogeo_addLineString(atopology, rec.geom, tolerance)
+       WHEN rec.dims = 2 THEN
+         topology.topogeo_addPolygon(atopology, rec.geom, tolerance)
+       END as primitive
+    LOOP
+      elem := ARRAY[rec.dims+1, rec2.primitive];
+      IF elems @> ARRAY[elem] THEN
 #ifdef POSTGIS_TOPOLOGY_DEBUG
-    RAISE DEBUG '%', sql;
+RAISE DEBUG 'Elem % already in %', elem, elems;
 #endif
-    EXECUTE sql;
+      ELSE
+#ifdef POSTGIS_TOPOLOGY_DEBUG
+RAISE DEBUG 'Elem % NOT in %', elem, elems;
+#endif
+        elems := elems || elem;
+        -- TODO: consider use a single INSERT statement for the whole thing
+        sql := 'INSERT INTO ' || quote_ident(atopology)
+            || '.relation(topogeo_id, layer_id, element_type, element_id) VALUES ('
+            || rec.id || ',' || rec.lyr || ',' || rec.dims+1
+            || ',' || rec2.primitive || ')'
+            -- NOTE: we're avoiding duplicated rows here
+            || ' EXCEPT SELECT ' || rec.id || ', ' || rec.lyr
+            || ', element_type, element_id FROM '
+            || quote_ident(topology_info.name)
+            || '.relation WHERE layer_id = ' || rec.lyr
+            || ' AND topogeo_id = ' || rec.id;
+#ifdef POSTGIS_TOPOLOGY_DEBUG
+        RAISE DEBUG '%', sql;
+#endif
+        EXECUTE sql;
+      END IF;
+    END LOOP;
   END LOOP;
 
   RETURN tg;
index afe230204de8f1c1ad5048aa52f4bd55ea956ef5..29ae7ccba06a9ccda2360c61bf76d6eb87eed074 100644 (file)
@@ -90,7 +90,6 @@ inp as ( select
 tg as ( select totopogeom(g, 'tt', 5) as g from inp )
 select St_AsText(inp.g), st_astext(tg.g::geometry) from inp, tg;
 
-
 -- Convert some empties
 SELECT ST_AsText(toTopoGeom('POINT EMPTY', 'tt', 1)::geometry);
 SELECT ST_AsText(toTopoGeom('MULTIPOINT EMPTY', 'tt', 1)::geometry);
@@ -169,6 +168,13 @@ with inp as ( select
 tg as ( select totopogeom(g, 'tt', 5) as g from inp )
 select '#1790.3', ST_HausdorffDistance(inp.g, tg.g::geometry), ST_HausdorffDistance(tg.g::geometry, inp.g) FROM inp, tg;
 
+-- http://trac.osgeo.org/postgis/ticket/1968
+with inp as ( select
+'MULTILINESTRING ((0 0, 10 0),(5 0, 5 5))'
+::geometry as g ),
+tg as ( select totopogeom(g, 'tt', 3) as g from inp )
+SELECT '#1968', ST_HausdorffDistance(inp.g, tg.g::geometry) FROM inp, tg;
+
 -- Test adding portions to an existing TopoGeometry
 INSERT INTO tt.f_areal (id, g)
  SELECT -1, toTopoGeom('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))', 'tt', 4);
index ae7ddac6d37922d1efe177f66f6d5b5e938917c2..e5bc5ad2e2facc3e5173c2897591db7e1699cdff 100644 (file)
@@ -39,6 +39,7 @@ custom_search_path|0
 #1790.1|0|0
 #1790.2|0|0
 #1790.3|0|0
+#1968|0
 tgup1.1|5|100|1
 tgup1.2|5|200|2
 tgup1.3|5|200|4