From: Sandro Santilli Date: Wed, 6 Mar 2013 18:11:27 +0000 (+0000) Subject: Fix missing edge from toTopoGeom return (#1968) X-Git-Tag: 2.1.0beta2~181 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=022f3d200a1f11c94a88f0995a534475b95d6ba7;p=postgis Fix missing edge from toTopoGeom return (#1968) git-svn-id: http://svn.osgeo.org/postgis/trunk@11152 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/topology/sql/topogeometry/totopogeom.sql.in.c b/topology/sql/topogeometry/totopogeom.sql.in.c index 74525a8d2..9c2821ac8 100644 --- a/topology/sql/topogeometry/totopogeom.sql.in.c +++ b/topology/sql/topogeometry/totopogeom.sql.in.c @@ -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; diff --git a/topology/test/regress/totopogeom.sql b/topology/test/regress/totopogeom.sql index afe230204..29ae7ccba 100644 --- a/topology/test/regress/totopogeom.sql +++ b/topology/test/regress/totopogeom.sql @@ -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); diff --git a/topology/test/regress/totopogeom_expected b/topology/test/regress/totopogeom_expected index ae7ddac6d..e5bc5ad2e 100644 --- a/topology/test/regress/totopogeom_expected +++ b/topology/test/regress/totopogeom_expected @@ -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