]> granicus.if.org Git - postgis/commitdiff
Implement TopoGeometry->Geometry converter for COLLECTION types
authorSandro Santilli <strk@keybit.net>
Wed, 4 Jan 2012 18:17:49 +0000 (18:17 +0000)
committerSandro Santilli <strk@keybit.net>
Wed, 4 Jan 2012 18:17:49 +0000 (18:17 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@8670 b70326c6-7e19-0410-871a-916f4a2858ee

topology/test/regress/createtopogeom_expected
topology/topology.sql.in.c

index b422a5438b492c61cebbeaeca47a8cd51f6c332a..95af83eb50a0a4e9ed20b70d1f77dfbe1327c87c 100644 (file)
@@ -24,7 +24,7 @@ l4|4
 MP|POINT(0 0)
 ML|LINESTRING(0 0,10 0)
 MA|POLYGON((10 0,0 0,5 5,10 0))
-MM|GEOMETRYCOLLECTION EMPTY
+MM|GEOMETRYCOLLECTION(POLYGON((10 0,0 0,5 5,10 0)),LINESTRING(0 0,10 0),POINT(0 0))
 POINT EMPTY|POINT EMPTY
 LINESTRING EMPTY|LINESTRING EMPTY
 POLYGON EMPTY|POLYGON EMPTY
index ff078370d18c954d089714c72a41f83266d73b89..a44b6462051857cfe9070875d58256ba67188f00 100644 (file)
@@ -1159,18 +1159,19 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
 --
 -- Construct a Geometry from a TopoGeometry.
 -- 
---
+-- }{
 CREATE OR REPLACE FUNCTION topology.Geometry(topogeom topology.TopoGeometry)
        RETURNS Geometry
 AS $$
 DECLARE
-       toponame varchar;
-       geom geometry;
-       rec RECORD;
-       plyr RECORD;
-       clyr RECORD;
-       query text;
-       ok BOOL;
+  toponame varchar;
+  geom geometry;
+  rec RECORD;
+  plyr RECORD;
+  clyr RECORD;
+  query text;
+  ok BOOL;
+  sql TEXT;
 BEGIN
         -- Get topology name
         SELECT name FROM topology.topology into toponame
@@ -1227,7 +1228,7 @@ BEGIN
        END IF;
        
 
-       IF topogeom.type = 3 THEN -- [multi]polygon
+  IF topogeom.type = 3 THEN -- [multi]polygon
                FOR rec IN EXECUTE 'SELECT st_union('
                        || 'topology.ST_GetFaceGeometry('
                        || quote_literal(toponame) || ','
@@ -1243,7 +1244,7 @@ BEGIN
                        geom := 'POLYGON EMPTY';
                END IF;
 
-       ELSIF topogeom.type = 2 THEN -- [multi]line
+  ELSIF topogeom.type = 2 THEN -- [multi]line
                FOR rec IN EXECUTE 'SELECT ST_LineMerge(ST_Collect(e.geom)) as g FROM '
                        || quote_ident(toponame) || '.edge e, '
                        || quote_ident(toponame) || '.relation r '
@@ -1258,7 +1259,7 @@ BEGIN
                        geom := 'LINESTRING EMPTY';
                END IF;
        
-       ELSIF topogeom.type = 1 THEN -- [multi]point
+  ELSIF topogeom.type = 1 THEN -- [multi]point
                FOR rec IN EXECUTE 'SELECT st_union(n.geom) as g FROM '
                        || quote_ident(toponame) || '.node n, '
                        || quote_ident(toponame) || '.relation r '
@@ -1273,10 +1274,41 @@ BEGIN
                        geom := 'POINT EMPTY';
                END IF;
 
-       ELSE
-               RAISE NOTICE 'Geometry from TopoGeometry does not support TopoGeometries of type % so far', topogeom.type;
-               geom := 'GEOMETRYCOLLECTION EMPTY';
-       END IF;
+  ELSIF topogeom.type = 4 THEN -- mixed collection
+    sql := 'WITH areas AS ( SELECT ST_Union('
+      || 'topology.ST_GetFaceGeometry('
+      || quote_literal(toponame) || ','
+      || 'element_id)) as g FROM ' 
+      || quote_ident(toponame)
+      || '.relation WHERE topogeo_id = '
+      || topogeom.id || ' AND layer_id = '
+      || topogeom.layer_id || ' AND element_type = 3), '
+      || 'lines AS ( SELECT ST_LineMerge(ST_Collect(e.geom)) as g FROM '
+      || quote_ident(toponame) || '.edge e, '
+      || quote_ident(toponame) || '.relation r '
+      || ' WHERE r.topogeo_id = ' || topogeom.id
+      || ' AND r.layer_id = ' || topogeom.layer_id
+      || ' AND r.element_type = 2 '
+      || ' AND abs(r.element_id) = e.edge_id ), '
+      || ' points as ( SELECT st_union(n.geom) as g FROM '
+      || quote_ident(toponame) || '.node n, '
+      || quote_ident(toponame) || '.relation r '
+      || ' WHERE r.topogeo_id = ' || topogeom.id
+      || ' AND r.layer_id = ' || topogeom.layer_id
+      || ' AND r.element_type = 1 '
+      || ' AND r.element_id = n.node_id ), '
+      || ' un as ( SELECT g FROM areas UNION ALL SELECT g FROM lines '
+      || '          UNION ALL SELECT g FROM points ) '
+      || 'SELECT ST_Collect(g) FROM un';
+    EXECUTE sql INTO geom;
+    IF geom IS NULL THEN
+      geom := 'GEOMETRYCOLLECTION EMPTY';
+    END IF;
+
+  ELSE
+    RAISE NOTICE 'Geometry from TopoGeometry does not support TopoGeometries of type % so far', topogeom.type;
+    geom := 'GEOMETRYCOLLECTION EMPTY';
+  END IF;
 
        RETURN geom;
 END