-- 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.
-- 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
-- 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;
-- 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';
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');
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');
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