n2|2
e1|1
ERROR: A TopoGeometry of type 2 cannot contain topology elements of type 1
-L1|LINESTRING(0 0,10 0)
+L1|MULTILINESTRING((0 0,10 0))
l3|3
e2|2
f1|1
ERROR: A Layer of type 3 cannot contain a TopoGeometry of type 2
ERROR: A TopoGeometry of type 3 cannot contain topology elements of type 2
-A1|POLYGON((10 0,0 0,5 5,10 0))
+A1|MULTIPOLYGON(((10 0,0 0,5 5,10 0)))
l4|4
-MP|POINT(0 0)
-ML|LINESTRING(0 0,10 0)
-MA|POLYGON((10 0,0 0,5 5,10 0))
+MP|MULTIPOINT(0 0)
+ML|MULTILINESTRING((0 0,10 0))
+MA|MULTIPOLYGON(((10 0,0 0,5 5,10 0)))
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
+POINT EMPTY|MULTIPOINT EMPTY
+LINESTRING EMPTY|MULTILINESTRING EMPTY
+POLYGON EMPTY|MULTIPOLYGON EMPTY
GEOMETRYCOLLECTION EMPTY|GEOMETRYCOLLECTION EMPTY
Topology 'MiX' dropped
6
features.big_signs.the_geom SRID:0 TYPE:MULTIPOINT DIMS:2
BEGIN
-P1|1|POLYGON((21 14,21 6,9 6,9 14,9 22,21 22,21 14))
-P2|2|POLYGON((35 14,35 6,21 6,21 14,21 22,35 22,35 14))
-P3|3|POLYGON((47 14,47 6,35 6,35 14,35 22,47 22,47 14))
-P4|4|POLYGON((25 30,17 30,17 40,31 40,31 30,25 30))
-P5|5|POLYGON((8 30,3 30,3 38,16 38,16 30,8 30),(4 31,7 31,7 34,4 34,4 31))
-F3|6|POLYGON((9 22,21 22,21 14,9 14,9 22))
-F6|7|POLYGON((9 14,21 14,21 6,9 6,9 14))
-F3F4|8|POLYGON((9 22,21 22,35 22,35 14,21 14,9 14,9 22))
-F1|9|POLYGON((8 30,3 30,3 38,16 38,16 30,8 30),(4 31,7 31,7 34,4 34,4 31))
-S1|1|POINT(21 14)
-S2|2|POINT(35 14)
-S3|3|POINT(57 33)
-S4|4|POINT(20 37)
+P1|1|MULTIPOLYGON(((21 14,21 6,9 6,9 14,9 22,21 22,21 14)))
+P2|2|MULTIPOLYGON(((35 14,35 6,21 6,21 14,21 22,35 22,35 14)))
+P3|3|MULTIPOLYGON(((47 14,47 6,35 6,35 14,35 22,47 22,47 14)))
+P4|4|MULTIPOLYGON(((25 30,17 30,17 40,31 40,31 30,25 30)))
+P5|5|MULTIPOLYGON(((8 30,3 30,3 38,16 38,16 30,8 30),(4 31,7 31,7 34,4 34,4 31)))
+F3|6|MULTIPOLYGON(((9 22,21 22,21 14,9 14,9 22)))
+F6|7|MULTIPOLYGON(((9 14,21 14,21 6,9 6,9 14)))
+F3F4|8|MULTIPOLYGON(((9 22,21 22,35 22,35 14,21 14,9 14,9 22)))
+F1|9|MULTIPOLYGON(((8 30,3 30,3 38,16 38,16 30,8 30),(4 31,7 31,7 34,4 34,4 31)))
+S1|1|MULTIPOINT(21 14)
+S2|2|MULTIPOINT(35 14)
+S3|3|MULTIPOINT(57 33)
+S4|4|MULTIPOINT(20 37)
N1N2N3|5|MULTIPOINT(8 30,25 30,25 35)
N1N6N14|6|MULTIPOINT(8 30,21 14,57 33)
N3N4|7|MULTIPOINT(20 37,25 35)
-N4|8|POINT(20 37)
-R1|1|LINESTRING(9 14,21 14,35 14)
-R2|2|LINESTRING(36 38,38 35,41 34,42 33,45 32,47 28,50 28,52 32,57 33,57 36,59 39,61 38,62 41,47 42,45 40,41 40)
-R3|3|LINESTRING(9 35,13 35)
-R4|4|LINESTRING(25 30,25 35)
-E7E8|5|LINESTRING(21 22,35 22,47 22)
-E20E19|6|LINESTRING(21 6,21 14,21 22)
-E25|7|LINESTRING(9 35,13 35)
-R1a|8|LINESTRING(9 14,21 14,35 14)
+N4|8|MULTIPOINT(20 37)
+R1|1|MULTILINESTRING((9 14,21 14,35 14))
+R2|2|MULTILINESTRING((36 38,38 35,41 34,42 33,45 32,47 28,50 28,52 32,57 33,57 36,59 39,61 38,62 41,47 42,45 40,41 40))
+R3|3|MULTILINESTRING((9 35,13 35))
+R4|4|MULTILINESTRING((25 30,25 35))
+E7E8|5|MULTILINESTRING((21 22,35 22,47 22))
+E20E19|6|MULTILINESTRING((21 6,21 14,21 22))
+E25|7|MULTILINESTRING((9 35,13 35))
+R1a|8|MULTILINESTRING((9 14,21 14,35 14))
S1S2|MULTIPOINT(21 14,35 14)
R1R2|MULTILINESTRING((36 38,38 35,41 34,42 33,45 32,47 28,50 28,52 32,57 33,57 36,59 39,61 38,62 41,47 42,45 40,41 40),(9 14,21 14,35 14))
-R4|LINESTRING(25 30,25 35)
-P1P2|POLYGON((21 6,9 6,9 14,9 22,21 22,35 22,35 14,35 6,21 6))
+R4|MULTILINESTRING((25 30,25 35))
+P1P2|MULTIPOLYGON(((21 6,9 6,9 14,9 22,21 22,35 22,35 14,35 6,21 6)))
P3P4|MULTIPOLYGON(((47 14,47 6,35 6,35 14,35 22,47 22,47 14)),((25 30,17 30,17 40,31 40,31 30,25 30)))
-F3F6|POLYGON((21 14,21 6,9 6,9 14,9 22,21 22,21 14))
+F3F6|MULTIPOLYGON(((21 14,21 6,9 6,9 14,9 22,21 22,21 14)))
COMMIT
Topology 'city_data' dropped
t
1
2
-f1|POLYGON((0 0 30,0 10 25,10 10 20,10 0 18,0 0 30))
-l1|LINESTRING(0 0 30,0 10 25,10 10 20,10 0 18,0 0 30)
+f1|MULTIPOLYGON(((0 0 30,0 10 25,10 10 20,10 0 18,0 0 30)))
+l1|MULTILINESTRING((0 0 30,0 10 25,10 10 20,10 0 18,0 0 30))
Topology 'tt3d' dropped
MULTILINESTRING((-1 10,-10 10),(-10 8,-2 9))|t
MULTIPOLYGON(((100 20,110 20,105 30,100 20),(102 22,108 22,105 28,102 22)),((80 20,90 20,90 60,80 20)))|t
GEOMETRYCOLLECTION(POINT(-100 -100),LINESTRING(-100 -90,-90 -90),POLYGON((-100 -80,-90 -80,-95 -70,-100 -80),(-98 -78,-92 -78,-95 -72,-98 -78)),MULTIPOINT(-100 -110,-95 -110),LINESTRING EMPTY,MULTILINESTRING((-101 -90,-110 -90),(-110 -92,-102 -91)),MULTIPOLYGON(((0 -80,10 -80,5 -70,0 -80),(2 -78,8 -78,5 -72,2 -78)),((-20 -80,-10 -80,-10 -40,-20 -80))))|GEOMETRYCOLLECTION(MULTIPOLYGON(((-100 -80,-95 -70,-90 -80,-100 -80),(-98 -78,-92 -78,-95 -72,-98 -78)),((0 -80,5 -70,10 -80,0 -80),(2 -78,8 -78,5 -72,2 -78)),((-20 -80,-10 -40,-10 -80,-20 -80))),MULTILINESTRING((-110 -92,-102 -91),(-101 -90,-110 -90),(-100 -90,-90 -90)),MULTIPOINT(-100 -110,-100 -100,-95 -110))
-POINT EMPTY
-POINT EMPTY
-LINESTRING EMPTY
-LINESTRING EMPTY
-POLYGON EMPTY
-POLYGON EMPTY
+MULTIPOINT EMPTY
+MULTIPOINT EMPTY
+MULTILINESTRING EMPTY
+MULTILINESTRING EMPTY
+MULTIPOLYGON EMPTY
+MULTIPOLYGON EMPTY
GEOMETRYCOLLECTION EMPTY
Topology 'tt' dropped
rec RECORD;
plyr RECORD;
clyr RECORD;
- query text;
- ok BOOL;
sql TEXT;
BEGIN
- -- Get topology name
- SELECT name FROM topology.topology into toponame
- WHERE id = topogeom.topology_id;
- -- Get layer info
- ok = false;
- FOR rec IN EXECUTE 'SELECT * FROM topology.layer '
- || ' WHERE topology_id = ' || topogeom.topology_id
- || ' AND layer_id = ' || topogeom.layer_id
- LOOP
- ok = true;
- plyr = rec;
- END LOOP;
+ -- Get topology name
+ SELECT name FROM topology.topology
+ WHERE id = topogeom.topology_id
+ INTO toponame;
+ IF toponame IS NULL THEN
+ RAISE EXCEPTION 'Invalid TopoGeometry (unexistent topology id %)', topogeom.topology_id;
+ END IF;
- IF NOT ok THEN
- RAISE EXCEPTION 'Could not find TopoGeometry layer % in topology %', topogeom.layer_id, topogeom.topology_id;
- END IF;
+ -- Get layer info
+ SELECT * FROM topology.layer
+ WHERE topology_id = topogeom.topology_id
+ AND layer_id = topogeom.layer_id
+ INTO plyr;
+ IF plyr IS NULL THEN
+ RAISE EXCEPTION 'Could not find TopoGeometry layer % in topology %', topogeom.layer_id, topogeom.topology_id;
+ END IF;
- --
- -- If this feature layer is on any level > 0 we will
- -- compute the topological union of all child features
- -- in fact recursing.
- --
- IF plyr.level > 0 THEN
-
- -- Get child layer info
- SELECT * INTO STRICT clyr FROM topology.layer
- WHERE layer_id = plyr.child_id
- AND topology_id = topogeom.topology_id;
-
- query = 'SELECT st_union(topology.Geometry('
- || quote_ident(clyr.feature_column)
- || ')) as geom FROM '
- || quote_ident(clyr.schema_name) || '.'
- || quote_ident(clyr.table_name)
- || ', ' || quote_ident(toponame) || '.relation pr'
- || ' WHERE '
- || ' pr.topogeo_id = ' || topogeom.id
- || ' AND '
- || ' pr.layer_id = ' || topogeom.layer_id
- || ' AND '
- || ' id('||quote_ident(clyr.feature_column)
- || ') = pr.element_id '
- || ' AND '
- || 'layer_id('||quote_ident(clyr.feature_column)
- || ') = pr.element_type ';
- --RAISE DEBUG '%', query;
- FOR rec IN EXECUTE query
- LOOP
- RETURN rec.geom;
- END LOOP;
-
- END IF;
-
+ --
+ -- If this feature layer is on any level > 0 we will
+ -- compute the topological union of all child features
+ -- in fact recursing.
+ --
+ IF plyr.level > 0 THEN -- {
+
+ -- Get child layer info
+ SELECT * FROM topology.layer WHERE layer_id = plyr.child_id
+ AND topology_id = topogeom.topology_id
+ INTO clyr;
+ IF clyr IS NULL THEN
+ RAISE EXCEPTION 'Invalid layer % in topology % (unexistent child layer %)', topogeom.layer_id, topogeom.topology_id, plyr.child_id;
+ END IF;
- IF topogeom.type = 3 THEN -- [multi]polygon
- FOR rec IN EXECUTE '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 '
- LOOP
- geom := rec.g;
- END LOOP;
- IF geom IS NULL THEN
- geom := 'POLYGON EMPTY';
- END IF;
+ sql := 'SELECT st_multi(st_union(topology.Geometry('
+ || quote_ident(clyr.feature_column)
+ || '))) as geom FROM '
+ || quote_ident(clyr.schema_name) || '.'
+ || quote_ident(clyr.table_name)
+ || ', ' || quote_ident(toponame) || '.relation pr'
+ || ' WHERE '
+ || ' pr.topogeo_id = ' || topogeom.id
+ || ' AND '
+ || ' pr.layer_id = ' || topogeom.layer_id
+ || ' AND '
+ || ' id('||quote_ident(clyr.feature_column)
+ || ') = pr.element_id '
+ || ' AND '
+ || 'layer_id('||quote_ident(clyr.feature_column)
+ || ') = pr.element_type ';
+ --RAISE DEBUG '%', query;
+ EXECUTE sql INTO geom;
+
+ ELSIF topogeom.type = 3 THEN -- [multi]polygon -- }{
- 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 '
- || ' 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'
- LOOP
- geom := rec.g;
- END LOOP;
- IF geom IS NULL THEN
- geom := 'LINESTRING EMPTY';
- END IF;
-
- 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 '
- || ' 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'
- LOOP
- geom := rec.g;
- END LOOP;
- IF geom IS NULL THEN
- geom := 'POINT EMPTY';
- END IF;
+ sql := 'SELECT st_multi(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 ';
+ EXECUTE sql INTO geom;
+
+ ELSIF topogeom.type = 2 THEN -- [multi]line -- }{
+
+ sql :=
+ 'SELECT st_multi(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';
+ EXECUTE sql INTO geom;
+
+ ELSIF topogeom.type = 1 THEN -- [multi]point -- }{
+
+ sql :=
+ 'SELECT st_multi(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';
+ EXECUTE sql INTO geom;
+
+ ELSIF topogeom.type = 4 THEN -- mixed collection -- }{
- ELSIF topogeom.type = 4 THEN -- mixed collection
sql := 'WITH areas AS ( SELECT ST_Union('
|| 'topology.ST_GetFaceGeometry('
|| quote_literal(toponame) || ','
|| ' 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';
+ || 'SELECT ST_Multi(ST_Collect(g)) FROM un';
EXECUTE sql INTO geom;
- IF geom IS NULL THEN
+
+ ELSE -- }{
+
+ RAISE EXCEPTION 'Invalid TopoGeometries (unknown type %)', topogeom.type;
+
+ END IF; -- }
+
+ IF geom IS NULL THEN
+ IF topogeom.type = 3 THEN -- [multi]polygon
+ geom := 'MULTIPOLYGON EMPTY';
+ ELSIF topogeom.type = 2 THEN -- [multi]line
+ geom := 'MULTILINESTRING EMPTY';
+ ELSIF topogeom.type = 1 THEN -- [multi]point
+ geom := 'MULTIPOINT EMPTY';
+ ELSE
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;
+ RETURN geom;
END
$$
LANGUAGE 'plpgsql' VOLATILE STRICT;