From: Sandro Santilli Date: Thu, 29 Dec 2011 06:48:18 +0000 (+0000) Subject: topology.toTopoGeom: add type compatibility checks (#1017) X-Git-Tag: 2.0.0alpha1~270 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4a8fdcb47cbc9a69f47623889b034acb2ef3e482;p=postgis topology.toTopoGeom: add type compatibility checks (#1017) git-svn-id: http://svn.osgeo.org/postgis/trunk@8605 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/topology/sql/topogeometry/totopogeom.sql b/topology/sql/topogeometry/totopogeom.sql index 6d9408b2f..4ef8cc447 100644 --- a/topology/sql/topogeometry/totopogeom.sql +++ b/topology/sql/topogeometry/totopogeom.sql @@ -3,7 +3,7 @@ -- PostGIS - Spatial Types for PostgreSQL -- http://postgis.refractions.net -- --- Copyright (C) 2012 Sandro Santilli +-- Copyright (C) 2011-2012 Sandro Santilli -- -- 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'; diff --git a/topology/test/regress/totopogeom.sql b/topology/test/regress/totopogeom.sql index 7afcda8ff..d011b308e 100644 --- a/topology/test/regress/totopogeom.sql +++ b/topology/test/regress/totopogeom.sql @@ -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'); diff --git a/topology/test/regress/totopogeom_expected b/topology/test/regress/totopogeom_expected index caff7f5a0..8fbcabf77 100644 --- a/topology/test/regress/totopogeom_expected +++ b/topology/test/regress/totopogeom_expected @@ -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