]> granicus.if.org Git - postgis/commitdiff
Add support for creating topologies allowing 3d vertices on edges and nodes. Includes...
authorSandro Santilli <strk@keybit.net>
Thu, 31 Mar 2011 09:35:11 +0000 (09:35 +0000)
committerSandro Santilli <strk@keybit.net>
Thu, 31 Mar 2011 09:35:11 +0000 (09:35 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@6991 b70326c6-7e19-0410-871a-916f4a2858ee

topology/test/Makefile
topology/test/regress/createtopology.sql [new file with mode: 0644]
topology/test/regress/createtopology_expected [new file with mode: 0644]
topology/test/regress/topo2.5d.sql [new file with mode: 0644]
topology/test/regress/topo2.5d_expected [new file with mode: 0644]
topology/topology.sql.in.c

index bbc0f92e612f195331eed977d95a97413d9b0456..1e61e4c31cf601b01e96772e07781af913543719 100644 (file)
@@ -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 (file)
index 0000000..fc44176
--- /dev/null
@@ -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 (file)
index 0000000..c417666
--- /dev/null
@@ -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 (file)
index 0000000..de1804a
--- /dev/null
@@ -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 (file)
index 0000000..6bffb88
--- /dev/null
@@ -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
index 938bd57bd6ecfddc2fed3a99fe42b72049d304e2..9dcce4cbe618b9eb7e20523322bbc7f16178c9c2 100644 (file)
@@ -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)