]> granicus.if.org Git - postgis/commitdiff
topology.toTopoGeom: add type compatibility checks (#1017)
authorSandro Santilli <strk@keybit.net>
Thu, 29 Dec 2011 06:48:18 +0000 (06:48 +0000)
committerSandro Santilli <strk@keybit.net>
Thu, 29 Dec 2011 06:48:18 +0000 (06:48 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@8605 b70326c6-7e19-0410-871a-916f4a2858ee

topology/sql/topogeometry/totopogeom.sql
topology/test/regress/totopogeom.sql
topology/test/regress/totopogeom_expected

index 6d9408b2f5b7f53fc5eb3cf3553754df7beb48a7..4ef8cc44735bd1ea6cb4608665834c10baefe4fa 100644 (file)
@@ -3,7 +3,7 @@
 -- PostGIS - Spatial Types for PostgreSQL
 -- http://postgis.refractions.net
 --
--- Copyright (C) 2012 Sandro Santilli <strk@keybit.net>
+-- Copyright (C) 2011-2012 Sandro Santilli <strk@keybit.net>
 --
 -- This is free software; you can redistribute and/or modify it under
 -- the terms of the GNU General Public Licence. See the COPYING file.
@@ -27,7 +27,8 @@ BEGIN
 
   -- Get topology information
   BEGIN
-    SELECT * FROM topology.topology
+    SELECT *
+    FROM topology.topology
       INTO STRICT topology_info WHERE name = toponame;
   EXCEPTION
     WHEN NO_DATA_FOUND THEN
@@ -37,7 +38,14 @@ BEGIN
 
   -- Get layer information
   BEGIN
-    SELECT * FROM topology.layer l
+    SELECT *, CASE
+      WHEN feature_type = 1 THEN 'puntal'
+      WHEN feature_type = 2 THEN 'lineal'
+      WHEN feature_type = 3 THEN 'areal'
+      WHEN feature_type = 4 THEN 'mixed'
+      ELSE 'unexpected_'||feature_type
+      END as typename
+    FROM topology.layer l
       INTO STRICT layer_info
       WHERE l.layer_id = layer_id
       AND l.topology_id = topology_info.id;
@@ -49,18 +57,50 @@ BEGIN
 
   -- Can't convert to a hierarchical topogeometry
   IF layer_info.level > 0 THEN
-      RAISE EXCEPTION 'Layer "%" of topology "%" is hierarchical, cannot convert to it',
+      RAISE EXCEPTION 'Layer "%" of topology "%" is hierarchical, cannot convert to it.',
         layer_id, toponame;
   END IF;
 
+
   -- 
-  -- TODO: Check type compatibility 
-  --  A point can go in puntal or collection layer
-  --  A line can go in lineal or collection layer
-  --  An area can go in areal or collection layer
-  --  A collection can only go collection layer
-  --  What to do with EMPTies ?
-  -- 
+  -- Check type compatibility 
+  -- 1:puntal, 2:lineal, 3:areal, 4:collection
+  --
+  IF geometrytype(geom) = 'GEOMETRYCOLLECTION' THEN
+    --  A collection can only go collection layer
+    IF layer_info.feature_type != 4 THEN
+      RAISE EXCEPTION
+        'Layer "%" of topology "%" is %, cannot hold a collection feature.',
+        layer_info.layer_id, topology_info.name, layer_info.typename;
+    END IF;
+  ELSIF ST_Dimension(geom) = 0 THEN -- puntal
+    --  A point can go in puntal or collection layer
+    IF layer_info.feature_type != 4 and layer_info.feature_type != 1 THEN
+      RAISE EXCEPTION
+        'Layer "%" of topology "%" is %, cannot hold a puntal feature.',
+        layer_info.layer_id, topology_info.name, layer_info.typename;
+    END IF;
+  ELSIF ST_Dimension(geom) = 1 THEN -- lineal
+    --  A line can go in lineal or collection layer
+    IF layer_info.feature_type != 4 and layer_info.feature_type != 2 THEN
+      RAISE EXCEPTION
+        'Layer "%" of topology "%" is %, cannot hold a lineal feature.',
+        layer_info.layer_id, topology_info.name, layer_info.typename;
+    END IF;
+  ELSIF ST_Dimension(geom) = 2 THEN -- areal
+    --  An area can go in areal or collection layer
+    IF layer_info.feature_type != 4 and layer_info.feature_type != 3 THEN
+      RAISE EXCEPTION
+        'Layer "%" of topology "%" is %, cannot hold an areal feature.',
+        layer_info.layer_id, topology_info.name, layer_info.typename;
+    END IF;
+  ELSE
+      -- Should never happen
+      RAISE EXCEPTION
+        'Unexpected feature dimension %', ST_Dimension(geom);
+  END IF;
+
+  -- TODO: handle empty
 
   RAISE EXCEPTION 'toTopoGeometry not implemented yet';
 
index 7afcda8ff4e4f555c43c631432315396a9001f5a..d011b308e586f111d0df5aa9f23cfb42d5fe7c42 100644 (file)
@@ -11,7 +11,7 @@ select totopogeom('POINT(0 0)'::geometry, '', 1);
 select totopogeom('POINT(0 0)'::geometry, null, 1);
 select totopogeom('POINT(0 0)'::geometry, 'tt', null);
 
--- Create simple puntual layer ( will be layer 2 )
+-- Create simple puntual layer (will be layer 1)
 CREATE TABLE tt.f_puntal(id serial);
 SELECT 'simple_puntual_layer', AddTopoGeometryColumn('tt', 'tt', 'f_puntal','g','POINT');
 
@@ -19,12 +19,33 @@ SELECT 'simple_puntual_layer', AddTopoGeometryColumn('tt', 'tt', 'f_puntal','g',
 CREATE TABLE tt.f_hier(id serial);
 SELECT 'hierarchical_layer', AddTopoGeometryColumn('tt', 'tt', 'f_hier','g','COLLECTION', 1);
 
+-- Create a lineal layer (will be layer 3)
+CREATE TABLE tt.f_lineal(id serial);
+SELECT 'simple_lineal_layer', AddTopoGeometryColumn('tt', 'tt', 'f_lineal','g','LINE');
+
+-- Create an areal layer (will be layer 4)
+CREATE TABLE tt.f_areal(id serial);
+SELECT 'simple_areal_layer', AddTopoGeometryColumn('tt', 'tt', 'f_areal','g','POLYGON');
+
+-- Create a collection layer (will be layer 5)
+CREATE TABLE tt.f_coll(id serial);
+SELECT 'simple_collection_layer', AddTopoGeometryColumn('tt', 'tt', 'f_coll','g','COLLECTION');
+
 -- A couple more invalid calls
-select totopogeom('POINT(0 0)'::geometry, 'tt', 3); -- non existent layer
+select totopogeom('POINT(0 0)'::geometry, 'tt', 30); -- non existent layer
 select totopogeom('POINT(0 0)'::geometry, 'tt', 2); -- invalid (hierarchical) layer
--- TODO: add more invalid calls due to type mismatch
+select totopogeom('LINESTRING(0 0, 10 10)'::geometry, 'tt', 1); -- invalid (puntual) layer
+select totopogeom('LINESTRING(0 0, 10 10)'::geometry, 'tt', 4); -- invalid (areal) layer
+select totopogeom('MULTIPOINT(0 0, 10 10)'::geometry, 'tt', 3); -- invalid (lineal) layer
+select totopogeom('MULTIPOINT(0 0, 10 10)'::geometry, 'tt', 4); -- invalid (areal) layer
+select totopogeom('POLYGON((0 0, 10 10, 10 0, 0 0))'::geometry, 'tt', 1); -- invalid (puntal) layer
+select totopogeom('POLYGON((0 0, 10 10, 10 0, 0 0))'::geometry, 'tt', 3); -- invalid (lineal) layer
+
 
 
+DROP TABLE tt.f_coll;
+DROP TABLE tt.f_areal;
+DROP TABLE tt.f_lineal;
 DROP TABLE tt.f_hier;
 DROP TABLE tt.f_puntal;
 select droptopology('tt');
index caff7f5a00384f1381318f29a32b47098a980ee2..8fbcabf77eab1761725a370e3324f4abb629d8f2 100644 (file)
@@ -4,6 +4,15 @@ ERROR:  No layer with id "1" in topology "tt"
 ERROR:  No topology with name "" in topology.topology
 simple_puntual_layer|1
 hierarchical_layer|2
-ERROR:  No layer with id "3" in topology "tt"
-ERROR:  Layer "2" of topology "tt" is hierarchical, cannot convert to it
+simple_lineal_layer|3
+simple_areal_layer|4
+simple_collection_layer|5
+ERROR:  No layer with id "30" in topology "tt"
+ERROR:  Layer "2" of topology "tt" is hierarchical, cannot convert to it.
+ERROR:  Layer "1" of topology "tt" is puntal, cannot hold a lineal feature.
+ERROR:  Layer "4" of topology "tt" is areal, cannot hold a lineal feature.
+ERROR:  Layer "3" of topology "tt" is lineal, cannot hold a puntal feature.
+ERROR:  Layer "4" of topology "tt" is areal, cannot hold a puntal feature.
+ERROR:  Layer "1" of topology "tt" is puntal, cannot hold an areal feature.
+ERROR:  Layer "3" of topology "tt" is lineal, cannot hold an areal feature.
 Topology 'tt' dropped