From: Sandro Santilli Date: Thu, 31 Mar 2011 09:35:11 +0000 (+0000) Subject: Add support for creating topologies allowing 3d vertices on edges and nodes. Includes... X-Git-Tag: 2.0.0alpha1~1811 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f69dd26749baf85bf9f7aa9cbbb8be8d0792e95b;p=postgis Add support for creating topologies allowing 3d vertices on edges and nodes. Includes regress testing [RT-SIGTA] git-svn-id: http://svn.osgeo.org/postgis/trunk@6991 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/topology/test/Makefile b/topology/test/Makefile index bbc0f92e6..1e61e4c31 100644 --- a/topology/test/Makefile +++ b/topology/test/Makefile @@ -29,9 +29,11 @@ TESTS = regress/legacy_validate.sql regress/legacy_predicate.sql \ regress/st_getfacegeometry.sql \ regress/topoelement.sql \ regress/topoelementarray_agg.sql \ + regress/topo2.5d.sql \ regress/droptopology.sql \ regress/copytopology.sql \ regress/createtopogeom.sql \ + regress/createtopology.sql \ regress/gml.sql \ regress/getnodebypoint.sql \ regress/getedgebypoint.sql \ diff --git a/topology/test/regress/createtopology.sql b/topology/test/regress/createtopology.sql new file mode 100644 index 000000000..fc441767f --- /dev/null +++ b/topology/test/regress/createtopology.sql @@ -0,0 +1,28 @@ +\set VERBOSITY terse +set client_min_messages to WARNING; + +SELECT topology.CreateTopology('2d') > 0; + +SELECT topology.CreateTopology('2dAgain', -1, 0, false) > 0; + +SELECT topology.CreateTopology('3d', -1, 0, true) > 0; + +SELECT topology.CreateTopology('3d'); -- already exists + +SELECT name,srid,precision,hasz from topology.topology +WHERE name in ('2d', '2dAgain', '3d' ) +ORDER by name; + +-- Only 3dZ accepted in 3d topo +SELECT topology.AddNode('3d', 'POINT(0 0)'); +SELECT topology.AddNode('3d', 'POINTM(1 1 1)'); +SELECT topology.AddNode('3d', 'POINT(2 2 2)'); + +-- Only 2d accepted in 2d topo +SELECT topology.AddNode('2d', 'POINTM(0 0 0)'); +SELECT topology.AddNode('2d', 'POINT(1 1 1)'); +SELECT topology.AddNode('2d', 'POINT(2 2)'); + +SELECT topology.DropTopology('2d'); +SELECT topology.DropTopology('2dAgain'); +SELECT topology.DropTopology('3d'); diff --git a/topology/test/regress/createtopology_expected b/topology/test/regress/createtopology_expected new file mode 100644 index 000000000..c4176669a --- /dev/null +++ b/topology/test/regress/createtopology_expected @@ -0,0 +1,16 @@ +t +t +t +ERROR: schema "3d" already exists +2d|-1|0|f +2dAgain|-1|0|f +3d|-1|0|t +ERROR: new row for relation "node" violates check constraint "enforce_dims_geom" +ERROR: new row for relation "node" violates check constraint "enforce_geotype_geom" +3 +ERROR: new row for relation "node" violates check constraint "enforce_geotype_geom" +ERROR: new row for relation "node" violates check constraint "enforce_dims_geom" +3 +Topology '2d' dropped +Topology '2dAgain' dropped +Topology '3d' dropped diff --git a/topology/test/regress/topo2.5d.sql b/topology/test/regress/topo2.5d.sql new file mode 100644 index 000000000..de1804a73 --- /dev/null +++ b/topology/test/regress/topo2.5d.sql @@ -0,0 +1,51 @@ +\set VERBOSITY terse +set client_min_messages to WARNING; + +SELECT topology.CreateTopology('tt3d', -1, 0, true) > 0; + +COPY tt3d.face(face_id) FROM STDIN; +1 +\. + +COPY tt3d.node(node_id, geom) FROM STDIN; +1 POINT(0 0 30) +2 POINT(10 10 20) +\. + +COPY tt3d.edge_data( + edge_id, start_node, end_node, + abs_next_left_edge, abs_next_right_edge, + next_left_edge, next_right_edge, + left_face, right_face, geom) FROM STDIN; +1 1 2 2 2 2 2 0 1 LINESTRING(0 0 30, 0 10 25, 10 10 20) +2 2 1 1 1 1 1 0 1 LINESTRING(10 10 20, 10 0 18, 0 0 30) +\. + +-- 2.5d face geometries +CREATE TABLE public.faces (id serial); +SELECT topology.AddTopoGeometryColumn('tt3d', 'public', 'faces', 'g', + 'POLYGON'); +INSERT INTO public.faces (g) VALUES ( + topology.CreateTopoGeom( + 'tt3d', -- Topology name + 3, -- Topology geometry type (polygon/multipolygon) + 1, -- TG_LAYER_ID for this topology (from topology.layer) + '{{1,3}}') -- face_id:1 + ); + +-- 2.5d line geometries +CREATE TABLE lines (id serial); +SELECT topology.AddTopoGeometryColumn('tt3d', 'public', 'lines', 'g', + 'LINE'); +INSERT INTO public.lines (g) VALUES ( + topology.CreateTopoGeom( + 'tt3d', -- Topology name + 2, -- Topology geometry type (lineal) + 2, -- TG_LAYER_ID for this topology (from topology.layer) + '{{1,2},{2,2}}') -- edge_id:1 edge_id:2 + ); + +SELECT 'f'||id, ST_AsEWKT(topology.geometry(g)) from public.faces; +SELECT 'l'||id, ST_AsEWKT(topology.geometry(g)) from public.lines; + +SELECT topology.DropTopology('tt3d'); diff --git a/topology/test/regress/topo2.5d_expected b/topology/test/regress/topo2.5d_expected new file mode 100644 index 000000000..6bffb8869 --- /dev/null +++ b/topology/test/regress/topo2.5d_expected @@ -0,0 +1,6 @@ +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) +Topology 'tt3d' dropped diff --git a/topology/topology.sql.in.c b/topology/topology.sql.in.c index 938bd57bd..9dcce4cbe 100644 --- a/topology/topology.sql.in.c +++ b/topology/topology.sql.in.c @@ -190,6 +190,8 @@ CREATE TABLE topology.topology ( precision FLOAT8 NOT NULL ); +ALTER TABLE topology.topology ADD hasz BOOLEAN NOT NULL DEFAULT false; + --{ LayerTrigger() -- -- Layer integrity trigger @@ -1592,22 +1594,20 @@ LANGUAGE 'plpgsql'; --} TopoGeo_AddPolygon --{ --- CreateTopology(name, SRID, precision) +-- CreateTopology(name, SRID, precision, hasZ) -- -- Create a topology schema, add a topology info record -- in the topology.topology relation, return it's numeric -- id. -- -CREATE OR REPLACE FUNCTION topology.CreateTopology(varchar, integer, float8) +CREATE OR REPLACE FUNCTION topology.CreateTopology(atopology varchar, srid integer, prec float8, hasZ boolean) RETURNS integer AS $$ DECLARE - atopology alias for $1; - srid alias for $2; - precision alias for $3; rec RECORD; topology_id integer; + ndims integer; BEGIN -- FOR rec IN SELECT * FROM pg_namespace WHERE text(nspname) = atopology @@ -1615,6 +1615,9 @@ BEGIN -- RAISE EXCEPTION 'SQL/MM Spatial exception - schema already exists'; -- END LOOP; + ndims = 2; + IF hasZ THEN ndims = 3; END IF; + ------ Fetch next id for the new topology FOR rec IN SELECT nextval('topology.topology_id_seq') LOOP @@ -1637,7 +1640,7 @@ CREATE SCHEMA ' || quote_ident(atopology) || '; EXECUTE 'SELECT AddGeometryColumn('||quote_literal(atopology) ||',''face'',''mbr'','||quote_literal(srid) - ||',''POLYGON'',''2'')'; + ||',''POLYGON'',' || ndims || ')'; -------------} END OF face CREATION @@ -1664,7 +1667,7 @@ CREATE SCHEMA ' || quote_ident(atopology) || '; EXECUTE 'SELECT AddGeometryColumn('||quote_literal(atopology) ||',''node'',''geom'','||quote_literal(srid) - ||',''POINT'',''2'')'; + ||',''POINT'',' || ndims || ')'; --------------} END OF node CREATION @@ -1715,7 +1718,7 @@ CREATE SCHEMA ' || quote_ident(atopology) || '; EXECUTE 'SELECT AddGeometryColumn('||quote_literal(atopology) ||',''edge_data'',''geom'','||quote_literal(srid) - ||',''LINESTRING'',''2'')'; + ||',''LINESTRING'',' || ndims || ')'; -- edge standard view (select rule) @@ -1822,10 +1825,12 @@ CREATE SCHEMA ' || quote_ident(atopology) || '; || '.edge_data (right_face);'; ------- Add record to the "topology" metadata table - EXECUTE 'INSERT INTO topology.topology (id, name, srid, precision) ' - || ' VALUES (' || quote_literal(topology_id) || ',' + EXECUTE 'INSERT INTO topology.topology ' + || '(id, name, srid, precision, hasZ) VALUES (' + || quote_literal(topology_id) || ',' || quote_literal(atopology) || ',' - || quote_literal(srid) || ',' || quote_literal(precision) + || quote_literal(srid) || ',' || quote_literal(prec) + || ',' || hasZ || ')'; RETURN topology_id; @@ -1833,7 +1838,15 @@ END $$ LANGUAGE 'plpgsql' VOLATILE STRICT; --- wrappers for unspecified srid or precision +--} CreateTopology + +--{ CreateTopology wrappers for unspecified srid or precision or hasZ + +-- CreateTopology(name, SRID, precision) -- hasZ = false +CREATE OR REPLACE FUNCTION topology.CreateTopology(toponame varchar, srid integer, prec float8) +RETURNS integer AS +' SELECT topology.CreateTopology($1, $2, $3, false);' +LANGUAGE 'SQL' VOLATILE STRICT; -- CreateTopology(name, SRID) -- precision = 0 CREATE OR REPLACE FUNCTION topology.CreateTopology(varchar, integer)