]> granicus.if.org Git - postgis/commitdiff
Fix toTopoGeom handling of duplicated primitives (#1790)
authorSandro Santilli <strk@keybit.net>
Wed, 25 Apr 2012 19:41:33 +0000 (19:41 +0000)
committerSandro Santilli <strk@keybit.net>
Wed, 25 Apr 2012 19:41:33 +0000 (19:41 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@9675 b70326c6-7e19-0410-871a-916f4a2858ee

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

diff --git a/NEWS b/NEWS
index ecd013c97bf923bc189dcb21a084e1529a9d8f13..4b27a5fd68886f3610b9644ffb538bbea00c35df 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -13,6 +13,7 @@ PostGIS 2.0.1
   - #1763, topology.toTopoGeom use with custom search_path.
   - #1755, ST_GeographyFromText support for higher dimensions.
   - #1782, fix spatial reference string handling in raster.
+  - #1790, fix toTopoGeom handling of duplicated primitives.
 
 * Enhancements *
 
index 86d2e2307ca88289485bbf39e7b385ff0ab3af8a..40efd8da175d5deb596f950de01d6bc7db446714 100644 (file)
@@ -114,44 +114,34 @@ BEGIN
         'Unexpected feature dimension %', ST_Dimension(ageom);
   END IF;
 
-  -- Now that we have a topogeometry, we loop over components 
+  -- Now that we have a topogeometry, we loop over distinct components 
   -- 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 (ST_Dump(ageom)).geom LOOP
-    IF ST_IsEmpty(rec.geom) THEN
-      RAISE DEBUG 'Skipped empty component';
-    ELSIF ST_Dimension(rec.geom) = 0 THEN
-      sql := 'INSERT INTO ' || quote_ident(atopology)
-        || '.relation(topogeo_id, layer_id, element_type, element_id) SELECT '
-        || id(tg) || ', ' || alayer || ', 1, topology.topogeo_addPoint('
-        || quote_literal(atopology) || ', '
-        || quote_literal(rec.geom::text) || '::geometry, ' || tolerance
-        || ');';
-      --RAISE DEBUG '%', sql;
-      EXECUTE sql;
-    ELSIF ST_Dimension(rec.geom) = 1 THEN
-      sql := 'INSERT INTO ' || quote_ident(atopology)
-        || '.relation(topogeo_id, layer_id, element_type, element_id) SELECT '
-        || id(tg) || ', ' || alayer || ', 2, topology.topogeo_addLineString('
-        || quote_literal(atopology) || ', '
-        || quote_literal(rec.geom::text) || '::geometry, ' || tolerance
-        || ');';
-      --RAISE DEBUG '%', sql;
-      EXECUTE sql;
-    ELSIF ST_Dimension(rec.geom) = 2 THEN
-      sql := 'INSERT INTO ' || quote_ident(atopology)
-        || '.relation(topogeo_id, layer_id, element_type, element_id) SELECT '
-        || id(tg) || ', ' || alayer || ', 3, topology.topogeo_addPolygon('
-        || quote_literal(atopology) || ', '
-        || quote_literal(rec.geom::text) || '::geometry, ' || tolerance
-        || ');';
-      --RAISE DEBUG '%', sql;
-      EXECUTE sql;
-    ELSE
-      RAISE EXCEPTION 'Unexpected dimension % for component %', ST_Dimension(rec.geom), ST_AsText(rec.geom);
-    END IF;
-
+  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(atopology, geom, tolerance)
+         WHEN ST_Dimension(geom) = 1 THEN
+           topology.topogeo_addLineString(atopology, geom, tolerance)
+         WHEN ST_Dimension(geom) = 2 THEN
+           topology.topogeo_addPolygon(atopology, geom, tolerance)
+    END as primitive
+    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(atopology)
+        || '.relation(topogeo_id, layer_id, element_type, element_id) VALUES ('
+        || rec.id || ',' || rec.lyr || ',' || rec.type
+        || ',' || rec.primitive || ')';
+#ifdef POSTGIS_TOPOLOGY_DEBUG
+    RAISE DEBUG '%', sql;
+#endif
+    EXECUTE sql;
   END LOOP;
 
   RETURN tg;
index d6d5b06bf4c6039371659f9497067fbf3e2dc17d..e2ee7561d2a165914a0becac03aab63ad1e1ca9c 100644 (file)
@@ -137,6 +137,33 @@ tg as ( select topology.totopogeom(g, 'tt', 1) as g from inp )
 select 'custom_search_path', ST_HausdorffDistance(inp.g, tg.g::geometry) FROM inp, tg;
 reset search_path;
 
+-- http://trac.osgeo.org/postgis/ticket/1790
+UPDATE topology.topology SET precision=0 WHERE name = 'tt';
+with inp as ( select
+'GEOMETRYCOLLECTION(
+ POINT(200 200),
+ POINT(200 200)
+)'
+ ::geometry as g),
+tg as ( select totopogeom(g, 'tt', 5) as g from inp )
+select '#1790.1', ST_HausdorffDistance(inp.g, tg.g::geometry), ST_HausdorffDistance(tg.g::geometry, inp.g) FROM inp, tg;
+with inp as ( select
+'GEOMETRYCOLLECTION(
+ LINESTRING(300 300, 310 300),
+ LINESTRING(300 300, 310 300)
+)'
+ ::geometry as g),
+tg as ( select totopogeom(g, 'tt', 5) as g from inp )
+select '#1790.2', ST_HausdorffDistance(inp.g, tg.g::geometry), ST_HausdorffDistance(tg.g::geometry, inp.g) FROM inp, tg;
+with inp as ( select
+'GEOMETRYCOLLECTION(
+ POLYGON((400 400, 450 450, 500 400, 400 400)),
+ POLYGON((400 400, 450 450, 500 400, 400 400))
+)'
+ ::geometry as g),
+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;
+
 
 DROP TABLE tt.f_coll;
 DROP TABLE tt.f_areal;
index 92f08434d85a55faddda6be125266fde2a11a6f2..c04be1421bb40afa91ed3d83c1d12cc630b425ff 100644 (file)
@@ -33,4 +33,7 @@ tolerance_1|0.5
 tolerance_topo_1|0.5
 tolerance_0|0
 custom_search_path|0
+#1790.1|0|0
+#1790.2|0|0
+#1790.3|0|0
 Topology 'tt' dropped