Skip to content

Instantly share code, notes, and snippets.

@Sharpie
Created December 6, 2012 07:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Sharpie/65057cf9fb6a56a5929c to your computer and use it in GitHub Desktop.
Save Sharpie/65057cf9fb6a56a5929c to your computer and use it in GitHub Desktop.
PostGIS: GCC preprocessor vs. GPP v2.24
diff --git a/gcc/postgis_extension/postgis--2.0.0--2.0.2.sql b/gpp/postgis_extension/postgis--2.0.0--2.0.2.sql
index 2b555e1..f5109f4 100644
--- a/gcc/postgis_extension/postgis--2.0.0--2.0.2.sql
+++ b/gpp/postgis_extension/postgis--2.0.0--2.0.2.sql
@@ -1604,7 +1604,7 @@ CREATE OR REPLACE FUNCTION postgis_libxml_version() RETURNS text
AS '$libdir/postgis-2.0'
LANGUAGE 'c' IMMUTABLE;
CREATE OR REPLACE FUNCTION postgis_scripts_build_date() RETURNS text
- AS 'SELECT ''2012-12-05 22:40:44''::text AS version'
+ AS 'SELECT ''2012-12-05 23:21:55''::text AS version'
LANGUAGE 'sql' IMMUTABLE;
CREATE OR REPLACE FUNCTION postgis_lib_build_date() RETURNS text
AS '$libdir/postgis-2.0'
@@ -4251,14 +4251,12 @@ DROP FUNCTION IF EXISTS SnapToGrid(geometry, float8, float8);
DROP FUNCTION IF EXISTS ST_AsBinary(text); -- deprecated in 2.0
DROP FUNCTION IF EXISTS postgis_uses_stats(); -- deprecated in 2.0
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: rtpostgis_drop.sql.in.c 7884 2011-09-22 15:07:25Z robe $
--
-- PostGIS Raster - Raster Type for PostGIS
--- http://trac.osgeo.org/postgis/wiki/WKTRaster
+-- http:
--
-- Copyright (C) 2011 Regina Obe <lr@pcorp.us>
-- Copyright (C) 2011 Regents of the University of California
@@ -4580,14 +4578,12 @@ DROP FUNCTION IF EXISTS st_intersection(raster, integer, raster, integer, text,
DROP FUNCTION IF EXISTS st_intersection(raster, integer, raster, integer, regprocedure);
DROP FUNCTION IF EXISTS st_intersection(raster, raster, text, regprocedure);
DROP FUNCTION IF EXISTS st_intersection(raster, raster, regprocedure);
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: rtpostgis_upgrade.sql.in.c 8448 2011-12-16 22:07:26Z dustymugs $
--
-- PostGIS Raster - Raster Type for PostGIS
--- http://trac.osgeo.org/postgis/wiki/WKTRaster
+-- http:
--
-- Copyright (c) 2011 Regina Obe <lr@pcorp.us>
-- Copyright (C) 2011 Regents of the University of California
@@ -4621,6 +4617,23 @@ DROP FUNCTION IF EXISTS st_intersection(raster, raster, regprocedure);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-- drop st_bytea
SELECT postgis_extension_drop_if_exists('postgis', 'DROP CAST IF EXISTS (raster AS bytea);');DROP CAST IF EXISTS (raster AS bytea);
DROP FUNCTION IF EXISTS st_bytea(raster);
@@ -4637,6 +4650,7 @@ SELECT postgis_extension_drop_if_exists('postgis', 'DROP CAST IF EXISTS (raster
DROP FUNCTION IF EXISTS box2d(raster);
-- create box3d cast if it does not exist
+
-- If we are running 9.0+ we can use DO plpgsql to check
-- and only create if not exists so no need to force a drop
-- that way if people are using it, we will not mess them up
@@ -4656,17 +4670,17 @@ BEGIN
END IF;
END$$;
+
+
-- make geometry cast ASSIGNMENT
SELECT postgis_extension_drop_if_exists('postgis', 'DROP CAST IF EXISTS (raster AS geometry);');DROP CAST IF EXISTS (raster AS geometry);
CREATE CAST (raster AS geometry)
WITH FUNCTION st_convexhull(raster) AS ASSIGNMENT;
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
--
-- PostGIS Raster - Raster Type for PostGIS
--- http://trac.osgeo.org/postgis/wiki/WKTRaster
+-- http:
--
-- Copyright (c) 2009-2012 Sandro Santilli <strk@keybit.net>
-- Copyright (c) 2009-2010 Pierre Racine <pierre.racine@sbf.ulaval.ca>
@@ -4696,6 +4710,23 @@ CREATE CAST (raster AS geometry)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
SET client_min_messages TO warning;
@@ -9316,7 +9347,7 @@ CREATE OR REPLACE FUNCTION DropRasterConstraints (
-- raster_columns
--
-- The metadata is documented in the PostGIS Raster specification:
--- http://trac.osgeo.org/postgis/wiki/WKTRaster/SpecificationFinal01
+-- http:
------------------------------------------------------------------------------
CREATE OR REPLACE VIEW raster_columns AS
diff --git a/gcc/postgis_extension/postgis--2.0.0alpha1--2.0.2.sql b/gpp/postgis_extension/postgis--2.0.0alpha1--2.0.2.sql
index 2b555e1..f5109f4 100644
--- a/gcc/postgis_extension/postgis--2.0.0alpha1--2.0.2.sql
+++ b/gpp/postgis_extension/postgis--2.0.0alpha1--2.0.2.sql
@@ -1604,7 +1604,7 @@ CREATE OR REPLACE FUNCTION postgis_libxml_version() RETURNS text
AS '$libdir/postgis-2.0'
LANGUAGE 'c' IMMUTABLE;
CREATE OR REPLACE FUNCTION postgis_scripts_build_date() RETURNS text
- AS 'SELECT ''2012-12-05 22:40:44''::text AS version'
+ AS 'SELECT ''2012-12-05 23:21:55''::text AS version'
LANGUAGE 'sql' IMMUTABLE;
CREATE OR REPLACE FUNCTION postgis_lib_build_date() RETURNS text
AS '$libdir/postgis-2.0'
@@ -4251,14 +4251,12 @@ DROP FUNCTION IF EXISTS SnapToGrid(geometry, float8, float8);
DROP FUNCTION IF EXISTS ST_AsBinary(text); -- deprecated in 2.0
DROP FUNCTION IF EXISTS postgis_uses_stats(); -- deprecated in 2.0
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: rtpostgis_drop.sql.in.c 7884 2011-09-22 15:07:25Z robe $
--
-- PostGIS Raster - Raster Type for PostGIS
--- http://trac.osgeo.org/postgis/wiki/WKTRaster
+-- http:
--
-- Copyright (C) 2011 Regina Obe <lr@pcorp.us>
-- Copyright (C) 2011 Regents of the University of California
@@ -4580,14 +4578,12 @@ DROP FUNCTION IF EXISTS st_intersection(raster, integer, raster, integer, text,
DROP FUNCTION IF EXISTS st_intersection(raster, integer, raster, integer, regprocedure);
DROP FUNCTION IF EXISTS st_intersection(raster, raster, text, regprocedure);
DROP FUNCTION IF EXISTS st_intersection(raster, raster, regprocedure);
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: rtpostgis_upgrade.sql.in.c 8448 2011-12-16 22:07:26Z dustymugs $
--
-- PostGIS Raster - Raster Type for PostGIS
--- http://trac.osgeo.org/postgis/wiki/WKTRaster
+-- http:
--
-- Copyright (c) 2011 Regina Obe <lr@pcorp.us>
-- Copyright (C) 2011 Regents of the University of California
@@ -4621,6 +4617,23 @@ DROP FUNCTION IF EXISTS st_intersection(raster, raster, regprocedure);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-- drop st_bytea
SELECT postgis_extension_drop_if_exists('postgis', 'DROP CAST IF EXISTS (raster AS bytea);');DROP CAST IF EXISTS (raster AS bytea);
DROP FUNCTION IF EXISTS st_bytea(raster);
@@ -4637,6 +4650,7 @@ SELECT postgis_extension_drop_if_exists('postgis', 'DROP CAST IF EXISTS (raster
DROP FUNCTION IF EXISTS box2d(raster);
-- create box3d cast if it does not exist
+
-- If we are running 9.0+ we can use DO plpgsql to check
-- and only create if not exists so no need to force a drop
-- that way if people are using it, we will not mess them up
@@ -4656,17 +4670,17 @@ BEGIN
END IF;
END$$;
+
+
-- make geometry cast ASSIGNMENT
SELECT postgis_extension_drop_if_exists('postgis', 'DROP CAST IF EXISTS (raster AS geometry);');DROP CAST IF EXISTS (raster AS geometry);
CREATE CAST (raster AS geometry)
WITH FUNCTION st_convexhull(raster) AS ASSIGNMENT;
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
--
-- PostGIS Raster - Raster Type for PostGIS
--- http://trac.osgeo.org/postgis/wiki/WKTRaster
+-- http:
--
-- Copyright (c) 2009-2012 Sandro Santilli <strk@keybit.net>
-- Copyright (c) 2009-2010 Pierre Racine <pierre.racine@sbf.ulaval.ca>
@@ -4696,6 +4710,23 @@ CREATE CAST (raster AS geometry)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
SET client_min_messages TO warning;
@@ -9316,7 +9347,7 @@ CREATE OR REPLACE FUNCTION DropRasterConstraints (
-- raster_columns
--
-- The metadata is documented in the PostGIS Raster specification:
--- http://trac.osgeo.org/postgis/wiki/WKTRaster/SpecificationFinal01
+-- http:
------------------------------------------------------------------------------
CREATE OR REPLACE VIEW raster_columns AS
diff --git a/gcc/postgis_extension/postgis--2.0.0alpha2--2.0.2.sql b/gpp/postgis_extension/postgis--2.0.0alpha2--2.0.2.sql
index 2b555e1..f5109f4 100644
--- a/gcc/postgis_extension/postgis--2.0.0alpha2--2.0.2.sql
+++ b/gpp/postgis_extension/postgis--2.0.0alpha2--2.0.2.sql
@@ -1604,7 +1604,7 @@ CREATE OR REPLACE FUNCTION postgis_libxml_version() RETURNS text
AS '$libdir/postgis-2.0'
LANGUAGE 'c' IMMUTABLE;
CREATE OR REPLACE FUNCTION postgis_scripts_build_date() RETURNS text
- AS 'SELECT ''2012-12-05 22:40:44''::text AS version'
+ AS 'SELECT ''2012-12-05 23:21:55''::text AS version'
LANGUAGE 'sql' IMMUTABLE;
CREATE OR REPLACE FUNCTION postgis_lib_build_date() RETURNS text
AS '$libdir/postgis-2.0'
@@ -4251,14 +4251,12 @@ DROP FUNCTION IF EXISTS SnapToGrid(geometry, float8, float8);
DROP FUNCTION IF EXISTS ST_AsBinary(text); -- deprecated in 2.0
DROP FUNCTION IF EXISTS postgis_uses_stats(); -- deprecated in 2.0
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: rtpostgis_drop.sql.in.c 7884 2011-09-22 15:07:25Z robe $
--
-- PostGIS Raster - Raster Type for PostGIS
--- http://trac.osgeo.org/postgis/wiki/WKTRaster
+-- http:
--
-- Copyright (C) 2011 Regina Obe <lr@pcorp.us>
-- Copyright (C) 2011 Regents of the University of California
@@ -4580,14 +4578,12 @@ DROP FUNCTION IF EXISTS st_intersection(raster, integer, raster, integer, text,
DROP FUNCTION IF EXISTS st_intersection(raster, integer, raster, integer, regprocedure);
DROP FUNCTION IF EXISTS st_intersection(raster, raster, text, regprocedure);
DROP FUNCTION IF EXISTS st_intersection(raster, raster, regprocedure);
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: rtpostgis_upgrade.sql.in.c 8448 2011-12-16 22:07:26Z dustymugs $
--
-- PostGIS Raster - Raster Type for PostGIS
--- http://trac.osgeo.org/postgis/wiki/WKTRaster
+-- http:
--
-- Copyright (c) 2011 Regina Obe <lr@pcorp.us>
-- Copyright (C) 2011 Regents of the University of California
@@ -4621,6 +4617,23 @@ DROP FUNCTION IF EXISTS st_intersection(raster, raster, regprocedure);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-- drop st_bytea
SELECT postgis_extension_drop_if_exists('postgis', 'DROP CAST IF EXISTS (raster AS bytea);');DROP CAST IF EXISTS (raster AS bytea);
DROP FUNCTION IF EXISTS st_bytea(raster);
@@ -4637,6 +4650,7 @@ SELECT postgis_extension_drop_if_exists('postgis', 'DROP CAST IF EXISTS (raster
DROP FUNCTION IF EXISTS box2d(raster);
-- create box3d cast if it does not exist
+
-- If we are running 9.0+ we can use DO plpgsql to check
-- and only create if not exists so no need to force a drop
-- that way if people are using it, we will not mess them up
@@ -4656,17 +4670,17 @@ BEGIN
END IF;
END$$;
+
+
-- make geometry cast ASSIGNMENT
SELECT postgis_extension_drop_if_exists('postgis', 'DROP CAST IF EXISTS (raster AS geometry);');DROP CAST IF EXISTS (raster AS geometry);
CREATE CAST (raster AS geometry)
WITH FUNCTION st_convexhull(raster) AS ASSIGNMENT;
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
--
-- PostGIS Raster - Raster Type for PostGIS
--- http://trac.osgeo.org/postgis/wiki/WKTRaster
+-- http:
--
-- Copyright (c) 2009-2012 Sandro Santilli <strk@keybit.net>
-- Copyright (c) 2009-2010 Pierre Racine <pierre.racine@sbf.ulaval.ca>
@@ -4696,6 +4710,23 @@ CREATE CAST (raster AS geometry)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
SET client_min_messages TO warning;
@@ -9316,7 +9347,7 @@ CREATE OR REPLACE FUNCTION DropRasterConstraints (
-- raster_columns
--
-- The metadata is documented in the PostGIS Raster specification:
--- http://trac.osgeo.org/postgis/wiki/WKTRaster/SpecificationFinal01
+-- http:
------------------------------------------------------------------------------
CREATE OR REPLACE VIEW raster_columns AS
diff --git a/gcc/postgis_extension/postgis--2.0.0alpha3--2.0.2.sql b/gpp/postgis_extension/postgis--2.0.0alpha3--2.0.2.sql
index 2b555e1..f5109f4 100644
--- a/gcc/postgis_extension/postgis--2.0.0alpha3--2.0.2.sql
+++ b/gpp/postgis_extension/postgis--2.0.0alpha3--2.0.2.sql
@@ -1604,7 +1604,7 @@ CREATE OR REPLACE FUNCTION postgis_libxml_version() RETURNS text
AS '$libdir/postgis-2.0'
LANGUAGE 'c' IMMUTABLE;
CREATE OR REPLACE FUNCTION postgis_scripts_build_date() RETURNS text
- AS 'SELECT ''2012-12-05 22:40:44''::text AS version'
+ AS 'SELECT ''2012-12-05 23:21:55''::text AS version'
LANGUAGE 'sql' IMMUTABLE;
CREATE OR REPLACE FUNCTION postgis_lib_build_date() RETURNS text
AS '$libdir/postgis-2.0'
@@ -4251,14 +4251,12 @@ DROP FUNCTION IF EXISTS SnapToGrid(geometry, float8, float8);
DROP FUNCTION IF EXISTS ST_AsBinary(text); -- deprecated in 2.0
DROP FUNCTION IF EXISTS postgis_uses_stats(); -- deprecated in 2.0
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: rtpostgis_drop.sql.in.c 7884 2011-09-22 15:07:25Z robe $
--
-- PostGIS Raster - Raster Type for PostGIS
--- http://trac.osgeo.org/postgis/wiki/WKTRaster
+-- http:
--
-- Copyright (C) 2011 Regina Obe <lr@pcorp.us>
-- Copyright (C) 2011 Regents of the University of California
@@ -4580,14 +4578,12 @@ DROP FUNCTION IF EXISTS st_intersection(raster, integer, raster, integer, text,
DROP FUNCTION IF EXISTS st_intersection(raster, integer, raster, integer, regprocedure);
DROP FUNCTION IF EXISTS st_intersection(raster, raster, text, regprocedure);
DROP FUNCTION IF EXISTS st_intersection(raster, raster, regprocedure);
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: rtpostgis_upgrade.sql.in.c 8448 2011-12-16 22:07:26Z dustymugs $
--
-- PostGIS Raster - Raster Type for PostGIS
--- http://trac.osgeo.org/postgis/wiki/WKTRaster
+-- http:
--
-- Copyright (c) 2011 Regina Obe <lr@pcorp.us>
-- Copyright (C) 2011 Regents of the University of California
@@ -4621,6 +4617,23 @@ DROP FUNCTION IF EXISTS st_intersection(raster, raster, regprocedure);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-- drop st_bytea
SELECT postgis_extension_drop_if_exists('postgis', 'DROP CAST IF EXISTS (raster AS bytea);');DROP CAST IF EXISTS (raster AS bytea);
DROP FUNCTION IF EXISTS st_bytea(raster);
@@ -4637,6 +4650,7 @@ SELECT postgis_extension_drop_if_exists('postgis', 'DROP CAST IF EXISTS (raster
DROP FUNCTION IF EXISTS box2d(raster);
-- create box3d cast if it does not exist
+
-- If we are running 9.0+ we can use DO plpgsql to check
-- and only create if not exists so no need to force a drop
-- that way if people are using it, we will not mess them up
@@ -4656,17 +4670,17 @@ BEGIN
END IF;
END$$;
+
+
-- make geometry cast ASSIGNMENT
SELECT postgis_extension_drop_if_exists('postgis', 'DROP CAST IF EXISTS (raster AS geometry);');DROP CAST IF EXISTS (raster AS geometry);
CREATE CAST (raster AS geometry)
WITH FUNCTION st_convexhull(raster) AS ASSIGNMENT;
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
--
-- PostGIS Raster - Raster Type for PostGIS
--- http://trac.osgeo.org/postgis/wiki/WKTRaster
+-- http:
--
-- Copyright (c) 2009-2012 Sandro Santilli <strk@keybit.net>
-- Copyright (c) 2009-2010 Pierre Racine <pierre.racine@sbf.ulaval.ca>
@@ -4696,6 +4710,23 @@ CREATE CAST (raster AS geometry)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
SET client_min_messages TO warning;
@@ -9316,7 +9347,7 @@ CREATE OR REPLACE FUNCTION DropRasterConstraints (
-- raster_columns
--
-- The metadata is documented in the PostGIS Raster specification:
--- http://trac.osgeo.org/postgis/wiki/WKTRaster/SpecificationFinal01
+-- http:
------------------------------------------------------------------------------
CREATE OR REPLACE VIEW raster_columns AS
diff --git a/gcc/postgis_extension/postgis--2.0.0alpha4--2.0.2.sql b/gpp/postgis_extension/postgis--2.0.0alpha4--2.0.2.sql
index 2b555e1..f5109f4 100644
--- a/gcc/postgis_extension/postgis--2.0.0alpha4--2.0.2.sql
+++ b/gpp/postgis_extension/postgis--2.0.0alpha4--2.0.2.sql
@@ -1604,7 +1604,7 @@ CREATE OR REPLACE FUNCTION postgis_libxml_version() RETURNS text
AS '$libdir/postgis-2.0'
LANGUAGE 'c' IMMUTABLE;
CREATE OR REPLACE FUNCTION postgis_scripts_build_date() RETURNS text
- AS 'SELECT ''2012-12-05 22:40:44''::text AS version'
+ AS 'SELECT ''2012-12-05 23:21:55''::text AS version'
LANGUAGE 'sql' IMMUTABLE;
CREATE OR REPLACE FUNCTION postgis_lib_build_date() RETURNS text
AS '$libdir/postgis-2.0'
@@ -4251,14 +4251,12 @@ DROP FUNCTION IF EXISTS SnapToGrid(geometry, float8, float8);
DROP FUNCTION IF EXISTS ST_AsBinary(text); -- deprecated in 2.0
DROP FUNCTION IF EXISTS postgis_uses_stats(); -- deprecated in 2.0
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: rtpostgis_drop.sql.in.c 7884 2011-09-22 15:07:25Z robe $
--
-- PostGIS Raster - Raster Type for PostGIS
--- http://trac.osgeo.org/postgis/wiki/WKTRaster
+-- http:
--
-- Copyright (C) 2011 Regina Obe <lr@pcorp.us>
-- Copyright (C) 2011 Regents of the University of California
@@ -4580,14 +4578,12 @@ DROP FUNCTION IF EXISTS st_intersection(raster, integer, raster, integer, text,
DROP FUNCTION IF EXISTS st_intersection(raster, integer, raster, integer, regprocedure);
DROP FUNCTION IF EXISTS st_intersection(raster, raster, text, regprocedure);
DROP FUNCTION IF EXISTS st_intersection(raster, raster, regprocedure);
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: rtpostgis_upgrade.sql.in.c 8448 2011-12-16 22:07:26Z dustymugs $
--
-- PostGIS Raster - Raster Type for PostGIS
--- http://trac.osgeo.org/postgis/wiki/WKTRaster
+-- http:
--
-- Copyright (c) 2011 Regina Obe <lr@pcorp.us>
-- Copyright (C) 2011 Regents of the University of California
@@ -4621,6 +4617,23 @@ DROP FUNCTION IF EXISTS st_intersection(raster, raster, regprocedure);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-- drop st_bytea
SELECT postgis_extension_drop_if_exists('postgis', 'DROP CAST IF EXISTS (raster AS bytea);');DROP CAST IF EXISTS (raster AS bytea);
DROP FUNCTION IF EXISTS st_bytea(raster);
@@ -4637,6 +4650,7 @@ SELECT postgis_extension_drop_if_exists('postgis', 'DROP CAST IF EXISTS (raster
DROP FUNCTION IF EXISTS box2d(raster);
-- create box3d cast if it does not exist
+
-- If we are running 9.0+ we can use DO plpgsql to check
-- and only create if not exists so no need to force a drop
-- that way if people are using it, we will not mess them up
@@ -4656,17 +4670,17 @@ BEGIN
END IF;
END$$;
+
+
-- make geometry cast ASSIGNMENT
SELECT postgis_extension_drop_if_exists('postgis', 'DROP CAST IF EXISTS (raster AS geometry);');DROP CAST IF EXISTS (raster AS geometry);
CREATE CAST (raster AS geometry)
WITH FUNCTION st_convexhull(raster) AS ASSIGNMENT;
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
--
-- PostGIS Raster - Raster Type for PostGIS
--- http://trac.osgeo.org/postgis/wiki/WKTRaster
+-- http:
--
-- Copyright (c) 2009-2012 Sandro Santilli <strk@keybit.net>
-- Copyright (c) 2009-2010 Pierre Racine <pierre.racine@sbf.ulaval.ca>
@@ -4696,6 +4710,23 @@ CREATE CAST (raster AS geometry)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
SET client_min_messages TO warning;
@@ -9316,7 +9347,7 @@ CREATE OR REPLACE FUNCTION DropRasterConstraints (
-- raster_columns
--
-- The metadata is documented in the PostGIS Raster specification:
--- http://trac.osgeo.org/postgis/wiki/WKTRaster/SpecificationFinal01
+-- http:
------------------------------------------------------------------------------
CREATE OR REPLACE VIEW raster_columns AS
diff --git a/gcc/postgis_extension/postgis--2.0.0alpha5--2.0.2.sql b/gpp/postgis_extension/postgis--2.0.0alpha5--2.0.2.sql
index 2b555e1..f5109f4 100644
--- a/gcc/postgis_extension/postgis--2.0.0alpha5--2.0.2.sql
+++ b/gpp/postgis_extension/postgis--2.0.0alpha5--2.0.2.sql
@@ -1604,7 +1604,7 @@ CREATE OR REPLACE FUNCTION postgis_libxml_version() RETURNS text
AS '$libdir/postgis-2.0'
LANGUAGE 'c' IMMUTABLE;
CREATE OR REPLACE FUNCTION postgis_scripts_build_date() RETURNS text
- AS 'SELECT ''2012-12-05 22:40:44''::text AS version'
+ AS 'SELECT ''2012-12-05 23:21:55''::text AS version'
LANGUAGE 'sql' IMMUTABLE;
CREATE OR REPLACE FUNCTION postgis_lib_build_date() RETURNS text
AS '$libdir/postgis-2.0'
@@ -4251,14 +4251,12 @@ DROP FUNCTION IF EXISTS SnapToGrid(geometry, float8, float8);
DROP FUNCTION IF EXISTS ST_AsBinary(text); -- deprecated in 2.0
DROP FUNCTION IF EXISTS postgis_uses_stats(); -- deprecated in 2.0
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: rtpostgis_drop.sql.in.c 7884 2011-09-22 15:07:25Z robe $
--
-- PostGIS Raster - Raster Type for PostGIS
--- http://trac.osgeo.org/postgis/wiki/WKTRaster
+-- http:
--
-- Copyright (C) 2011 Regina Obe <lr@pcorp.us>
-- Copyright (C) 2011 Regents of the University of California
@@ -4580,14 +4578,12 @@ DROP FUNCTION IF EXISTS st_intersection(raster, integer, raster, integer, text,
DROP FUNCTION IF EXISTS st_intersection(raster, integer, raster, integer, regprocedure);
DROP FUNCTION IF EXISTS st_intersection(raster, raster, text, regprocedure);
DROP FUNCTION IF EXISTS st_intersection(raster, raster, regprocedure);
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: rtpostgis_upgrade.sql.in.c 8448 2011-12-16 22:07:26Z dustymugs $
--
-- PostGIS Raster - Raster Type for PostGIS
--- http://trac.osgeo.org/postgis/wiki/WKTRaster
+-- http:
--
-- Copyright (c) 2011 Regina Obe <lr@pcorp.us>
-- Copyright (C) 2011 Regents of the University of California
@@ -4621,6 +4617,23 @@ DROP FUNCTION IF EXISTS st_intersection(raster, raster, regprocedure);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-- drop st_bytea
SELECT postgis_extension_drop_if_exists('postgis', 'DROP CAST IF EXISTS (raster AS bytea);');DROP CAST IF EXISTS (raster AS bytea);
DROP FUNCTION IF EXISTS st_bytea(raster);
@@ -4637,6 +4650,7 @@ SELECT postgis_extension_drop_if_exists('postgis', 'DROP CAST IF EXISTS (raster
DROP FUNCTION IF EXISTS box2d(raster);
-- create box3d cast if it does not exist
+
-- If we are running 9.0+ we can use DO plpgsql to check
-- and only create if not exists so no need to force a drop
-- that way if people are using it, we will not mess them up
@@ -4656,17 +4670,17 @@ BEGIN
END IF;
END$$;
+
+
-- make geometry cast ASSIGNMENT
SELECT postgis_extension_drop_if_exists('postgis', 'DROP CAST IF EXISTS (raster AS geometry);');DROP CAST IF EXISTS (raster AS geometry);
CREATE CAST (raster AS geometry)
WITH FUNCTION st_convexhull(raster) AS ASSIGNMENT;
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
--
-- PostGIS Raster - Raster Type for PostGIS
--- http://trac.osgeo.org/postgis/wiki/WKTRaster
+-- http:
--
-- Copyright (c) 2009-2012 Sandro Santilli <strk@keybit.net>
-- Copyright (c) 2009-2010 Pierre Racine <pierre.racine@sbf.ulaval.ca>
@@ -4696,6 +4710,23 @@ CREATE CAST (raster AS geometry)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
SET client_min_messages TO warning;
@@ -9316,7 +9347,7 @@ CREATE OR REPLACE FUNCTION DropRasterConstraints (
-- raster_columns
--
-- The metadata is documented in the PostGIS Raster specification:
--- http://trac.osgeo.org/postgis/wiki/WKTRaster/SpecificationFinal01
+-- http:
------------------------------------------------------------------------------
CREATE OR REPLACE VIEW raster_columns AS
diff --git a/gcc/postgis_extension/postgis--2.0.0alpha6--2.0.2.sql b/gpp/postgis_extension/postgis--2.0.0alpha6--2.0.2.sql
index 2b555e1..f5109f4 100644
--- a/gcc/postgis_extension/postgis--2.0.0alpha6--2.0.2.sql
+++ b/gpp/postgis_extension/postgis--2.0.0alpha6--2.0.2.sql
@@ -1604,7 +1604,7 @@ CREATE OR REPLACE FUNCTION postgis_libxml_version() RETURNS text
AS '$libdir/postgis-2.0'
LANGUAGE 'c' IMMUTABLE;
CREATE OR REPLACE FUNCTION postgis_scripts_build_date() RETURNS text
- AS 'SELECT ''2012-12-05 22:40:44''::text AS version'
+ AS 'SELECT ''2012-12-05 23:21:55''::text AS version'
LANGUAGE 'sql' IMMUTABLE;
CREATE OR REPLACE FUNCTION postgis_lib_build_date() RETURNS text
AS '$libdir/postgis-2.0'
@@ -4251,14 +4251,12 @@ DROP FUNCTION IF EXISTS SnapToGrid(geometry, float8, float8);
DROP FUNCTION IF EXISTS ST_AsBinary(text); -- deprecated in 2.0
DROP FUNCTION IF EXISTS postgis_uses_stats(); -- deprecated in 2.0
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: rtpostgis_drop.sql.in.c 7884 2011-09-22 15:07:25Z robe $
--
-- PostGIS Raster - Raster Type for PostGIS
--- http://trac.osgeo.org/postgis/wiki/WKTRaster
+-- http:
--
-- Copyright (C) 2011 Regina Obe <lr@pcorp.us>
-- Copyright (C) 2011 Regents of the University of California
@@ -4580,14 +4578,12 @@ DROP FUNCTION IF EXISTS st_intersection(raster, integer, raster, integer, text,
DROP FUNCTION IF EXISTS st_intersection(raster, integer, raster, integer, regprocedure);
DROP FUNCTION IF EXISTS st_intersection(raster, raster, text, regprocedure);
DROP FUNCTION IF EXISTS st_intersection(raster, raster, regprocedure);
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: rtpostgis_upgrade.sql.in.c 8448 2011-12-16 22:07:26Z dustymugs $
--
-- PostGIS Raster - Raster Type for PostGIS
--- http://trac.osgeo.org/postgis/wiki/WKTRaster
+-- http:
--
-- Copyright (c) 2011 Regina Obe <lr@pcorp.us>
-- Copyright (C) 2011 Regents of the University of California
@@ -4621,6 +4617,23 @@ DROP FUNCTION IF EXISTS st_intersection(raster, raster, regprocedure);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-- drop st_bytea
SELECT postgis_extension_drop_if_exists('postgis', 'DROP CAST IF EXISTS (raster AS bytea);');DROP CAST IF EXISTS (raster AS bytea);
DROP FUNCTION IF EXISTS st_bytea(raster);
@@ -4637,6 +4650,7 @@ SELECT postgis_extension_drop_if_exists('postgis', 'DROP CAST IF EXISTS (raster
DROP FUNCTION IF EXISTS box2d(raster);
-- create box3d cast if it does not exist
+
-- If we are running 9.0+ we can use DO plpgsql to check
-- and only create if not exists so no need to force a drop
-- that way if people are using it, we will not mess them up
@@ -4656,17 +4670,17 @@ BEGIN
END IF;
END$$;
+
+
-- make geometry cast ASSIGNMENT
SELECT postgis_extension_drop_if_exists('postgis', 'DROP CAST IF EXISTS (raster AS geometry);');DROP CAST IF EXISTS (raster AS geometry);
CREATE CAST (raster AS geometry)
WITH FUNCTION st_convexhull(raster) AS ASSIGNMENT;
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
--
-- PostGIS Raster - Raster Type for PostGIS
--- http://trac.osgeo.org/postgis/wiki/WKTRaster
+-- http:
--
-- Copyright (c) 2009-2012 Sandro Santilli <strk@keybit.net>
-- Copyright (c) 2009-2010 Pierre Racine <pierre.racine@sbf.ulaval.ca>
@@ -4696,6 +4710,23 @@ CREATE CAST (raster AS geometry)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
SET client_min_messages TO warning;
@@ -9316,7 +9347,7 @@ CREATE OR REPLACE FUNCTION DropRasterConstraints (
-- raster_columns
--
-- The metadata is documented in the PostGIS Raster specification:
--- http://trac.osgeo.org/postgis/wiki/WKTRaster/SpecificationFinal01
+-- http:
------------------------------------------------------------------------------
CREATE OR REPLACE VIEW raster_columns AS
diff --git a/gcc/postgis_extension/postgis--2.0.0beta1--2.0.2.sql b/gpp/postgis_extension/postgis--2.0.0beta1--2.0.2.sql
index 2b555e1..f5109f4 100644
--- a/gcc/postgis_extension/postgis--2.0.0beta1--2.0.2.sql
+++ b/gpp/postgis_extension/postgis--2.0.0beta1--2.0.2.sql
@@ -1604,7 +1604,7 @@ CREATE OR REPLACE FUNCTION postgis_libxml_version() RETURNS text
AS '$libdir/postgis-2.0'
LANGUAGE 'c' IMMUTABLE;
CREATE OR REPLACE FUNCTION postgis_scripts_build_date() RETURNS text
- AS 'SELECT ''2012-12-05 22:40:44''::text AS version'
+ AS 'SELECT ''2012-12-05 23:21:55''::text AS version'
LANGUAGE 'sql' IMMUTABLE;
CREATE OR REPLACE FUNCTION postgis_lib_build_date() RETURNS text
AS '$libdir/postgis-2.0'
@@ -4251,14 +4251,12 @@ DROP FUNCTION IF EXISTS SnapToGrid(geometry, float8, float8);
DROP FUNCTION IF EXISTS ST_AsBinary(text); -- deprecated in 2.0
DROP FUNCTION IF EXISTS postgis_uses_stats(); -- deprecated in 2.0
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: rtpostgis_drop.sql.in.c 7884 2011-09-22 15:07:25Z robe $
--
-- PostGIS Raster - Raster Type for PostGIS
--- http://trac.osgeo.org/postgis/wiki/WKTRaster
+-- http:
--
-- Copyright (C) 2011 Regina Obe <lr@pcorp.us>
-- Copyright (C) 2011 Regents of the University of California
@@ -4580,14 +4578,12 @@ DROP FUNCTION IF EXISTS st_intersection(raster, integer, raster, integer, text,
DROP FUNCTION IF EXISTS st_intersection(raster, integer, raster, integer, regprocedure);
DROP FUNCTION IF EXISTS st_intersection(raster, raster, text, regprocedure);
DROP FUNCTION IF EXISTS st_intersection(raster, raster, regprocedure);
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: rtpostgis_upgrade.sql.in.c 8448 2011-12-16 22:07:26Z dustymugs $
--
-- PostGIS Raster - Raster Type for PostGIS
--- http://trac.osgeo.org/postgis/wiki/WKTRaster
+-- http:
--
-- Copyright (c) 2011 Regina Obe <lr@pcorp.us>
-- Copyright (C) 2011 Regents of the University of California
@@ -4621,6 +4617,23 @@ DROP FUNCTION IF EXISTS st_intersection(raster, raster, regprocedure);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-- drop st_bytea
SELECT postgis_extension_drop_if_exists('postgis', 'DROP CAST IF EXISTS (raster AS bytea);');DROP CAST IF EXISTS (raster AS bytea);
DROP FUNCTION IF EXISTS st_bytea(raster);
@@ -4637,6 +4650,7 @@ SELECT postgis_extension_drop_if_exists('postgis', 'DROP CAST IF EXISTS (raster
DROP FUNCTION IF EXISTS box2d(raster);
-- create box3d cast if it does not exist
+
-- If we are running 9.0+ we can use DO plpgsql to check
-- and only create if not exists so no need to force a drop
-- that way if people are using it, we will not mess them up
@@ -4656,17 +4670,17 @@ BEGIN
END IF;
END$$;
+
+
-- make geometry cast ASSIGNMENT
SELECT postgis_extension_drop_if_exists('postgis', 'DROP CAST IF EXISTS (raster AS geometry);');DROP CAST IF EXISTS (raster AS geometry);
CREATE CAST (raster AS geometry)
WITH FUNCTION st_convexhull(raster) AS ASSIGNMENT;
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
--
-- PostGIS Raster - Raster Type for PostGIS
--- http://trac.osgeo.org/postgis/wiki/WKTRaster
+-- http:
--
-- Copyright (c) 2009-2012 Sandro Santilli <strk@keybit.net>
-- Copyright (c) 2009-2010 Pierre Racine <pierre.racine@sbf.ulaval.ca>
@@ -4696,6 +4710,23 @@ CREATE CAST (raster AS geometry)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
SET client_min_messages TO warning;
@@ -9316,7 +9347,7 @@ CREATE OR REPLACE FUNCTION DropRasterConstraints (
-- raster_columns
--
-- The metadata is documented in the PostGIS Raster specification:
--- http://trac.osgeo.org/postgis/wiki/WKTRaster/SpecificationFinal01
+-- http:
------------------------------------------------------------------------------
CREATE OR REPLACE VIEW raster_columns AS
diff --git a/gcc/postgis_extension/postgis--2.0.0beta2--2.0.2.sql b/gpp/postgis_extension/postgis--2.0.0beta2--2.0.2.sql
index 2b555e1..f5109f4 100644
--- a/gcc/postgis_extension/postgis--2.0.0beta2--2.0.2.sql
+++ b/gpp/postgis_extension/postgis--2.0.0beta2--2.0.2.sql
@@ -1604,7 +1604,7 @@ CREATE OR REPLACE FUNCTION postgis_libxml_version() RETURNS text
AS '$libdir/postgis-2.0'
LANGUAGE 'c' IMMUTABLE;
CREATE OR REPLACE FUNCTION postgis_scripts_build_date() RETURNS text
- AS 'SELECT ''2012-12-05 22:40:44''::text AS version'
+ AS 'SELECT ''2012-12-05 23:21:55''::text AS version'
LANGUAGE 'sql' IMMUTABLE;
CREATE OR REPLACE FUNCTION postgis_lib_build_date() RETURNS text
AS '$libdir/postgis-2.0'
@@ -4251,14 +4251,12 @@ DROP FUNCTION IF EXISTS SnapToGrid(geometry, float8, float8);
DROP FUNCTION IF EXISTS ST_AsBinary(text); -- deprecated in 2.0
DROP FUNCTION IF EXISTS postgis_uses_stats(); -- deprecated in 2.0
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: rtpostgis_drop.sql.in.c 7884 2011-09-22 15:07:25Z robe $
--
-- PostGIS Raster - Raster Type for PostGIS
--- http://trac.osgeo.org/postgis/wiki/WKTRaster
+-- http:
--
-- Copyright (C) 2011 Regina Obe <lr@pcorp.us>
-- Copyright (C) 2011 Regents of the University of California
@@ -4580,14 +4578,12 @@ DROP FUNCTION IF EXISTS st_intersection(raster, integer, raster, integer, text,
DROP FUNCTION IF EXISTS st_intersection(raster, integer, raster, integer, regprocedure);
DROP FUNCTION IF EXISTS st_intersection(raster, raster, text, regprocedure);
DROP FUNCTION IF EXISTS st_intersection(raster, raster, regprocedure);
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: rtpostgis_upgrade.sql.in.c 8448 2011-12-16 22:07:26Z dustymugs $
--
-- PostGIS Raster - Raster Type for PostGIS
--- http://trac.osgeo.org/postgis/wiki/WKTRaster
+-- http:
--
-- Copyright (c) 2011 Regina Obe <lr@pcorp.us>
-- Copyright (C) 2011 Regents of the University of California
@@ -4621,6 +4617,23 @@ DROP FUNCTION IF EXISTS st_intersection(raster, raster, regprocedure);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-- drop st_bytea
SELECT postgis_extension_drop_if_exists('postgis', 'DROP CAST IF EXISTS (raster AS bytea);');DROP CAST IF EXISTS (raster AS bytea);
DROP FUNCTION IF EXISTS st_bytea(raster);
@@ -4637,6 +4650,7 @@ SELECT postgis_extension_drop_if_exists('postgis', 'DROP CAST IF EXISTS (raster
DROP FUNCTION IF EXISTS box2d(raster);
-- create box3d cast if it does not exist
+
-- If we are running 9.0+ we can use DO plpgsql to check
-- and only create if not exists so no need to force a drop
-- that way if people are using it, we will not mess them up
@@ -4656,17 +4670,17 @@ BEGIN
END IF;
END$$;
+
+
-- make geometry cast ASSIGNMENT
SELECT postgis_extension_drop_if_exists('postgis', 'DROP CAST IF EXISTS (raster AS geometry);');DROP CAST IF EXISTS (raster AS geometry);
CREATE CAST (raster AS geometry)
WITH FUNCTION st_convexhull(raster) AS ASSIGNMENT;
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
--
-- PostGIS Raster - Raster Type for PostGIS
--- http://trac.osgeo.org/postgis/wiki/WKTRaster
+-- http:
--
-- Copyright (c) 2009-2012 Sandro Santilli <strk@keybit.net>
-- Copyright (c) 2009-2010 Pierre Racine <pierre.racine@sbf.ulaval.ca>
@@ -4696,6 +4710,23 @@ CREATE CAST (raster AS geometry)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
SET client_min_messages TO warning;
@@ -9316,7 +9347,7 @@ CREATE OR REPLACE FUNCTION DropRasterConstraints (
-- raster_columns
--
-- The metadata is documented in the PostGIS Raster specification:
--- http://trac.osgeo.org/postgis/wiki/WKTRaster/SpecificationFinal01
+-- http:
------------------------------------------------------------------------------
CREATE OR REPLACE VIEW raster_columns AS
diff --git a/gcc/postgis_extension/postgis--2.0.0beta3--2.0.2.sql b/gpp/postgis_extension/postgis--2.0.0beta3--2.0.2.sql
index 2b555e1..f5109f4 100644
--- a/gcc/postgis_extension/postgis--2.0.0beta3--2.0.2.sql
+++ b/gpp/postgis_extension/postgis--2.0.0beta3--2.0.2.sql
@@ -1604,7 +1604,7 @@ CREATE OR REPLACE FUNCTION postgis_libxml_version() RETURNS text
AS '$libdir/postgis-2.0'
LANGUAGE 'c' IMMUTABLE;
CREATE OR REPLACE FUNCTION postgis_scripts_build_date() RETURNS text
- AS 'SELECT ''2012-12-05 22:40:44''::text AS version'
+ AS 'SELECT ''2012-12-05 23:21:55''::text AS version'
LANGUAGE 'sql' IMMUTABLE;
CREATE OR REPLACE FUNCTION postgis_lib_build_date() RETURNS text
AS '$libdir/postgis-2.0'
@@ -4251,14 +4251,12 @@ DROP FUNCTION IF EXISTS SnapToGrid(geometry, float8, float8);
DROP FUNCTION IF EXISTS ST_AsBinary(text); -- deprecated in 2.0
DROP FUNCTION IF EXISTS postgis_uses_stats(); -- deprecated in 2.0
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: rtpostgis_drop.sql.in.c 7884 2011-09-22 15:07:25Z robe $
--
-- PostGIS Raster - Raster Type for PostGIS
--- http://trac.osgeo.org/postgis/wiki/WKTRaster
+-- http:
--
-- Copyright (C) 2011 Regina Obe <lr@pcorp.us>
-- Copyright (C) 2011 Regents of the University of California
@@ -4580,14 +4578,12 @@ DROP FUNCTION IF EXISTS st_intersection(raster, integer, raster, integer, text,
DROP FUNCTION IF EXISTS st_intersection(raster, integer, raster, integer, regprocedure);
DROP FUNCTION IF EXISTS st_intersection(raster, raster, text, regprocedure);
DROP FUNCTION IF EXISTS st_intersection(raster, raster, regprocedure);
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: rtpostgis_upgrade.sql.in.c 8448 2011-12-16 22:07:26Z dustymugs $
--
-- PostGIS Raster - Raster Type for PostGIS
--- http://trac.osgeo.org/postgis/wiki/WKTRaster
+-- http:
--
-- Copyright (c) 2011 Regina Obe <lr@pcorp.us>
-- Copyright (C) 2011 Regents of the University of California
@@ -4621,6 +4617,23 @@ DROP FUNCTION IF EXISTS st_intersection(raster, raster, regprocedure);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-- drop st_bytea
SELECT postgis_extension_drop_if_exists('postgis', 'DROP CAST IF EXISTS (raster AS bytea);');DROP CAST IF EXISTS (raster AS bytea);
DROP FUNCTION IF EXISTS st_bytea(raster);
@@ -4637,6 +4650,7 @@ SELECT postgis_extension_drop_if_exists('postgis', 'DROP CAST IF EXISTS (raster
DROP FUNCTION IF EXISTS box2d(raster);
-- create box3d cast if it does not exist
+
-- If we are running 9.0+ we can use DO plpgsql to check
-- and only create if not exists so no need to force a drop
-- that way if people are using it, we will not mess them up
@@ -4656,17 +4670,17 @@ BEGIN
END IF;
END$$;
+
+
-- make geometry cast ASSIGNMENT
SELECT postgis_extension_drop_if_exists('postgis', 'DROP CAST IF EXISTS (raster AS geometry);');DROP CAST IF EXISTS (raster AS geometry);
CREATE CAST (raster AS geometry)
WITH FUNCTION st_convexhull(raster) AS ASSIGNMENT;
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
--
-- PostGIS Raster - Raster Type for PostGIS
--- http://trac.osgeo.org/postgis/wiki/WKTRaster
+-- http:
--
-- Copyright (c) 2009-2012 Sandro Santilli <strk@keybit.net>
-- Copyright (c) 2009-2010 Pierre Racine <pierre.racine@sbf.ulaval.ca>
@@ -4696,6 +4710,23 @@ CREATE CAST (raster AS geometry)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
SET client_min_messages TO warning;
@@ -9316,7 +9347,7 @@ CREATE OR REPLACE FUNCTION DropRasterConstraints (
-- raster_columns
--
-- The metadata is documented in the PostGIS Raster specification:
--- http://trac.osgeo.org/postgis/wiki/WKTRaster/SpecificationFinal01
+-- http:
------------------------------------------------------------------------------
CREATE OR REPLACE VIEW raster_columns AS
diff --git a/gcc/postgis_extension/postgis--2.0.0beta4--2.0.2.sql b/gpp/postgis_extension/postgis--2.0.0beta4--2.0.2.sql
index 2b555e1..f5109f4 100644
--- a/gcc/postgis_extension/postgis--2.0.0beta4--2.0.2.sql
+++ b/gpp/postgis_extension/postgis--2.0.0beta4--2.0.2.sql
@@ -1604,7 +1604,7 @@ CREATE OR REPLACE FUNCTION postgis_libxml_version() RETURNS text
AS '$libdir/postgis-2.0'
LANGUAGE 'c' IMMUTABLE;
CREATE OR REPLACE FUNCTION postgis_scripts_build_date() RETURNS text
- AS 'SELECT ''2012-12-05 22:40:44''::text AS version'
+ AS 'SELECT ''2012-12-05 23:21:55''::text AS version'
LANGUAGE 'sql' IMMUTABLE;
CREATE OR REPLACE FUNCTION postgis_lib_build_date() RETURNS text
AS '$libdir/postgis-2.0'
@@ -4251,14 +4251,12 @@ DROP FUNCTION IF EXISTS SnapToGrid(geometry, float8, float8);
DROP FUNCTION IF EXISTS ST_AsBinary(text); -- deprecated in 2.0
DROP FUNCTION IF EXISTS postgis_uses_stats(); -- deprecated in 2.0
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: rtpostgis_drop.sql.in.c 7884 2011-09-22 15:07:25Z robe $
--
-- PostGIS Raster - Raster Type for PostGIS
--- http://trac.osgeo.org/postgis/wiki/WKTRaster
+-- http:
--
-- Copyright (C) 2011 Regina Obe <lr@pcorp.us>
-- Copyright (C) 2011 Regents of the University of California
@@ -4580,14 +4578,12 @@ DROP FUNCTION IF EXISTS st_intersection(raster, integer, raster, integer, text,
DROP FUNCTION IF EXISTS st_intersection(raster, integer, raster, integer, regprocedure);
DROP FUNCTION IF EXISTS st_intersection(raster, raster, text, regprocedure);
DROP FUNCTION IF EXISTS st_intersection(raster, raster, regprocedure);
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: rtpostgis_upgrade.sql.in.c 8448 2011-12-16 22:07:26Z dustymugs $
--
-- PostGIS Raster - Raster Type for PostGIS
--- http://trac.osgeo.org/postgis/wiki/WKTRaster
+-- http:
--
-- Copyright (c) 2011 Regina Obe <lr@pcorp.us>
-- Copyright (C) 2011 Regents of the University of California
@@ -4621,6 +4617,23 @@ DROP FUNCTION IF EXISTS st_intersection(raster, raster, regprocedure);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-- drop st_bytea
SELECT postgis_extension_drop_if_exists('postgis', 'DROP CAST IF EXISTS (raster AS bytea);');DROP CAST IF EXISTS (raster AS bytea);
DROP FUNCTION IF EXISTS st_bytea(raster);
@@ -4637,6 +4650,7 @@ SELECT postgis_extension_drop_if_exists('postgis', 'DROP CAST IF EXISTS (raster
DROP FUNCTION IF EXISTS box2d(raster);
-- create box3d cast if it does not exist
+
-- If we are running 9.0+ we can use DO plpgsql to check
-- and only create if not exists so no need to force a drop
-- that way if people are using it, we will not mess them up
@@ -4656,17 +4670,17 @@ BEGIN
END IF;
END$$;
+
+
-- make geometry cast ASSIGNMENT
SELECT postgis_extension_drop_if_exists('postgis', 'DROP CAST IF EXISTS (raster AS geometry);');DROP CAST IF EXISTS (raster AS geometry);
CREATE CAST (raster AS geometry)
WITH FUNCTION st_convexhull(raster) AS ASSIGNMENT;
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
--
-- PostGIS Raster - Raster Type for PostGIS
--- http://trac.osgeo.org/postgis/wiki/WKTRaster
+-- http:
--
-- Copyright (c) 2009-2012 Sandro Santilli <strk@keybit.net>
-- Copyright (c) 2009-2010 Pierre Racine <pierre.racine@sbf.ulaval.ca>
@@ -4696,6 +4710,23 @@ CREATE CAST (raster AS geometry)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
SET client_min_messages TO warning;
@@ -9316,7 +9347,7 @@ CREATE OR REPLACE FUNCTION DropRasterConstraints (
-- raster_columns
--
-- The metadata is documented in the PostGIS Raster specification:
--- http://trac.osgeo.org/postgis/wiki/WKTRaster/SpecificationFinal01
+-- http:
------------------------------------------------------------------------------
CREATE OR REPLACE VIEW raster_columns AS
diff --git a/gcc/postgis_extension/postgis--2.0.0rc1--2.0.2.sql b/gpp/postgis_extension/postgis--2.0.0rc1--2.0.2.sql
index 2b555e1..f5109f4 100644
--- a/gcc/postgis_extension/postgis--2.0.0rc1--2.0.2.sql
+++ b/gpp/postgis_extension/postgis--2.0.0rc1--2.0.2.sql
@@ -1604,7 +1604,7 @@ CREATE OR REPLACE FUNCTION postgis_libxml_version() RETURNS text
AS '$libdir/postgis-2.0'
LANGUAGE 'c' IMMUTABLE;
CREATE OR REPLACE FUNCTION postgis_scripts_build_date() RETURNS text
- AS 'SELECT ''2012-12-05 22:40:44''::text AS version'
+ AS 'SELECT ''2012-12-05 23:21:55''::text AS version'
LANGUAGE 'sql' IMMUTABLE;
CREATE OR REPLACE FUNCTION postgis_lib_build_date() RETURNS text
AS '$libdir/postgis-2.0'
@@ -4251,14 +4251,12 @@ DROP FUNCTION IF EXISTS SnapToGrid(geometry, float8, float8);
DROP FUNCTION IF EXISTS ST_AsBinary(text); -- deprecated in 2.0
DROP FUNCTION IF EXISTS postgis_uses_stats(); -- deprecated in 2.0
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: rtpostgis_drop.sql.in.c 7884 2011-09-22 15:07:25Z robe $
--
-- PostGIS Raster - Raster Type for PostGIS
--- http://trac.osgeo.org/postgis/wiki/WKTRaster
+-- http:
--
-- Copyright (C) 2011 Regina Obe <lr@pcorp.us>
-- Copyright (C) 2011 Regents of the University of California
@@ -4580,14 +4578,12 @@ DROP FUNCTION IF EXISTS st_intersection(raster, integer, raster, integer, text,
DROP FUNCTION IF EXISTS st_intersection(raster, integer, raster, integer, regprocedure);
DROP FUNCTION IF EXISTS st_intersection(raster, raster, text, regprocedure);
DROP FUNCTION IF EXISTS st_intersection(raster, raster, regprocedure);
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: rtpostgis_upgrade.sql.in.c 8448 2011-12-16 22:07:26Z dustymugs $
--
-- PostGIS Raster - Raster Type for PostGIS
--- http://trac.osgeo.org/postgis/wiki/WKTRaster
+-- http:
--
-- Copyright (c) 2011 Regina Obe <lr@pcorp.us>
-- Copyright (C) 2011 Regents of the University of California
@@ -4621,6 +4617,23 @@ DROP FUNCTION IF EXISTS st_intersection(raster, raster, regprocedure);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-- drop st_bytea
SELECT postgis_extension_drop_if_exists('postgis', 'DROP CAST IF EXISTS (raster AS bytea);');DROP CAST IF EXISTS (raster AS bytea);
DROP FUNCTION IF EXISTS st_bytea(raster);
@@ -4637,6 +4650,7 @@ SELECT postgis_extension_drop_if_exists('postgis', 'DROP CAST IF EXISTS (raster
DROP FUNCTION IF EXISTS box2d(raster);
-- create box3d cast if it does not exist
+
-- If we are running 9.0+ we can use DO plpgsql to check
-- and only create if not exists so no need to force a drop
-- that way if people are using it, we will not mess them up
@@ -4656,17 +4670,17 @@ BEGIN
END IF;
END$$;
+
+
-- make geometry cast ASSIGNMENT
SELECT postgis_extension_drop_if_exists('postgis', 'DROP CAST IF EXISTS (raster AS geometry);');DROP CAST IF EXISTS (raster AS geometry);
CREATE CAST (raster AS geometry)
WITH FUNCTION st_convexhull(raster) AS ASSIGNMENT;
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
--
-- PostGIS Raster - Raster Type for PostGIS
--- http://trac.osgeo.org/postgis/wiki/WKTRaster
+-- http:
--
-- Copyright (c) 2009-2012 Sandro Santilli <strk@keybit.net>
-- Copyright (c) 2009-2010 Pierre Racine <pierre.racine@sbf.ulaval.ca>
@@ -4696,6 +4710,23 @@ CREATE CAST (raster AS geometry)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
SET client_min_messages TO warning;
@@ -9316,7 +9347,7 @@ CREATE OR REPLACE FUNCTION DropRasterConstraints (
-- raster_columns
--
-- The metadata is documented in the PostGIS Raster specification:
--- http://trac.osgeo.org/postgis/wiki/WKTRaster/SpecificationFinal01
+-- http:
------------------------------------------------------------------------------
CREATE OR REPLACE VIEW raster_columns AS
diff --git a/gcc/postgis_extension/postgis--2.0.0rc2--2.0.2.sql b/gpp/postgis_extension/postgis--2.0.0rc2--2.0.2.sql
index 2b555e1..f5109f4 100644
--- a/gcc/postgis_extension/postgis--2.0.0rc2--2.0.2.sql
+++ b/gpp/postgis_extension/postgis--2.0.0rc2--2.0.2.sql
@@ -1604,7 +1604,7 @@ CREATE OR REPLACE FUNCTION postgis_libxml_version() RETURNS text
AS '$libdir/postgis-2.0'
LANGUAGE 'c' IMMUTABLE;
CREATE OR REPLACE FUNCTION postgis_scripts_build_date() RETURNS text
- AS 'SELECT ''2012-12-05 22:40:44''::text AS version'
+ AS 'SELECT ''2012-12-05 23:21:55''::text AS version'
LANGUAGE 'sql' IMMUTABLE;
CREATE OR REPLACE FUNCTION postgis_lib_build_date() RETURNS text
AS '$libdir/postgis-2.0'
@@ -4251,14 +4251,12 @@ DROP FUNCTION IF EXISTS SnapToGrid(geometry, float8, float8);
DROP FUNCTION IF EXISTS ST_AsBinary(text); -- deprecated in 2.0
DROP FUNCTION IF EXISTS postgis_uses_stats(); -- deprecated in 2.0
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: rtpostgis_drop.sql.in.c 7884 2011-09-22 15:07:25Z robe $
--
-- PostGIS Raster - Raster Type for PostGIS
--- http://trac.osgeo.org/postgis/wiki/WKTRaster
+-- http:
--
-- Copyright (C) 2011 Regina Obe <lr@pcorp.us>
-- Copyright (C) 2011 Regents of the University of California
@@ -4580,14 +4578,12 @@ DROP FUNCTION IF EXISTS st_intersection(raster, integer, raster, integer, text,
DROP FUNCTION IF EXISTS st_intersection(raster, integer, raster, integer, regprocedure);
DROP FUNCTION IF EXISTS st_intersection(raster, raster, text, regprocedure);
DROP FUNCTION IF EXISTS st_intersection(raster, raster, regprocedure);
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: rtpostgis_upgrade.sql.in.c 8448 2011-12-16 22:07:26Z dustymugs $
--
-- PostGIS Raster - Raster Type for PostGIS
--- http://trac.osgeo.org/postgis/wiki/WKTRaster
+-- http:
--
-- Copyright (c) 2011 Regina Obe <lr@pcorp.us>
-- Copyright (C) 2011 Regents of the University of California
@@ -4621,6 +4617,23 @@ DROP FUNCTION IF EXISTS st_intersection(raster, raster, regprocedure);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-- drop st_bytea
SELECT postgis_extension_drop_if_exists('postgis', 'DROP CAST IF EXISTS (raster AS bytea);');DROP CAST IF EXISTS (raster AS bytea);
DROP FUNCTION IF EXISTS st_bytea(raster);
@@ -4637,6 +4650,7 @@ SELECT postgis_extension_drop_if_exists('postgis', 'DROP CAST IF EXISTS (raster
DROP FUNCTION IF EXISTS box2d(raster);
-- create box3d cast if it does not exist
+
-- If we are running 9.0+ we can use DO plpgsql to check
-- and only create if not exists so no need to force a drop
-- that way if people are using it, we will not mess them up
@@ -4656,17 +4670,17 @@ BEGIN
END IF;
END$$;
+
+
-- make geometry cast ASSIGNMENT
SELECT postgis_extension_drop_if_exists('postgis', 'DROP CAST IF EXISTS (raster AS geometry);');DROP CAST IF EXISTS (raster AS geometry);
CREATE CAST (raster AS geometry)
WITH FUNCTION st_convexhull(raster) AS ASSIGNMENT;
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
--
-- PostGIS Raster - Raster Type for PostGIS
--- http://trac.osgeo.org/postgis/wiki/WKTRaster
+-- http:
--
-- Copyright (c) 2009-2012 Sandro Santilli <strk@keybit.net>
-- Copyright (c) 2009-2010 Pierre Racine <pierre.racine@sbf.ulaval.ca>
@@ -4696,6 +4710,23 @@ CREATE CAST (raster AS geometry)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
SET client_min_messages TO warning;
@@ -9316,7 +9347,7 @@ CREATE OR REPLACE FUNCTION DropRasterConstraints (
-- raster_columns
--
-- The metadata is documented in the PostGIS Raster specification:
--- http://trac.osgeo.org/postgis/wiki/WKTRaster/SpecificationFinal01
+-- http:
------------------------------------------------------------------------------
CREATE OR REPLACE VIEW raster_columns AS
diff --git a/gcc/postgis_extension/postgis--2.0.1--2.0.2.sql b/gpp/postgis_extension/postgis--2.0.1--2.0.2.sql
index 2b555e1..f5109f4 100644
--- a/gcc/postgis_extension/postgis--2.0.1--2.0.2.sql
+++ b/gpp/postgis_extension/postgis--2.0.1--2.0.2.sql
@@ -1604,7 +1604,7 @@ CREATE OR REPLACE FUNCTION postgis_libxml_version() RETURNS text
AS '$libdir/postgis-2.0'
LANGUAGE 'c' IMMUTABLE;
CREATE OR REPLACE FUNCTION postgis_scripts_build_date() RETURNS text
- AS 'SELECT ''2012-12-05 22:40:44''::text AS version'
+ AS 'SELECT ''2012-12-05 23:21:55''::text AS version'
LANGUAGE 'sql' IMMUTABLE;
CREATE OR REPLACE FUNCTION postgis_lib_build_date() RETURNS text
AS '$libdir/postgis-2.0'
@@ -4251,14 +4251,12 @@ DROP FUNCTION IF EXISTS SnapToGrid(geometry, float8, float8);
DROP FUNCTION IF EXISTS ST_AsBinary(text); -- deprecated in 2.0
DROP FUNCTION IF EXISTS postgis_uses_stats(); -- deprecated in 2.0
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: rtpostgis_drop.sql.in.c 7884 2011-09-22 15:07:25Z robe $
--
-- PostGIS Raster - Raster Type for PostGIS
--- http://trac.osgeo.org/postgis/wiki/WKTRaster
+-- http:
--
-- Copyright (C) 2011 Regina Obe <lr@pcorp.us>
-- Copyright (C) 2011 Regents of the University of California
@@ -4580,14 +4578,12 @@ DROP FUNCTION IF EXISTS st_intersection(raster, integer, raster, integer, text,
DROP FUNCTION IF EXISTS st_intersection(raster, integer, raster, integer, regprocedure);
DROP FUNCTION IF EXISTS st_intersection(raster, raster, text, regprocedure);
DROP FUNCTION IF EXISTS st_intersection(raster, raster, regprocedure);
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: rtpostgis_upgrade.sql.in.c 8448 2011-12-16 22:07:26Z dustymugs $
--
-- PostGIS Raster - Raster Type for PostGIS
--- http://trac.osgeo.org/postgis/wiki/WKTRaster
+-- http:
--
-- Copyright (c) 2011 Regina Obe <lr@pcorp.us>
-- Copyright (C) 2011 Regents of the University of California
@@ -4621,6 +4617,23 @@ DROP FUNCTION IF EXISTS st_intersection(raster, raster, regprocedure);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-- drop st_bytea
SELECT postgis_extension_drop_if_exists('postgis', 'DROP CAST IF EXISTS (raster AS bytea);');DROP CAST IF EXISTS (raster AS bytea);
DROP FUNCTION IF EXISTS st_bytea(raster);
@@ -4637,6 +4650,7 @@ SELECT postgis_extension_drop_if_exists('postgis', 'DROP CAST IF EXISTS (raster
DROP FUNCTION IF EXISTS box2d(raster);
-- create box3d cast if it does not exist
+
-- If we are running 9.0+ we can use DO plpgsql to check
-- and only create if not exists so no need to force a drop
-- that way if people are using it, we will not mess them up
@@ -4656,17 +4670,17 @@ BEGIN
END IF;
END$$;
+
+
-- make geometry cast ASSIGNMENT
SELECT postgis_extension_drop_if_exists('postgis', 'DROP CAST IF EXISTS (raster AS geometry);');DROP CAST IF EXISTS (raster AS geometry);
CREATE CAST (raster AS geometry)
WITH FUNCTION st_convexhull(raster) AS ASSIGNMENT;
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
--
-- PostGIS Raster - Raster Type for PostGIS
--- http://trac.osgeo.org/postgis/wiki/WKTRaster
+-- http:
--
-- Copyright (c) 2009-2012 Sandro Santilli <strk@keybit.net>
-- Copyright (c) 2009-2010 Pierre Racine <pierre.racine@sbf.ulaval.ca>
@@ -4696,6 +4710,23 @@ CREATE CAST (raster AS geometry)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
SET client_min_messages TO warning;
@@ -9316,7 +9347,7 @@ CREATE OR REPLACE FUNCTION DropRasterConstraints (
-- raster_columns
--
-- The metadata is documented in the PostGIS Raster specification:
--- http://trac.osgeo.org/postgis/wiki/WKTRaster/SpecificationFinal01
+-- http:
------------------------------------------------------------------------------
CREATE OR REPLACE VIEW raster_columns AS
diff --git a/gcc/postgis_extension/postgis--2.0.2.sql b/gpp/postgis_extension/postgis--2.0.2.sql
index a3fa39b..7a365f2 100644
--- a/gcc/postgis_extension/postgis--2.0.2.sql
+++ b/gpp/postgis_extension/postgis--2.0.2.sql
@@ -1,11 +1,9 @@
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: postgis.sql.in.c 9900 2012-06-12 13:04:49Z strk $
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
-- Copyright 2001-2003 Refractions Research Inc.
--
-- This is free software; you can redistribute and/or modify it under
@@ -34,6 +32,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
SET client_min_messages TO warning;
-- INSTALL VERSION: 2.0.2
@@ -442,6 +455,7 @@ CREATE OR REPLACE FUNCTION geometry_distance_box(geom1 geometry, geom2 geometry)
AS '$libdir/postgis-2.0' ,'gserialized_distance_box_2d'
LANGUAGE 'c' IMMUTABLE STRICT;
+
CREATE OPERATOR <-> (
LEFTARG = geometry, RIGHTARG = geometry, PROCEDURE = geometry_distance_centroid,
COMMUTATOR = '<->'
@@ -452,6 +466,7 @@ CREATE OPERATOR <#> (
COMMUTATOR = '<#>'
);
+
-- Availability: 2.0.0
CREATE OR REPLACE FUNCTION geometry_contains(geom1 geometry, geom2 geometry)
RETURNS bool
@@ -588,9 +603,11 @@ CREATE OPERATOR CLASS gist_geometry_ops_2d
OPERATOR 10 <<| ,
OPERATOR 11 |>> ,
OPERATOR 12 |&> ,
+
OPERATOR 13 <-> FOR ORDER BY pg_catalog.float_ops,
OPERATOR 14 <#> FOR ORDER BY pg_catalog.float_ops,
FUNCTION 8 geometry_gist_distance_2d (internal, geometry, int4),
+
FUNCTION 1 geometry_gist_consistent_2d (internal, geometry, int4),
FUNCTION 2 geometry_gist_union_2d (bytea, internal),
FUNCTION 3 geometry_gist_compress_2d (internal),
@@ -2349,7 +2366,7 @@ CREATE OR REPLACE FUNCTION postgis_libxml_version() RETURNS text
LANGUAGE 'c' IMMUTABLE;
CREATE OR REPLACE FUNCTION postgis_scripts_build_date() RETURNS text
- AS 'SELECT ''2012-12-05 22:40:44''::text AS version'
+ AS 'SELECT ''2012-12-05 23:21:55''::text AS version'
LANGUAGE 'sql' IMMUTABLE;
CREATE OR REPLACE FUNCTION postgis_lib_build_date() RETURNS text
@@ -4263,7 +4280,7 @@ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
-- $Id: long_xact.sql.in.c 9735 2012-05-16 08:29:14Z robe $
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
-- Copyright 2001-2003 Refractions Research Inc.
--
-- This is free software; you can redistribute and/or modify it under
@@ -4274,6 +4291,10 @@ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
+
+
+
+
-----------------------------------------------------------------------
-- LONG TERM LOCKING
-----------------------------------------------------------------------
@@ -4584,6 +4605,7 @@ LANGUAGE 'plpgsql';
-- END
---------------------------------------------------------------
+
---------------------------------------------------------------------------
-- $Id: geography.sql.in.c 9900 2012-06-12 13:04:49Z strk $
--
@@ -5303,6 +5325,7 @@ CREATE OR REPLACE FUNCTION ST_Summary(geography)
+
-- Availability: 1.2.2
CREATE OR REPLACE FUNCTION ST_distance_sphere(geom1 geometry, geom2 geometry)
RETURNS FLOAT8
@@ -6718,13 +6741,11 @@ COMMENT ON FUNCTION PostGIS_AddBBox(geometry ) IS 'args: geomA - Add bounding bo
COMMENT ON FUNCTION PostGIS_DropBBox(geometry ) IS 'args: geomA - Drop the bounding box cache from the geometry.';
COMMENT ON FUNCTION PostGIS_HasBBox(geometry ) IS 'args: geomA - Returns TRUE if the bbox of this geometry is cached, FALSE otherwise.';
-
-
--- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
--
-- PostGIS Raster - Raster Type for PostGIS
--- http://trac.osgeo.org/postgis/wiki/WKTRaster
+-- http:
--
-- Copyright (c) 2009-2012 Sandro Santilli <strk@keybit.net>
-- Copyright (c) 2009-2010 Pierre Racine <pierre.racine@sbf.ulaval.ca>
@@ -6754,6 +6775,23 @@ COMMENT ON FUNCTION PostGIS_HasBBox(geometry ) IS 'args: geomA - Returns TRUE if
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
SET client_min_messages TO warning;
@@ -11474,7 +11512,7 @@ CREATE OR REPLACE FUNCTION DropRasterConstraints (
-- raster_columns
--
-- The metadata is documented in the PostGIS Raster specification:
--- http://trac.osgeo.org/postgis/wiki/WKTRaster/SpecificationFinal01
+-- http:
------------------------------------------------------------------------------
CREATE OR REPLACE VIEW raster_columns AS
diff --git a/gcc/postgis_extension/postgis_topology--2.0.0--2.0.2.sql b/gpp/postgis_extension/postgis_topology--2.0.0--2.0.2.sql
index 80c44f9..a257064 100644
--- a/gcc/postgis_extension/postgis_topology--2.0.0--2.0.2.sql
+++ b/gpp/postgis_extension/postgis_topology--2.0.0--2.0.2.sql
@@ -100,14 +100,12 @@ LANGUAGE plpgsql VOLATILE;
-- during upgrade
SELECT postgis_extension_remove_objects('postgis_topology', 'FUNCTION');
SELECT postgis_extension_remove_objects('postgis_topology', 'AGGREGATE');
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: topology.sql.in.c 10643 2012-11-05 10:25:41Z strk $
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -306,6 +304,23 @@ SELECT postgis_extension_remove_objects('postgis_topology', 'AGGREGATE');
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-- Doing everything outside of a transaction helps
-- upgrading in the best case.
@@ -481,7 +496,9 @@ ALTER DOMAIN topology.TopoElement ADD
array_lower(VALUE, 1) = 1
);
ALTER DOMAIN topology.TopoElement DROP CONSTRAINT
+
IF EXISTS
+
type_range;
ALTER DOMAIN topology.TopoElement ADD
CONSTRAINT type_range CHECK (
@@ -777,6 +794,7 @@ BEGIN
-- corrupting the topology anyway ...
--
+
RETURN newlayer_id;
END;
$$
@@ -1120,6 +1138,7 @@ BEGIN
|| ') as obj ORDER BY obj';
+
-- TODO: why not using array_agg here ?
i = 1;
@@ -1517,7 +1536,7 @@ BEGIN
--
-- Closed lines have no boundary, so endpoint
-- intersection would be considered interior
- -- See http://trac.osgeo.org/postgis/ticket/770
+ -- See http:
-- See also full explanation in topology.AddEdge
--
@@ -1681,6 +1700,7 @@ BEGIN
END LOOP;
+
DROP TABLE face_check;
RETURN;
@@ -1910,7 +1930,7 @@ BEGIN
------- Indexes on left_face and right_face of edge_data
------- NOTE: these indexes speed up GetFaceGeometry (and thus
------- TopoGeometry::Geometry) by a factor of 10 !
- ------- See http://trac.osgeo.org/postgis/ticket/806
+ ------- See http:
EXECUTE 'CREATE INDEX edge_left_face_idx ON '
|| quote_ident(atopology)
|| '.edge_data (left_face);';
@@ -1921,7 +1941,7 @@ BEGIN
------- Indexes on start_node and end_node of edge_data
------- NOTE: this indexes speed up node deletion
------- by a factor of 1000 !
- ------- See http://trac.osgeo.org/postgis/ticket/2082
+ ------- See http:
EXECUTE 'CREATE INDEX edge_start_node_idx ON '
|| quote_ident(atopology)
|| '.edge_data (start_node);';
@@ -2029,7 +2049,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -2180,10 +2200,11 @@ $$
LANGUAGE 'plpgsql' STABLE STRICT;
--} TopologySummary
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -2280,11 +2301,12 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
--} TopologySummary
+
-- Spatial predicates
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011-2012 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -2798,11 +2820,12 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--} equals(TopoGeometry, TopoGeometry)
+
-- Querying
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -2888,10 +2911,11 @@ $$
LANGUAGE 'plpgsql' STABLE STRICT;
--} GetNodeByPoint
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -2979,10 +3003,11 @@ END
$$
LANGUAGE 'plpgsql' STABLE STRICT;
--} GetEdgeByPoint
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -3138,11 +3163,12 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--} GetFaceByPoint
+
-- Populating
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010-2012 Sandro Santilli <strk@keybit.net>
--
@@ -3163,7 +3189,7 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--
--
-- A pragmatic test conducted using algoritm shown here:
--- http://stackoverflow.com/questions/7408407/generate-next-largest-or-smallest-representable-floating-point-number-without-bi
+-- http:
-- showed the "tolerance" growing by an order of magnitude proportionally
-- with the order of magnitude of the input, starting with something like
-- 3.5527136788005009294e-15 for the starting value of 9.0
@@ -3219,7 +3245,7 @@ $$ LANGUAGE 'plpgsql' STABLE STRICT;
-- The newly added nodes have no containing face.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3287,6 +3313,7 @@ BEGIN
IF setContainingFace THEN
containing_face := topology.GetFaceByPoint(atopology, apoint, 0);
+
ELSE
containing_face := NULL;
END IF;
@@ -3346,7 +3373,7 @@ LANGUAGE 'sql' VOLATILE;
-- Calling code is expected to do further linking.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3435,6 +3462,7 @@ BEGIN
-- Reuse an EQUAL edge (be it closed or not)
IF ST_RelateMatch(rec.im, '1FFF*FFF2') THEN
+
RETURN rec.edge_id;
END IF;
@@ -3539,7 +3567,7 @@ LANGUAGE 'plpgsql' VOLATILE;
-- o The polygon overlaps an existing face.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3661,6 +3689,7 @@ BEGIN
ST_Line_Locate_Point(bounds, p2);
+
IF right_side THEN
right_edges := array_append(right_edges, rec.edge_id);
old_faceid = rec.right_face;
@@ -3687,6 +3716,8 @@ BEGIN
END IF;
+
+
--
-- Check that all edges found, taken togheter,
-- fully match the ring boundary and nothing more
@@ -3706,8 +3737,10 @@ BEGIN
IF faceid IS NOT NULL AND faceid != 0 THEN
IF NOT force_new THEN
+
RETURN faceid;
ELSE
+
END IF;
END IF;
@@ -3834,12 +3867,14 @@ BEGIN
|| tol || ') ORDER BY ST_Distance('
|| quote_literal(apoint::text)
|| '::geometry, a.geom) LIMIT 1;';
+
EXECUTE sql INTO id;
IF id IS NOT NULL THEN
RETURN id;
END IF;
+
-- 2. Check if any existing edge falls within tolerance
-- and if so split it by a point projected on it
sql := 'SELECT a.edge_id, a.geom FROM '
@@ -3849,35 +3884,42 @@ BEGIN
|| tol || ') ORDER BY ST_Distance('
|| quote_literal(apoint::text)
|| '::geometry, a.geom) LIMIT 1;';
+
EXECUTE sql INTO rec;
IF rec IS NOT NULL THEN
-- project point to line, split edge by point
prj := ST_ClosestPoint(rec.geom, apoint);
-- This is a workaround for ClosestPoint lack of Z support:
- -- http://trac.osgeo.org/postgis/ticket/2033
+ -- http:
z := ST_Z(apoint);
IF z IS NOT NULL THEN
prj := ST_Translate(ST_Force_3DZ(prj), 0, 0, z); -- no ST_SetZ ...
END IF;
+
IF NOT ST_Contains(rec.geom, prj) THEN
+
-- The tolerance must be big enough for snapping to happen
-- and small enough to snap only to the projected point.
-- Unfortunately ST_Distance returns 0 because it also uses
-- a projected point internally, so we need another way.
snaptol := topology._st_mintolerance(prj);
+
snapedge := ST_Snap(rec.geom, prj, snaptol);
-- Snapping currently snaps the first point below tolerance
-- so may possibly move first point. See ticket #1631
IF NOT ST_Equals(ST_StartPoint(rec.geom), ST_StartPoint(snapedge))
THEN
+
snapedge := ST_MakeLine(ST_StartPoint(rec.geom), snapedge);
END IF;
+
PERFORM ST_ChangeEdgeGeom(atopology, rec.edge_id, snapedge);
END IF;
id := topology.ST_ModEdgeSplit(atopology, rec.edge_id, prj);
ELSE
+
id := topology.ST_AddIsoNode(atopology, NULL, apoint);
END IF;
@@ -3923,6 +3965,7 @@ BEGIN
-- 1. Self-node
noded := ST_UnaryUnion(aline);
+
-- 2. Node to edges falling within tol distance
sql := 'WITH nearby AS ( SELECT e.geom FROM '
|| quote_ident(atopology)
@@ -3930,20 +3973,27 @@ BEGIN
|| quote_literal(noded::text)
|| '::geometry, '
|| tol || ') ) SELECT st_collect(geom) FROM nearby;';
+
EXECUTE sql INTO iedges;
IF iedges IS NOT NULL THEN
+
snapped := ST_Snap(noded, iedges, tol);
+
noded := ST_Difference(snapped, iedges);
+
set1 := ST_Intersection(snapped, iedges);
+
set2 := ST_LineMerge(set1);
+
noded := ST_Union(noded, set2);
+
END IF;
-- 2.1. Node with existing nodes within tol
@@ -3954,26 +4004,32 @@ BEGIN
|| quote_literal(noded::text)
|| '::geometry, '
|| tol || ') ) SELECT st_collect(geom) FROM nearby;';
+
EXECUTE sql INTO inodes;
IF inodes IS NOT NULL THEN -- {
+
-- TODO: consider snapping once against all elements
--- (rather than once with edges and once with nodes)
noded := ST_Snap(noded, inodes, tol);
+
FOR rec IN SELECT (ST_Dump(inodes)).*
LOOP
-- Use the node to split edges
SELECT ST_Collect(geom)
FROM ST_Dump(ST_Split(noded, rec.geom))
INTO STRICT noded;
+
END LOOP;
+
-- re-node to account for ST_Snap introduced self-intersections
- -- See http://trac.osgeo.org/postgis/ticket/1714
+ -- See http:
-- TODO: consider running UnaryUnion once after all noding
noded := ST_UnaryUnion(noded);
+
END IF; -- }
-- 3. For each (now-noded) segment, insert an edge
@@ -3982,14 +4038,17 @@ BEGIN
-- TODO: skip point elements ?
+
start_node := topology.TopoGeo_AddPoint(atopology,
ST_StartPoint(rec.geom),
tol);
+
end_node := topology.TopoGeo_AddPoint(atopology,
ST_EndPoint(rec.geom),
tol);
+
-- Added endpoints may have drifted due to tolerance, so
-- we need to re-snap the edge to the new nodes before adding it
sql := 'SELECT n1.geom as sn, n2.geom as en FROM ' || quote_ident(atopology)
@@ -3997,6 +4056,7 @@ BEGIN
|| '.node n2 WHERE n1.node_id = '
|| start_node || ' AND n2.node_id = ' || end_node;
+
EXECUTE sql INTO STRICT rec2;
snapped := ST_SetPoint(
@@ -4007,8 +4067,10 @@ BEGIN
snapped := ST_CollectionExtract(ST_MakeValid(snapped), 2);
+
-- Check if the so-snapped edge collapsed (see #1650)
IF ST_IsEmpty(snapped) THEN
+
CONTINUE;
END IF;
@@ -4016,11 +4078,14 @@ BEGIN
sql := 'SELECT edge_id FROM ' || quote_ident(atopology)
|| '.edge_data WHERE ST_Equals(geom, ' || quote_literal(snapped::text)
|| '::geometry)';
+
EXECUTE sql INTO id;
IF id IS NULL THEN
id := topology.ST_AddEdgeModFace(atopology, start_node, end_node,
snapped);
+
ELSE
+
END IF;
RETURN NEXT id;
@@ -4062,9 +4127,11 @@ BEGIN
-- 1. Extract boundary
boundary := ST_Boundary(apoly);
+
-- 2. Add boundaries as edges
FOR rec IN SELECT (ST_Dump(boundary)).geom LOOP
edges := array_cat(edges, array_agg(x)) FROM ( select topology.TopoGeo_addLinestring(atopology, rec.geom, tol) as x ) as foo;
+
END LOOP;
-- 3. Find faces covered by input polygon
@@ -4073,10 +4140,12 @@ BEGIN
|| '.face f WHERE f.mbr && '
|| quote_literal(apoly::text)
|| '::geometry';
+
FOR rec IN EXECUTE sql LOOP
-- check for actual containment
fgeom := ST_PointOnSurface(ST_GetFaceGeometry(atopology, rec.face_id));
IF NOT ST_Covers(apoly, fgeom) THEN
+
CONTINUE;
END IF;
RETURN NEXT rec.face_id;
@@ -4102,10 +4171,11 @@ END
$$
LANGUAGE 'plpgsql';
--} TopoGeo_AddGeometry
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4154,11 +4224,12 @@ $$
LANGUAGE 'plpgsql';
--} Polygonize(toponame)
+
-- TopoElement
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4172,7 +4243,7 @@ LANGUAGE 'plpgsql';
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -4214,11 +4285,12 @@ CREATE AGGREGATE topology.TopoElementArray_agg(
);
--} TopoElementArray_agg
+
-- TopoGeometry
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4274,10 +4346,11 @@ $$
$$
LANGUAGE 'sql' STABLE STRICT;
-- }
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011-2012 Sandro Santilli <strk@keybit.net>
--
@@ -4289,7 +4362,7 @@ LANGUAGE 'sql' STABLE STRICT;
-- {
-- Convert a simple geometry to a topologically-defined one
--
--- See http://trac.osgeo.org/postgis/ticket/1017
+-- See http:
--
-- }{
CREATE OR REPLACE FUNCTION topology.toTopoGeom(ageom Geometry, atopology varchar, alayer int, atolerance float8 DEFAULT 0)
@@ -4414,6 +4487,7 @@ BEGIN
|| '.relation(topogeo_id, layer_id, element_type, element_id) VALUES ('
|| rec.id || ',' || rec.lyr || ',' || rec.type
|| ',' || rec.primitive || ')';
+
EXECUTE sql;
END LOOP;
@@ -4424,11 +4498,12 @@ $$
LANGUAGE 'plpgsql' VOLATILE STRICT;
-- }
+
-- GML
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4442,7 +4517,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -4989,13 +5064,14 @@ $$ LANGUAGE 'sql' STABLE; -- does NOT write into visited table
-- } AsGML(TopoGeometry)
+
--=} POSTGIS-SPECIFIC block
-- SQL/MM block
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011, 2012 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -5101,6 +5177,7 @@ BEGIN
LOOP
+
retrec.sequence = n;
retrec.edge = rec.edge_id;
@@ -5399,6 +5476,7 @@ BEGIN
|| ' AND l.layer_id = r.layer_id AND abs(r.element_id) = '
|| e1id
;
+
EXECUTE sql;
@@ -5747,6 +5825,7 @@ BEGIN
|| 'WHERE l.level = 0 AND l.feature_type = 2 '
|| ' AND l.topology_id = ' || topoid
|| ' AND abs(r.element_id) = ' || e1id ;
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented dropping edge %',
rec.topogeo_id, rec.layer_id,
@@ -5771,6 +5850,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge < 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -5788,6 +5868,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge > 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -5803,6 +5884,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge < 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -5820,6 +5902,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge > 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -5865,6 +5948,7 @@ BEGIN
END IF; -- }
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented healing faces % and %',
rec.topogeo_id, rec.layer_id,
@@ -5907,6 +5991,7 @@ BEGIN
|| '.face WHERE face_id IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
END IF; -- }
@@ -5917,6 +6002,7 @@ BEGIN
|| ' WHERE left_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update right_face for all edges still referencing old faces
@@ -5925,6 +6011,7 @@ BEGIN
|| ' WHERE right_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update containing_face for all nodes still referencing old faces
@@ -5933,6 +6020,7 @@ BEGIN
|| ' WHERE containing_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- NOT IN THE SPECS:
@@ -5945,6 +6033,7 @@ BEGIN
|| ' AND l.topology_id = ' || topoid
|| ' AND l.layer_id = r.layer_id AND abs(r.element_id) = '
|| e1rec.left_face;
+
EXECUTE sql;
sql := 'UPDATE ' || quote_ident(toponame)
|| '.relation r '
@@ -5953,6 +6042,7 @@ BEGIN
|| ' AND l.topology_id = ' || topoid
|| ' AND l.layer_id = r.layer_id AND r.element_id = '
|| e1rec.right_face;
+
EXECUTE sql;
END IF; -- } two faces healed...
@@ -5960,6 +6050,7 @@ BEGIN
-- Delete the edge
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.edge_data WHERE edge_id = ' || e1id;
+
EXECUTE sql;
-- Check if any of the edge nodes remains isolated,
@@ -5971,6 +6062,7 @@ BEGIN
|| e1rec.end_node || ') AND NOT EXISTS (SELECT edge_id FROM '
|| quote_ident(toponame)
|| '.edge_data WHERE start_node = n.node_id OR end_node = n.node_id)';
+
EXECUTE sql;
IF e1rec.right_face != e1rec.left_face THEN -- {
@@ -5979,6 +6071,7 @@ BEGIN
IF e1rec.left_face != 0 THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.left_face;
+
EXECUTE sql;
END IF;
@@ -5987,6 +6080,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.right_face;
+
EXECUTE sql;
END IF;
@@ -6071,6 +6165,7 @@ BEGIN
|| 'WHERE l.level = 0 AND l.feature_type = 2 '
|| ' AND l.topology_id = ' || topoid
|| ' AND abs(r.element_id) = ' || e1id ;
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented dropping edge %',
rec.topogeo_id, rec.layer_id,
@@ -6095,6 +6190,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge < 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -6112,6 +6208,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge > 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -6127,6 +6224,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge < 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -6144,6 +6242,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge > 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -6187,6 +6286,7 @@ BEGIN
END IF; -- }
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented healing faces % and %',
rec.topogeo_id, rec.layer_id,
@@ -6219,6 +6319,7 @@ BEGIN
|| '.face WHERE face_id IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ') ) WHERE face_id = ' || floodfaceid ;
+
EXECUTE sql;
END IF; -- }
@@ -6229,6 +6330,7 @@ BEGIN
|| ' WHERE left_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update right_face for all edges still referencing old faces
@@ -6237,6 +6339,7 @@ BEGIN
|| ' WHERE right_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update containing_face for all nodes still referencing old faces
@@ -6245,6 +6348,7 @@ BEGIN
|| ' WHERE containing_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- NOT IN THE SPECS:
@@ -6259,6 +6363,7 @@ BEGIN
|| e1rec.left_face || ',' || e1rec.right_face
|| ') AND abs(r.element_id) != '
|| floodfaceid; -- could be optimized..
+
EXECUTE sql;
END IF; -- } two faces healed...
@@ -6266,6 +6371,7 @@ BEGIN
-- Delete the edge
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.edge_data WHERE edge_id = ' || e1id;
+
EXECUTE sql;
-- Check if any of the edge nodes remains isolated,
@@ -6277,6 +6383,7 @@ BEGIN
|| e1rec.end_node || ') AND NOT EXISTS (SELECT edge_id FROM '
|| quote_ident(toponame)
|| '.edge_data WHERE start_node = n.node_id OR end_node = n.node_id)';
+
EXECUTE sql;
IF e1rec.right_face != e1rec.left_face THEN -- {
@@ -6286,6 +6393,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.left_face;
+
EXECUTE sql;
END IF;
@@ -6294,6 +6402,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.right_face;
+
EXECUTE sql;
END IF;
@@ -6451,6 +6560,7 @@ BEGIN
sql := sql || ' AND f.face_id = ' || aface;
END IF;
+
EXECUTE sql INTO containingface;
-- If aface was specified, check that it was correct
@@ -6484,6 +6594,7 @@ BEGIN
|| '::geometry,' || containingface
|| ' RETURNING node_id';
+
EXECUTE sql INTO nodeid;
RETURN nodeid;
@@ -6624,7 +6735,7 @@ LANGUAGE 'plpgsql' VOLATILE;
--} ST_RemoveIsoNode
--{
--- According to http://trac.osgeo.org/postgis/ticket/798
+-- According to http:
-- ST_RemoveIsoNode was renamed to ST_RemIsoNode in the final ISO
-- document
--
@@ -6826,6 +6937,7 @@ BEGIN
END LOOP;
+
--RAISE NOTICE 'EdgeId1 % EdgeId2 %', edgeid1, edgeid2;
--RAISE DEBUG 'oldedge.next_left_edge: %', oldedge.next_left_edge;
@@ -7111,6 +7223,7 @@ BEGIN
END LOOP;
+
--
-- Insert the new edge
--
@@ -7618,25 +7731,32 @@ BEGIN
tmp1 := ST_MakeLine(ST_EndPoint(oldedge.geom), ST_StartPoint(oldedge.geom));
+
tmp2 := ST_MakeLine(oldedge.geom, tmp1);
IF ST_NumPoints(tmp2) < 4 THEN
tmp2 := ST_AddPoint(tmp2, ST_StartPoint(oldedge.geom));
END IF;
+
tmp2 := ST_CollectionExtract(ST_MakeValid(ST_MakePolygon(tmp2)), 3);
+
range := ST_MakeLine(acurve, tmp1);
IF ST_NumPoints(range) < 4 THEN
range := ST_AddPoint(range, ST_StartPoint(oldedge.geom));
END IF;
+
range := ST_CollectionExtract(ST_MakeValid(ST_MakePolygon(range)), 3);
+
range := ST_SymDifference(range, tmp2);
+
sql := 'SELECT node_id, geom FROM '
|| quote_ident(atopology)
|| '.node WHERE ST_Contains('
|| quote_literal(range::text)
|| '::geometry, geom) LIMIT 1';
+
FOR rec IN EXECUTE sql LOOP -- {
RAISE EXCEPTION 'Edge motion collision at %', ST_AsText(rec.geom);
END LOOP; -- }
@@ -7652,11 +7772,13 @@ BEGIN
) as pre, NULL::integer[] as post
INTO STRICT snode_info;
+
SELECT topology._ST_AdjacentEdges(
atopology, oldedge.end_node, -anedge
) as pre, NULL::integer[] as post
INTO STRICT enode_info;
+
--}
--
@@ -7674,10 +7796,12 @@ BEGIN
atopology, oldedge.start_node, anedge
);
+
enode_info.post := topology._ST_AdjacentEdges(
atopology, oldedge.end_node, -anedge
);
+
IF snode_info.pre != snode_info.post THEN
RAISE EXCEPTION 'Edge changed disposition around start node %',
oldedge.start_node;
@@ -7754,6 +7878,7 @@ DECLARE
BEGIN
IF oface = 0 AND mbr_only THEN
+
RETURN NULL;
END IF;
@@ -7766,24 +7891,31 @@ BEGIN
INTO STRICT fan.newring_edges;
+
-- You can't get to the other side of an edge forming a ring
IF fan.newring_edges @> ARRAY[-anedge] THEN
+
RETURN 0;
END IF;
+
sql := 'WITH ids as ( select row_number() over () as seq, edge from unnest('
|| quote_literal(fan.newring_edges::text)
|| '::int[] ) u(edge) ), edges AS ( select CASE WHEN i.edge < 0 THEN ST_Reverse(e.geom) ELSE e.geom END as g FROM ids i left join '
|| quote_ident(atopology) || '.edge_data e ON(e.edge_id = abs(i.edge)) ORDER BY seq) SELECT ST_MakePolygon(ST_MakeLine(g.g)) FROM edges g;';
+
EXECUTE sql INTO fan.shell;
+
isccw := NOT ST_OrderingEquals(fan.shell, ST_ForceRHR(fan.shell));
+
IF oface = 0 THEN
IF NOT isccw THEN
+
RETURN NULL;
END IF;
END IF;
@@ -7795,6 +7927,7 @@ BEGIN
|| quote_ident(atopology) || '.face SET mbr = '
|| quote_literal(ST_Envelope(fan.shell)::text)
|| '::geometry WHERE face_id = ' || oface;
+
EXECUTE sql;
END IF; -- }
RETURN NULL;
@@ -7815,6 +7948,7 @@ BEGIN
END IF; -- }
-- Insert new face
+
EXECUTE sql INTO STRICT newface;
-- Update forward edges
@@ -7823,6 +7957,7 @@ BEGIN
|| ' WHERE left_face = ' || oface || ' AND edge_id = ANY ('
|| quote_literal(array( select +(x) from unnest(fan.newring_edges) u(x) )::text)
|| ')';
+
EXECUTE sql;
-- Update backward edges
@@ -7831,12 +7966,15 @@ BEGIN
|| ' WHERE right_face = ' || oface || ' AND edge_id = ANY ('
|| quote_literal(array( select -(x) from unnest(fan.newring_edges) u(x) )::text)
|| ')';
+
EXECUTE sql;
IF oface != 0 AND NOT isccw THEN -- {
-- face shrinked, must update all non-contained edges and nodes
+
ishole := true;
ELSE
+
ishole := false;
END IF; -- }
@@ -7858,6 +7996,7 @@ BEGIN
sql := sql || 'ST_Contains(' || quote_literal(fan.shell::text)
-- We only need to check a single point, but must not be an endpoint
|| '::geometry, ST_Line_Interpolate_Point(geom, 0.2))';
+
EXECUTE sql;
-- Update isolated nodes in new new face
@@ -7867,6 +8006,7 @@ BEGIN
|| ' AND ';
IF ishole THEN sql := sql || 'NOT '; END IF;
sql := sql || 'ST_Contains(' || quote_literal(fan.shell::text) || '::geometry, geom)';
+
EXECUTE sql;
RETURN newface;
@@ -7990,6 +8130,7 @@ BEGIN
|| ')'
LOOP
IF rec.containing_face IS NOT NULL THEN
+
IF newedge.left_face IS NULL THEN
newedge.left_face := rec.containing_face;
newedge.right_face := rec.containing_face;
@@ -8097,6 +8238,7 @@ BEGIN
-- Find links on start node -- {
+
sql :=
'SELECT edge_id, -1 AS end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8142,6 +8284,7 @@ BEGIN
END IF;
+
az = az - span.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8181,6 +8324,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN span.was_isolated = true; END IF;
ELSE
@@ -8197,12 +8341,16 @@ BEGIN
END IF;
+
+
+
-- } start_node analysis
-- Find links on end_node {
+
sql :=
'SELECT edge_id, -1 as end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8244,6 +8392,7 @@ BEGIN
END IF;
+
az := az - epan.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8283,6 +8432,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN epan.was_isolated = true; END IF;
ELSE
@@ -8301,6 +8451,9 @@ BEGIN
-- } end_node analysis
+
+
+
----------------------------------------------------------------------
--
-- If we don't have faces setup by now we must have encountered
@@ -8396,15 +8549,18 @@ BEGIN
--------------------------------------------
+
SELECT topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, false)
INTO newface;
IF newface = 0 THEN
+
RETURN newedge.edge_id;
END IF;
newfaces[1] := newface;
+
SELECT topology._ST_AddFaceSplit(atopology, newedge.edge_id, newedge.left_face, false)
INTO newface;
@@ -8427,6 +8583,7 @@ BEGIN
FOR rec IN EXECUTE sql
LOOP
+
-- Add reference to the other face
sql := 'INSERT INTO ' || quote_ident(atopology)
|| '.relation VALUES( ' || rec.topogeo_id
@@ -8564,6 +8721,7 @@ BEGIN
|| ')'
LOOP
IF rec.containing_face IS NOT NULL THEN
+
IF newedge.left_face IS NULL THEN
newedge.left_face := rec.containing_face;
newedge.right_face := rec.containing_face;
@@ -8669,6 +8827,7 @@ BEGIN
-- Find links on start node -- {
+
sql :=
'SELECT edge_id, -1 AS end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8714,6 +8873,7 @@ BEGIN
END IF;
+
az = az - span.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8753,6 +8913,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN span.was_isolated = true; END IF;
ELSE
@@ -8769,12 +8930,16 @@ BEGIN
END IF;
+
+
+
-- } start_node analysis
-- Find links on end_node {
+
sql :=
'SELECT edge_id, -1 as end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8816,6 +8981,7 @@ BEGIN
END IF;
+
az := az - epan.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8855,6 +9021,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN epan.was_isolated = true; END IF;
ELSE
@@ -8873,6 +9040,9 @@ BEGIN
-- } end_node analysis
+
+
+
----------------------------------------------------------------------
--
-- If we don't have faces setup by now we must have encountered
@@ -8967,20 +9137,25 @@ BEGIN
-- Check face splitting
--------------------------------------------
+
SELECT topology._ST_AddFaceSplit(atopology, newedge.edge_id, newedge.left_face, false)
INTO newface;
IF newface = 0 THEN
+
RETURN newedge.edge_id;
END IF;
IF newface IS NULL THEN -- must be forming a maximal ring in universal face
+
SELECT topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, false)
INTO newface;
ELSE
+
PERFORM topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, true);
END IF;
IF newface IS NULL THEN
+
RETURN newedge.edge_id;
END IF;
@@ -9004,6 +9179,7 @@ BEGIN
FOR rec IN EXECUTE sql
LOOP
+
-- Add reference to the other face
sql := 'INSERT INTO ' || quote_ident(atopology)
|| '.relation VALUES( ' || rec.topogeo_id
@@ -9134,6 +9310,7 @@ BEGIN
END; -- }
+
--
-- Node input linework with itself
--
@@ -9147,6 +9324,7 @@ BEGIN
) as linework INTO STRICT nodededges;
+
--
-- Linemerge the resulting edges, to reduce the working set
-- NOTE: this is more of a workaround for GEOS splitting overlapping
@@ -9156,6 +9334,7 @@ BEGIN
+
--
-- Collect input points and input lines endpoints
--
@@ -9169,6 +9348,7 @@ BEGIN
) as nodes INTO STRICT points;
+
--
-- Further split edges by points
-- TODO: optimize this adding ST_Split support for multiline/multipoint
@@ -9183,6 +9363,7 @@ BEGIN
SELECT ST_UnaryUnion(nodededges) INTO STRICT nodededges;
+
--
-- Collect all nodes (from points and noded linework endpoints)
--
@@ -9201,6 +9382,7 @@ BEGIN
) as endpoints INTO points;
+
--
-- Add all nodes as isolated so that
-- later calls to AddEdgeModFace will tweak their being
@@ -9231,11 +9413,12 @@ LANGUAGE 'plpgsql' VOLATILE;
--=} SQL/MM block
+
-- The following files needs getfaceedges_returntype, defined in sqlmm.sql
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 2012 Sandro Santilli <strk@keybit.net>
--
@@ -9245,7 +9428,7 @@ LANGUAGE 'plpgsql' VOLATILE;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -9312,10 +9495,11 @@ END
$$
LANGUAGE 'plpgsql' STABLE;
--} GetRingEdges
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2012 Sandro Santilli <strk@keybit.net>
--
@@ -9356,9 +9540,11 @@ BEGIN
|| ' UNION ALL SELECT -edge_id, ST_Azimuth(ST_EndPoint(geom), ST_PointN(geom, ST_NumPoints(geom)-1)) FROM incident_edges WHERE end_node = ' || anode
|| ' ORDER BY az';
+
FOR rec IN EXECUTE sql
LOOP -- incident edges {
+
n := n + 1;
retrec.sequence := n;
retrec.edge := rec.edge_id;
@@ -9370,11 +9556,12 @@ $$
LANGUAGE 'plpgsql' STABLE;
--} GetRingEdges
+
--general management --
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://www.postgis.org
+-- http:
--
-- Copyright (C) 2011 Regina Obe <lr@pcorp.us>
--
@@ -9413,6 +9600,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
--} AddToSearchPath
+
CREATE OR REPLACE FUNCTION postgis_topology_scripts_installed() RETURNS text
AS $$ SELECT '2.0.2'::text || ' r' || 10789::text AS version $$
LANGUAGE 'sql' IMMUTABLE;
diff --git a/gcc/postgis_extension/postgis_topology--2.0.0alpha1--2.0.2.sql b/gpp/postgis_extension/postgis_topology--2.0.0alpha1--2.0.2.sql
index 80c44f9..a257064 100644
--- a/gcc/postgis_extension/postgis_topology--2.0.0alpha1--2.0.2.sql
+++ b/gpp/postgis_extension/postgis_topology--2.0.0alpha1--2.0.2.sql
@@ -100,14 +100,12 @@ LANGUAGE plpgsql VOLATILE;
-- during upgrade
SELECT postgis_extension_remove_objects('postgis_topology', 'FUNCTION');
SELECT postgis_extension_remove_objects('postgis_topology', 'AGGREGATE');
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: topology.sql.in.c 10643 2012-11-05 10:25:41Z strk $
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -306,6 +304,23 @@ SELECT postgis_extension_remove_objects('postgis_topology', 'AGGREGATE');
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-- Doing everything outside of a transaction helps
-- upgrading in the best case.
@@ -481,7 +496,9 @@ ALTER DOMAIN topology.TopoElement ADD
array_lower(VALUE, 1) = 1
);
ALTER DOMAIN topology.TopoElement DROP CONSTRAINT
+
IF EXISTS
+
type_range;
ALTER DOMAIN topology.TopoElement ADD
CONSTRAINT type_range CHECK (
@@ -777,6 +794,7 @@ BEGIN
-- corrupting the topology anyway ...
--
+
RETURN newlayer_id;
END;
$$
@@ -1120,6 +1138,7 @@ BEGIN
|| ') as obj ORDER BY obj';
+
-- TODO: why not using array_agg here ?
i = 1;
@@ -1517,7 +1536,7 @@ BEGIN
--
-- Closed lines have no boundary, so endpoint
-- intersection would be considered interior
- -- See http://trac.osgeo.org/postgis/ticket/770
+ -- See http:
-- See also full explanation in topology.AddEdge
--
@@ -1681,6 +1700,7 @@ BEGIN
END LOOP;
+
DROP TABLE face_check;
RETURN;
@@ -1910,7 +1930,7 @@ BEGIN
------- Indexes on left_face and right_face of edge_data
------- NOTE: these indexes speed up GetFaceGeometry (and thus
------- TopoGeometry::Geometry) by a factor of 10 !
- ------- See http://trac.osgeo.org/postgis/ticket/806
+ ------- See http:
EXECUTE 'CREATE INDEX edge_left_face_idx ON '
|| quote_ident(atopology)
|| '.edge_data (left_face);';
@@ -1921,7 +1941,7 @@ BEGIN
------- Indexes on start_node and end_node of edge_data
------- NOTE: this indexes speed up node deletion
------- by a factor of 1000 !
- ------- See http://trac.osgeo.org/postgis/ticket/2082
+ ------- See http:
EXECUTE 'CREATE INDEX edge_start_node_idx ON '
|| quote_ident(atopology)
|| '.edge_data (start_node);';
@@ -2029,7 +2049,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -2180,10 +2200,11 @@ $$
LANGUAGE 'plpgsql' STABLE STRICT;
--} TopologySummary
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -2280,11 +2301,12 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
--} TopologySummary
+
-- Spatial predicates
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011-2012 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -2798,11 +2820,12 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--} equals(TopoGeometry, TopoGeometry)
+
-- Querying
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -2888,10 +2911,11 @@ $$
LANGUAGE 'plpgsql' STABLE STRICT;
--} GetNodeByPoint
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -2979,10 +3003,11 @@ END
$$
LANGUAGE 'plpgsql' STABLE STRICT;
--} GetEdgeByPoint
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -3138,11 +3163,12 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--} GetFaceByPoint
+
-- Populating
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010-2012 Sandro Santilli <strk@keybit.net>
--
@@ -3163,7 +3189,7 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--
--
-- A pragmatic test conducted using algoritm shown here:
--- http://stackoverflow.com/questions/7408407/generate-next-largest-or-smallest-representable-floating-point-number-without-bi
+-- http:
-- showed the "tolerance" growing by an order of magnitude proportionally
-- with the order of magnitude of the input, starting with something like
-- 3.5527136788005009294e-15 for the starting value of 9.0
@@ -3219,7 +3245,7 @@ $$ LANGUAGE 'plpgsql' STABLE STRICT;
-- The newly added nodes have no containing face.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3287,6 +3313,7 @@ BEGIN
IF setContainingFace THEN
containing_face := topology.GetFaceByPoint(atopology, apoint, 0);
+
ELSE
containing_face := NULL;
END IF;
@@ -3346,7 +3373,7 @@ LANGUAGE 'sql' VOLATILE;
-- Calling code is expected to do further linking.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3435,6 +3462,7 @@ BEGIN
-- Reuse an EQUAL edge (be it closed or not)
IF ST_RelateMatch(rec.im, '1FFF*FFF2') THEN
+
RETURN rec.edge_id;
END IF;
@@ -3539,7 +3567,7 @@ LANGUAGE 'plpgsql' VOLATILE;
-- o The polygon overlaps an existing face.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3661,6 +3689,7 @@ BEGIN
ST_Line_Locate_Point(bounds, p2);
+
IF right_side THEN
right_edges := array_append(right_edges, rec.edge_id);
old_faceid = rec.right_face;
@@ -3687,6 +3716,8 @@ BEGIN
END IF;
+
+
--
-- Check that all edges found, taken togheter,
-- fully match the ring boundary and nothing more
@@ -3706,8 +3737,10 @@ BEGIN
IF faceid IS NOT NULL AND faceid != 0 THEN
IF NOT force_new THEN
+
RETURN faceid;
ELSE
+
END IF;
END IF;
@@ -3834,12 +3867,14 @@ BEGIN
|| tol || ') ORDER BY ST_Distance('
|| quote_literal(apoint::text)
|| '::geometry, a.geom) LIMIT 1;';
+
EXECUTE sql INTO id;
IF id IS NOT NULL THEN
RETURN id;
END IF;
+
-- 2. Check if any existing edge falls within tolerance
-- and if so split it by a point projected on it
sql := 'SELECT a.edge_id, a.geom FROM '
@@ -3849,35 +3884,42 @@ BEGIN
|| tol || ') ORDER BY ST_Distance('
|| quote_literal(apoint::text)
|| '::geometry, a.geom) LIMIT 1;';
+
EXECUTE sql INTO rec;
IF rec IS NOT NULL THEN
-- project point to line, split edge by point
prj := ST_ClosestPoint(rec.geom, apoint);
-- This is a workaround for ClosestPoint lack of Z support:
- -- http://trac.osgeo.org/postgis/ticket/2033
+ -- http:
z := ST_Z(apoint);
IF z IS NOT NULL THEN
prj := ST_Translate(ST_Force_3DZ(prj), 0, 0, z); -- no ST_SetZ ...
END IF;
+
IF NOT ST_Contains(rec.geom, prj) THEN
+
-- The tolerance must be big enough for snapping to happen
-- and small enough to snap only to the projected point.
-- Unfortunately ST_Distance returns 0 because it also uses
-- a projected point internally, so we need another way.
snaptol := topology._st_mintolerance(prj);
+
snapedge := ST_Snap(rec.geom, prj, snaptol);
-- Snapping currently snaps the first point below tolerance
-- so may possibly move first point. See ticket #1631
IF NOT ST_Equals(ST_StartPoint(rec.geom), ST_StartPoint(snapedge))
THEN
+
snapedge := ST_MakeLine(ST_StartPoint(rec.geom), snapedge);
END IF;
+
PERFORM ST_ChangeEdgeGeom(atopology, rec.edge_id, snapedge);
END IF;
id := topology.ST_ModEdgeSplit(atopology, rec.edge_id, prj);
ELSE
+
id := topology.ST_AddIsoNode(atopology, NULL, apoint);
END IF;
@@ -3923,6 +3965,7 @@ BEGIN
-- 1. Self-node
noded := ST_UnaryUnion(aline);
+
-- 2. Node to edges falling within tol distance
sql := 'WITH nearby AS ( SELECT e.geom FROM '
|| quote_ident(atopology)
@@ -3930,20 +3973,27 @@ BEGIN
|| quote_literal(noded::text)
|| '::geometry, '
|| tol || ') ) SELECT st_collect(geom) FROM nearby;';
+
EXECUTE sql INTO iedges;
IF iedges IS NOT NULL THEN
+
snapped := ST_Snap(noded, iedges, tol);
+
noded := ST_Difference(snapped, iedges);
+
set1 := ST_Intersection(snapped, iedges);
+
set2 := ST_LineMerge(set1);
+
noded := ST_Union(noded, set2);
+
END IF;
-- 2.1. Node with existing nodes within tol
@@ -3954,26 +4004,32 @@ BEGIN
|| quote_literal(noded::text)
|| '::geometry, '
|| tol || ') ) SELECT st_collect(geom) FROM nearby;';
+
EXECUTE sql INTO inodes;
IF inodes IS NOT NULL THEN -- {
+
-- TODO: consider snapping once against all elements
--- (rather than once with edges and once with nodes)
noded := ST_Snap(noded, inodes, tol);
+
FOR rec IN SELECT (ST_Dump(inodes)).*
LOOP
-- Use the node to split edges
SELECT ST_Collect(geom)
FROM ST_Dump(ST_Split(noded, rec.geom))
INTO STRICT noded;
+
END LOOP;
+
-- re-node to account for ST_Snap introduced self-intersections
- -- See http://trac.osgeo.org/postgis/ticket/1714
+ -- See http:
-- TODO: consider running UnaryUnion once after all noding
noded := ST_UnaryUnion(noded);
+
END IF; -- }
-- 3. For each (now-noded) segment, insert an edge
@@ -3982,14 +4038,17 @@ BEGIN
-- TODO: skip point elements ?
+
start_node := topology.TopoGeo_AddPoint(atopology,
ST_StartPoint(rec.geom),
tol);
+
end_node := topology.TopoGeo_AddPoint(atopology,
ST_EndPoint(rec.geom),
tol);
+
-- Added endpoints may have drifted due to tolerance, so
-- we need to re-snap the edge to the new nodes before adding it
sql := 'SELECT n1.geom as sn, n2.geom as en FROM ' || quote_ident(atopology)
@@ -3997,6 +4056,7 @@ BEGIN
|| '.node n2 WHERE n1.node_id = '
|| start_node || ' AND n2.node_id = ' || end_node;
+
EXECUTE sql INTO STRICT rec2;
snapped := ST_SetPoint(
@@ -4007,8 +4067,10 @@ BEGIN
snapped := ST_CollectionExtract(ST_MakeValid(snapped), 2);
+
-- Check if the so-snapped edge collapsed (see #1650)
IF ST_IsEmpty(snapped) THEN
+
CONTINUE;
END IF;
@@ -4016,11 +4078,14 @@ BEGIN
sql := 'SELECT edge_id FROM ' || quote_ident(atopology)
|| '.edge_data WHERE ST_Equals(geom, ' || quote_literal(snapped::text)
|| '::geometry)';
+
EXECUTE sql INTO id;
IF id IS NULL THEN
id := topology.ST_AddEdgeModFace(atopology, start_node, end_node,
snapped);
+
ELSE
+
END IF;
RETURN NEXT id;
@@ -4062,9 +4127,11 @@ BEGIN
-- 1. Extract boundary
boundary := ST_Boundary(apoly);
+
-- 2. Add boundaries as edges
FOR rec IN SELECT (ST_Dump(boundary)).geom LOOP
edges := array_cat(edges, array_agg(x)) FROM ( select topology.TopoGeo_addLinestring(atopology, rec.geom, tol) as x ) as foo;
+
END LOOP;
-- 3. Find faces covered by input polygon
@@ -4073,10 +4140,12 @@ BEGIN
|| '.face f WHERE f.mbr && '
|| quote_literal(apoly::text)
|| '::geometry';
+
FOR rec IN EXECUTE sql LOOP
-- check for actual containment
fgeom := ST_PointOnSurface(ST_GetFaceGeometry(atopology, rec.face_id));
IF NOT ST_Covers(apoly, fgeom) THEN
+
CONTINUE;
END IF;
RETURN NEXT rec.face_id;
@@ -4102,10 +4171,11 @@ END
$$
LANGUAGE 'plpgsql';
--} TopoGeo_AddGeometry
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4154,11 +4224,12 @@ $$
LANGUAGE 'plpgsql';
--} Polygonize(toponame)
+
-- TopoElement
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4172,7 +4243,7 @@ LANGUAGE 'plpgsql';
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -4214,11 +4285,12 @@ CREATE AGGREGATE topology.TopoElementArray_agg(
);
--} TopoElementArray_agg
+
-- TopoGeometry
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4274,10 +4346,11 @@ $$
$$
LANGUAGE 'sql' STABLE STRICT;
-- }
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011-2012 Sandro Santilli <strk@keybit.net>
--
@@ -4289,7 +4362,7 @@ LANGUAGE 'sql' STABLE STRICT;
-- {
-- Convert a simple geometry to a topologically-defined one
--
--- See http://trac.osgeo.org/postgis/ticket/1017
+-- See http:
--
-- }{
CREATE OR REPLACE FUNCTION topology.toTopoGeom(ageom Geometry, atopology varchar, alayer int, atolerance float8 DEFAULT 0)
@@ -4414,6 +4487,7 @@ BEGIN
|| '.relation(topogeo_id, layer_id, element_type, element_id) VALUES ('
|| rec.id || ',' || rec.lyr || ',' || rec.type
|| ',' || rec.primitive || ')';
+
EXECUTE sql;
END LOOP;
@@ -4424,11 +4498,12 @@ $$
LANGUAGE 'plpgsql' VOLATILE STRICT;
-- }
+
-- GML
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4442,7 +4517,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -4989,13 +5064,14 @@ $$ LANGUAGE 'sql' STABLE; -- does NOT write into visited table
-- } AsGML(TopoGeometry)
+
--=} POSTGIS-SPECIFIC block
-- SQL/MM block
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011, 2012 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -5101,6 +5177,7 @@ BEGIN
LOOP
+
retrec.sequence = n;
retrec.edge = rec.edge_id;
@@ -5399,6 +5476,7 @@ BEGIN
|| ' AND l.layer_id = r.layer_id AND abs(r.element_id) = '
|| e1id
;
+
EXECUTE sql;
@@ -5747,6 +5825,7 @@ BEGIN
|| 'WHERE l.level = 0 AND l.feature_type = 2 '
|| ' AND l.topology_id = ' || topoid
|| ' AND abs(r.element_id) = ' || e1id ;
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented dropping edge %',
rec.topogeo_id, rec.layer_id,
@@ -5771,6 +5850,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge < 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -5788,6 +5868,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge > 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -5803,6 +5884,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge < 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -5820,6 +5902,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge > 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -5865,6 +5948,7 @@ BEGIN
END IF; -- }
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented healing faces % and %',
rec.topogeo_id, rec.layer_id,
@@ -5907,6 +5991,7 @@ BEGIN
|| '.face WHERE face_id IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
END IF; -- }
@@ -5917,6 +6002,7 @@ BEGIN
|| ' WHERE left_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update right_face for all edges still referencing old faces
@@ -5925,6 +6011,7 @@ BEGIN
|| ' WHERE right_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update containing_face for all nodes still referencing old faces
@@ -5933,6 +6020,7 @@ BEGIN
|| ' WHERE containing_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- NOT IN THE SPECS:
@@ -5945,6 +6033,7 @@ BEGIN
|| ' AND l.topology_id = ' || topoid
|| ' AND l.layer_id = r.layer_id AND abs(r.element_id) = '
|| e1rec.left_face;
+
EXECUTE sql;
sql := 'UPDATE ' || quote_ident(toponame)
|| '.relation r '
@@ -5953,6 +6042,7 @@ BEGIN
|| ' AND l.topology_id = ' || topoid
|| ' AND l.layer_id = r.layer_id AND r.element_id = '
|| e1rec.right_face;
+
EXECUTE sql;
END IF; -- } two faces healed...
@@ -5960,6 +6050,7 @@ BEGIN
-- Delete the edge
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.edge_data WHERE edge_id = ' || e1id;
+
EXECUTE sql;
-- Check if any of the edge nodes remains isolated,
@@ -5971,6 +6062,7 @@ BEGIN
|| e1rec.end_node || ') AND NOT EXISTS (SELECT edge_id FROM '
|| quote_ident(toponame)
|| '.edge_data WHERE start_node = n.node_id OR end_node = n.node_id)';
+
EXECUTE sql;
IF e1rec.right_face != e1rec.left_face THEN -- {
@@ -5979,6 +6071,7 @@ BEGIN
IF e1rec.left_face != 0 THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.left_face;
+
EXECUTE sql;
END IF;
@@ -5987,6 +6080,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.right_face;
+
EXECUTE sql;
END IF;
@@ -6071,6 +6165,7 @@ BEGIN
|| 'WHERE l.level = 0 AND l.feature_type = 2 '
|| ' AND l.topology_id = ' || topoid
|| ' AND abs(r.element_id) = ' || e1id ;
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented dropping edge %',
rec.topogeo_id, rec.layer_id,
@@ -6095,6 +6190,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge < 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -6112,6 +6208,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge > 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -6127,6 +6224,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge < 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -6144,6 +6242,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge > 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -6187,6 +6286,7 @@ BEGIN
END IF; -- }
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented healing faces % and %',
rec.topogeo_id, rec.layer_id,
@@ -6219,6 +6319,7 @@ BEGIN
|| '.face WHERE face_id IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ') ) WHERE face_id = ' || floodfaceid ;
+
EXECUTE sql;
END IF; -- }
@@ -6229,6 +6330,7 @@ BEGIN
|| ' WHERE left_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update right_face for all edges still referencing old faces
@@ -6237,6 +6339,7 @@ BEGIN
|| ' WHERE right_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update containing_face for all nodes still referencing old faces
@@ -6245,6 +6348,7 @@ BEGIN
|| ' WHERE containing_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- NOT IN THE SPECS:
@@ -6259,6 +6363,7 @@ BEGIN
|| e1rec.left_face || ',' || e1rec.right_face
|| ') AND abs(r.element_id) != '
|| floodfaceid; -- could be optimized..
+
EXECUTE sql;
END IF; -- } two faces healed...
@@ -6266,6 +6371,7 @@ BEGIN
-- Delete the edge
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.edge_data WHERE edge_id = ' || e1id;
+
EXECUTE sql;
-- Check if any of the edge nodes remains isolated,
@@ -6277,6 +6383,7 @@ BEGIN
|| e1rec.end_node || ') AND NOT EXISTS (SELECT edge_id FROM '
|| quote_ident(toponame)
|| '.edge_data WHERE start_node = n.node_id OR end_node = n.node_id)';
+
EXECUTE sql;
IF e1rec.right_face != e1rec.left_face THEN -- {
@@ -6286,6 +6393,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.left_face;
+
EXECUTE sql;
END IF;
@@ -6294,6 +6402,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.right_face;
+
EXECUTE sql;
END IF;
@@ -6451,6 +6560,7 @@ BEGIN
sql := sql || ' AND f.face_id = ' || aface;
END IF;
+
EXECUTE sql INTO containingface;
-- If aface was specified, check that it was correct
@@ -6484,6 +6594,7 @@ BEGIN
|| '::geometry,' || containingface
|| ' RETURNING node_id';
+
EXECUTE sql INTO nodeid;
RETURN nodeid;
@@ -6624,7 +6735,7 @@ LANGUAGE 'plpgsql' VOLATILE;
--} ST_RemoveIsoNode
--{
--- According to http://trac.osgeo.org/postgis/ticket/798
+-- According to http:
-- ST_RemoveIsoNode was renamed to ST_RemIsoNode in the final ISO
-- document
--
@@ -6826,6 +6937,7 @@ BEGIN
END LOOP;
+
--RAISE NOTICE 'EdgeId1 % EdgeId2 %', edgeid1, edgeid2;
--RAISE DEBUG 'oldedge.next_left_edge: %', oldedge.next_left_edge;
@@ -7111,6 +7223,7 @@ BEGIN
END LOOP;
+
--
-- Insert the new edge
--
@@ -7618,25 +7731,32 @@ BEGIN
tmp1 := ST_MakeLine(ST_EndPoint(oldedge.geom), ST_StartPoint(oldedge.geom));
+
tmp2 := ST_MakeLine(oldedge.geom, tmp1);
IF ST_NumPoints(tmp2) < 4 THEN
tmp2 := ST_AddPoint(tmp2, ST_StartPoint(oldedge.geom));
END IF;
+
tmp2 := ST_CollectionExtract(ST_MakeValid(ST_MakePolygon(tmp2)), 3);
+
range := ST_MakeLine(acurve, tmp1);
IF ST_NumPoints(range) < 4 THEN
range := ST_AddPoint(range, ST_StartPoint(oldedge.geom));
END IF;
+
range := ST_CollectionExtract(ST_MakeValid(ST_MakePolygon(range)), 3);
+
range := ST_SymDifference(range, tmp2);
+
sql := 'SELECT node_id, geom FROM '
|| quote_ident(atopology)
|| '.node WHERE ST_Contains('
|| quote_literal(range::text)
|| '::geometry, geom) LIMIT 1';
+
FOR rec IN EXECUTE sql LOOP -- {
RAISE EXCEPTION 'Edge motion collision at %', ST_AsText(rec.geom);
END LOOP; -- }
@@ -7652,11 +7772,13 @@ BEGIN
) as pre, NULL::integer[] as post
INTO STRICT snode_info;
+
SELECT topology._ST_AdjacentEdges(
atopology, oldedge.end_node, -anedge
) as pre, NULL::integer[] as post
INTO STRICT enode_info;
+
--}
--
@@ -7674,10 +7796,12 @@ BEGIN
atopology, oldedge.start_node, anedge
);
+
enode_info.post := topology._ST_AdjacentEdges(
atopology, oldedge.end_node, -anedge
);
+
IF snode_info.pre != snode_info.post THEN
RAISE EXCEPTION 'Edge changed disposition around start node %',
oldedge.start_node;
@@ -7754,6 +7878,7 @@ DECLARE
BEGIN
IF oface = 0 AND mbr_only THEN
+
RETURN NULL;
END IF;
@@ -7766,24 +7891,31 @@ BEGIN
INTO STRICT fan.newring_edges;
+
-- You can't get to the other side of an edge forming a ring
IF fan.newring_edges @> ARRAY[-anedge] THEN
+
RETURN 0;
END IF;
+
sql := 'WITH ids as ( select row_number() over () as seq, edge from unnest('
|| quote_literal(fan.newring_edges::text)
|| '::int[] ) u(edge) ), edges AS ( select CASE WHEN i.edge < 0 THEN ST_Reverse(e.geom) ELSE e.geom END as g FROM ids i left join '
|| quote_ident(atopology) || '.edge_data e ON(e.edge_id = abs(i.edge)) ORDER BY seq) SELECT ST_MakePolygon(ST_MakeLine(g.g)) FROM edges g;';
+
EXECUTE sql INTO fan.shell;
+
isccw := NOT ST_OrderingEquals(fan.shell, ST_ForceRHR(fan.shell));
+
IF oface = 0 THEN
IF NOT isccw THEN
+
RETURN NULL;
END IF;
END IF;
@@ -7795,6 +7927,7 @@ BEGIN
|| quote_ident(atopology) || '.face SET mbr = '
|| quote_literal(ST_Envelope(fan.shell)::text)
|| '::geometry WHERE face_id = ' || oface;
+
EXECUTE sql;
END IF; -- }
RETURN NULL;
@@ -7815,6 +7948,7 @@ BEGIN
END IF; -- }
-- Insert new face
+
EXECUTE sql INTO STRICT newface;
-- Update forward edges
@@ -7823,6 +7957,7 @@ BEGIN
|| ' WHERE left_face = ' || oface || ' AND edge_id = ANY ('
|| quote_literal(array( select +(x) from unnest(fan.newring_edges) u(x) )::text)
|| ')';
+
EXECUTE sql;
-- Update backward edges
@@ -7831,12 +7966,15 @@ BEGIN
|| ' WHERE right_face = ' || oface || ' AND edge_id = ANY ('
|| quote_literal(array( select -(x) from unnest(fan.newring_edges) u(x) )::text)
|| ')';
+
EXECUTE sql;
IF oface != 0 AND NOT isccw THEN -- {
-- face shrinked, must update all non-contained edges and nodes
+
ishole := true;
ELSE
+
ishole := false;
END IF; -- }
@@ -7858,6 +7996,7 @@ BEGIN
sql := sql || 'ST_Contains(' || quote_literal(fan.shell::text)
-- We only need to check a single point, but must not be an endpoint
|| '::geometry, ST_Line_Interpolate_Point(geom, 0.2))';
+
EXECUTE sql;
-- Update isolated nodes in new new face
@@ -7867,6 +8006,7 @@ BEGIN
|| ' AND ';
IF ishole THEN sql := sql || 'NOT '; END IF;
sql := sql || 'ST_Contains(' || quote_literal(fan.shell::text) || '::geometry, geom)';
+
EXECUTE sql;
RETURN newface;
@@ -7990,6 +8130,7 @@ BEGIN
|| ')'
LOOP
IF rec.containing_face IS NOT NULL THEN
+
IF newedge.left_face IS NULL THEN
newedge.left_face := rec.containing_face;
newedge.right_face := rec.containing_face;
@@ -8097,6 +8238,7 @@ BEGIN
-- Find links on start node -- {
+
sql :=
'SELECT edge_id, -1 AS end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8142,6 +8284,7 @@ BEGIN
END IF;
+
az = az - span.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8181,6 +8324,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN span.was_isolated = true; END IF;
ELSE
@@ -8197,12 +8341,16 @@ BEGIN
END IF;
+
+
+
-- } start_node analysis
-- Find links on end_node {
+
sql :=
'SELECT edge_id, -1 as end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8244,6 +8392,7 @@ BEGIN
END IF;
+
az := az - epan.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8283,6 +8432,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN epan.was_isolated = true; END IF;
ELSE
@@ -8301,6 +8451,9 @@ BEGIN
-- } end_node analysis
+
+
+
----------------------------------------------------------------------
--
-- If we don't have faces setup by now we must have encountered
@@ -8396,15 +8549,18 @@ BEGIN
--------------------------------------------
+
SELECT topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, false)
INTO newface;
IF newface = 0 THEN
+
RETURN newedge.edge_id;
END IF;
newfaces[1] := newface;
+
SELECT topology._ST_AddFaceSplit(atopology, newedge.edge_id, newedge.left_face, false)
INTO newface;
@@ -8427,6 +8583,7 @@ BEGIN
FOR rec IN EXECUTE sql
LOOP
+
-- Add reference to the other face
sql := 'INSERT INTO ' || quote_ident(atopology)
|| '.relation VALUES( ' || rec.topogeo_id
@@ -8564,6 +8721,7 @@ BEGIN
|| ')'
LOOP
IF rec.containing_face IS NOT NULL THEN
+
IF newedge.left_face IS NULL THEN
newedge.left_face := rec.containing_face;
newedge.right_face := rec.containing_face;
@@ -8669,6 +8827,7 @@ BEGIN
-- Find links on start node -- {
+
sql :=
'SELECT edge_id, -1 AS end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8714,6 +8873,7 @@ BEGIN
END IF;
+
az = az - span.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8753,6 +8913,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN span.was_isolated = true; END IF;
ELSE
@@ -8769,12 +8930,16 @@ BEGIN
END IF;
+
+
+
-- } start_node analysis
-- Find links on end_node {
+
sql :=
'SELECT edge_id, -1 as end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8816,6 +8981,7 @@ BEGIN
END IF;
+
az := az - epan.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8855,6 +9021,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN epan.was_isolated = true; END IF;
ELSE
@@ -8873,6 +9040,9 @@ BEGIN
-- } end_node analysis
+
+
+
----------------------------------------------------------------------
--
-- If we don't have faces setup by now we must have encountered
@@ -8967,20 +9137,25 @@ BEGIN
-- Check face splitting
--------------------------------------------
+
SELECT topology._ST_AddFaceSplit(atopology, newedge.edge_id, newedge.left_face, false)
INTO newface;
IF newface = 0 THEN
+
RETURN newedge.edge_id;
END IF;
IF newface IS NULL THEN -- must be forming a maximal ring in universal face
+
SELECT topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, false)
INTO newface;
ELSE
+
PERFORM topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, true);
END IF;
IF newface IS NULL THEN
+
RETURN newedge.edge_id;
END IF;
@@ -9004,6 +9179,7 @@ BEGIN
FOR rec IN EXECUTE sql
LOOP
+
-- Add reference to the other face
sql := 'INSERT INTO ' || quote_ident(atopology)
|| '.relation VALUES( ' || rec.topogeo_id
@@ -9134,6 +9310,7 @@ BEGIN
END; -- }
+
--
-- Node input linework with itself
--
@@ -9147,6 +9324,7 @@ BEGIN
) as linework INTO STRICT nodededges;
+
--
-- Linemerge the resulting edges, to reduce the working set
-- NOTE: this is more of a workaround for GEOS splitting overlapping
@@ -9156,6 +9334,7 @@ BEGIN
+
--
-- Collect input points and input lines endpoints
--
@@ -9169,6 +9348,7 @@ BEGIN
) as nodes INTO STRICT points;
+
--
-- Further split edges by points
-- TODO: optimize this adding ST_Split support for multiline/multipoint
@@ -9183,6 +9363,7 @@ BEGIN
SELECT ST_UnaryUnion(nodededges) INTO STRICT nodededges;
+
--
-- Collect all nodes (from points and noded linework endpoints)
--
@@ -9201,6 +9382,7 @@ BEGIN
) as endpoints INTO points;
+
--
-- Add all nodes as isolated so that
-- later calls to AddEdgeModFace will tweak their being
@@ -9231,11 +9413,12 @@ LANGUAGE 'plpgsql' VOLATILE;
--=} SQL/MM block
+
-- The following files needs getfaceedges_returntype, defined in sqlmm.sql
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 2012 Sandro Santilli <strk@keybit.net>
--
@@ -9245,7 +9428,7 @@ LANGUAGE 'plpgsql' VOLATILE;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -9312,10 +9495,11 @@ END
$$
LANGUAGE 'plpgsql' STABLE;
--} GetRingEdges
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2012 Sandro Santilli <strk@keybit.net>
--
@@ -9356,9 +9540,11 @@ BEGIN
|| ' UNION ALL SELECT -edge_id, ST_Azimuth(ST_EndPoint(geom), ST_PointN(geom, ST_NumPoints(geom)-1)) FROM incident_edges WHERE end_node = ' || anode
|| ' ORDER BY az';
+
FOR rec IN EXECUTE sql
LOOP -- incident edges {
+
n := n + 1;
retrec.sequence := n;
retrec.edge := rec.edge_id;
@@ -9370,11 +9556,12 @@ $$
LANGUAGE 'plpgsql' STABLE;
--} GetRingEdges
+
--general management --
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://www.postgis.org
+-- http:
--
-- Copyright (C) 2011 Regina Obe <lr@pcorp.us>
--
@@ -9413,6 +9600,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
--} AddToSearchPath
+
CREATE OR REPLACE FUNCTION postgis_topology_scripts_installed() RETURNS text
AS $$ SELECT '2.0.2'::text || ' r' || 10789::text AS version $$
LANGUAGE 'sql' IMMUTABLE;
diff --git a/gcc/postgis_extension/postgis_topology--2.0.0alpha2--2.0.2.sql b/gpp/postgis_extension/postgis_topology--2.0.0alpha2--2.0.2.sql
index 80c44f9..a257064 100644
--- a/gcc/postgis_extension/postgis_topology--2.0.0alpha2--2.0.2.sql
+++ b/gpp/postgis_extension/postgis_topology--2.0.0alpha2--2.0.2.sql
@@ -100,14 +100,12 @@ LANGUAGE plpgsql VOLATILE;
-- during upgrade
SELECT postgis_extension_remove_objects('postgis_topology', 'FUNCTION');
SELECT postgis_extension_remove_objects('postgis_topology', 'AGGREGATE');
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: topology.sql.in.c 10643 2012-11-05 10:25:41Z strk $
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -306,6 +304,23 @@ SELECT postgis_extension_remove_objects('postgis_topology', 'AGGREGATE');
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-- Doing everything outside of a transaction helps
-- upgrading in the best case.
@@ -481,7 +496,9 @@ ALTER DOMAIN topology.TopoElement ADD
array_lower(VALUE, 1) = 1
);
ALTER DOMAIN topology.TopoElement DROP CONSTRAINT
+
IF EXISTS
+
type_range;
ALTER DOMAIN topology.TopoElement ADD
CONSTRAINT type_range CHECK (
@@ -777,6 +794,7 @@ BEGIN
-- corrupting the topology anyway ...
--
+
RETURN newlayer_id;
END;
$$
@@ -1120,6 +1138,7 @@ BEGIN
|| ') as obj ORDER BY obj';
+
-- TODO: why not using array_agg here ?
i = 1;
@@ -1517,7 +1536,7 @@ BEGIN
--
-- Closed lines have no boundary, so endpoint
-- intersection would be considered interior
- -- See http://trac.osgeo.org/postgis/ticket/770
+ -- See http:
-- See also full explanation in topology.AddEdge
--
@@ -1681,6 +1700,7 @@ BEGIN
END LOOP;
+
DROP TABLE face_check;
RETURN;
@@ -1910,7 +1930,7 @@ BEGIN
------- Indexes on left_face and right_face of edge_data
------- NOTE: these indexes speed up GetFaceGeometry (and thus
------- TopoGeometry::Geometry) by a factor of 10 !
- ------- See http://trac.osgeo.org/postgis/ticket/806
+ ------- See http:
EXECUTE 'CREATE INDEX edge_left_face_idx ON '
|| quote_ident(atopology)
|| '.edge_data (left_face);';
@@ -1921,7 +1941,7 @@ BEGIN
------- Indexes on start_node and end_node of edge_data
------- NOTE: this indexes speed up node deletion
------- by a factor of 1000 !
- ------- See http://trac.osgeo.org/postgis/ticket/2082
+ ------- See http:
EXECUTE 'CREATE INDEX edge_start_node_idx ON '
|| quote_ident(atopology)
|| '.edge_data (start_node);';
@@ -2029,7 +2049,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -2180,10 +2200,11 @@ $$
LANGUAGE 'plpgsql' STABLE STRICT;
--} TopologySummary
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -2280,11 +2301,12 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
--} TopologySummary
+
-- Spatial predicates
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011-2012 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -2798,11 +2820,12 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--} equals(TopoGeometry, TopoGeometry)
+
-- Querying
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -2888,10 +2911,11 @@ $$
LANGUAGE 'plpgsql' STABLE STRICT;
--} GetNodeByPoint
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -2979,10 +3003,11 @@ END
$$
LANGUAGE 'plpgsql' STABLE STRICT;
--} GetEdgeByPoint
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -3138,11 +3163,12 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--} GetFaceByPoint
+
-- Populating
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010-2012 Sandro Santilli <strk@keybit.net>
--
@@ -3163,7 +3189,7 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--
--
-- A pragmatic test conducted using algoritm shown here:
--- http://stackoverflow.com/questions/7408407/generate-next-largest-or-smallest-representable-floating-point-number-without-bi
+-- http:
-- showed the "tolerance" growing by an order of magnitude proportionally
-- with the order of magnitude of the input, starting with something like
-- 3.5527136788005009294e-15 for the starting value of 9.0
@@ -3219,7 +3245,7 @@ $$ LANGUAGE 'plpgsql' STABLE STRICT;
-- The newly added nodes have no containing face.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3287,6 +3313,7 @@ BEGIN
IF setContainingFace THEN
containing_face := topology.GetFaceByPoint(atopology, apoint, 0);
+
ELSE
containing_face := NULL;
END IF;
@@ -3346,7 +3373,7 @@ LANGUAGE 'sql' VOLATILE;
-- Calling code is expected to do further linking.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3435,6 +3462,7 @@ BEGIN
-- Reuse an EQUAL edge (be it closed or not)
IF ST_RelateMatch(rec.im, '1FFF*FFF2') THEN
+
RETURN rec.edge_id;
END IF;
@@ -3539,7 +3567,7 @@ LANGUAGE 'plpgsql' VOLATILE;
-- o The polygon overlaps an existing face.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3661,6 +3689,7 @@ BEGIN
ST_Line_Locate_Point(bounds, p2);
+
IF right_side THEN
right_edges := array_append(right_edges, rec.edge_id);
old_faceid = rec.right_face;
@@ -3687,6 +3716,8 @@ BEGIN
END IF;
+
+
--
-- Check that all edges found, taken togheter,
-- fully match the ring boundary and nothing more
@@ -3706,8 +3737,10 @@ BEGIN
IF faceid IS NOT NULL AND faceid != 0 THEN
IF NOT force_new THEN
+
RETURN faceid;
ELSE
+
END IF;
END IF;
@@ -3834,12 +3867,14 @@ BEGIN
|| tol || ') ORDER BY ST_Distance('
|| quote_literal(apoint::text)
|| '::geometry, a.geom) LIMIT 1;';
+
EXECUTE sql INTO id;
IF id IS NOT NULL THEN
RETURN id;
END IF;
+
-- 2. Check if any existing edge falls within tolerance
-- and if so split it by a point projected on it
sql := 'SELECT a.edge_id, a.geom FROM '
@@ -3849,35 +3884,42 @@ BEGIN
|| tol || ') ORDER BY ST_Distance('
|| quote_literal(apoint::text)
|| '::geometry, a.geom) LIMIT 1;';
+
EXECUTE sql INTO rec;
IF rec IS NOT NULL THEN
-- project point to line, split edge by point
prj := ST_ClosestPoint(rec.geom, apoint);
-- This is a workaround for ClosestPoint lack of Z support:
- -- http://trac.osgeo.org/postgis/ticket/2033
+ -- http:
z := ST_Z(apoint);
IF z IS NOT NULL THEN
prj := ST_Translate(ST_Force_3DZ(prj), 0, 0, z); -- no ST_SetZ ...
END IF;
+
IF NOT ST_Contains(rec.geom, prj) THEN
+
-- The tolerance must be big enough for snapping to happen
-- and small enough to snap only to the projected point.
-- Unfortunately ST_Distance returns 0 because it also uses
-- a projected point internally, so we need another way.
snaptol := topology._st_mintolerance(prj);
+
snapedge := ST_Snap(rec.geom, prj, snaptol);
-- Snapping currently snaps the first point below tolerance
-- so may possibly move first point. See ticket #1631
IF NOT ST_Equals(ST_StartPoint(rec.geom), ST_StartPoint(snapedge))
THEN
+
snapedge := ST_MakeLine(ST_StartPoint(rec.geom), snapedge);
END IF;
+
PERFORM ST_ChangeEdgeGeom(atopology, rec.edge_id, snapedge);
END IF;
id := topology.ST_ModEdgeSplit(atopology, rec.edge_id, prj);
ELSE
+
id := topology.ST_AddIsoNode(atopology, NULL, apoint);
END IF;
@@ -3923,6 +3965,7 @@ BEGIN
-- 1. Self-node
noded := ST_UnaryUnion(aline);
+
-- 2. Node to edges falling within tol distance
sql := 'WITH nearby AS ( SELECT e.geom FROM '
|| quote_ident(atopology)
@@ -3930,20 +3973,27 @@ BEGIN
|| quote_literal(noded::text)
|| '::geometry, '
|| tol || ') ) SELECT st_collect(geom) FROM nearby;';
+
EXECUTE sql INTO iedges;
IF iedges IS NOT NULL THEN
+
snapped := ST_Snap(noded, iedges, tol);
+
noded := ST_Difference(snapped, iedges);
+
set1 := ST_Intersection(snapped, iedges);
+
set2 := ST_LineMerge(set1);
+
noded := ST_Union(noded, set2);
+
END IF;
-- 2.1. Node with existing nodes within tol
@@ -3954,26 +4004,32 @@ BEGIN
|| quote_literal(noded::text)
|| '::geometry, '
|| tol || ') ) SELECT st_collect(geom) FROM nearby;';
+
EXECUTE sql INTO inodes;
IF inodes IS NOT NULL THEN -- {
+
-- TODO: consider snapping once against all elements
--- (rather than once with edges and once with nodes)
noded := ST_Snap(noded, inodes, tol);
+
FOR rec IN SELECT (ST_Dump(inodes)).*
LOOP
-- Use the node to split edges
SELECT ST_Collect(geom)
FROM ST_Dump(ST_Split(noded, rec.geom))
INTO STRICT noded;
+
END LOOP;
+
-- re-node to account for ST_Snap introduced self-intersections
- -- See http://trac.osgeo.org/postgis/ticket/1714
+ -- See http:
-- TODO: consider running UnaryUnion once after all noding
noded := ST_UnaryUnion(noded);
+
END IF; -- }
-- 3. For each (now-noded) segment, insert an edge
@@ -3982,14 +4038,17 @@ BEGIN
-- TODO: skip point elements ?
+
start_node := topology.TopoGeo_AddPoint(atopology,
ST_StartPoint(rec.geom),
tol);
+
end_node := topology.TopoGeo_AddPoint(atopology,
ST_EndPoint(rec.geom),
tol);
+
-- Added endpoints may have drifted due to tolerance, so
-- we need to re-snap the edge to the new nodes before adding it
sql := 'SELECT n1.geom as sn, n2.geom as en FROM ' || quote_ident(atopology)
@@ -3997,6 +4056,7 @@ BEGIN
|| '.node n2 WHERE n1.node_id = '
|| start_node || ' AND n2.node_id = ' || end_node;
+
EXECUTE sql INTO STRICT rec2;
snapped := ST_SetPoint(
@@ -4007,8 +4067,10 @@ BEGIN
snapped := ST_CollectionExtract(ST_MakeValid(snapped), 2);
+
-- Check if the so-snapped edge collapsed (see #1650)
IF ST_IsEmpty(snapped) THEN
+
CONTINUE;
END IF;
@@ -4016,11 +4078,14 @@ BEGIN
sql := 'SELECT edge_id FROM ' || quote_ident(atopology)
|| '.edge_data WHERE ST_Equals(geom, ' || quote_literal(snapped::text)
|| '::geometry)';
+
EXECUTE sql INTO id;
IF id IS NULL THEN
id := topology.ST_AddEdgeModFace(atopology, start_node, end_node,
snapped);
+
ELSE
+
END IF;
RETURN NEXT id;
@@ -4062,9 +4127,11 @@ BEGIN
-- 1. Extract boundary
boundary := ST_Boundary(apoly);
+
-- 2. Add boundaries as edges
FOR rec IN SELECT (ST_Dump(boundary)).geom LOOP
edges := array_cat(edges, array_agg(x)) FROM ( select topology.TopoGeo_addLinestring(atopology, rec.geom, tol) as x ) as foo;
+
END LOOP;
-- 3. Find faces covered by input polygon
@@ -4073,10 +4140,12 @@ BEGIN
|| '.face f WHERE f.mbr && '
|| quote_literal(apoly::text)
|| '::geometry';
+
FOR rec IN EXECUTE sql LOOP
-- check for actual containment
fgeom := ST_PointOnSurface(ST_GetFaceGeometry(atopology, rec.face_id));
IF NOT ST_Covers(apoly, fgeom) THEN
+
CONTINUE;
END IF;
RETURN NEXT rec.face_id;
@@ -4102,10 +4171,11 @@ END
$$
LANGUAGE 'plpgsql';
--} TopoGeo_AddGeometry
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4154,11 +4224,12 @@ $$
LANGUAGE 'plpgsql';
--} Polygonize(toponame)
+
-- TopoElement
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4172,7 +4243,7 @@ LANGUAGE 'plpgsql';
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -4214,11 +4285,12 @@ CREATE AGGREGATE topology.TopoElementArray_agg(
);
--} TopoElementArray_agg
+
-- TopoGeometry
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4274,10 +4346,11 @@ $$
$$
LANGUAGE 'sql' STABLE STRICT;
-- }
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011-2012 Sandro Santilli <strk@keybit.net>
--
@@ -4289,7 +4362,7 @@ LANGUAGE 'sql' STABLE STRICT;
-- {
-- Convert a simple geometry to a topologically-defined one
--
--- See http://trac.osgeo.org/postgis/ticket/1017
+-- See http:
--
-- }{
CREATE OR REPLACE FUNCTION topology.toTopoGeom(ageom Geometry, atopology varchar, alayer int, atolerance float8 DEFAULT 0)
@@ -4414,6 +4487,7 @@ BEGIN
|| '.relation(topogeo_id, layer_id, element_type, element_id) VALUES ('
|| rec.id || ',' || rec.lyr || ',' || rec.type
|| ',' || rec.primitive || ')';
+
EXECUTE sql;
END LOOP;
@@ -4424,11 +4498,12 @@ $$
LANGUAGE 'plpgsql' VOLATILE STRICT;
-- }
+
-- GML
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4442,7 +4517,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -4989,13 +5064,14 @@ $$ LANGUAGE 'sql' STABLE; -- does NOT write into visited table
-- } AsGML(TopoGeometry)
+
--=} POSTGIS-SPECIFIC block
-- SQL/MM block
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011, 2012 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -5101,6 +5177,7 @@ BEGIN
LOOP
+
retrec.sequence = n;
retrec.edge = rec.edge_id;
@@ -5399,6 +5476,7 @@ BEGIN
|| ' AND l.layer_id = r.layer_id AND abs(r.element_id) = '
|| e1id
;
+
EXECUTE sql;
@@ -5747,6 +5825,7 @@ BEGIN
|| 'WHERE l.level = 0 AND l.feature_type = 2 '
|| ' AND l.topology_id = ' || topoid
|| ' AND abs(r.element_id) = ' || e1id ;
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented dropping edge %',
rec.topogeo_id, rec.layer_id,
@@ -5771,6 +5850,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge < 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -5788,6 +5868,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge > 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -5803,6 +5884,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge < 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -5820,6 +5902,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge > 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -5865,6 +5948,7 @@ BEGIN
END IF; -- }
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented healing faces % and %',
rec.topogeo_id, rec.layer_id,
@@ -5907,6 +5991,7 @@ BEGIN
|| '.face WHERE face_id IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
END IF; -- }
@@ -5917,6 +6002,7 @@ BEGIN
|| ' WHERE left_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update right_face for all edges still referencing old faces
@@ -5925,6 +6011,7 @@ BEGIN
|| ' WHERE right_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update containing_face for all nodes still referencing old faces
@@ -5933,6 +6020,7 @@ BEGIN
|| ' WHERE containing_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- NOT IN THE SPECS:
@@ -5945,6 +6033,7 @@ BEGIN
|| ' AND l.topology_id = ' || topoid
|| ' AND l.layer_id = r.layer_id AND abs(r.element_id) = '
|| e1rec.left_face;
+
EXECUTE sql;
sql := 'UPDATE ' || quote_ident(toponame)
|| '.relation r '
@@ -5953,6 +6042,7 @@ BEGIN
|| ' AND l.topology_id = ' || topoid
|| ' AND l.layer_id = r.layer_id AND r.element_id = '
|| e1rec.right_face;
+
EXECUTE sql;
END IF; -- } two faces healed...
@@ -5960,6 +6050,7 @@ BEGIN
-- Delete the edge
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.edge_data WHERE edge_id = ' || e1id;
+
EXECUTE sql;
-- Check if any of the edge nodes remains isolated,
@@ -5971,6 +6062,7 @@ BEGIN
|| e1rec.end_node || ') AND NOT EXISTS (SELECT edge_id FROM '
|| quote_ident(toponame)
|| '.edge_data WHERE start_node = n.node_id OR end_node = n.node_id)';
+
EXECUTE sql;
IF e1rec.right_face != e1rec.left_face THEN -- {
@@ -5979,6 +6071,7 @@ BEGIN
IF e1rec.left_face != 0 THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.left_face;
+
EXECUTE sql;
END IF;
@@ -5987,6 +6080,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.right_face;
+
EXECUTE sql;
END IF;
@@ -6071,6 +6165,7 @@ BEGIN
|| 'WHERE l.level = 0 AND l.feature_type = 2 '
|| ' AND l.topology_id = ' || topoid
|| ' AND abs(r.element_id) = ' || e1id ;
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented dropping edge %',
rec.topogeo_id, rec.layer_id,
@@ -6095,6 +6190,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge < 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -6112,6 +6208,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge > 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -6127,6 +6224,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge < 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -6144,6 +6242,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge > 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -6187,6 +6286,7 @@ BEGIN
END IF; -- }
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented healing faces % and %',
rec.topogeo_id, rec.layer_id,
@@ -6219,6 +6319,7 @@ BEGIN
|| '.face WHERE face_id IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ') ) WHERE face_id = ' || floodfaceid ;
+
EXECUTE sql;
END IF; -- }
@@ -6229,6 +6330,7 @@ BEGIN
|| ' WHERE left_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update right_face for all edges still referencing old faces
@@ -6237,6 +6339,7 @@ BEGIN
|| ' WHERE right_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update containing_face for all nodes still referencing old faces
@@ -6245,6 +6348,7 @@ BEGIN
|| ' WHERE containing_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- NOT IN THE SPECS:
@@ -6259,6 +6363,7 @@ BEGIN
|| e1rec.left_face || ',' || e1rec.right_face
|| ') AND abs(r.element_id) != '
|| floodfaceid; -- could be optimized..
+
EXECUTE sql;
END IF; -- } two faces healed...
@@ -6266,6 +6371,7 @@ BEGIN
-- Delete the edge
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.edge_data WHERE edge_id = ' || e1id;
+
EXECUTE sql;
-- Check if any of the edge nodes remains isolated,
@@ -6277,6 +6383,7 @@ BEGIN
|| e1rec.end_node || ') AND NOT EXISTS (SELECT edge_id FROM '
|| quote_ident(toponame)
|| '.edge_data WHERE start_node = n.node_id OR end_node = n.node_id)';
+
EXECUTE sql;
IF e1rec.right_face != e1rec.left_face THEN -- {
@@ -6286,6 +6393,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.left_face;
+
EXECUTE sql;
END IF;
@@ -6294,6 +6402,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.right_face;
+
EXECUTE sql;
END IF;
@@ -6451,6 +6560,7 @@ BEGIN
sql := sql || ' AND f.face_id = ' || aface;
END IF;
+
EXECUTE sql INTO containingface;
-- If aface was specified, check that it was correct
@@ -6484,6 +6594,7 @@ BEGIN
|| '::geometry,' || containingface
|| ' RETURNING node_id';
+
EXECUTE sql INTO nodeid;
RETURN nodeid;
@@ -6624,7 +6735,7 @@ LANGUAGE 'plpgsql' VOLATILE;
--} ST_RemoveIsoNode
--{
--- According to http://trac.osgeo.org/postgis/ticket/798
+-- According to http:
-- ST_RemoveIsoNode was renamed to ST_RemIsoNode in the final ISO
-- document
--
@@ -6826,6 +6937,7 @@ BEGIN
END LOOP;
+
--RAISE NOTICE 'EdgeId1 % EdgeId2 %', edgeid1, edgeid2;
--RAISE DEBUG 'oldedge.next_left_edge: %', oldedge.next_left_edge;
@@ -7111,6 +7223,7 @@ BEGIN
END LOOP;
+
--
-- Insert the new edge
--
@@ -7618,25 +7731,32 @@ BEGIN
tmp1 := ST_MakeLine(ST_EndPoint(oldedge.geom), ST_StartPoint(oldedge.geom));
+
tmp2 := ST_MakeLine(oldedge.geom, tmp1);
IF ST_NumPoints(tmp2) < 4 THEN
tmp2 := ST_AddPoint(tmp2, ST_StartPoint(oldedge.geom));
END IF;
+
tmp2 := ST_CollectionExtract(ST_MakeValid(ST_MakePolygon(tmp2)), 3);
+
range := ST_MakeLine(acurve, tmp1);
IF ST_NumPoints(range) < 4 THEN
range := ST_AddPoint(range, ST_StartPoint(oldedge.geom));
END IF;
+
range := ST_CollectionExtract(ST_MakeValid(ST_MakePolygon(range)), 3);
+
range := ST_SymDifference(range, tmp2);
+
sql := 'SELECT node_id, geom FROM '
|| quote_ident(atopology)
|| '.node WHERE ST_Contains('
|| quote_literal(range::text)
|| '::geometry, geom) LIMIT 1';
+
FOR rec IN EXECUTE sql LOOP -- {
RAISE EXCEPTION 'Edge motion collision at %', ST_AsText(rec.geom);
END LOOP; -- }
@@ -7652,11 +7772,13 @@ BEGIN
) as pre, NULL::integer[] as post
INTO STRICT snode_info;
+
SELECT topology._ST_AdjacentEdges(
atopology, oldedge.end_node, -anedge
) as pre, NULL::integer[] as post
INTO STRICT enode_info;
+
--}
--
@@ -7674,10 +7796,12 @@ BEGIN
atopology, oldedge.start_node, anedge
);
+
enode_info.post := topology._ST_AdjacentEdges(
atopology, oldedge.end_node, -anedge
);
+
IF snode_info.pre != snode_info.post THEN
RAISE EXCEPTION 'Edge changed disposition around start node %',
oldedge.start_node;
@@ -7754,6 +7878,7 @@ DECLARE
BEGIN
IF oface = 0 AND mbr_only THEN
+
RETURN NULL;
END IF;
@@ -7766,24 +7891,31 @@ BEGIN
INTO STRICT fan.newring_edges;
+
-- You can't get to the other side of an edge forming a ring
IF fan.newring_edges @> ARRAY[-anedge] THEN
+
RETURN 0;
END IF;
+
sql := 'WITH ids as ( select row_number() over () as seq, edge from unnest('
|| quote_literal(fan.newring_edges::text)
|| '::int[] ) u(edge) ), edges AS ( select CASE WHEN i.edge < 0 THEN ST_Reverse(e.geom) ELSE e.geom END as g FROM ids i left join '
|| quote_ident(atopology) || '.edge_data e ON(e.edge_id = abs(i.edge)) ORDER BY seq) SELECT ST_MakePolygon(ST_MakeLine(g.g)) FROM edges g;';
+
EXECUTE sql INTO fan.shell;
+
isccw := NOT ST_OrderingEquals(fan.shell, ST_ForceRHR(fan.shell));
+
IF oface = 0 THEN
IF NOT isccw THEN
+
RETURN NULL;
END IF;
END IF;
@@ -7795,6 +7927,7 @@ BEGIN
|| quote_ident(atopology) || '.face SET mbr = '
|| quote_literal(ST_Envelope(fan.shell)::text)
|| '::geometry WHERE face_id = ' || oface;
+
EXECUTE sql;
END IF; -- }
RETURN NULL;
@@ -7815,6 +7948,7 @@ BEGIN
END IF; -- }
-- Insert new face
+
EXECUTE sql INTO STRICT newface;
-- Update forward edges
@@ -7823,6 +7957,7 @@ BEGIN
|| ' WHERE left_face = ' || oface || ' AND edge_id = ANY ('
|| quote_literal(array( select +(x) from unnest(fan.newring_edges) u(x) )::text)
|| ')';
+
EXECUTE sql;
-- Update backward edges
@@ -7831,12 +7966,15 @@ BEGIN
|| ' WHERE right_face = ' || oface || ' AND edge_id = ANY ('
|| quote_literal(array( select -(x) from unnest(fan.newring_edges) u(x) )::text)
|| ')';
+
EXECUTE sql;
IF oface != 0 AND NOT isccw THEN -- {
-- face shrinked, must update all non-contained edges and nodes
+
ishole := true;
ELSE
+
ishole := false;
END IF; -- }
@@ -7858,6 +7996,7 @@ BEGIN
sql := sql || 'ST_Contains(' || quote_literal(fan.shell::text)
-- We only need to check a single point, but must not be an endpoint
|| '::geometry, ST_Line_Interpolate_Point(geom, 0.2))';
+
EXECUTE sql;
-- Update isolated nodes in new new face
@@ -7867,6 +8006,7 @@ BEGIN
|| ' AND ';
IF ishole THEN sql := sql || 'NOT '; END IF;
sql := sql || 'ST_Contains(' || quote_literal(fan.shell::text) || '::geometry, geom)';
+
EXECUTE sql;
RETURN newface;
@@ -7990,6 +8130,7 @@ BEGIN
|| ')'
LOOP
IF rec.containing_face IS NOT NULL THEN
+
IF newedge.left_face IS NULL THEN
newedge.left_face := rec.containing_face;
newedge.right_face := rec.containing_face;
@@ -8097,6 +8238,7 @@ BEGIN
-- Find links on start node -- {
+
sql :=
'SELECT edge_id, -1 AS end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8142,6 +8284,7 @@ BEGIN
END IF;
+
az = az - span.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8181,6 +8324,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN span.was_isolated = true; END IF;
ELSE
@@ -8197,12 +8341,16 @@ BEGIN
END IF;
+
+
+
-- } start_node analysis
-- Find links on end_node {
+
sql :=
'SELECT edge_id, -1 as end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8244,6 +8392,7 @@ BEGIN
END IF;
+
az := az - epan.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8283,6 +8432,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN epan.was_isolated = true; END IF;
ELSE
@@ -8301,6 +8451,9 @@ BEGIN
-- } end_node analysis
+
+
+
----------------------------------------------------------------------
--
-- If we don't have faces setup by now we must have encountered
@@ -8396,15 +8549,18 @@ BEGIN
--------------------------------------------
+
SELECT topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, false)
INTO newface;
IF newface = 0 THEN
+
RETURN newedge.edge_id;
END IF;
newfaces[1] := newface;
+
SELECT topology._ST_AddFaceSplit(atopology, newedge.edge_id, newedge.left_face, false)
INTO newface;
@@ -8427,6 +8583,7 @@ BEGIN
FOR rec IN EXECUTE sql
LOOP
+
-- Add reference to the other face
sql := 'INSERT INTO ' || quote_ident(atopology)
|| '.relation VALUES( ' || rec.topogeo_id
@@ -8564,6 +8721,7 @@ BEGIN
|| ')'
LOOP
IF rec.containing_face IS NOT NULL THEN
+
IF newedge.left_face IS NULL THEN
newedge.left_face := rec.containing_face;
newedge.right_face := rec.containing_face;
@@ -8669,6 +8827,7 @@ BEGIN
-- Find links on start node -- {
+
sql :=
'SELECT edge_id, -1 AS end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8714,6 +8873,7 @@ BEGIN
END IF;
+
az = az - span.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8753,6 +8913,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN span.was_isolated = true; END IF;
ELSE
@@ -8769,12 +8930,16 @@ BEGIN
END IF;
+
+
+
-- } start_node analysis
-- Find links on end_node {
+
sql :=
'SELECT edge_id, -1 as end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8816,6 +8981,7 @@ BEGIN
END IF;
+
az := az - epan.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8855,6 +9021,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN epan.was_isolated = true; END IF;
ELSE
@@ -8873,6 +9040,9 @@ BEGIN
-- } end_node analysis
+
+
+
----------------------------------------------------------------------
--
-- If we don't have faces setup by now we must have encountered
@@ -8967,20 +9137,25 @@ BEGIN
-- Check face splitting
--------------------------------------------
+
SELECT topology._ST_AddFaceSplit(atopology, newedge.edge_id, newedge.left_face, false)
INTO newface;
IF newface = 0 THEN
+
RETURN newedge.edge_id;
END IF;
IF newface IS NULL THEN -- must be forming a maximal ring in universal face
+
SELECT topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, false)
INTO newface;
ELSE
+
PERFORM topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, true);
END IF;
IF newface IS NULL THEN
+
RETURN newedge.edge_id;
END IF;
@@ -9004,6 +9179,7 @@ BEGIN
FOR rec IN EXECUTE sql
LOOP
+
-- Add reference to the other face
sql := 'INSERT INTO ' || quote_ident(atopology)
|| '.relation VALUES( ' || rec.topogeo_id
@@ -9134,6 +9310,7 @@ BEGIN
END; -- }
+
--
-- Node input linework with itself
--
@@ -9147,6 +9324,7 @@ BEGIN
) as linework INTO STRICT nodededges;
+
--
-- Linemerge the resulting edges, to reduce the working set
-- NOTE: this is more of a workaround for GEOS splitting overlapping
@@ -9156,6 +9334,7 @@ BEGIN
+
--
-- Collect input points and input lines endpoints
--
@@ -9169,6 +9348,7 @@ BEGIN
) as nodes INTO STRICT points;
+
--
-- Further split edges by points
-- TODO: optimize this adding ST_Split support for multiline/multipoint
@@ -9183,6 +9363,7 @@ BEGIN
SELECT ST_UnaryUnion(nodededges) INTO STRICT nodededges;
+
--
-- Collect all nodes (from points and noded linework endpoints)
--
@@ -9201,6 +9382,7 @@ BEGIN
) as endpoints INTO points;
+
--
-- Add all nodes as isolated so that
-- later calls to AddEdgeModFace will tweak their being
@@ -9231,11 +9413,12 @@ LANGUAGE 'plpgsql' VOLATILE;
--=} SQL/MM block
+
-- The following files needs getfaceedges_returntype, defined in sqlmm.sql
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 2012 Sandro Santilli <strk@keybit.net>
--
@@ -9245,7 +9428,7 @@ LANGUAGE 'plpgsql' VOLATILE;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -9312,10 +9495,11 @@ END
$$
LANGUAGE 'plpgsql' STABLE;
--} GetRingEdges
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2012 Sandro Santilli <strk@keybit.net>
--
@@ -9356,9 +9540,11 @@ BEGIN
|| ' UNION ALL SELECT -edge_id, ST_Azimuth(ST_EndPoint(geom), ST_PointN(geom, ST_NumPoints(geom)-1)) FROM incident_edges WHERE end_node = ' || anode
|| ' ORDER BY az';
+
FOR rec IN EXECUTE sql
LOOP -- incident edges {
+
n := n + 1;
retrec.sequence := n;
retrec.edge := rec.edge_id;
@@ -9370,11 +9556,12 @@ $$
LANGUAGE 'plpgsql' STABLE;
--} GetRingEdges
+
--general management --
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://www.postgis.org
+-- http:
--
-- Copyright (C) 2011 Regina Obe <lr@pcorp.us>
--
@@ -9413,6 +9600,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
--} AddToSearchPath
+
CREATE OR REPLACE FUNCTION postgis_topology_scripts_installed() RETURNS text
AS $$ SELECT '2.0.2'::text || ' r' || 10789::text AS version $$
LANGUAGE 'sql' IMMUTABLE;
diff --git a/gcc/postgis_extension/postgis_topology--2.0.0alpha3--2.0.2.sql b/gpp/postgis_extension/postgis_topology--2.0.0alpha3--2.0.2.sql
index 80c44f9..a257064 100644
--- a/gcc/postgis_extension/postgis_topology--2.0.0alpha3--2.0.2.sql
+++ b/gpp/postgis_extension/postgis_topology--2.0.0alpha3--2.0.2.sql
@@ -100,14 +100,12 @@ LANGUAGE plpgsql VOLATILE;
-- during upgrade
SELECT postgis_extension_remove_objects('postgis_topology', 'FUNCTION');
SELECT postgis_extension_remove_objects('postgis_topology', 'AGGREGATE');
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: topology.sql.in.c 10643 2012-11-05 10:25:41Z strk $
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -306,6 +304,23 @@ SELECT postgis_extension_remove_objects('postgis_topology', 'AGGREGATE');
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-- Doing everything outside of a transaction helps
-- upgrading in the best case.
@@ -481,7 +496,9 @@ ALTER DOMAIN topology.TopoElement ADD
array_lower(VALUE, 1) = 1
);
ALTER DOMAIN topology.TopoElement DROP CONSTRAINT
+
IF EXISTS
+
type_range;
ALTER DOMAIN topology.TopoElement ADD
CONSTRAINT type_range CHECK (
@@ -777,6 +794,7 @@ BEGIN
-- corrupting the topology anyway ...
--
+
RETURN newlayer_id;
END;
$$
@@ -1120,6 +1138,7 @@ BEGIN
|| ') as obj ORDER BY obj';
+
-- TODO: why not using array_agg here ?
i = 1;
@@ -1517,7 +1536,7 @@ BEGIN
--
-- Closed lines have no boundary, so endpoint
-- intersection would be considered interior
- -- See http://trac.osgeo.org/postgis/ticket/770
+ -- See http:
-- See also full explanation in topology.AddEdge
--
@@ -1681,6 +1700,7 @@ BEGIN
END LOOP;
+
DROP TABLE face_check;
RETURN;
@@ -1910,7 +1930,7 @@ BEGIN
------- Indexes on left_face and right_face of edge_data
------- NOTE: these indexes speed up GetFaceGeometry (and thus
------- TopoGeometry::Geometry) by a factor of 10 !
- ------- See http://trac.osgeo.org/postgis/ticket/806
+ ------- See http:
EXECUTE 'CREATE INDEX edge_left_face_idx ON '
|| quote_ident(atopology)
|| '.edge_data (left_face);';
@@ -1921,7 +1941,7 @@ BEGIN
------- Indexes on start_node and end_node of edge_data
------- NOTE: this indexes speed up node deletion
------- by a factor of 1000 !
- ------- See http://trac.osgeo.org/postgis/ticket/2082
+ ------- See http:
EXECUTE 'CREATE INDEX edge_start_node_idx ON '
|| quote_ident(atopology)
|| '.edge_data (start_node);';
@@ -2029,7 +2049,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -2180,10 +2200,11 @@ $$
LANGUAGE 'plpgsql' STABLE STRICT;
--} TopologySummary
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -2280,11 +2301,12 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
--} TopologySummary
+
-- Spatial predicates
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011-2012 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -2798,11 +2820,12 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--} equals(TopoGeometry, TopoGeometry)
+
-- Querying
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -2888,10 +2911,11 @@ $$
LANGUAGE 'plpgsql' STABLE STRICT;
--} GetNodeByPoint
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -2979,10 +3003,11 @@ END
$$
LANGUAGE 'plpgsql' STABLE STRICT;
--} GetEdgeByPoint
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -3138,11 +3163,12 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--} GetFaceByPoint
+
-- Populating
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010-2012 Sandro Santilli <strk@keybit.net>
--
@@ -3163,7 +3189,7 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--
--
-- A pragmatic test conducted using algoritm shown here:
--- http://stackoverflow.com/questions/7408407/generate-next-largest-or-smallest-representable-floating-point-number-without-bi
+-- http:
-- showed the "tolerance" growing by an order of magnitude proportionally
-- with the order of magnitude of the input, starting with something like
-- 3.5527136788005009294e-15 for the starting value of 9.0
@@ -3219,7 +3245,7 @@ $$ LANGUAGE 'plpgsql' STABLE STRICT;
-- The newly added nodes have no containing face.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3287,6 +3313,7 @@ BEGIN
IF setContainingFace THEN
containing_face := topology.GetFaceByPoint(atopology, apoint, 0);
+
ELSE
containing_face := NULL;
END IF;
@@ -3346,7 +3373,7 @@ LANGUAGE 'sql' VOLATILE;
-- Calling code is expected to do further linking.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3435,6 +3462,7 @@ BEGIN
-- Reuse an EQUAL edge (be it closed or not)
IF ST_RelateMatch(rec.im, '1FFF*FFF2') THEN
+
RETURN rec.edge_id;
END IF;
@@ -3539,7 +3567,7 @@ LANGUAGE 'plpgsql' VOLATILE;
-- o The polygon overlaps an existing face.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3661,6 +3689,7 @@ BEGIN
ST_Line_Locate_Point(bounds, p2);
+
IF right_side THEN
right_edges := array_append(right_edges, rec.edge_id);
old_faceid = rec.right_face;
@@ -3687,6 +3716,8 @@ BEGIN
END IF;
+
+
--
-- Check that all edges found, taken togheter,
-- fully match the ring boundary and nothing more
@@ -3706,8 +3737,10 @@ BEGIN
IF faceid IS NOT NULL AND faceid != 0 THEN
IF NOT force_new THEN
+
RETURN faceid;
ELSE
+
END IF;
END IF;
@@ -3834,12 +3867,14 @@ BEGIN
|| tol || ') ORDER BY ST_Distance('
|| quote_literal(apoint::text)
|| '::geometry, a.geom) LIMIT 1;';
+
EXECUTE sql INTO id;
IF id IS NOT NULL THEN
RETURN id;
END IF;
+
-- 2. Check if any existing edge falls within tolerance
-- and if so split it by a point projected on it
sql := 'SELECT a.edge_id, a.geom FROM '
@@ -3849,35 +3884,42 @@ BEGIN
|| tol || ') ORDER BY ST_Distance('
|| quote_literal(apoint::text)
|| '::geometry, a.geom) LIMIT 1;';
+
EXECUTE sql INTO rec;
IF rec IS NOT NULL THEN
-- project point to line, split edge by point
prj := ST_ClosestPoint(rec.geom, apoint);
-- This is a workaround for ClosestPoint lack of Z support:
- -- http://trac.osgeo.org/postgis/ticket/2033
+ -- http:
z := ST_Z(apoint);
IF z IS NOT NULL THEN
prj := ST_Translate(ST_Force_3DZ(prj), 0, 0, z); -- no ST_SetZ ...
END IF;
+
IF NOT ST_Contains(rec.geom, prj) THEN
+
-- The tolerance must be big enough for snapping to happen
-- and small enough to snap only to the projected point.
-- Unfortunately ST_Distance returns 0 because it also uses
-- a projected point internally, so we need another way.
snaptol := topology._st_mintolerance(prj);
+
snapedge := ST_Snap(rec.geom, prj, snaptol);
-- Snapping currently snaps the first point below tolerance
-- so may possibly move first point. See ticket #1631
IF NOT ST_Equals(ST_StartPoint(rec.geom), ST_StartPoint(snapedge))
THEN
+
snapedge := ST_MakeLine(ST_StartPoint(rec.geom), snapedge);
END IF;
+
PERFORM ST_ChangeEdgeGeom(atopology, rec.edge_id, snapedge);
END IF;
id := topology.ST_ModEdgeSplit(atopology, rec.edge_id, prj);
ELSE
+
id := topology.ST_AddIsoNode(atopology, NULL, apoint);
END IF;
@@ -3923,6 +3965,7 @@ BEGIN
-- 1. Self-node
noded := ST_UnaryUnion(aline);
+
-- 2. Node to edges falling within tol distance
sql := 'WITH nearby AS ( SELECT e.geom FROM '
|| quote_ident(atopology)
@@ -3930,20 +3973,27 @@ BEGIN
|| quote_literal(noded::text)
|| '::geometry, '
|| tol || ') ) SELECT st_collect(geom) FROM nearby;';
+
EXECUTE sql INTO iedges;
IF iedges IS NOT NULL THEN
+
snapped := ST_Snap(noded, iedges, tol);
+
noded := ST_Difference(snapped, iedges);
+
set1 := ST_Intersection(snapped, iedges);
+
set2 := ST_LineMerge(set1);
+
noded := ST_Union(noded, set2);
+
END IF;
-- 2.1. Node with existing nodes within tol
@@ -3954,26 +4004,32 @@ BEGIN
|| quote_literal(noded::text)
|| '::geometry, '
|| tol || ') ) SELECT st_collect(geom) FROM nearby;';
+
EXECUTE sql INTO inodes;
IF inodes IS NOT NULL THEN -- {
+
-- TODO: consider snapping once against all elements
--- (rather than once with edges and once with nodes)
noded := ST_Snap(noded, inodes, tol);
+
FOR rec IN SELECT (ST_Dump(inodes)).*
LOOP
-- Use the node to split edges
SELECT ST_Collect(geom)
FROM ST_Dump(ST_Split(noded, rec.geom))
INTO STRICT noded;
+
END LOOP;
+
-- re-node to account for ST_Snap introduced self-intersections
- -- See http://trac.osgeo.org/postgis/ticket/1714
+ -- See http:
-- TODO: consider running UnaryUnion once after all noding
noded := ST_UnaryUnion(noded);
+
END IF; -- }
-- 3. For each (now-noded) segment, insert an edge
@@ -3982,14 +4038,17 @@ BEGIN
-- TODO: skip point elements ?
+
start_node := topology.TopoGeo_AddPoint(atopology,
ST_StartPoint(rec.geom),
tol);
+
end_node := topology.TopoGeo_AddPoint(atopology,
ST_EndPoint(rec.geom),
tol);
+
-- Added endpoints may have drifted due to tolerance, so
-- we need to re-snap the edge to the new nodes before adding it
sql := 'SELECT n1.geom as sn, n2.geom as en FROM ' || quote_ident(atopology)
@@ -3997,6 +4056,7 @@ BEGIN
|| '.node n2 WHERE n1.node_id = '
|| start_node || ' AND n2.node_id = ' || end_node;
+
EXECUTE sql INTO STRICT rec2;
snapped := ST_SetPoint(
@@ -4007,8 +4067,10 @@ BEGIN
snapped := ST_CollectionExtract(ST_MakeValid(snapped), 2);
+
-- Check if the so-snapped edge collapsed (see #1650)
IF ST_IsEmpty(snapped) THEN
+
CONTINUE;
END IF;
@@ -4016,11 +4078,14 @@ BEGIN
sql := 'SELECT edge_id FROM ' || quote_ident(atopology)
|| '.edge_data WHERE ST_Equals(geom, ' || quote_literal(snapped::text)
|| '::geometry)';
+
EXECUTE sql INTO id;
IF id IS NULL THEN
id := topology.ST_AddEdgeModFace(atopology, start_node, end_node,
snapped);
+
ELSE
+
END IF;
RETURN NEXT id;
@@ -4062,9 +4127,11 @@ BEGIN
-- 1. Extract boundary
boundary := ST_Boundary(apoly);
+
-- 2. Add boundaries as edges
FOR rec IN SELECT (ST_Dump(boundary)).geom LOOP
edges := array_cat(edges, array_agg(x)) FROM ( select topology.TopoGeo_addLinestring(atopology, rec.geom, tol) as x ) as foo;
+
END LOOP;
-- 3. Find faces covered by input polygon
@@ -4073,10 +4140,12 @@ BEGIN
|| '.face f WHERE f.mbr && '
|| quote_literal(apoly::text)
|| '::geometry';
+
FOR rec IN EXECUTE sql LOOP
-- check for actual containment
fgeom := ST_PointOnSurface(ST_GetFaceGeometry(atopology, rec.face_id));
IF NOT ST_Covers(apoly, fgeom) THEN
+
CONTINUE;
END IF;
RETURN NEXT rec.face_id;
@@ -4102,10 +4171,11 @@ END
$$
LANGUAGE 'plpgsql';
--} TopoGeo_AddGeometry
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4154,11 +4224,12 @@ $$
LANGUAGE 'plpgsql';
--} Polygonize(toponame)
+
-- TopoElement
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4172,7 +4243,7 @@ LANGUAGE 'plpgsql';
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -4214,11 +4285,12 @@ CREATE AGGREGATE topology.TopoElementArray_agg(
);
--} TopoElementArray_agg
+
-- TopoGeometry
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4274,10 +4346,11 @@ $$
$$
LANGUAGE 'sql' STABLE STRICT;
-- }
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011-2012 Sandro Santilli <strk@keybit.net>
--
@@ -4289,7 +4362,7 @@ LANGUAGE 'sql' STABLE STRICT;
-- {
-- Convert a simple geometry to a topologically-defined one
--
--- See http://trac.osgeo.org/postgis/ticket/1017
+-- See http:
--
-- }{
CREATE OR REPLACE FUNCTION topology.toTopoGeom(ageom Geometry, atopology varchar, alayer int, atolerance float8 DEFAULT 0)
@@ -4414,6 +4487,7 @@ BEGIN
|| '.relation(topogeo_id, layer_id, element_type, element_id) VALUES ('
|| rec.id || ',' || rec.lyr || ',' || rec.type
|| ',' || rec.primitive || ')';
+
EXECUTE sql;
END LOOP;
@@ -4424,11 +4498,12 @@ $$
LANGUAGE 'plpgsql' VOLATILE STRICT;
-- }
+
-- GML
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4442,7 +4517,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -4989,13 +5064,14 @@ $$ LANGUAGE 'sql' STABLE; -- does NOT write into visited table
-- } AsGML(TopoGeometry)
+
--=} POSTGIS-SPECIFIC block
-- SQL/MM block
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011, 2012 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -5101,6 +5177,7 @@ BEGIN
LOOP
+
retrec.sequence = n;
retrec.edge = rec.edge_id;
@@ -5399,6 +5476,7 @@ BEGIN
|| ' AND l.layer_id = r.layer_id AND abs(r.element_id) = '
|| e1id
;
+
EXECUTE sql;
@@ -5747,6 +5825,7 @@ BEGIN
|| 'WHERE l.level = 0 AND l.feature_type = 2 '
|| ' AND l.topology_id = ' || topoid
|| ' AND abs(r.element_id) = ' || e1id ;
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented dropping edge %',
rec.topogeo_id, rec.layer_id,
@@ -5771,6 +5850,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge < 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -5788,6 +5868,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge > 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -5803,6 +5884,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge < 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -5820,6 +5902,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge > 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -5865,6 +5948,7 @@ BEGIN
END IF; -- }
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented healing faces % and %',
rec.topogeo_id, rec.layer_id,
@@ -5907,6 +5991,7 @@ BEGIN
|| '.face WHERE face_id IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
END IF; -- }
@@ -5917,6 +6002,7 @@ BEGIN
|| ' WHERE left_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update right_face for all edges still referencing old faces
@@ -5925,6 +6011,7 @@ BEGIN
|| ' WHERE right_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update containing_face for all nodes still referencing old faces
@@ -5933,6 +6020,7 @@ BEGIN
|| ' WHERE containing_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- NOT IN THE SPECS:
@@ -5945,6 +6033,7 @@ BEGIN
|| ' AND l.topology_id = ' || topoid
|| ' AND l.layer_id = r.layer_id AND abs(r.element_id) = '
|| e1rec.left_face;
+
EXECUTE sql;
sql := 'UPDATE ' || quote_ident(toponame)
|| '.relation r '
@@ -5953,6 +6042,7 @@ BEGIN
|| ' AND l.topology_id = ' || topoid
|| ' AND l.layer_id = r.layer_id AND r.element_id = '
|| e1rec.right_face;
+
EXECUTE sql;
END IF; -- } two faces healed...
@@ -5960,6 +6050,7 @@ BEGIN
-- Delete the edge
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.edge_data WHERE edge_id = ' || e1id;
+
EXECUTE sql;
-- Check if any of the edge nodes remains isolated,
@@ -5971,6 +6062,7 @@ BEGIN
|| e1rec.end_node || ') AND NOT EXISTS (SELECT edge_id FROM '
|| quote_ident(toponame)
|| '.edge_data WHERE start_node = n.node_id OR end_node = n.node_id)';
+
EXECUTE sql;
IF e1rec.right_face != e1rec.left_face THEN -- {
@@ -5979,6 +6071,7 @@ BEGIN
IF e1rec.left_face != 0 THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.left_face;
+
EXECUTE sql;
END IF;
@@ -5987,6 +6080,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.right_face;
+
EXECUTE sql;
END IF;
@@ -6071,6 +6165,7 @@ BEGIN
|| 'WHERE l.level = 0 AND l.feature_type = 2 '
|| ' AND l.topology_id = ' || topoid
|| ' AND abs(r.element_id) = ' || e1id ;
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented dropping edge %',
rec.topogeo_id, rec.layer_id,
@@ -6095,6 +6190,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge < 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -6112,6 +6208,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge > 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -6127,6 +6224,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge < 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -6144,6 +6242,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge > 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -6187,6 +6286,7 @@ BEGIN
END IF; -- }
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented healing faces % and %',
rec.topogeo_id, rec.layer_id,
@@ -6219,6 +6319,7 @@ BEGIN
|| '.face WHERE face_id IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ') ) WHERE face_id = ' || floodfaceid ;
+
EXECUTE sql;
END IF; -- }
@@ -6229,6 +6330,7 @@ BEGIN
|| ' WHERE left_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update right_face for all edges still referencing old faces
@@ -6237,6 +6339,7 @@ BEGIN
|| ' WHERE right_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update containing_face for all nodes still referencing old faces
@@ -6245,6 +6348,7 @@ BEGIN
|| ' WHERE containing_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- NOT IN THE SPECS:
@@ -6259,6 +6363,7 @@ BEGIN
|| e1rec.left_face || ',' || e1rec.right_face
|| ') AND abs(r.element_id) != '
|| floodfaceid; -- could be optimized..
+
EXECUTE sql;
END IF; -- } two faces healed...
@@ -6266,6 +6371,7 @@ BEGIN
-- Delete the edge
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.edge_data WHERE edge_id = ' || e1id;
+
EXECUTE sql;
-- Check if any of the edge nodes remains isolated,
@@ -6277,6 +6383,7 @@ BEGIN
|| e1rec.end_node || ') AND NOT EXISTS (SELECT edge_id FROM '
|| quote_ident(toponame)
|| '.edge_data WHERE start_node = n.node_id OR end_node = n.node_id)';
+
EXECUTE sql;
IF e1rec.right_face != e1rec.left_face THEN -- {
@@ -6286,6 +6393,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.left_face;
+
EXECUTE sql;
END IF;
@@ -6294,6 +6402,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.right_face;
+
EXECUTE sql;
END IF;
@@ -6451,6 +6560,7 @@ BEGIN
sql := sql || ' AND f.face_id = ' || aface;
END IF;
+
EXECUTE sql INTO containingface;
-- If aface was specified, check that it was correct
@@ -6484,6 +6594,7 @@ BEGIN
|| '::geometry,' || containingface
|| ' RETURNING node_id';
+
EXECUTE sql INTO nodeid;
RETURN nodeid;
@@ -6624,7 +6735,7 @@ LANGUAGE 'plpgsql' VOLATILE;
--} ST_RemoveIsoNode
--{
--- According to http://trac.osgeo.org/postgis/ticket/798
+-- According to http:
-- ST_RemoveIsoNode was renamed to ST_RemIsoNode in the final ISO
-- document
--
@@ -6826,6 +6937,7 @@ BEGIN
END LOOP;
+
--RAISE NOTICE 'EdgeId1 % EdgeId2 %', edgeid1, edgeid2;
--RAISE DEBUG 'oldedge.next_left_edge: %', oldedge.next_left_edge;
@@ -7111,6 +7223,7 @@ BEGIN
END LOOP;
+
--
-- Insert the new edge
--
@@ -7618,25 +7731,32 @@ BEGIN
tmp1 := ST_MakeLine(ST_EndPoint(oldedge.geom), ST_StartPoint(oldedge.geom));
+
tmp2 := ST_MakeLine(oldedge.geom, tmp1);
IF ST_NumPoints(tmp2) < 4 THEN
tmp2 := ST_AddPoint(tmp2, ST_StartPoint(oldedge.geom));
END IF;
+
tmp2 := ST_CollectionExtract(ST_MakeValid(ST_MakePolygon(tmp2)), 3);
+
range := ST_MakeLine(acurve, tmp1);
IF ST_NumPoints(range) < 4 THEN
range := ST_AddPoint(range, ST_StartPoint(oldedge.geom));
END IF;
+
range := ST_CollectionExtract(ST_MakeValid(ST_MakePolygon(range)), 3);
+
range := ST_SymDifference(range, tmp2);
+
sql := 'SELECT node_id, geom FROM '
|| quote_ident(atopology)
|| '.node WHERE ST_Contains('
|| quote_literal(range::text)
|| '::geometry, geom) LIMIT 1';
+
FOR rec IN EXECUTE sql LOOP -- {
RAISE EXCEPTION 'Edge motion collision at %', ST_AsText(rec.geom);
END LOOP; -- }
@@ -7652,11 +7772,13 @@ BEGIN
) as pre, NULL::integer[] as post
INTO STRICT snode_info;
+
SELECT topology._ST_AdjacentEdges(
atopology, oldedge.end_node, -anedge
) as pre, NULL::integer[] as post
INTO STRICT enode_info;
+
--}
--
@@ -7674,10 +7796,12 @@ BEGIN
atopology, oldedge.start_node, anedge
);
+
enode_info.post := topology._ST_AdjacentEdges(
atopology, oldedge.end_node, -anedge
);
+
IF snode_info.pre != snode_info.post THEN
RAISE EXCEPTION 'Edge changed disposition around start node %',
oldedge.start_node;
@@ -7754,6 +7878,7 @@ DECLARE
BEGIN
IF oface = 0 AND mbr_only THEN
+
RETURN NULL;
END IF;
@@ -7766,24 +7891,31 @@ BEGIN
INTO STRICT fan.newring_edges;
+
-- You can't get to the other side of an edge forming a ring
IF fan.newring_edges @> ARRAY[-anedge] THEN
+
RETURN 0;
END IF;
+
sql := 'WITH ids as ( select row_number() over () as seq, edge from unnest('
|| quote_literal(fan.newring_edges::text)
|| '::int[] ) u(edge) ), edges AS ( select CASE WHEN i.edge < 0 THEN ST_Reverse(e.geom) ELSE e.geom END as g FROM ids i left join '
|| quote_ident(atopology) || '.edge_data e ON(e.edge_id = abs(i.edge)) ORDER BY seq) SELECT ST_MakePolygon(ST_MakeLine(g.g)) FROM edges g;';
+
EXECUTE sql INTO fan.shell;
+
isccw := NOT ST_OrderingEquals(fan.shell, ST_ForceRHR(fan.shell));
+
IF oface = 0 THEN
IF NOT isccw THEN
+
RETURN NULL;
END IF;
END IF;
@@ -7795,6 +7927,7 @@ BEGIN
|| quote_ident(atopology) || '.face SET mbr = '
|| quote_literal(ST_Envelope(fan.shell)::text)
|| '::geometry WHERE face_id = ' || oface;
+
EXECUTE sql;
END IF; -- }
RETURN NULL;
@@ -7815,6 +7948,7 @@ BEGIN
END IF; -- }
-- Insert new face
+
EXECUTE sql INTO STRICT newface;
-- Update forward edges
@@ -7823,6 +7957,7 @@ BEGIN
|| ' WHERE left_face = ' || oface || ' AND edge_id = ANY ('
|| quote_literal(array( select +(x) from unnest(fan.newring_edges) u(x) )::text)
|| ')';
+
EXECUTE sql;
-- Update backward edges
@@ -7831,12 +7966,15 @@ BEGIN
|| ' WHERE right_face = ' || oface || ' AND edge_id = ANY ('
|| quote_literal(array( select -(x) from unnest(fan.newring_edges) u(x) )::text)
|| ')';
+
EXECUTE sql;
IF oface != 0 AND NOT isccw THEN -- {
-- face shrinked, must update all non-contained edges and nodes
+
ishole := true;
ELSE
+
ishole := false;
END IF; -- }
@@ -7858,6 +7996,7 @@ BEGIN
sql := sql || 'ST_Contains(' || quote_literal(fan.shell::text)
-- We only need to check a single point, but must not be an endpoint
|| '::geometry, ST_Line_Interpolate_Point(geom, 0.2))';
+
EXECUTE sql;
-- Update isolated nodes in new new face
@@ -7867,6 +8006,7 @@ BEGIN
|| ' AND ';
IF ishole THEN sql := sql || 'NOT '; END IF;
sql := sql || 'ST_Contains(' || quote_literal(fan.shell::text) || '::geometry, geom)';
+
EXECUTE sql;
RETURN newface;
@@ -7990,6 +8130,7 @@ BEGIN
|| ')'
LOOP
IF rec.containing_face IS NOT NULL THEN
+
IF newedge.left_face IS NULL THEN
newedge.left_face := rec.containing_face;
newedge.right_face := rec.containing_face;
@@ -8097,6 +8238,7 @@ BEGIN
-- Find links on start node -- {
+
sql :=
'SELECT edge_id, -1 AS end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8142,6 +8284,7 @@ BEGIN
END IF;
+
az = az - span.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8181,6 +8324,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN span.was_isolated = true; END IF;
ELSE
@@ -8197,12 +8341,16 @@ BEGIN
END IF;
+
+
+
-- } start_node analysis
-- Find links on end_node {
+
sql :=
'SELECT edge_id, -1 as end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8244,6 +8392,7 @@ BEGIN
END IF;
+
az := az - epan.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8283,6 +8432,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN epan.was_isolated = true; END IF;
ELSE
@@ -8301,6 +8451,9 @@ BEGIN
-- } end_node analysis
+
+
+
----------------------------------------------------------------------
--
-- If we don't have faces setup by now we must have encountered
@@ -8396,15 +8549,18 @@ BEGIN
--------------------------------------------
+
SELECT topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, false)
INTO newface;
IF newface = 0 THEN
+
RETURN newedge.edge_id;
END IF;
newfaces[1] := newface;
+
SELECT topology._ST_AddFaceSplit(atopology, newedge.edge_id, newedge.left_face, false)
INTO newface;
@@ -8427,6 +8583,7 @@ BEGIN
FOR rec IN EXECUTE sql
LOOP
+
-- Add reference to the other face
sql := 'INSERT INTO ' || quote_ident(atopology)
|| '.relation VALUES( ' || rec.topogeo_id
@@ -8564,6 +8721,7 @@ BEGIN
|| ')'
LOOP
IF rec.containing_face IS NOT NULL THEN
+
IF newedge.left_face IS NULL THEN
newedge.left_face := rec.containing_face;
newedge.right_face := rec.containing_face;
@@ -8669,6 +8827,7 @@ BEGIN
-- Find links on start node -- {
+
sql :=
'SELECT edge_id, -1 AS end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8714,6 +8873,7 @@ BEGIN
END IF;
+
az = az - span.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8753,6 +8913,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN span.was_isolated = true; END IF;
ELSE
@@ -8769,12 +8930,16 @@ BEGIN
END IF;
+
+
+
-- } start_node analysis
-- Find links on end_node {
+
sql :=
'SELECT edge_id, -1 as end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8816,6 +8981,7 @@ BEGIN
END IF;
+
az := az - epan.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8855,6 +9021,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN epan.was_isolated = true; END IF;
ELSE
@@ -8873,6 +9040,9 @@ BEGIN
-- } end_node analysis
+
+
+
----------------------------------------------------------------------
--
-- If we don't have faces setup by now we must have encountered
@@ -8967,20 +9137,25 @@ BEGIN
-- Check face splitting
--------------------------------------------
+
SELECT topology._ST_AddFaceSplit(atopology, newedge.edge_id, newedge.left_face, false)
INTO newface;
IF newface = 0 THEN
+
RETURN newedge.edge_id;
END IF;
IF newface IS NULL THEN -- must be forming a maximal ring in universal face
+
SELECT topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, false)
INTO newface;
ELSE
+
PERFORM topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, true);
END IF;
IF newface IS NULL THEN
+
RETURN newedge.edge_id;
END IF;
@@ -9004,6 +9179,7 @@ BEGIN
FOR rec IN EXECUTE sql
LOOP
+
-- Add reference to the other face
sql := 'INSERT INTO ' || quote_ident(atopology)
|| '.relation VALUES( ' || rec.topogeo_id
@@ -9134,6 +9310,7 @@ BEGIN
END; -- }
+
--
-- Node input linework with itself
--
@@ -9147,6 +9324,7 @@ BEGIN
) as linework INTO STRICT nodededges;
+
--
-- Linemerge the resulting edges, to reduce the working set
-- NOTE: this is more of a workaround for GEOS splitting overlapping
@@ -9156,6 +9334,7 @@ BEGIN
+
--
-- Collect input points and input lines endpoints
--
@@ -9169,6 +9348,7 @@ BEGIN
) as nodes INTO STRICT points;
+
--
-- Further split edges by points
-- TODO: optimize this adding ST_Split support for multiline/multipoint
@@ -9183,6 +9363,7 @@ BEGIN
SELECT ST_UnaryUnion(nodededges) INTO STRICT nodededges;
+
--
-- Collect all nodes (from points and noded linework endpoints)
--
@@ -9201,6 +9382,7 @@ BEGIN
) as endpoints INTO points;
+
--
-- Add all nodes as isolated so that
-- later calls to AddEdgeModFace will tweak their being
@@ -9231,11 +9413,12 @@ LANGUAGE 'plpgsql' VOLATILE;
--=} SQL/MM block
+
-- The following files needs getfaceedges_returntype, defined in sqlmm.sql
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 2012 Sandro Santilli <strk@keybit.net>
--
@@ -9245,7 +9428,7 @@ LANGUAGE 'plpgsql' VOLATILE;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -9312,10 +9495,11 @@ END
$$
LANGUAGE 'plpgsql' STABLE;
--} GetRingEdges
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2012 Sandro Santilli <strk@keybit.net>
--
@@ -9356,9 +9540,11 @@ BEGIN
|| ' UNION ALL SELECT -edge_id, ST_Azimuth(ST_EndPoint(geom), ST_PointN(geom, ST_NumPoints(geom)-1)) FROM incident_edges WHERE end_node = ' || anode
|| ' ORDER BY az';
+
FOR rec IN EXECUTE sql
LOOP -- incident edges {
+
n := n + 1;
retrec.sequence := n;
retrec.edge := rec.edge_id;
@@ -9370,11 +9556,12 @@ $$
LANGUAGE 'plpgsql' STABLE;
--} GetRingEdges
+
--general management --
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://www.postgis.org
+-- http:
--
-- Copyright (C) 2011 Regina Obe <lr@pcorp.us>
--
@@ -9413,6 +9600,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
--} AddToSearchPath
+
CREATE OR REPLACE FUNCTION postgis_topology_scripts_installed() RETURNS text
AS $$ SELECT '2.0.2'::text || ' r' || 10789::text AS version $$
LANGUAGE 'sql' IMMUTABLE;
diff --git a/gcc/postgis_extension/postgis_topology--2.0.0alpha4--2.0.2.sql b/gpp/postgis_extension/postgis_topology--2.0.0alpha4--2.0.2.sql
index 80c44f9..a257064 100644
--- a/gcc/postgis_extension/postgis_topology--2.0.0alpha4--2.0.2.sql
+++ b/gpp/postgis_extension/postgis_topology--2.0.0alpha4--2.0.2.sql
@@ -100,14 +100,12 @@ LANGUAGE plpgsql VOLATILE;
-- during upgrade
SELECT postgis_extension_remove_objects('postgis_topology', 'FUNCTION');
SELECT postgis_extension_remove_objects('postgis_topology', 'AGGREGATE');
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: topology.sql.in.c 10643 2012-11-05 10:25:41Z strk $
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -306,6 +304,23 @@ SELECT postgis_extension_remove_objects('postgis_topology', 'AGGREGATE');
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-- Doing everything outside of a transaction helps
-- upgrading in the best case.
@@ -481,7 +496,9 @@ ALTER DOMAIN topology.TopoElement ADD
array_lower(VALUE, 1) = 1
);
ALTER DOMAIN topology.TopoElement DROP CONSTRAINT
+
IF EXISTS
+
type_range;
ALTER DOMAIN topology.TopoElement ADD
CONSTRAINT type_range CHECK (
@@ -777,6 +794,7 @@ BEGIN
-- corrupting the topology anyway ...
--
+
RETURN newlayer_id;
END;
$$
@@ -1120,6 +1138,7 @@ BEGIN
|| ') as obj ORDER BY obj';
+
-- TODO: why not using array_agg here ?
i = 1;
@@ -1517,7 +1536,7 @@ BEGIN
--
-- Closed lines have no boundary, so endpoint
-- intersection would be considered interior
- -- See http://trac.osgeo.org/postgis/ticket/770
+ -- See http:
-- See also full explanation in topology.AddEdge
--
@@ -1681,6 +1700,7 @@ BEGIN
END LOOP;
+
DROP TABLE face_check;
RETURN;
@@ -1910,7 +1930,7 @@ BEGIN
------- Indexes on left_face and right_face of edge_data
------- NOTE: these indexes speed up GetFaceGeometry (and thus
------- TopoGeometry::Geometry) by a factor of 10 !
- ------- See http://trac.osgeo.org/postgis/ticket/806
+ ------- See http:
EXECUTE 'CREATE INDEX edge_left_face_idx ON '
|| quote_ident(atopology)
|| '.edge_data (left_face);';
@@ -1921,7 +1941,7 @@ BEGIN
------- Indexes on start_node and end_node of edge_data
------- NOTE: this indexes speed up node deletion
------- by a factor of 1000 !
- ------- See http://trac.osgeo.org/postgis/ticket/2082
+ ------- See http:
EXECUTE 'CREATE INDEX edge_start_node_idx ON '
|| quote_ident(atopology)
|| '.edge_data (start_node);';
@@ -2029,7 +2049,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -2180,10 +2200,11 @@ $$
LANGUAGE 'plpgsql' STABLE STRICT;
--} TopologySummary
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -2280,11 +2301,12 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
--} TopologySummary
+
-- Spatial predicates
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011-2012 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -2798,11 +2820,12 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--} equals(TopoGeometry, TopoGeometry)
+
-- Querying
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -2888,10 +2911,11 @@ $$
LANGUAGE 'plpgsql' STABLE STRICT;
--} GetNodeByPoint
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -2979,10 +3003,11 @@ END
$$
LANGUAGE 'plpgsql' STABLE STRICT;
--} GetEdgeByPoint
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -3138,11 +3163,12 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--} GetFaceByPoint
+
-- Populating
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010-2012 Sandro Santilli <strk@keybit.net>
--
@@ -3163,7 +3189,7 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--
--
-- A pragmatic test conducted using algoritm shown here:
--- http://stackoverflow.com/questions/7408407/generate-next-largest-or-smallest-representable-floating-point-number-without-bi
+-- http:
-- showed the "tolerance" growing by an order of magnitude proportionally
-- with the order of magnitude of the input, starting with something like
-- 3.5527136788005009294e-15 for the starting value of 9.0
@@ -3219,7 +3245,7 @@ $$ LANGUAGE 'plpgsql' STABLE STRICT;
-- The newly added nodes have no containing face.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3287,6 +3313,7 @@ BEGIN
IF setContainingFace THEN
containing_face := topology.GetFaceByPoint(atopology, apoint, 0);
+
ELSE
containing_face := NULL;
END IF;
@@ -3346,7 +3373,7 @@ LANGUAGE 'sql' VOLATILE;
-- Calling code is expected to do further linking.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3435,6 +3462,7 @@ BEGIN
-- Reuse an EQUAL edge (be it closed or not)
IF ST_RelateMatch(rec.im, '1FFF*FFF2') THEN
+
RETURN rec.edge_id;
END IF;
@@ -3539,7 +3567,7 @@ LANGUAGE 'plpgsql' VOLATILE;
-- o The polygon overlaps an existing face.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3661,6 +3689,7 @@ BEGIN
ST_Line_Locate_Point(bounds, p2);
+
IF right_side THEN
right_edges := array_append(right_edges, rec.edge_id);
old_faceid = rec.right_face;
@@ -3687,6 +3716,8 @@ BEGIN
END IF;
+
+
--
-- Check that all edges found, taken togheter,
-- fully match the ring boundary and nothing more
@@ -3706,8 +3737,10 @@ BEGIN
IF faceid IS NOT NULL AND faceid != 0 THEN
IF NOT force_new THEN
+
RETURN faceid;
ELSE
+
END IF;
END IF;
@@ -3834,12 +3867,14 @@ BEGIN
|| tol || ') ORDER BY ST_Distance('
|| quote_literal(apoint::text)
|| '::geometry, a.geom) LIMIT 1;';
+
EXECUTE sql INTO id;
IF id IS NOT NULL THEN
RETURN id;
END IF;
+
-- 2. Check if any existing edge falls within tolerance
-- and if so split it by a point projected on it
sql := 'SELECT a.edge_id, a.geom FROM '
@@ -3849,35 +3884,42 @@ BEGIN
|| tol || ') ORDER BY ST_Distance('
|| quote_literal(apoint::text)
|| '::geometry, a.geom) LIMIT 1;';
+
EXECUTE sql INTO rec;
IF rec IS NOT NULL THEN
-- project point to line, split edge by point
prj := ST_ClosestPoint(rec.geom, apoint);
-- This is a workaround for ClosestPoint lack of Z support:
- -- http://trac.osgeo.org/postgis/ticket/2033
+ -- http:
z := ST_Z(apoint);
IF z IS NOT NULL THEN
prj := ST_Translate(ST_Force_3DZ(prj), 0, 0, z); -- no ST_SetZ ...
END IF;
+
IF NOT ST_Contains(rec.geom, prj) THEN
+
-- The tolerance must be big enough for snapping to happen
-- and small enough to snap only to the projected point.
-- Unfortunately ST_Distance returns 0 because it also uses
-- a projected point internally, so we need another way.
snaptol := topology._st_mintolerance(prj);
+
snapedge := ST_Snap(rec.geom, prj, snaptol);
-- Snapping currently snaps the first point below tolerance
-- so may possibly move first point. See ticket #1631
IF NOT ST_Equals(ST_StartPoint(rec.geom), ST_StartPoint(snapedge))
THEN
+
snapedge := ST_MakeLine(ST_StartPoint(rec.geom), snapedge);
END IF;
+
PERFORM ST_ChangeEdgeGeom(atopology, rec.edge_id, snapedge);
END IF;
id := topology.ST_ModEdgeSplit(atopology, rec.edge_id, prj);
ELSE
+
id := topology.ST_AddIsoNode(atopology, NULL, apoint);
END IF;
@@ -3923,6 +3965,7 @@ BEGIN
-- 1. Self-node
noded := ST_UnaryUnion(aline);
+
-- 2. Node to edges falling within tol distance
sql := 'WITH nearby AS ( SELECT e.geom FROM '
|| quote_ident(atopology)
@@ -3930,20 +3973,27 @@ BEGIN
|| quote_literal(noded::text)
|| '::geometry, '
|| tol || ') ) SELECT st_collect(geom) FROM nearby;';
+
EXECUTE sql INTO iedges;
IF iedges IS NOT NULL THEN
+
snapped := ST_Snap(noded, iedges, tol);
+
noded := ST_Difference(snapped, iedges);
+
set1 := ST_Intersection(snapped, iedges);
+
set2 := ST_LineMerge(set1);
+
noded := ST_Union(noded, set2);
+
END IF;
-- 2.1. Node with existing nodes within tol
@@ -3954,26 +4004,32 @@ BEGIN
|| quote_literal(noded::text)
|| '::geometry, '
|| tol || ') ) SELECT st_collect(geom) FROM nearby;';
+
EXECUTE sql INTO inodes;
IF inodes IS NOT NULL THEN -- {
+
-- TODO: consider snapping once against all elements
--- (rather than once with edges and once with nodes)
noded := ST_Snap(noded, inodes, tol);
+
FOR rec IN SELECT (ST_Dump(inodes)).*
LOOP
-- Use the node to split edges
SELECT ST_Collect(geom)
FROM ST_Dump(ST_Split(noded, rec.geom))
INTO STRICT noded;
+
END LOOP;
+
-- re-node to account for ST_Snap introduced self-intersections
- -- See http://trac.osgeo.org/postgis/ticket/1714
+ -- See http:
-- TODO: consider running UnaryUnion once after all noding
noded := ST_UnaryUnion(noded);
+
END IF; -- }
-- 3. For each (now-noded) segment, insert an edge
@@ -3982,14 +4038,17 @@ BEGIN
-- TODO: skip point elements ?
+
start_node := topology.TopoGeo_AddPoint(atopology,
ST_StartPoint(rec.geom),
tol);
+
end_node := topology.TopoGeo_AddPoint(atopology,
ST_EndPoint(rec.geom),
tol);
+
-- Added endpoints may have drifted due to tolerance, so
-- we need to re-snap the edge to the new nodes before adding it
sql := 'SELECT n1.geom as sn, n2.geom as en FROM ' || quote_ident(atopology)
@@ -3997,6 +4056,7 @@ BEGIN
|| '.node n2 WHERE n1.node_id = '
|| start_node || ' AND n2.node_id = ' || end_node;
+
EXECUTE sql INTO STRICT rec2;
snapped := ST_SetPoint(
@@ -4007,8 +4067,10 @@ BEGIN
snapped := ST_CollectionExtract(ST_MakeValid(snapped), 2);
+
-- Check if the so-snapped edge collapsed (see #1650)
IF ST_IsEmpty(snapped) THEN
+
CONTINUE;
END IF;
@@ -4016,11 +4078,14 @@ BEGIN
sql := 'SELECT edge_id FROM ' || quote_ident(atopology)
|| '.edge_data WHERE ST_Equals(geom, ' || quote_literal(snapped::text)
|| '::geometry)';
+
EXECUTE sql INTO id;
IF id IS NULL THEN
id := topology.ST_AddEdgeModFace(atopology, start_node, end_node,
snapped);
+
ELSE
+
END IF;
RETURN NEXT id;
@@ -4062,9 +4127,11 @@ BEGIN
-- 1. Extract boundary
boundary := ST_Boundary(apoly);
+
-- 2. Add boundaries as edges
FOR rec IN SELECT (ST_Dump(boundary)).geom LOOP
edges := array_cat(edges, array_agg(x)) FROM ( select topology.TopoGeo_addLinestring(atopology, rec.geom, tol) as x ) as foo;
+
END LOOP;
-- 3. Find faces covered by input polygon
@@ -4073,10 +4140,12 @@ BEGIN
|| '.face f WHERE f.mbr && '
|| quote_literal(apoly::text)
|| '::geometry';
+
FOR rec IN EXECUTE sql LOOP
-- check for actual containment
fgeom := ST_PointOnSurface(ST_GetFaceGeometry(atopology, rec.face_id));
IF NOT ST_Covers(apoly, fgeom) THEN
+
CONTINUE;
END IF;
RETURN NEXT rec.face_id;
@@ -4102,10 +4171,11 @@ END
$$
LANGUAGE 'plpgsql';
--} TopoGeo_AddGeometry
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4154,11 +4224,12 @@ $$
LANGUAGE 'plpgsql';
--} Polygonize(toponame)
+
-- TopoElement
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4172,7 +4243,7 @@ LANGUAGE 'plpgsql';
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -4214,11 +4285,12 @@ CREATE AGGREGATE topology.TopoElementArray_agg(
);
--} TopoElementArray_agg
+
-- TopoGeometry
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4274,10 +4346,11 @@ $$
$$
LANGUAGE 'sql' STABLE STRICT;
-- }
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011-2012 Sandro Santilli <strk@keybit.net>
--
@@ -4289,7 +4362,7 @@ LANGUAGE 'sql' STABLE STRICT;
-- {
-- Convert a simple geometry to a topologically-defined one
--
--- See http://trac.osgeo.org/postgis/ticket/1017
+-- See http:
--
-- }{
CREATE OR REPLACE FUNCTION topology.toTopoGeom(ageom Geometry, atopology varchar, alayer int, atolerance float8 DEFAULT 0)
@@ -4414,6 +4487,7 @@ BEGIN
|| '.relation(topogeo_id, layer_id, element_type, element_id) VALUES ('
|| rec.id || ',' || rec.lyr || ',' || rec.type
|| ',' || rec.primitive || ')';
+
EXECUTE sql;
END LOOP;
@@ -4424,11 +4498,12 @@ $$
LANGUAGE 'plpgsql' VOLATILE STRICT;
-- }
+
-- GML
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4442,7 +4517,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -4989,13 +5064,14 @@ $$ LANGUAGE 'sql' STABLE; -- does NOT write into visited table
-- } AsGML(TopoGeometry)
+
--=} POSTGIS-SPECIFIC block
-- SQL/MM block
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011, 2012 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -5101,6 +5177,7 @@ BEGIN
LOOP
+
retrec.sequence = n;
retrec.edge = rec.edge_id;
@@ -5399,6 +5476,7 @@ BEGIN
|| ' AND l.layer_id = r.layer_id AND abs(r.element_id) = '
|| e1id
;
+
EXECUTE sql;
@@ -5747,6 +5825,7 @@ BEGIN
|| 'WHERE l.level = 0 AND l.feature_type = 2 '
|| ' AND l.topology_id = ' || topoid
|| ' AND abs(r.element_id) = ' || e1id ;
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented dropping edge %',
rec.topogeo_id, rec.layer_id,
@@ -5771,6 +5850,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge < 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -5788,6 +5868,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge > 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -5803,6 +5884,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge < 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -5820,6 +5902,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge > 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -5865,6 +5948,7 @@ BEGIN
END IF; -- }
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented healing faces % and %',
rec.topogeo_id, rec.layer_id,
@@ -5907,6 +5991,7 @@ BEGIN
|| '.face WHERE face_id IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
END IF; -- }
@@ -5917,6 +6002,7 @@ BEGIN
|| ' WHERE left_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update right_face for all edges still referencing old faces
@@ -5925,6 +6011,7 @@ BEGIN
|| ' WHERE right_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update containing_face for all nodes still referencing old faces
@@ -5933,6 +6020,7 @@ BEGIN
|| ' WHERE containing_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- NOT IN THE SPECS:
@@ -5945,6 +6033,7 @@ BEGIN
|| ' AND l.topology_id = ' || topoid
|| ' AND l.layer_id = r.layer_id AND abs(r.element_id) = '
|| e1rec.left_face;
+
EXECUTE sql;
sql := 'UPDATE ' || quote_ident(toponame)
|| '.relation r '
@@ -5953,6 +6042,7 @@ BEGIN
|| ' AND l.topology_id = ' || topoid
|| ' AND l.layer_id = r.layer_id AND r.element_id = '
|| e1rec.right_face;
+
EXECUTE sql;
END IF; -- } two faces healed...
@@ -5960,6 +6050,7 @@ BEGIN
-- Delete the edge
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.edge_data WHERE edge_id = ' || e1id;
+
EXECUTE sql;
-- Check if any of the edge nodes remains isolated,
@@ -5971,6 +6062,7 @@ BEGIN
|| e1rec.end_node || ') AND NOT EXISTS (SELECT edge_id FROM '
|| quote_ident(toponame)
|| '.edge_data WHERE start_node = n.node_id OR end_node = n.node_id)';
+
EXECUTE sql;
IF e1rec.right_face != e1rec.left_face THEN -- {
@@ -5979,6 +6071,7 @@ BEGIN
IF e1rec.left_face != 0 THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.left_face;
+
EXECUTE sql;
END IF;
@@ -5987,6 +6080,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.right_face;
+
EXECUTE sql;
END IF;
@@ -6071,6 +6165,7 @@ BEGIN
|| 'WHERE l.level = 0 AND l.feature_type = 2 '
|| ' AND l.topology_id = ' || topoid
|| ' AND abs(r.element_id) = ' || e1id ;
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented dropping edge %',
rec.topogeo_id, rec.layer_id,
@@ -6095,6 +6190,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge < 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -6112,6 +6208,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge > 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -6127,6 +6224,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge < 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -6144,6 +6242,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge > 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -6187,6 +6286,7 @@ BEGIN
END IF; -- }
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented healing faces % and %',
rec.topogeo_id, rec.layer_id,
@@ -6219,6 +6319,7 @@ BEGIN
|| '.face WHERE face_id IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ') ) WHERE face_id = ' || floodfaceid ;
+
EXECUTE sql;
END IF; -- }
@@ -6229,6 +6330,7 @@ BEGIN
|| ' WHERE left_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update right_face for all edges still referencing old faces
@@ -6237,6 +6339,7 @@ BEGIN
|| ' WHERE right_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update containing_face for all nodes still referencing old faces
@@ -6245,6 +6348,7 @@ BEGIN
|| ' WHERE containing_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- NOT IN THE SPECS:
@@ -6259,6 +6363,7 @@ BEGIN
|| e1rec.left_face || ',' || e1rec.right_face
|| ') AND abs(r.element_id) != '
|| floodfaceid; -- could be optimized..
+
EXECUTE sql;
END IF; -- } two faces healed...
@@ -6266,6 +6371,7 @@ BEGIN
-- Delete the edge
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.edge_data WHERE edge_id = ' || e1id;
+
EXECUTE sql;
-- Check if any of the edge nodes remains isolated,
@@ -6277,6 +6383,7 @@ BEGIN
|| e1rec.end_node || ') AND NOT EXISTS (SELECT edge_id FROM '
|| quote_ident(toponame)
|| '.edge_data WHERE start_node = n.node_id OR end_node = n.node_id)';
+
EXECUTE sql;
IF e1rec.right_face != e1rec.left_face THEN -- {
@@ -6286,6 +6393,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.left_face;
+
EXECUTE sql;
END IF;
@@ -6294,6 +6402,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.right_face;
+
EXECUTE sql;
END IF;
@@ -6451,6 +6560,7 @@ BEGIN
sql := sql || ' AND f.face_id = ' || aface;
END IF;
+
EXECUTE sql INTO containingface;
-- If aface was specified, check that it was correct
@@ -6484,6 +6594,7 @@ BEGIN
|| '::geometry,' || containingface
|| ' RETURNING node_id';
+
EXECUTE sql INTO nodeid;
RETURN nodeid;
@@ -6624,7 +6735,7 @@ LANGUAGE 'plpgsql' VOLATILE;
--} ST_RemoveIsoNode
--{
--- According to http://trac.osgeo.org/postgis/ticket/798
+-- According to http:
-- ST_RemoveIsoNode was renamed to ST_RemIsoNode in the final ISO
-- document
--
@@ -6826,6 +6937,7 @@ BEGIN
END LOOP;
+
--RAISE NOTICE 'EdgeId1 % EdgeId2 %', edgeid1, edgeid2;
--RAISE DEBUG 'oldedge.next_left_edge: %', oldedge.next_left_edge;
@@ -7111,6 +7223,7 @@ BEGIN
END LOOP;
+
--
-- Insert the new edge
--
@@ -7618,25 +7731,32 @@ BEGIN
tmp1 := ST_MakeLine(ST_EndPoint(oldedge.geom), ST_StartPoint(oldedge.geom));
+
tmp2 := ST_MakeLine(oldedge.geom, tmp1);
IF ST_NumPoints(tmp2) < 4 THEN
tmp2 := ST_AddPoint(tmp2, ST_StartPoint(oldedge.geom));
END IF;
+
tmp2 := ST_CollectionExtract(ST_MakeValid(ST_MakePolygon(tmp2)), 3);
+
range := ST_MakeLine(acurve, tmp1);
IF ST_NumPoints(range) < 4 THEN
range := ST_AddPoint(range, ST_StartPoint(oldedge.geom));
END IF;
+
range := ST_CollectionExtract(ST_MakeValid(ST_MakePolygon(range)), 3);
+
range := ST_SymDifference(range, tmp2);
+
sql := 'SELECT node_id, geom FROM '
|| quote_ident(atopology)
|| '.node WHERE ST_Contains('
|| quote_literal(range::text)
|| '::geometry, geom) LIMIT 1';
+
FOR rec IN EXECUTE sql LOOP -- {
RAISE EXCEPTION 'Edge motion collision at %', ST_AsText(rec.geom);
END LOOP; -- }
@@ -7652,11 +7772,13 @@ BEGIN
) as pre, NULL::integer[] as post
INTO STRICT snode_info;
+
SELECT topology._ST_AdjacentEdges(
atopology, oldedge.end_node, -anedge
) as pre, NULL::integer[] as post
INTO STRICT enode_info;
+
--}
--
@@ -7674,10 +7796,12 @@ BEGIN
atopology, oldedge.start_node, anedge
);
+
enode_info.post := topology._ST_AdjacentEdges(
atopology, oldedge.end_node, -anedge
);
+
IF snode_info.pre != snode_info.post THEN
RAISE EXCEPTION 'Edge changed disposition around start node %',
oldedge.start_node;
@@ -7754,6 +7878,7 @@ DECLARE
BEGIN
IF oface = 0 AND mbr_only THEN
+
RETURN NULL;
END IF;
@@ -7766,24 +7891,31 @@ BEGIN
INTO STRICT fan.newring_edges;
+
-- You can't get to the other side of an edge forming a ring
IF fan.newring_edges @> ARRAY[-anedge] THEN
+
RETURN 0;
END IF;
+
sql := 'WITH ids as ( select row_number() over () as seq, edge from unnest('
|| quote_literal(fan.newring_edges::text)
|| '::int[] ) u(edge) ), edges AS ( select CASE WHEN i.edge < 0 THEN ST_Reverse(e.geom) ELSE e.geom END as g FROM ids i left join '
|| quote_ident(atopology) || '.edge_data e ON(e.edge_id = abs(i.edge)) ORDER BY seq) SELECT ST_MakePolygon(ST_MakeLine(g.g)) FROM edges g;';
+
EXECUTE sql INTO fan.shell;
+
isccw := NOT ST_OrderingEquals(fan.shell, ST_ForceRHR(fan.shell));
+
IF oface = 0 THEN
IF NOT isccw THEN
+
RETURN NULL;
END IF;
END IF;
@@ -7795,6 +7927,7 @@ BEGIN
|| quote_ident(atopology) || '.face SET mbr = '
|| quote_literal(ST_Envelope(fan.shell)::text)
|| '::geometry WHERE face_id = ' || oface;
+
EXECUTE sql;
END IF; -- }
RETURN NULL;
@@ -7815,6 +7948,7 @@ BEGIN
END IF; -- }
-- Insert new face
+
EXECUTE sql INTO STRICT newface;
-- Update forward edges
@@ -7823,6 +7957,7 @@ BEGIN
|| ' WHERE left_face = ' || oface || ' AND edge_id = ANY ('
|| quote_literal(array( select +(x) from unnest(fan.newring_edges) u(x) )::text)
|| ')';
+
EXECUTE sql;
-- Update backward edges
@@ -7831,12 +7966,15 @@ BEGIN
|| ' WHERE right_face = ' || oface || ' AND edge_id = ANY ('
|| quote_literal(array( select -(x) from unnest(fan.newring_edges) u(x) )::text)
|| ')';
+
EXECUTE sql;
IF oface != 0 AND NOT isccw THEN -- {
-- face shrinked, must update all non-contained edges and nodes
+
ishole := true;
ELSE
+
ishole := false;
END IF; -- }
@@ -7858,6 +7996,7 @@ BEGIN
sql := sql || 'ST_Contains(' || quote_literal(fan.shell::text)
-- We only need to check a single point, but must not be an endpoint
|| '::geometry, ST_Line_Interpolate_Point(geom, 0.2))';
+
EXECUTE sql;
-- Update isolated nodes in new new face
@@ -7867,6 +8006,7 @@ BEGIN
|| ' AND ';
IF ishole THEN sql := sql || 'NOT '; END IF;
sql := sql || 'ST_Contains(' || quote_literal(fan.shell::text) || '::geometry, geom)';
+
EXECUTE sql;
RETURN newface;
@@ -7990,6 +8130,7 @@ BEGIN
|| ')'
LOOP
IF rec.containing_face IS NOT NULL THEN
+
IF newedge.left_face IS NULL THEN
newedge.left_face := rec.containing_face;
newedge.right_face := rec.containing_face;
@@ -8097,6 +8238,7 @@ BEGIN
-- Find links on start node -- {
+
sql :=
'SELECT edge_id, -1 AS end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8142,6 +8284,7 @@ BEGIN
END IF;
+
az = az - span.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8181,6 +8324,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN span.was_isolated = true; END IF;
ELSE
@@ -8197,12 +8341,16 @@ BEGIN
END IF;
+
+
+
-- } start_node analysis
-- Find links on end_node {
+
sql :=
'SELECT edge_id, -1 as end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8244,6 +8392,7 @@ BEGIN
END IF;
+
az := az - epan.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8283,6 +8432,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN epan.was_isolated = true; END IF;
ELSE
@@ -8301,6 +8451,9 @@ BEGIN
-- } end_node analysis
+
+
+
----------------------------------------------------------------------
--
-- If we don't have faces setup by now we must have encountered
@@ -8396,15 +8549,18 @@ BEGIN
--------------------------------------------
+
SELECT topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, false)
INTO newface;
IF newface = 0 THEN
+
RETURN newedge.edge_id;
END IF;
newfaces[1] := newface;
+
SELECT topology._ST_AddFaceSplit(atopology, newedge.edge_id, newedge.left_face, false)
INTO newface;
@@ -8427,6 +8583,7 @@ BEGIN
FOR rec IN EXECUTE sql
LOOP
+
-- Add reference to the other face
sql := 'INSERT INTO ' || quote_ident(atopology)
|| '.relation VALUES( ' || rec.topogeo_id
@@ -8564,6 +8721,7 @@ BEGIN
|| ')'
LOOP
IF rec.containing_face IS NOT NULL THEN
+
IF newedge.left_face IS NULL THEN
newedge.left_face := rec.containing_face;
newedge.right_face := rec.containing_face;
@@ -8669,6 +8827,7 @@ BEGIN
-- Find links on start node -- {
+
sql :=
'SELECT edge_id, -1 AS end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8714,6 +8873,7 @@ BEGIN
END IF;
+
az = az - span.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8753,6 +8913,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN span.was_isolated = true; END IF;
ELSE
@@ -8769,12 +8930,16 @@ BEGIN
END IF;
+
+
+
-- } start_node analysis
-- Find links on end_node {
+
sql :=
'SELECT edge_id, -1 as end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8816,6 +8981,7 @@ BEGIN
END IF;
+
az := az - epan.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8855,6 +9021,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN epan.was_isolated = true; END IF;
ELSE
@@ -8873,6 +9040,9 @@ BEGIN
-- } end_node analysis
+
+
+
----------------------------------------------------------------------
--
-- If we don't have faces setup by now we must have encountered
@@ -8967,20 +9137,25 @@ BEGIN
-- Check face splitting
--------------------------------------------
+
SELECT topology._ST_AddFaceSplit(atopology, newedge.edge_id, newedge.left_face, false)
INTO newface;
IF newface = 0 THEN
+
RETURN newedge.edge_id;
END IF;
IF newface IS NULL THEN -- must be forming a maximal ring in universal face
+
SELECT topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, false)
INTO newface;
ELSE
+
PERFORM topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, true);
END IF;
IF newface IS NULL THEN
+
RETURN newedge.edge_id;
END IF;
@@ -9004,6 +9179,7 @@ BEGIN
FOR rec IN EXECUTE sql
LOOP
+
-- Add reference to the other face
sql := 'INSERT INTO ' || quote_ident(atopology)
|| '.relation VALUES( ' || rec.topogeo_id
@@ -9134,6 +9310,7 @@ BEGIN
END; -- }
+
--
-- Node input linework with itself
--
@@ -9147,6 +9324,7 @@ BEGIN
) as linework INTO STRICT nodededges;
+
--
-- Linemerge the resulting edges, to reduce the working set
-- NOTE: this is more of a workaround for GEOS splitting overlapping
@@ -9156,6 +9334,7 @@ BEGIN
+
--
-- Collect input points and input lines endpoints
--
@@ -9169,6 +9348,7 @@ BEGIN
) as nodes INTO STRICT points;
+
--
-- Further split edges by points
-- TODO: optimize this adding ST_Split support for multiline/multipoint
@@ -9183,6 +9363,7 @@ BEGIN
SELECT ST_UnaryUnion(nodededges) INTO STRICT nodededges;
+
--
-- Collect all nodes (from points and noded linework endpoints)
--
@@ -9201,6 +9382,7 @@ BEGIN
) as endpoints INTO points;
+
--
-- Add all nodes as isolated so that
-- later calls to AddEdgeModFace will tweak their being
@@ -9231,11 +9413,12 @@ LANGUAGE 'plpgsql' VOLATILE;
--=} SQL/MM block
+
-- The following files needs getfaceedges_returntype, defined in sqlmm.sql
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 2012 Sandro Santilli <strk@keybit.net>
--
@@ -9245,7 +9428,7 @@ LANGUAGE 'plpgsql' VOLATILE;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -9312,10 +9495,11 @@ END
$$
LANGUAGE 'plpgsql' STABLE;
--} GetRingEdges
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2012 Sandro Santilli <strk@keybit.net>
--
@@ -9356,9 +9540,11 @@ BEGIN
|| ' UNION ALL SELECT -edge_id, ST_Azimuth(ST_EndPoint(geom), ST_PointN(geom, ST_NumPoints(geom)-1)) FROM incident_edges WHERE end_node = ' || anode
|| ' ORDER BY az';
+
FOR rec IN EXECUTE sql
LOOP -- incident edges {
+
n := n + 1;
retrec.sequence := n;
retrec.edge := rec.edge_id;
@@ -9370,11 +9556,12 @@ $$
LANGUAGE 'plpgsql' STABLE;
--} GetRingEdges
+
--general management --
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://www.postgis.org
+-- http:
--
-- Copyright (C) 2011 Regina Obe <lr@pcorp.us>
--
@@ -9413,6 +9600,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
--} AddToSearchPath
+
CREATE OR REPLACE FUNCTION postgis_topology_scripts_installed() RETURNS text
AS $$ SELECT '2.0.2'::text || ' r' || 10789::text AS version $$
LANGUAGE 'sql' IMMUTABLE;
diff --git a/gcc/postgis_extension/postgis_topology--2.0.0alpha5--2.0.2.sql b/gpp/postgis_extension/postgis_topology--2.0.0alpha5--2.0.2.sql
index 80c44f9..a257064 100644
--- a/gcc/postgis_extension/postgis_topology--2.0.0alpha5--2.0.2.sql
+++ b/gpp/postgis_extension/postgis_topology--2.0.0alpha5--2.0.2.sql
@@ -100,14 +100,12 @@ LANGUAGE plpgsql VOLATILE;
-- during upgrade
SELECT postgis_extension_remove_objects('postgis_topology', 'FUNCTION');
SELECT postgis_extension_remove_objects('postgis_topology', 'AGGREGATE');
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: topology.sql.in.c 10643 2012-11-05 10:25:41Z strk $
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -306,6 +304,23 @@ SELECT postgis_extension_remove_objects('postgis_topology', 'AGGREGATE');
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-- Doing everything outside of a transaction helps
-- upgrading in the best case.
@@ -481,7 +496,9 @@ ALTER DOMAIN topology.TopoElement ADD
array_lower(VALUE, 1) = 1
);
ALTER DOMAIN topology.TopoElement DROP CONSTRAINT
+
IF EXISTS
+
type_range;
ALTER DOMAIN topology.TopoElement ADD
CONSTRAINT type_range CHECK (
@@ -777,6 +794,7 @@ BEGIN
-- corrupting the topology anyway ...
--
+
RETURN newlayer_id;
END;
$$
@@ -1120,6 +1138,7 @@ BEGIN
|| ') as obj ORDER BY obj';
+
-- TODO: why not using array_agg here ?
i = 1;
@@ -1517,7 +1536,7 @@ BEGIN
--
-- Closed lines have no boundary, so endpoint
-- intersection would be considered interior
- -- See http://trac.osgeo.org/postgis/ticket/770
+ -- See http:
-- See also full explanation in topology.AddEdge
--
@@ -1681,6 +1700,7 @@ BEGIN
END LOOP;
+
DROP TABLE face_check;
RETURN;
@@ -1910,7 +1930,7 @@ BEGIN
------- Indexes on left_face and right_face of edge_data
------- NOTE: these indexes speed up GetFaceGeometry (and thus
------- TopoGeometry::Geometry) by a factor of 10 !
- ------- See http://trac.osgeo.org/postgis/ticket/806
+ ------- See http:
EXECUTE 'CREATE INDEX edge_left_face_idx ON '
|| quote_ident(atopology)
|| '.edge_data (left_face);';
@@ -1921,7 +1941,7 @@ BEGIN
------- Indexes on start_node and end_node of edge_data
------- NOTE: this indexes speed up node deletion
------- by a factor of 1000 !
- ------- See http://trac.osgeo.org/postgis/ticket/2082
+ ------- See http:
EXECUTE 'CREATE INDEX edge_start_node_idx ON '
|| quote_ident(atopology)
|| '.edge_data (start_node);';
@@ -2029,7 +2049,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -2180,10 +2200,11 @@ $$
LANGUAGE 'plpgsql' STABLE STRICT;
--} TopologySummary
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -2280,11 +2301,12 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
--} TopologySummary
+
-- Spatial predicates
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011-2012 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -2798,11 +2820,12 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--} equals(TopoGeometry, TopoGeometry)
+
-- Querying
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -2888,10 +2911,11 @@ $$
LANGUAGE 'plpgsql' STABLE STRICT;
--} GetNodeByPoint
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -2979,10 +3003,11 @@ END
$$
LANGUAGE 'plpgsql' STABLE STRICT;
--} GetEdgeByPoint
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -3138,11 +3163,12 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--} GetFaceByPoint
+
-- Populating
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010-2012 Sandro Santilli <strk@keybit.net>
--
@@ -3163,7 +3189,7 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--
--
-- A pragmatic test conducted using algoritm shown here:
--- http://stackoverflow.com/questions/7408407/generate-next-largest-or-smallest-representable-floating-point-number-without-bi
+-- http:
-- showed the "tolerance" growing by an order of magnitude proportionally
-- with the order of magnitude of the input, starting with something like
-- 3.5527136788005009294e-15 for the starting value of 9.0
@@ -3219,7 +3245,7 @@ $$ LANGUAGE 'plpgsql' STABLE STRICT;
-- The newly added nodes have no containing face.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3287,6 +3313,7 @@ BEGIN
IF setContainingFace THEN
containing_face := topology.GetFaceByPoint(atopology, apoint, 0);
+
ELSE
containing_face := NULL;
END IF;
@@ -3346,7 +3373,7 @@ LANGUAGE 'sql' VOLATILE;
-- Calling code is expected to do further linking.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3435,6 +3462,7 @@ BEGIN
-- Reuse an EQUAL edge (be it closed or not)
IF ST_RelateMatch(rec.im, '1FFF*FFF2') THEN
+
RETURN rec.edge_id;
END IF;
@@ -3539,7 +3567,7 @@ LANGUAGE 'plpgsql' VOLATILE;
-- o The polygon overlaps an existing face.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3661,6 +3689,7 @@ BEGIN
ST_Line_Locate_Point(bounds, p2);
+
IF right_side THEN
right_edges := array_append(right_edges, rec.edge_id);
old_faceid = rec.right_face;
@@ -3687,6 +3716,8 @@ BEGIN
END IF;
+
+
--
-- Check that all edges found, taken togheter,
-- fully match the ring boundary and nothing more
@@ -3706,8 +3737,10 @@ BEGIN
IF faceid IS NOT NULL AND faceid != 0 THEN
IF NOT force_new THEN
+
RETURN faceid;
ELSE
+
END IF;
END IF;
@@ -3834,12 +3867,14 @@ BEGIN
|| tol || ') ORDER BY ST_Distance('
|| quote_literal(apoint::text)
|| '::geometry, a.geom) LIMIT 1;';
+
EXECUTE sql INTO id;
IF id IS NOT NULL THEN
RETURN id;
END IF;
+
-- 2. Check if any existing edge falls within tolerance
-- and if so split it by a point projected on it
sql := 'SELECT a.edge_id, a.geom FROM '
@@ -3849,35 +3884,42 @@ BEGIN
|| tol || ') ORDER BY ST_Distance('
|| quote_literal(apoint::text)
|| '::geometry, a.geom) LIMIT 1;';
+
EXECUTE sql INTO rec;
IF rec IS NOT NULL THEN
-- project point to line, split edge by point
prj := ST_ClosestPoint(rec.geom, apoint);
-- This is a workaround for ClosestPoint lack of Z support:
- -- http://trac.osgeo.org/postgis/ticket/2033
+ -- http:
z := ST_Z(apoint);
IF z IS NOT NULL THEN
prj := ST_Translate(ST_Force_3DZ(prj), 0, 0, z); -- no ST_SetZ ...
END IF;
+
IF NOT ST_Contains(rec.geom, prj) THEN
+
-- The tolerance must be big enough for snapping to happen
-- and small enough to snap only to the projected point.
-- Unfortunately ST_Distance returns 0 because it also uses
-- a projected point internally, so we need another way.
snaptol := topology._st_mintolerance(prj);
+
snapedge := ST_Snap(rec.geom, prj, snaptol);
-- Snapping currently snaps the first point below tolerance
-- so may possibly move first point. See ticket #1631
IF NOT ST_Equals(ST_StartPoint(rec.geom), ST_StartPoint(snapedge))
THEN
+
snapedge := ST_MakeLine(ST_StartPoint(rec.geom), snapedge);
END IF;
+
PERFORM ST_ChangeEdgeGeom(atopology, rec.edge_id, snapedge);
END IF;
id := topology.ST_ModEdgeSplit(atopology, rec.edge_id, prj);
ELSE
+
id := topology.ST_AddIsoNode(atopology, NULL, apoint);
END IF;
@@ -3923,6 +3965,7 @@ BEGIN
-- 1. Self-node
noded := ST_UnaryUnion(aline);
+
-- 2. Node to edges falling within tol distance
sql := 'WITH nearby AS ( SELECT e.geom FROM '
|| quote_ident(atopology)
@@ -3930,20 +3973,27 @@ BEGIN
|| quote_literal(noded::text)
|| '::geometry, '
|| tol || ') ) SELECT st_collect(geom) FROM nearby;';
+
EXECUTE sql INTO iedges;
IF iedges IS NOT NULL THEN
+
snapped := ST_Snap(noded, iedges, tol);
+
noded := ST_Difference(snapped, iedges);
+
set1 := ST_Intersection(snapped, iedges);
+
set2 := ST_LineMerge(set1);
+
noded := ST_Union(noded, set2);
+
END IF;
-- 2.1. Node with existing nodes within tol
@@ -3954,26 +4004,32 @@ BEGIN
|| quote_literal(noded::text)
|| '::geometry, '
|| tol || ') ) SELECT st_collect(geom) FROM nearby;';
+
EXECUTE sql INTO inodes;
IF inodes IS NOT NULL THEN -- {
+
-- TODO: consider snapping once against all elements
--- (rather than once with edges and once with nodes)
noded := ST_Snap(noded, inodes, tol);
+
FOR rec IN SELECT (ST_Dump(inodes)).*
LOOP
-- Use the node to split edges
SELECT ST_Collect(geom)
FROM ST_Dump(ST_Split(noded, rec.geom))
INTO STRICT noded;
+
END LOOP;
+
-- re-node to account for ST_Snap introduced self-intersections
- -- See http://trac.osgeo.org/postgis/ticket/1714
+ -- See http:
-- TODO: consider running UnaryUnion once after all noding
noded := ST_UnaryUnion(noded);
+
END IF; -- }
-- 3. For each (now-noded) segment, insert an edge
@@ -3982,14 +4038,17 @@ BEGIN
-- TODO: skip point elements ?
+
start_node := topology.TopoGeo_AddPoint(atopology,
ST_StartPoint(rec.geom),
tol);
+
end_node := topology.TopoGeo_AddPoint(atopology,
ST_EndPoint(rec.geom),
tol);
+
-- Added endpoints may have drifted due to tolerance, so
-- we need to re-snap the edge to the new nodes before adding it
sql := 'SELECT n1.geom as sn, n2.geom as en FROM ' || quote_ident(atopology)
@@ -3997,6 +4056,7 @@ BEGIN
|| '.node n2 WHERE n1.node_id = '
|| start_node || ' AND n2.node_id = ' || end_node;
+
EXECUTE sql INTO STRICT rec2;
snapped := ST_SetPoint(
@@ -4007,8 +4067,10 @@ BEGIN
snapped := ST_CollectionExtract(ST_MakeValid(snapped), 2);
+
-- Check if the so-snapped edge collapsed (see #1650)
IF ST_IsEmpty(snapped) THEN
+
CONTINUE;
END IF;
@@ -4016,11 +4078,14 @@ BEGIN
sql := 'SELECT edge_id FROM ' || quote_ident(atopology)
|| '.edge_data WHERE ST_Equals(geom, ' || quote_literal(snapped::text)
|| '::geometry)';
+
EXECUTE sql INTO id;
IF id IS NULL THEN
id := topology.ST_AddEdgeModFace(atopology, start_node, end_node,
snapped);
+
ELSE
+
END IF;
RETURN NEXT id;
@@ -4062,9 +4127,11 @@ BEGIN
-- 1. Extract boundary
boundary := ST_Boundary(apoly);
+
-- 2. Add boundaries as edges
FOR rec IN SELECT (ST_Dump(boundary)).geom LOOP
edges := array_cat(edges, array_agg(x)) FROM ( select topology.TopoGeo_addLinestring(atopology, rec.geom, tol) as x ) as foo;
+
END LOOP;
-- 3. Find faces covered by input polygon
@@ -4073,10 +4140,12 @@ BEGIN
|| '.face f WHERE f.mbr && '
|| quote_literal(apoly::text)
|| '::geometry';
+
FOR rec IN EXECUTE sql LOOP
-- check for actual containment
fgeom := ST_PointOnSurface(ST_GetFaceGeometry(atopology, rec.face_id));
IF NOT ST_Covers(apoly, fgeom) THEN
+
CONTINUE;
END IF;
RETURN NEXT rec.face_id;
@@ -4102,10 +4171,11 @@ END
$$
LANGUAGE 'plpgsql';
--} TopoGeo_AddGeometry
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4154,11 +4224,12 @@ $$
LANGUAGE 'plpgsql';
--} Polygonize(toponame)
+
-- TopoElement
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4172,7 +4243,7 @@ LANGUAGE 'plpgsql';
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -4214,11 +4285,12 @@ CREATE AGGREGATE topology.TopoElementArray_agg(
);
--} TopoElementArray_agg
+
-- TopoGeometry
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4274,10 +4346,11 @@ $$
$$
LANGUAGE 'sql' STABLE STRICT;
-- }
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011-2012 Sandro Santilli <strk@keybit.net>
--
@@ -4289,7 +4362,7 @@ LANGUAGE 'sql' STABLE STRICT;
-- {
-- Convert a simple geometry to a topologically-defined one
--
--- See http://trac.osgeo.org/postgis/ticket/1017
+-- See http:
--
-- }{
CREATE OR REPLACE FUNCTION topology.toTopoGeom(ageom Geometry, atopology varchar, alayer int, atolerance float8 DEFAULT 0)
@@ -4414,6 +4487,7 @@ BEGIN
|| '.relation(topogeo_id, layer_id, element_type, element_id) VALUES ('
|| rec.id || ',' || rec.lyr || ',' || rec.type
|| ',' || rec.primitive || ')';
+
EXECUTE sql;
END LOOP;
@@ -4424,11 +4498,12 @@ $$
LANGUAGE 'plpgsql' VOLATILE STRICT;
-- }
+
-- GML
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4442,7 +4517,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -4989,13 +5064,14 @@ $$ LANGUAGE 'sql' STABLE; -- does NOT write into visited table
-- } AsGML(TopoGeometry)
+
--=} POSTGIS-SPECIFIC block
-- SQL/MM block
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011, 2012 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -5101,6 +5177,7 @@ BEGIN
LOOP
+
retrec.sequence = n;
retrec.edge = rec.edge_id;
@@ -5399,6 +5476,7 @@ BEGIN
|| ' AND l.layer_id = r.layer_id AND abs(r.element_id) = '
|| e1id
;
+
EXECUTE sql;
@@ -5747,6 +5825,7 @@ BEGIN
|| 'WHERE l.level = 0 AND l.feature_type = 2 '
|| ' AND l.topology_id = ' || topoid
|| ' AND abs(r.element_id) = ' || e1id ;
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented dropping edge %',
rec.topogeo_id, rec.layer_id,
@@ -5771,6 +5850,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge < 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -5788,6 +5868,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge > 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -5803,6 +5884,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge < 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -5820,6 +5902,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge > 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -5865,6 +5948,7 @@ BEGIN
END IF; -- }
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented healing faces % and %',
rec.topogeo_id, rec.layer_id,
@@ -5907,6 +5991,7 @@ BEGIN
|| '.face WHERE face_id IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
END IF; -- }
@@ -5917,6 +6002,7 @@ BEGIN
|| ' WHERE left_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update right_face for all edges still referencing old faces
@@ -5925,6 +6011,7 @@ BEGIN
|| ' WHERE right_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update containing_face for all nodes still referencing old faces
@@ -5933,6 +6020,7 @@ BEGIN
|| ' WHERE containing_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- NOT IN THE SPECS:
@@ -5945,6 +6033,7 @@ BEGIN
|| ' AND l.topology_id = ' || topoid
|| ' AND l.layer_id = r.layer_id AND abs(r.element_id) = '
|| e1rec.left_face;
+
EXECUTE sql;
sql := 'UPDATE ' || quote_ident(toponame)
|| '.relation r '
@@ -5953,6 +6042,7 @@ BEGIN
|| ' AND l.topology_id = ' || topoid
|| ' AND l.layer_id = r.layer_id AND r.element_id = '
|| e1rec.right_face;
+
EXECUTE sql;
END IF; -- } two faces healed...
@@ -5960,6 +6050,7 @@ BEGIN
-- Delete the edge
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.edge_data WHERE edge_id = ' || e1id;
+
EXECUTE sql;
-- Check if any of the edge nodes remains isolated,
@@ -5971,6 +6062,7 @@ BEGIN
|| e1rec.end_node || ') AND NOT EXISTS (SELECT edge_id FROM '
|| quote_ident(toponame)
|| '.edge_data WHERE start_node = n.node_id OR end_node = n.node_id)';
+
EXECUTE sql;
IF e1rec.right_face != e1rec.left_face THEN -- {
@@ -5979,6 +6071,7 @@ BEGIN
IF e1rec.left_face != 0 THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.left_face;
+
EXECUTE sql;
END IF;
@@ -5987,6 +6080,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.right_face;
+
EXECUTE sql;
END IF;
@@ -6071,6 +6165,7 @@ BEGIN
|| 'WHERE l.level = 0 AND l.feature_type = 2 '
|| ' AND l.topology_id = ' || topoid
|| ' AND abs(r.element_id) = ' || e1id ;
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented dropping edge %',
rec.topogeo_id, rec.layer_id,
@@ -6095,6 +6190,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge < 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -6112,6 +6208,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge > 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -6127,6 +6224,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge < 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -6144,6 +6242,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge > 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -6187,6 +6286,7 @@ BEGIN
END IF; -- }
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented healing faces % and %',
rec.topogeo_id, rec.layer_id,
@@ -6219,6 +6319,7 @@ BEGIN
|| '.face WHERE face_id IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ') ) WHERE face_id = ' || floodfaceid ;
+
EXECUTE sql;
END IF; -- }
@@ -6229,6 +6330,7 @@ BEGIN
|| ' WHERE left_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update right_face for all edges still referencing old faces
@@ -6237,6 +6339,7 @@ BEGIN
|| ' WHERE right_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update containing_face for all nodes still referencing old faces
@@ -6245,6 +6348,7 @@ BEGIN
|| ' WHERE containing_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- NOT IN THE SPECS:
@@ -6259,6 +6363,7 @@ BEGIN
|| e1rec.left_face || ',' || e1rec.right_face
|| ') AND abs(r.element_id) != '
|| floodfaceid; -- could be optimized..
+
EXECUTE sql;
END IF; -- } two faces healed...
@@ -6266,6 +6371,7 @@ BEGIN
-- Delete the edge
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.edge_data WHERE edge_id = ' || e1id;
+
EXECUTE sql;
-- Check if any of the edge nodes remains isolated,
@@ -6277,6 +6383,7 @@ BEGIN
|| e1rec.end_node || ') AND NOT EXISTS (SELECT edge_id FROM '
|| quote_ident(toponame)
|| '.edge_data WHERE start_node = n.node_id OR end_node = n.node_id)';
+
EXECUTE sql;
IF e1rec.right_face != e1rec.left_face THEN -- {
@@ -6286,6 +6393,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.left_face;
+
EXECUTE sql;
END IF;
@@ -6294,6 +6402,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.right_face;
+
EXECUTE sql;
END IF;
@@ -6451,6 +6560,7 @@ BEGIN
sql := sql || ' AND f.face_id = ' || aface;
END IF;
+
EXECUTE sql INTO containingface;
-- If aface was specified, check that it was correct
@@ -6484,6 +6594,7 @@ BEGIN
|| '::geometry,' || containingface
|| ' RETURNING node_id';
+
EXECUTE sql INTO nodeid;
RETURN nodeid;
@@ -6624,7 +6735,7 @@ LANGUAGE 'plpgsql' VOLATILE;
--} ST_RemoveIsoNode
--{
--- According to http://trac.osgeo.org/postgis/ticket/798
+-- According to http:
-- ST_RemoveIsoNode was renamed to ST_RemIsoNode in the final ISO
-- document
--
@@ -6826,6 +6937,7 @@ BEGIN
END LOOP;
+
--RAISE NOTICE 'EdgeId1 % EdgeId2 %', edgeid1, edgeid2;
--RAISE DEBUG 'oldedge.next_left_edge: %', oldedge.next_left_edge;
@@ -7111,6 +7223,7 @@ BEGIN
END LOOP;
+
--
-- Insert the new edge
--
@@ -7618,25 +7731,32 @@ BEGIN
tmp1 := ST_MakeLine(ST_EndPoint(oldedge.geom), ST_StartPoint(oldedge.geom));
+
tmp2 := ST_MakeLine(oldedge.geom, tmp1);
IF ST_NumPoints(tmp2) < 4 THEN
tmp2 := ST_AddPoint(tmp2, ST_StartPoint(oldedge.geom));
END IF;
+
tmp2 := ST_CollectionExtract(ST_MakeValid(ST_MakePolygon(tmp2)), 3);
+
range := ST_MakeLine(acurve, tmp1);
IF ST_NumPoints(range) < 4 THEN
range := ST_AddPoint(range, ST_StartPoint(oldedge.geom));
END IF;
+
range := ST_CollectionExtract(ST_MakeValid(ST_MakePolygon(range)), 3);
+
range := ST_SymDifference(range, tmp2);
+
sql := 'SELECT node_id, geom FROM '
|| quote_ident(atopology)
|| '.node WHERE ST_Contains('
|| quote_literal(range::text)
|| '::geometry, geom) LIMIT 1';
+
FOR rec IN EXECUTE sql LOOP -- {
RAISE EXCEPTION 'Edge motion collision at %', ST_AsText(rec.geom);
END LOOP; -- }
@@ -7652,11 +7772,13 @@ BEGIN
) as pre, NULL::integer[] as post
INTO STRICT snode_info;
+
SELECT topology._ST_AdjacentEdges(
atopology, oldedge.end_node, -anedge
) as pre, NULL::integer[] as post
INTO STRICT enode_info;
+
--}
--
@@ -7674,10 +7796,12 @@ BEGIN
atopology, oldedge.start_node, anedge
);
+
enode_info.post := topology._ST_AdjacentEdges(
atopology, oldedge.end_node, -anedge
);
+
IF snode_info.pre != snode_info.post THEN
RAISE EXCEPTION 'Edge changed disposition around start node %',
oldedge.start_node;
@@ -7754,6 +7878,7 @@ DECLARE
BEGIN
IF oface = 0 AND mbr_only THEN
+
RETURN NULL;
END IF;
@@ -7766,24 +7891,31 @@ BEGIN
INTO STRICT fan.newring_edges;
+
-- You can't get to the other side of an edge forming a ring
IF fan.newring_edges @> ARRAY[-anedge] THEN
+
RETURN 0;
END IF;
+
sql := 'WITH ids as ( select row_number() over () as seq, edge from unnest('
|| quote_literal(fan.newring_edges::text)
|| '::int[] ) u(edge) ), edges AS ( select CASE WHEN i.edge < 0 THEN ST_Reverse(e.geom) ELSE e.geom END as g FROM ids i left join '
|| quote_ident(atopology) || '.edge_data e ON(e.edge_id = abs(i.edge)) ORDER BY seq) SELECT ST_MakePolygon(ST_MakeLine(g.g)) FROM edges g;';
+
EXECUTE sql INTO fan.shell;
+
isccw := NOT ST_OrderingEquals(fan.shell, ST_ForceRHR(fan.shell));
+
IF oface = 0 THEN
IF NOT isccw THEN
+
RETURN NULL;
END IF;
END IF;
@@ -7795,6 +7927,7 @@ BEGIN
|| quote_ident(atopology) || '.face SET mbr = '
|| quote_literal(ST_Envelope(fan.shell)::text)
|| '::geometry WHERE face_id = ' || oface;
+
EXECUTE sql;
END IF; -- }
RETURN NULL;
@@ -7815,6 +7948,7 @@ BEGIN
END IF; -- }
-- Insert new face
+
EXECUTE sql INTO STRICT newface;
-- Update forward edges
@@ -7823,6 +7957,7 @@ BEGIN
|| ' WHERE left_face = ' || oface || ' AND edge_id = ANY ('
|| quote_literal(array( select +(x) from unnest(fan.newring_edges) u(x) )::text)
|| ')';
+
EXECUTE sql;
-- Update backward edges
@@ -7831,12 +7966,15 @@ BEGIN
|| ' WHERE right_face = ' || oface || ' AND edge_id = ANY ('
|| quote_literal(array( select -(x) from unnest(fan.newring_edges) u(x) )::text)
|| ')';
+
EXECUTE sql;
IF oface != 0 AND NOT isccw THEN -- {
-- face shrinked, must update all non-contained edges and nodes
+
ishole := true;
ELSE
+
ishole := false;
END IF; -- }
@@ -7858,6 +7996,7 @@ BEGIN
sql := sql || 'ST_Contains(' || quote_literal(fan.shell::text)
-- We only need to check a single point, but must not be an endpoint
|| '::geometry, ST_Line_Interpolate_Point(geom, 0.2))';
+
EXECUTE sql;
-- Update isolated nodes in new new face
@@ -7867,6 +8006,7 @@ BEGIN
|| ' AND ';
IF ishole THEN sql := sql || 'NOT '; END IF;
sql := sql || 'ST_Contains(' || quote_literal(fan.shell::text) || '::geometry, geom)';
+
EXECUTE sql;
RETURN newface;
@@ -7990,6 +8130,7 @@ BEGIN
|| ')'
LOOP
IF rec.containing_face IS NOT NULL THEN
+
IF newedge.left_face IS NULL THEN
newedge.left_face := rec.containing_face;
newedge.right_face := rec.containing_face;
@@ -8097,6 +8238,7 @@ BEGIN
-- Find links on start node -- {
+
sql :=
'SELECT edge_id, -1 AS end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8142,6 +8284,7 @@ BEGIN
END IF;
+
az = az - span.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8181,6 +8324,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN span.was_isolated = true; END IF;
ELSE
@@ -8197,12 +8341,16 @@ BEGIN
END IF;
+
+
+
-- } start_node analysis
-- Find links on end_node {
+
sql :=
'SELECT edge_id, -1 as end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8244,6 +8392,7 @@ BEGIN
END IF;
+
az := az - epan.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8283,6 +8432,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN epan.was_isolated = true; END IF;
ELSE
@@ -8301,6 +8451,9 @@ BEGIN
-- } end_node analysis
+
+
+
----------------------------------------------------------------------
--
-- If we don't have faces setup by now we must have encountered
@@ -8396,15 +8549,18 @@ BEGIN
--------------------------------------------
+
SELECT topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, false)
INTO newface;
IF newface = 0 THEN
+
RETURN newedge.edge_id;
END IF;
newfaces[1] := newface;
+
SELECT topology._ST_AddFaceSplit(atopology, newedge.edge_id, newedge.left_face, false)
INTO newface;
@@ -8427,6 +8583,7 @@ BEGIN
FOR rec IN EXECUTE sql
LOOP
+
-- Add reference to the other face
sql := 'INSERT INTO ' || quote_ident(atopology)
|| '.relation VALUES( ' || rec.topogeo_id
@@ -8564,6 +8721,7 @@ BEGIN
|| ')'
LOOP
IF rec.containing_face IS NOT NULL THEN
+
IF newedge.left_face IS NULL THEN
newedge.left_face := rec.containing_face;
newedge.right_face := rec.containing_face;
@@ -8669,6 +8827,7 @@ BEGIN
-- Find links on start node -- {
+
sql :=
'SELECT edge_id, -1 AS end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8714,6 +8873,7 @@ BEGIN
END IF;
+
az = az - span.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8753,6 +8913,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN span.was_isolated = true; END IF;
ELSE
@@ -8769,12 +8930,16 @@ BEGIN
END IF;
+
+
+
-- } start_node analysis
-- Find links on end_node {
+
sql :=
'SELECT edge_id, -1 as end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8816,6 +8981,7 @@ BEGIN
END IF;
+
az := az - epan.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8855,6 +9021,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN epan.was_isolated = true; END IF;
ELSE
@@ -8873,6 +9040,9 @@ BEGIN
-- } end_node analysis
+
+
+
----------------------------------------------------------------------
--
-- If we don't have faces setup by now we must have encountered
@@ -8967,20 +9137,25 @@ BEGIN
-- Check face splitting
--------------------------------------------
+
SELECT topology._ST_AddFaceSplit(atopology, newedge.edge_id, newedge.left_face, false)
INTO newface;
IF newface = 0 THEN
+
RETURN newedge.edge_id;
END IF;
IF newface IS NULL THEN -- must be forming a maximal ring in universal face
+
SELECT topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, false)
INTO newface;
ELSE
+
PERFORM topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, true);
END IF;
IF newface IS NULL THEN
+
RETURN newedge.edge_id;
END IF;
@@ -9004,6 +9179,7 @@ BEGIN
FOR rec IN EXECUTE sql
LOOP
+
-- Add reference to the other face
sql := 'INSERT INTO ' || quote_ident(atopology)
|| '.relation VALUES( ' || rec.topogeo_id
@@ -9134,6 +9310,7 @@ BEGIN
END; -- }
+
--
-- Node input linework with itself
--
@@ -9147,6 +9324,7 @@ BEGIN
) as linework INTO STRICT nodededges;
+
--
-- Linemerge the resulting edges, to reduce the working set
-- NOTE: this is more of a workaround for GEOS splitting overlapping
@@ -9156,6 +9334,7 @@ BEGIN
+
--
-- Collect input points and input lines endpoints
--
@@ -9169,6 +9348,7 @@ BEGIN
) as nodes INTO STRICT points;
+
--
-- Further split edges by points
-- TODO: optimize this adding ST_Split support for multiline/multipoint
@@ -9183,6 +9363,7 @@ BEGIN
SELECT ST_UnaryUnion(nodededges) INTO STRICT nodededges;
+
--
-- Collect all nodes (from points and noded linework endpoints)
--
@@ -9201,6 +9382,7 @@ BEGIN
) as endpoints INTO points;
+
--
-- Add all nodes as isolated so that
-- later calls to AddEdgeModFace will tweak their being
@@ -9231,11 +9413,12 @@ LANGUAGE 'plpgsql' VOLATILE;
--=} SQL/MM block
+
-- The following files needs getfaceedges_returntype, defined in sqlmm.sql
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 2012 Sandro Santilli <strk@keybit.net>
--
@@ -9245,7 +9428,7 @@ LANGUAGE 'plpgsql' VOLATILE;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -9312,10 +9495,11 @@ END
$$
LANGUAGE 'plpgsql' STABLE;
--} GetRingEdges
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2012 Sandro Santilli <strk@keybit.net>
--
@@ -9356,9 +9540,11 @@ BEGIN
|| ' UNION ALL SELECT -edge_id, ST_Azimuth(ST_EndPoint(geom), ST_PointN(geom, ST_NumPoints(geom)-1)) FROM incident_edges WHERE end_node = ' || anode
|| ' ORDER BY az';
+
FOR rec IN EXECUTE sql
LOOP -- incident edges {
+
n := n + 1;
retrec.sequence := n;
retrec.edge := rec.edge_id;
@@ -9370,11 +9556,12 @@ $$
LANGUAGE 'plpgsql' STABLE;
--} GetRingEdges
+
--general management --
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://www.postgis.org
+-- http:
--
-- Copyright (C) 2011 Regina Obe <lr@pcorp.us>
--
@@ -9413,6 +9600,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
--} AddToSearchPath
+
CREATE OR REPLACE FUNCTION postgis_topology_scripts_installed() RETURNS text
AS $$ SELECT '2.0.2'::text || ' r' || 10789::text AS version $$
LANGUAGE 'sql' IMMUTABLE;
diff --git a/gcc/postgis_extension/postgis_topology--2.0.0alpha6--2.0.2.sql b/gpp/postgis_extension/postgis_topology--2.0.0alpha6--2.0.2.sql
index 80c44f9..a257064 100644
--- a/gcc/postgis_extension/postgis_topology--2.0.0alpha6--2.0.2.sql
+++ b/gpp/postgis_extension/postgis_topology--2.0.0alpha6--2.0.2.sql
@@ -100,14 +100,12 @@ LANGUAGE plpgsql VOLATILE;
-- during upgrade
SELECT postgis_extension_remove_objects('postgis_topology', 'FUNCTION');
SELECT postgis_extension_remove_objects('postgis_topology', 'AGGREGATE');
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: topology.sql.in.c 10643 2012-11-05 10:25:41Z strk $
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -306,6 +304,23 @@ SELECT postgis_extension_remove_objects('postgis_topology', 'AGGREGATE');
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-- Doing everything outside of a transaction helps
-- upgrading in the best case.
@@ -481,7 +496,9 @@ ALTER DOMAIN topology.TopoElement ADD
array_lower(VALUE, 1) = 1
);
ALTER DOMAIN topology.TopoElement DROP CONSTRAINT
+
IF EXISTS
+
type_range;
ALTER DOMAIN topology.TopoElement ADD
CONSTRAINT type_range CHECK (
@@ -777,6 +794,7 @@ BEGIN
-- corrupting the topology anyway ...
--
+
RETURN newlayer_id;
END;
$$
@@ -1120,6 +1138,7 @@ BEGIN
|| ') as obj ORDER BY obj';
+
-- TODO: why not using array_agg here ?
i = 1;
@@ -1517,7 +1536,7 @@ BEGIN
--
-- Closed lines have no boundary, so endpoint
-- intersection would be considered interior
- -- See http://trac.osgeo.org/postgis/ticket/770
+ -- See http:
-- See also full explanation in topology.AddEdge
--
@@ -1681,6 +1700,7 @@ BEGIN
END LOOP;
+
DROP TABLE face_check;
RETURN;
@@ -1910,7 +1930,7 @@ BEGIN
------- Indexes on left_face and right_face of edge_data
------- NOTE: these indexes speed up GetFaceGeometry (and thus
------- TopoGeometry::Geometry) by a factor of 10 !
- ------- See http://trac.osgeo.org/postgis/ticket/806
+ ------- See http:
EXECUTE 'CREATE INDEX edge_left_face_idx ON '
|| quote_ident(atopology)
|| '.edge_data (left_face);';
@@ -1921,7 +1941,7 @@ BEGIN
------- Indexes on start_node and end_node of edge_data
------- NOTE: this indexes speed up node deletion
------- by a factor of 1000 !
- ------- See http://trac.osgeo.org/postgis/ticket/2082
+ ------- See http:
EXECUTE 'CREATE INDEX edge_start_node_idx ON '
|| quote_ident(atopology)
|| '.edge_data (start_node);';
@@ -2029,7 +2049,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -2180,10 +2200,11 @@ $$
LANGUAGE 'plpgsql' STABLE STRICT;
--} TopologySummary
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -2280,11 +2301,12 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
--} TopologySummary
+
-- Spatial predicates
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011-2012 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -2798,11 +2820,12 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--} equals(TopoGeometry, TopoGeometry)
+
-- Querying
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -2888,10 +2911,11 @@ $$
LANGUAGE 'plpgsql' STABLE STRICT;
--} GetNodeByPoint
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -2979,10 +3003,11 @@ END
$$
LANGUAGE 'plpgsql' STABLE STRICT;
--} GetEdgeByPoint
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -3138,11 +3163,12 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--} GetFaceByPoint
+
-- Populating
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010-2012 Sandro Santilli <strk@keybit.net>
--
@@ -3163,7 +3189,7 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--
--
-- A pragmatic test conducted using algoritm shown here:
--- http://stackoverflow.com/questions/7408407/generate-next-largest-or-smallest-representable-floating-point-number-without-bi
+-- http:
-- showed the "tolerance" growing by an order of magnitude proportionally
-- with the order of magnitude of the input, starting with something like
-- 3.5527136788005009294e-15 for the starting value of 9.0
@@ -3219,7 +3245,7 @@ $$ LANGUAGE 'plpgsql' STABLE STRICT;
-- The newly added nodes have no containing face.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3287,6 +3313,7 @@ BEGIN
IF setContainingFace THEN
containing_face := topology.GetFaceByPoint(atopology, apoint, 0);
+
ELSE
containing_face := NULL;
END IF;
@@ -3346,7 +3373,7 @@ LANGUAGE 'sql' VOLATILE;
-- Calling code is expected to do further linking.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3435,6 +3462,7 @@ BEGIN
-- Reuse an EQUAL edge (be it closed or not)
IF ST_RelateMatch(rec.im, '1FFF*FFF2') THEN
+
RETURN rec.edge_id;
END IF;
@@ -3539,7 +3567,7 @@ LANGUAGE 'plpgsql' VOLATILE;
-- o The polygon overlaps an existing face.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3661,6 +3689,7 @@ BEGIN
ST_Line_Locate_Point(bounds, p2);
+
IF right_side THEN
right_edges := array_append(right_edges, rec.edge_id);
old_faceid = rec.right_face;
@@ -3687,6 +3716,8 @@ BEGIN
END IF;
+
+
--
-- Check that all edges found, taken togheter,
-- fully match the ring boundary and nothing more
@@ -3706,8 +3737,10 @@ BEGIN
IF faceid IS NOT NULL AND faceid != 0 THEN
IF NOT force_new THEN
+
RETURN faceid;
ELSE
+
END IF;
END IF;
@@ -3834,12 +3867,14 @@ BEGIN
|| tol || ') ORDER BY ST_Distance('
|| quote_literal(apoint::text)
|| '::geometry, a.geom) LIMIT 1;';
+
EXECUTE sql INTO id;
IF id IS NOT NULL THEN
RETURN id;
END IF;
+
-- 2. Check if any existing edge falls within tolerance
-- and if so split it by a point projected on it
sql := 'SELECT a.edge_id, a.geom FROM '
@@ -3849,35 +3884,42 @@ BEGIN
|| tol || ') ORDER BY ST_Distance('
|| quote_literal(apoint::text)
|| '::geometry, a.geom) LIMIT 1;';
+
EXECUTE sql INTO rec;
IF rec IS NOT NULL THEN
-- project point to line, split edge by point
prj := ST_ClosestPoint(rec.geom, apoint);
-- This is a workaround for ClosestPoint lack of Z support:
- -- http://trac.osgeo.org/postgis/ticket/2033
+ -- http:
z := ST_Z(apoint);
IF z IS NOT NULL THEN
prj := ST_Translate(ST_Force_3DZ(prj), 0, 0, z); -- no ST_SetZ ...
END IF;
+
IF NOT ST_Contains(rec.geom, prj) THEN
+
-- The tolerance must be big enough for snapping to happen
-- and small enough to snap only to the projected point.
-- Unfortunately ST_Distance returns 0 because it also uses
-- a projected point internally, so we need another way.
snaptol := topology._st_mintolerance(prj);
+
snapedge := ST_Snap(rec.geom, prj, snaptol);
-- Snapping currently snaps the first point below tolerance
-- so may possibly move first point. See ticket #1631
IF NOT ST_Equals(ST_StartPoint(rec.geom), ST_StartPoint(snapedge))
THEN
+
snapedge := ST_MakeLine(ST_StartPoint(rec.geom), snapedge);
END IF;
+
PERFORM ST_ChangeEdgeGeom(atopology, rec.edge_id, snapedge);
END IF;
id := topology.ST_ModEdgeSplit(atopology, rec.edge_id, prj);
ELSE
+
id := topology.ST_AddIsoNode(atopology, NULL, apoint);
END IF;
@@ -3923,6 +3965,7 @@ BEGIN
-- 1. Self-node
noded := ST_UnaryUnion(aline);
+
-- 2. Node to edges falling within tol distance
sql := 'WITH nearby AS ( SELECT e.geom FROM '
|| quote_ident(atopology)
@@ -3930,20 +3973,27 @@ BEGIN
|| quote_literal(noded::text)
|| '::geometry, '
|| tol || ') ) SELECT st_collect(geom) FROM nearby;';
+
EXECUTE sql INTO iedges;
IF iedges IS NOT NULL THEN
+
snapped := ST_Snap(noded, iedges, tol);
+
noded := ST_Difference(snapped, iedges);
+
set1 := ST_Intersection(snapped, iedges);
+
set2 := ST_LineMerge(set1);
+
noded := ST_Union(noded, set2);
+
END IF;
-- 2.1. Node with existing nodes within tol
@@ -3954,26 +4004,32 @@ BEGIN
|| quote_literal(noded::text)
|| '::geometry, '
|| tol || ') ) SELECT st_collect(geom) FROM nearby;';
+
EXECUTE sql INTO inodes;
IF inodes IS NOT NULL THEN -- {
+
-- TODO: consider snapping once against all elements
--- (rather than once with edges and once with nodes)
noded := ST_Snap(noded, inodes, tol);
+
FOR rec IN SELECT (ST_Dump(inodes)).*
LOOP
-- Use the node to split edges
SELECT ST_Collect(geom)
FROM ST_Dump(ST_Split(noded, rec.geom))
INTO STRICT noded;
+
END LOOP;
+
-- re-node to account for ST_Snap introduced self-intersections
- -- See http://trac.osgeo.org/postgis/ticket/1714
+ -- See http:
-- TODO: consider running UnaryUnion once after all noding
noded := ST_UnaryUnion(noded);
+
END IF; -- }
-- 3. For each (now-noded) segment, insert an edge
@@ -3982,14 +4038,17 @@ BEGIN
-- TODO: skip point elements ?
+
start_node := topology.TopoGeo_AddPoint(atopology,
ST_StartPoint(rec.geom),
tol);
+
end_node := topology.TopoGeo_AddPoint(atopology,
ST_EndPoint(rec.geom),
tol);
+
-- Added endpoints may have drifted due to tolerance, so
-- we need to re-snap the edge to the new nodes before adding it
sql := 'SELECT n1.geom as sn, n2.geom as en FROM ' || quote_ident(atopology)
@@ -3997,6 +4056,7 @@ BEGIN
|| '.node n2 WHERE n1.node_id = '
|| start_node || ' AND n2.node_id = ' || end_node;
+
EXECUTE sql INTO STRICT rec2;
snapped := ST_SetPoint(
@@ -4007,8 +4067,10 @@ BEGIN
snapped := ST_CollectionExtract(ST_MakeValid(snapped), 2);
+
-- Check if the so-snapped edge collapsed (see #1650)
IF ST_IsEmpty(snapped) THEN
+
CONTINUE;
END IF;
@@ -4016,11 +4078,14 @@ BEGIN
sql := 'SELECT edge_id FROM ' || quote_ident(atopology)
|| '.edge_data WHERE ST_Equals(geom, ' || quote_literal(snapped::text)
|| '::geometry)';
+
EXECUTE sql INTO id;
IF id IS NULL THEN
id := topology.ST_AddEdgeModFace(atopology, start_node, end_node,
snapped);
+
ELSE
+
END IF;
RETURN NEXT id;
@@ -4062,9 +4127,11 @@ BEGIN
-- 1. Extract boundary
boundary := ST_Boundary(apoly);
+
-- 2. Add boundaries as edges
FOR rec IN SELECT (ST_Dump(boundary)).geom LOOP
edges := array_cat(edges, array_agg(x)) FROM ( select topology.TopoGeo_addLinestring(atopology, rec.geom, tol) as x ) as foo;
+
END LOOP;
-- 3. Find faces covered by input polygon
@@ -4073,10 +4140,12 @@ BEGIN
|| '.face f WHERE f.mbr && '
|| quote_literal(apoly::text)
|| '::geometry';
+
FOR rec IN EXECUTE sql LOOP
-- check for actual containment
fgeom := ST_PointOnSurface(ST_GetFaceGeometry(atopology, rec.face_id));
IF NOT ST_Covers(apoly, fgeom) THEN
+
CONTINUE;
END IF;
RETURN NEXT rec.face_id;
@@ -4102,10 +4171,11 @@ END
$$
LANGUAGE 'plpgsql';
--} TopoGeo_AddGeometry
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4154,11 +4224,12 @@ $$
LANGUAGE 'plpgsql';
--} Polygonize(toponame)
+
-- TopoElement
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4172,7 +4243,7 @@ LANGUAGE 'plpgsql';
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -4214,11 +4285,12 @@ CREATE AGGREGATE topology.TopoElementArray_agg(
);
--} TopoElementArray_agg
+
-- TopoGeometry
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4274,10 +4346,11 @@ $$
$$
LANGUAGE 'sql' STABLE STRICT;
-- }
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011-2012 Sandro Santilli <strk@keybit.net>
--
@@ -4289,7 +4362,7 @@ LANGUAGE 'sql' STABLE STRICT;
-- {
-- Convert a simple geometry to a topologically-defined one
--
--- See http://trac.osgeo.org/postgis/ticket/1017
+-- See http:
--
-- }{
CREATE OR REPLACE FUNCTION topology.toTopoGeom(ageom Geometry, atopology varchar, alayer int, atolerance float8 DEFAULT 0)
@@ -4414,6 +4487,7 @@ BEGIN
|| '.relation(topogeo_id, layer_id, element_type, element_id) VALUES ('
|| rec.id || ',' || rec.lyr || ',' || rec.type
|| ',' || rec.primitive || ')';
+
EXECUTE sql;
END LOOP;
@@ -4424,11 +4498,12 @@ $$
LANGUAGE 'plpgsql' VOLATILE STRICT;
-- }
+
-- GML
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4442,7 +4517,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -4989,13 +5064,14 @@ $$ LANGUAGE 'sql' STABLE; -- does NOT write into visited table
-- } AsGML(TopoGeometry)
+
--=} POSTGIS-SPECIFIC block
-- SQL/MM block
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011, 2012 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -5101,6 +5177,7 @@ BEGIN
LOOP
+
retrec.sequence = n;
retrec.edge = rec.edge_id;
@@ -5399,6 +5476,7 @@ BEGIN
|| ' AND l.layer_id = r.layer_id AND abs(r.element_id) = '
|| e1id
;
+
EXECUTE sql;
@@ -5747,6 +5825,7 @@ BEGIN
|| 'WHERE l.level = 0 AND l.feature_type = 2 '
|| ' AND l.topology_id = ' || topoid
|| ' AND abs(r.element_id) = ' || e1id ;
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented dropping edge %',
rec.topogeo_id, rec.layer_id,
@@ -5771,6 +5850,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge < 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -5788,6 +5868,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge > 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -5803,6 +5884,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge < 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -5820,6 +5902,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge > 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -5865,6 +5948,7 @@ BEGIN
END IF; -- }
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented healing faces % and %',
rec.topogeo_id, rec.layer_id,
@@ -5907,6 +5991,7 @@ BEGIN
|| '.face WHERE face_id IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
END IF; -- }
@@ -5917,6 +6002,7 @@ BEGIN
|| ' WHERE left_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update right_face for all edges still referencing old faces
@@ -5925,6 +6011,7 @@ BEGIN
|| ' WHERE right_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update containing_face for all nodes still referencing old faces
@@ -5933,6 +6020,7 @@ BEGIN
|| ' WHERE containing_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- NOT IN THE SPECS:
@@ -5945,6 +6033,7 @@ BEGIN
|| ' AND l.topology_id = ' || topoid
|| ' AND l.layer_id = r.layer_id AND abs(r.element_id) = '
|| e1rec.left_face;
+
EXECUTE sql;
sql := 'UPDATE ' || quote_ident(toponame)
|| '.relation r '
@@ -5953,6 +6042,7 @@ BEGIN
|| ' AND l.topology_id = ' || topoid
|| ' AND l.layer_id = r.layer_id AND r.element_id = '
|| e1rec.right_face;
+
EXECUTE sql;
END IF; -- } two faces healed...
@@ -5960,6 +6050,7 @@ BEGIN
-- Delete the edge
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.edge_data WHERE edge_id = ' || e1id;
+
EXECUTE sql;
-- Check if any of the edge nodes remains isolated,
@@ -5971,6 +6062,7 @@ BEGIN
|| e1rec.end_node || ') AND NOT EXISTS (SELECT edge_id FROM '
|| quote_ident(toponame)
|| '.edge_data WHERE start_node = n.node_id OR end_node = n.node_id)';
+
EXECUTE sql;
IF e1rec.right_face != e1rec.left_face THEN -- {
@@ -5979,6 +6071,7 @@ BEGIN
IF e1rec.left_face != 0 THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.left_face;
+
EXECUTE sql;
END IF;
@@ -5987,6 +6080,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.right_face;
+
EXECUTE sql;
END IF;
@@ -6071,6 +6165,7 @@ BEGIN
|| 'WHERE l.level = 0 AND l.feature_type = 2 '
|| ' AND l.topology_id = ' || topoid
|| ' AND abs(r.element_id) = ' || e1id ;
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented dropping edge %',
rec.topogeo_id, rec.layer_id,
@@ -6095,6 +6190,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge < 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -6112,6 +6208,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge > 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -6127,6 +6224,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge < 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -6144,6 +6242,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge > 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -6187,6 +6286,7 @@ BEGIN
END IF; -- }
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented healing faces % and %',
rec.topogeo_id, rec.layer_id,
@@ -6219,6 +6319,7 @@ BEGIN
|| '.face WHERE face_id IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ') ) WHERE face_id = ' || floodfaceid ;
+
EXECUTE sql;
END IF; -- }
@@ -6229,6 +6330,7 @@ BEGIN
|| ' WHERE left_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update right_face for all edges still referencing old faces
@@ -6237,6 +6339,7 @@ BEGIN
|| ' WHERE right_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update containing_face for all nodes still referencing old faces
@@ -6245,6 +6348,7 @@ BEGIN
|| ' WHERE containing_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- NOT IN THE SPECS:
@@ -6259,6 +6363,7 @@ BEGIN
|| e1rec.left_face || ',' || e1rec.right_face
|| ') AND abs(r.element_id) != '
|| floodfaceid; -- could be optimized..
+
EXECUTE sql;
END IF; -- } two faces healed...
@@ -6266,6 +6371,7 @@ BEGIN
-- Delete the edge
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.edge_data WHERE edge_id = ' || e1id;
+
EXECUTE sql;
-- Check if any of the edge nodes remains isolated,
@@ -6277,6 +6383,7 @@ BEGIN
|| e1rec.end_node || ') AND NOT EXISTS (SELECT edge_id FROM '
|| quote_ident(toponame)
|| '.edge_data WHERE start_node = n.node_id OR end_node = n.node_id)';
+
EXECUTE sql;
IF e1rec.right_face != e1rec.left_face THEN -- {
@@ -6286,6 +6393,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.left_face;
+
EXECUTE sql;
END IF;
@@ -6294,6 +6402,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.right_face;
+
EXECUTE sql;
END IF;
@@ -6451,6 +6560,7 @@ BEGIN
sql := sql || ' AND f.face_id = ' || aface;
END IF;
+
EXECUTE sql INTO containingface;
-- If aface was specified, check that it was correct
@@ -6484,6 +6594,7 @@ BEGIN
|| '::geometry,' || containingface
|| ' RETURNING node_id';
+
EXECUTE sql INTO nodeid;
RETURN nodeid;
@@ -6624,7 +6735,7 @@ LANGUAGE 'plpgsql' VOLATILE;
--} ST_RemoveIsoNode
--{
--- According to http://trac.osgeo.org/postgis/ticket/798
+-- According to http:
-- ST_RemoveIsoNode was renamed to ST_RemIsoNode in the final ISO
-- document
--
@@ -6826,6 +6937,7 @@ BEGIN
END LOOP;
+
--RAISE NOTICE 'EdgeId1 % EdgeId2 %', edgeid1, edgeid2;
--RAISE DEBUG 'oldedge.next_left_edge: %', oldedge.next_left_edge;
@@ -7111,6 +7223,7 @@ BEGIN
END LOOP;
+
--
-- Insert the new edge
--
@@ -7618,25 +7731,32 @@ BEGIN
tmp1 := ST_MakeLine(ST_EndPoint(oldedge.geom), ST_StartPoint(oldedge.geom));
+
tmp2 := ST_MakeLine(oldedge.geom, tmp1);
IF ST_NumPoints(tmp2) < 4 THEN
tmp2 := ST_AddPoint(tmp2, ST_StartPoint(oldedge.geom));
END IF;
+
tmp2 := ST_CollectionExtract(ST_MakeValid(ST_MakePolygon(tmp2)), 3);
+
range := ST_MakeLine(acurve, tmp1);
IF ST_NumPoints(range) < 4 THEN
range := ST_AddPoint(range, ST_StartPoint(oldedge.geom));
END IF;
+
range := ST_CollectionExtract(ST_MakeValid(ST_MakePolygon(range)), 3);
+
range := ST_SymDifference(range, tmp2);
+
sql := 'SELECT node_id, geom FROM '
|| quote_ident(atopology)
|| '.node WHERE ST_Contains('
|| quote_literal(range::text)
|| '::geometry, geom) LIMIT 1';
+
FOR rec IN EXECUTE sql LOOP -- {
RAISE EXCEPTION 'Edge motion collision at %', ST_AsText(rec.geom);
END LOOP; -- }
@@ -7652,11 +7772,13 @@ BEGIN
) as pre, NULL::integer[] as post
INTO STRICT snode_info;
+
SELECT topology._ST_AdjacentEdges(
atopology, oldedge.end_node, -anedge
) as pre, NULL::integer[] as post
INTO STRICT enode_info;
+
--}
--
@@ -7674,10 +7796,12 @@ BEGIN
atopology, oldedge.start_node, anedge
);
+
enode_info.post := topology._ST_AdjacentEdges(
atopology, oldedge.end_node, -anedge
);
+
IF snode_info.pre != snode_info.post THEN
RAISE EXCEPTION 'Edge changed disposition around start node %',
oldedge.start_node;
@@ -7754,6 +7878,7 @@ DECLARE
BEGIN
IF oface = 0 AND mbr_only THEN
+
RETURN NULL;
END IF;
@@ -7766,24 +7891,31 @@ BEGIN
INTO STRICT fan.newring_edges;
+
-- You can't get to the other side of an edge forming a ring
IF fan.newring_edges @> ARRAY[-anedge] THEN
+
RETURN 0;
END IF;
+
sql := 'WITH ids as ( select row_number() over () as seq, edge from unnest('
|| quote_literal(fan.newring_edges::text)
|| '::int[] ) u(edge) ), edges AS ( select CASE WHEN i.edge < 0 THEN ST_Reverse(e.geom) ELSE e.geom END as g FROM ids i left join '
|| quote_ident(atopology) || '.edge_data e ON(e.edge_id = abs(i.edge)) ORDER BY seq) SELECT ST_MakePolygon(ST_MakeLine(g.g)) FROM edges g;';
+
EXECUTE sql INTO fan.shell;
+
isccw := NOT ST_OrderingEquals(fan.shell, ST_ForceRHR(fan.shell));
+
IF oface = 0 THEN
IF NOT isccw THEN
+
RETURN NULL;
END IF;
END IF;
@@ -7795,6 +7927,7 @@ BEGIN
|| quote_ident(atopology) || '.face SET mbr = '
|| quote_literal(ST_Envelope(fan.shell)::text)
|| '::geometry WHERE face_id = ' || oface;
+
EXECUTE sql;
END IF; -- }
RETURN NULL;
@@ -7815,6 +7948,7 @@ BEGIN
END IF; -- }
-- Insert new face
+
EXECUTE sql INTO STRICT newface;
-- Update forward edges
@@ -7823,6 +7957,7 @@ BEGIN
|| ' WHERE left_face = ' || oface || ' AND edge_id = ANY ('
|| quote_literal(array( select +(x) from unnest(fan.newring_edges) u(x) )::text)
|| ')';
+
EXECUTE sql;
-- Update backward edges
@@ -7831,12 +7966,15 @@ BEGIN
|| ' WHERE right_face = ' || oface || ' AND edge_id = ANY ('
|| quote_literal(array( select -(x) from unnest(fan.newring_edges) u(x) )::text)
|| ')';
+
EXECUTE sql;
IF oface != 0 AND NOT isccw THEN -- {
-- face shrinked, must update all non-contained edges and nodes
+
ishole := true;
ELSE
+
ishole := false;
END IF; -- }
@@ -7858,6 +7996,7 @@ BEGIN
sql := sql || 'ST_Contains(' || quote_literal(fan.shell::text)
-- We only need to check a single point, but must not be an endpoint
|| '::geometry, ST_Line_Interpolate_Point(geom, 0.2))';
+
EXECUTE sql;
-- Update isolated nodes in new new face
@@ -7867,6 +8006,7 @@ BEGIN
|| ' AND ';
IF ishole THEN sql := sql || 'NOT '; END IF;
sql := sql || 'ST_Contains(' || quote_literal(fan.shell::text) || '::geometry, geom)';
+
EXECUTE sql;
RETURN newface;
@@ -7990,6 +8130,7 @@ BEGIN
|| ')'
LOOP
IF rec.containing_face IS NOT NULL THEN
+
IF newedge.left_face IS NULL THEN
newedge.left_face := rec.containing_face;
newedge.right_face := rec.containing_face;
@@ -8097,6 +8238,7 @@ BEGIN
-- Find links on start node -- {
+
sql :=
'SELECT edge_id, -1 AS end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8142,6 +8284,7 @@ BEGIN
END IF;
+
az = az - span.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8181,6 +8324,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN span.was_isolated = true; END IF;
ELSE
@@ -8197,12 +8341,16 @@ BEGIN
END IF;
+
+
+
-- } start_node analysis
-- Find links on end_node {
+
sql :=
'SELECT edge_id, -1 as end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8244,6 +8392,7 @@ BEGIN
END IF;
+
az := az - epan.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8283,6 +8432,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN epan.was_isolated = true; END IF;
ELSE
@@ -8301,6 +8451,9 @@ BEGIN
-- } end_node analysis
+
+
+
----------------------------------------------------------------------
--
-- If we don't have faces setup by now we must have encountered
@@ -8396,15 +8549,18 @@ BEGIN
--------------------------------------------
+
SELECT topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, false)
INTO newface;
IF newface = 0 THEN
+
RETURN newedge.edge_id;
END IF;
newfaces[1] := newface;
+
SELECT topology._ST_AddFaceSplit(atopology, newedge.edge_id, newedge.left_face, false)
INTO newface;
@@ -8427,6 +8583,7 @@ BEGIN
FOR rec IN EXECUTE sql
LOOP
+
-- Add reference to the other face
sql := 'INSERT INTO ' || quote_ident(atopology)
|| '.relation VALUES( ' || rec.topogeo_id
@@ -8564,6 +8721,7 @@ BEGIN
|| ')'
LOOP
IF rec.containing_face IS NOT NULL THEN
+
IF newedge.left_face IS NULL THEN
newedge.left_face := rec.containing_face;
newedge.right_face := rec.containing_face;
@@ -8669,6 +8827,7 @@ BEGIN
-- Find links on start node -- {
+
sql :=
'SELECT edge_id, -1 AS end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8714,6 +8873,7 @@ BEGIN
END IF;
+
az = az - span.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8753,6 +8913,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN span.was_isolated = true; END IF;
ELSE
@@ -8769,12 +8930,16 @@ BEGIN
END IF;
+
+
+
-- } start_node analysis
-- Find links on end_node {
+
sql :=
'SELECT edge_id, -1 as end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8816,6 +8981,7 @@ BEGIN
END IF;
+
az := az - epan.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8855,6 +9021,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN epan.was_isolated = true; END IF;
ELSE
@@ -8873,6 +9040,9 @@ BEGIN
-- } end_node analysis
+
+
+
----------------------------------------------------------------------
--
-- If we don't have faces setup by now we must have encountered
@@ -8967,20 +9137,25 @@ BEGIN
-- Check face splitting
--------------------------------------------
+
SELECT topology._ST_AddFaceSplit(atopology, newedge.edge_id, newedge.left_face, false)
INTO newface;
IF newface = 0 THEN
+
RETURN newedge.edge_id;
END IF;
IF newface IS NULL THEN -- must be forming a maximal ring in universal face
+
SELECT topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, false)
INTO newface;
ELSE
+
PERFORM topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, true);
END IF;
IF newface IS NULL THEN
+
RETURN newedge.edge_id;
END IF;
@@ -9004,6 +9179,7 @@ BEGIN
FOR rec IN EXECUTE sql
LOOP
+
-- Add reference to the other face
sql := 'INSERT INTO ' || quote_ident(atopology)
|| '.relation VALUES( ' || rec.topogeo_id
@@ -9134,6 +9310,7 @@ BEGIN
END; -- }
+
--
-- Node input linework with itself
--
@@ -9147,6 +9324,7 @@ BEGIN
) as linework INTO STRICT nodededges;
+
--
-- Linemerge the resulting edges, to reduce the working set
-- NOTE: this is more of a workaround for GEOS splitting overlapping
@@ -9156,6 +9334,7 @@ BEGIN
+
--
-- Collect input points and input lines endpoints
--
@@ -9169,6 +9348,7 @@ BEGIN
) as nodes INTO STRICT points;
+
--
-- Further split edges by points
-- TODO: optimize this adding ST_Split support for multiline/multipoint
@@ -9183,6 +9363,7 @@ BEGIN
SELECT ST_UnaryUnion(nodededges) INTO STRICT nodededges;
+
--
-- Collect all nodes (from points and noded linework endpoints)
--
@@ -9201,6 +9382,7 @@ BEGIN
) as endpoints INTO points;
+
--
-- Add all nodes as isolated so that
-- later calls to AddEdgeModFace will tweak their being
@@ -9231,11 +9413,12 @@ LANGUAGE 'plpgsql' VOLATILE;
--=} SQL/MM block
+
-- The following files needs getfaceedges_returntype, defined in sqlmm.sql
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 2012 Sandro Santilli <strk@keybit.net>
--
@@ -9245,7 +9428,7 @@ LANGUAGE 'plpgsql' VOLATILE;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -9312,10 +9495,11 @@ END
$$
LANGUAGE 'plpgsql' STABLE;
--} GetRingEdges
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2012 Sandro Santilli <strk@keybit.net>
--
@@ -9356,9 +9540,11 @@ BEGIN
|| ' UNION ALL SELECT -edge_id, ST_Azimuth(ST_EndPoint(geom), ST_PointN(geom, ST_NumPoints(geom)-1)) FROM incident_edges WHERE end_node = ' || anode
|| ' ORDER BY az';
+
FOR rec IN EXECUTE sql
LOOP -- incident edges {
+
n := n + 1;
retrec.sequence := n;
retrec.edge := rec.edge_id;
@@ -9370,11 +9556,12 @@ $$
LANGUAGE 'plpgsql' STABLE;
--} GetRingEdges
+
--general management --
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://www.postgis.org
+-- http:
--
-- Copyright (C) 2011 Regina Obe <lr@pcorp.us>
--
@@ -9413,6 +9600,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
--} AddToSearchPath
+
CREATE OR REPLACE FUNCTION postgis_topology_scripts_installed() RETURNS text
AS $$ SELECT '2.0.2'::text || ' r' || 10789::text AS version $$
LANGUAGE 'sql' IMMUTABLE;
diff --git a/gcc/postgis_extension/postgis_topology--2.0.0beta1--2.0.2.sql b/gpp/postgis_extension/postgis_topology--2.0.0beta1--2.0.2.sql
index 80c44f9..a257064 100644
--- a/gcc/postgis_extension/postgis_topology--2.0.0beta1--2.0.2.sql
+++ b/gpp/postgis_extension/postgis_topology--2.0.0beta1--2.0.2.sql
@@ -100,14 +100,12 @@ LANGUAGE plpgsql VOLATILE;
-- during upgrade
SELECT postgis_extension_remove_objects('postgis_topology', 'FUNCTION');
SELECT postgis_extension_remove_objects('postgis_topology', 'AGGREGATE');
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: topology.sql.in.c 10643 2012-11-05 10:25:41Z strk $
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -306,6 +304,23 @@ SELECT postgis_extension_remove_objects('postgis_topology', 'AGGREGATE');
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-- Doing everything outside of a transaction helps
-- upgrading in the best case.
@@ -481,7 +496,9 @@ ALTER DOMAIN topology.TopoElement ADD
array_lower(VALUE, 1) = 1
);
ALTER DOMAIN topology.TopoElement DROP CONSTRAINT
+
IF EXISTS
+
type_range;
ALTER DOMAIN topology.TopoElement ADD
CONSTRAINT type_range CHECK (
@@ -777,6 +794,7 @@ BEGIN
-- corrupting the topology anyway ...
--
+
RETURN newlayer_id;
END;
$$
@@ -1120,6 +1138,7 @@ BEGIN
|| ') as obj ORDER BY obj';
+
-- TODO: why not using array_agg here ?
i = 1;
@@ -1517,7 +1536,7 @@ BEGIN
--
-- Closed lines have no boundary, so endpoint
-- intersection would be considered interior
- -- See http://trac.osgeo.org/postgis/ticket/770
+ -- See http:
-- See also full explanation in topology.AddEdge
--
@@ -1681,6 +1700,7 @@ BEGIN
END LOOP;
+
DROP TABLE face_check;
RETURN;
@@ -1910,7 +1930,7 @@ BEGIN
------- Indexes on left_face and right_face of edge_data
------- NOTE: these indexes speed up GetFaceGeometry (and thus
------- TopoGeometry::Geometry) by a factor of 10 !
- ------- See http://trac.osgeo.org/postgis/ticket/806
+ ------- See http:
EXECUTE 'CREATE INDEX edge_left_face_idx ON '
|| quote_ident(atopology)
|| '.edge_data (left_face);';
@@ -1921,7 +1941,7 @@ BEGIN
------- Indexes on start_node and end_node of edge_data
------- NOTE: this indexes speed up node deletion
------- by a factor of 1000 !
- ------- See http://trac.osgeo.org/postgis/ticket/2082
+ ------- See http:
EXECUTE 'CREATE INDEX edge_start_node_idx ON '
|| quote_ident(atopology)
|| '.edge_data (start_node);';
@@ -2029,7 +2049,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -2180,10 +2200,11 @@ $$
LANGUAGE 'plpgsql' STABLE STRICT;
--} TopologySummary
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -2280,11 +2301,12 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
--} TopologySummary
+
-- Spatial predicates
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011-2012 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -2798,11 +2820,12 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--} equals(TopoGeometry, TopoGeometry)
+
-- Querying
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -2888,10 +2911,11 @@ $$
LANGUAGE 'plpgsql' STABLE STRICT;
--} GetNodeByPoint
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -2979,10 +3003,11 @@ END
$$
LANGUAGE 'plpgsql' STABLE STRICT;
--} GetEdgeByPoint
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -3138,11 +3163,12 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--} GetFaceByPoint
+
-- Populating
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010-2012 Sandro Santilli <strk@keybit.net>
--
@@ -3163,7 +3189,7 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--
--
-- A pragmatic test conducted using algoritm shown here:
--- http://stackoverflow.com/questions/7408407/generate-next-largest-or-smallest-representable-floating-point-number-without-bi
+-- http:
-- showed the "tolerance" growing by an order of magnitude proportionally
-- with the order of magnitude of the input, starting with something like
-- 3.5527136788005009294e-15 for the starting value of 9.0
@@ -3219,7 +3245,7 @@ $$ LANGUAGE 'plpgsql' STABLE STRICT;
-- The newly added nodes have no containing face.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3287,6 +3313,7 @@ BEGIN
IF setContainingFace THEN
containing_face := topology.GetFaceByPoint(atopology, apoint, 0);
+
ELSE
containing_face := NULL;
END IF;
@@ -3346,7 +3373,7 @@ LANGUAGE 'sql' VOLATILE;
-- Calling code is expected to do further linking.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3435,6 +3462,7 @@ BEGIN
-- Reuse an EQUAL edge (be it closed or not)
IF ST_RelateMatch(rec.im, '1FFF*FFF2') THEN
+
RETURN rec.edge_id;
END IF;
@@ -3539,7 +3567,7 @@ LANGUAGE 'plpgsql' VOLATILE;
-- o The polygon overlaps an existing face.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3661,6 +3689,7 @@ BEGIN
ST_Line_Locate_Point(bounds, p2);
+
IF right_side THEN
right_edges := array_append(right_edges, rec.edge_id);
old_faceid = rec.right_face;
@@ -3687,6 +3716,8 @@ BEGIN
END IF;
+
+
--
-- Check that all edges found, taken togheter,
-- fully match the ring boundary and nothing more
@@ -3706,8 +3737,10 @@ BEGIN
IF faceid IS NOT NULL AND faceid != 0 THEN
IF NOT force_new THEN
+
RETURN faceid;
ELSE
+
END IF;
END IF;
@@ -3834,12 +3867,14 @@ BEGIN
|| tol || ') ORDER BY ST_Distance('
|| quote_literal(apoint::text)
|| '::geometry, a.geom) LIMIT 1;';
+
EXECUTE sql INTO id;
IF id IS NOT NULL THEN
RETURN id;
END IF;
+
-- 2. Check if any existing edge falls within tolerance
-- and if so split it by a point projected on it
sql := 'SELECT a.edge_id, a.geom FROM '
@@ -3849,35 +3884,42 @@ BEGIN
|| tol || ') ORDER BY ST_Distance('
|| quote_literal(apoint::text)
|| '::geometry, a.geom) LIMIT 1;';
+
EXECUTE sql INTO rec;
IF rec IS NOT NULL THEN
-- project point to line, split edge by point
prj := ST_ClosestPoint(rec.geom, apoint);
-- This is a workaround for ClosestPoint lack of Z support:
- -- http://trac.osgeo.org/postgis/ticket/2033
+ -- http:
z := ST_Z(apoint);
IF z IS NOT NULL THEN
prj := ST_Translate(ST_Force_3DZ(prj), 0, 0, z); -- no ST_SetZ ...
END IF;
+
IF NOT ST_Contains(rec.geom, prj) THEN
+
-- The tolerance must be big enough for snapping to happen
-- and small enough to snap only to the projected point.
-- Unfortunately ST_Distance returns 0 because it also uses
-- a projected point internally, so we need another way.
snaptol := topology._st_mintolerance(prj);
+
snapedge := ST_Snap(rec.geom, prj, snaptol);
-- Snapping currently snaps the first point below tolerance
-- so may possibly move first point. See ticket #1631
IF NOT ST_Equals(ST_StartPoint(rec.geom), ST_StartPoint(snapedge))
THEN
+
snapedge := ST_MakeLine(ST_StartPoint(rec.geom), snapedge);
END IF;
+
PERFORM ST_ChangeEdgeGeom(atopology, rec.edge_id, snapedge);
END IF;
id := topology.ST_ModEdgeSplit(atopology, rec.edge_id, prj);
ELSE
+
id := topology.ST_AddIsoNode(atopology, NULL, apoint);
END IF;
@@ -3923,6 +3965,7 @@ BEGIN
-- 1. Self-node
noded := ST_UnaryUnion(aline);
+
-- 2. Node to edges falling within tol distance
sql := 'WITH nearby AS ( SELECT e.geom FROM '
|| quote_ident(atopology)
@@ -3930,20 +3973,27 @@ BEGIN
|| quote_literal(noded::text)
|| '::geometry, '
|| tol || ') ) SELECT st_collect(geom) FROM nearby;';
+
EXECUTE sql INTO iedges;
IF iedges IS NOT NULL THEN
+
snapped := ST_Snap(noded, iedges, tol);
+
noded := ST_Difference(snapped, iedges);
+
set1 := ST_Intersection(snapped, iedges);
+
set2 := ST_LineMerge(set1);
+
noded := ST_Union(noded, set2);
+
END IF;
-- 2.1. Node with existing nodes within tol
@@ -3954,26 +4004,32 @@ BEGIN
|| quote_literal(noded::text)
|| '::geometry, '
|| tol || ') ) SELECT st_collect(geom) FROM nearby;';
+
EXECUTE sql INTO inodes;
IF inodes IS NOT NULL THEN -- {
+
-- TODO: consider snapping once against all elements
--- (rather than once with edges and once with nodes)
noded := ST_Snap(noded, inodes, tol);
+
FOR rec IN SELECT (ST_Dump(inodes)).*
LOOP
-- Use the node to split edges
SELECT ST_Collect(geom)
FROM ST_Dump(ST_Split(noded, rec.geom))
INTO STRICT noded;
+
END LOOP;
+
-- re-node to account for ST_Snap introduced self-intersections
- -- See http://trac.osgeo.org/postgis/ticket/1714
+ -- See http:
-- TODO: consider running UnaryUnion once after all noding
noded := ST_UnaryUnion(noded);
+
END IF; -- }
-- 3. For each (now-noded) segment, insert an edge
@@ -3982,14 +4038,17 @@ BEGIN
-- TODO: skip point elements ?
+
start_node := topology.TopoGeo_AddPoint(atopology,
ST_StartPoint(rec.geom),
tol);
+
end_node := topology.TopoGeo_AddPoint(atopology,
ST_EndPoint(rec.geom),
tol);
+
-- Added endpoints may have drifted due to tolerance, so
-- we need to re-snap the edge to the new nodes before adding it
sql := 'SELECT n1.geom as sn, n2.geom as en FROM ' || quote_ident(atopology)
@@ -3997,6 +4056,7 @@ BEGIN
|| '.node n2 WHERE n1.node_id = '
|| start_node || ' AND n2.node_id = ' || end_node;
+
EXECUTE sql INTO STRICT rec2;
snapped := ST_SetPoint(
@@ -4007,8 +4067,10 @@ BEGIN
snapped := ST_CollectionExtract(ST_MakeValid(snapped), 2);
+
-- Check if the so-snapped edge collapsed (see #1650)
IF ST_IsEmpty(snapped) THEN
+
CONTINUE;
END IF;
@@ -4016,11 +4078,14 @@ BEGIN
sql := 'SELECT edge_id FROM ' || quote_ident(atopology)
|| '.edge_data WHERE ST_Equals(geom, ' || quote_literal(snapped::text)
|| '::geometry)';
+
EXECUTE sql INTO id;
IF id IS NULL THEN
id := topology.ST_AddEdgeModFace(atopology, start_node, end_node,
snapped);
+
ELSE
+
END IF;
RETURN NEXT id;
@@ -4062,9 +4127,11 @@ BEGIN
-- 1. Extract boundary
boundary := ST_Boundary(apoly);
+
-- 2. Add boundaries as edges
FOR rec IN SELECT (ST_Dump(boundary)).geom LOOP
edges := array_cat(edges, array_agg(x)) FROM ( select topology.TopoGeo_addLinestring(atopology, rec.geom, tol) as x ) as foo;
+
END LOOP;
-- 3. Find faces covered by input polygon
@@ -4073,10 +4140,12 @@ BEGIN
|| '.face f WHERE f.mbr && '
|| quote_literal(apoly::text)
|| '::geometry';
+
FOR rec IN EXECUTE sql LOOP
-- check for actual containment
fgeom := ST_PointOnSurface(ST_GetFaceGeometry(atopology, rec.face_id));
IF NOT ST_Covers(apoly, fgeom) THEN
+
CONTINUE;
END IF;
RETURN NEXT rec.face_id;
@@ -4102,10 +4171,11 @@ END
$$
LANGUAGE 'plpgsql';
--} TopoGeo_AddGeometry
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4154,11 +4224,12 @@ $$
LANGUAGE 'plpgsql';
--} Polygonize(toponame)
+
-- TopoElement
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4172,7 +4243,7 @@ LANGUAGE 'plpgsql';
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -4214,11 +4285,12 @@ CREATE AGGREGATE topology.TopoElementArray_agg(
);
--} TopoElementArray_agg
+
-- TopoGeometry
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4274,10 +4346,11 @@ $$
$$
LANGUAGE 'sql' STABLE STRICT;
-- }
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011-2012 Sandro Santilli <strk@keybit.net>
--
@@ -4289,7 +4362,7 @@ LANGUAGE 'sql' STABLE STRICT;
-- {
-- Convert a simple geometry to a topologically-defined one
--
--- See http://trac.osgeo.org/postgis/ticket/1017
+-- See http:
--
-- }{
CREATE OR REPLACE FUNCTION topology.toTopoGeom(ageom Geometry, atopology varchar, alayer int, atolerance float8 DEFAULT 0)
@@ -4414,6 +4487,7 @@ BEGIN
|| '.relation(topogeo_id, layer_id, element_type, element_id) VALUES ('
|| rec.id || ',' || rec.lyr || ',' || rec.type
|| ',' || rec.primitive || ')';
+
EXECUTE sql;
END LOOP;
@@ -4424,11 +4498,12 @@ $$
LANGUAGE 'plpgsql' VOLATILE STRICT;
-- }
+
-- GML
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4442,7 +4517,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -4989,13 +5064,14 @@ $$ LANGUAGE 'sql' STABLE; -- does NOT write into visited table
-- } AsGML(TopoGeometry)
+
--=} POSTGIS-SPECIFIC block
-- SQL/MM block
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011, 2012 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -5101,6 +5177,7 @@ BEGIN
LOOP
+
retrec.sequence = n;
retrec.edge = rec.edge_id;
@@ -5399,6 +5476,7 @@ BEGIN
|| ' AND l.layer_id = r.layer_id AND abs(r.element_id) = '
|| e1id
;
+
EXECUTE sql;
@@ -5747,6 +5825,7 @@ BEGIN
|| 'WHERE l.level = 0 AND l.feature_type = 2 '
|| ' AND l.topology_id = ' || topoid
|| ' AND abs(r.element_id) = ' || e1id ;
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented dropping edge %',
rec.topogeo_id, rec.layer_id,
@@ -5771,6 +5850,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge < 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -5788,6 +5868,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge > 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -5803,6 +5884,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge < 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -5820,6 +5902,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge > 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -5865,6 +5948,7 @@ BEGIN
END IF; -- }
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented healing faces % and %',
rec.topogeo_id, rec.layer_id,
@@ -5907,6 +5991,7 @@ BEGIN
|| '.face WHERE face_id IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
END IF; -- }
@@ -5917,6 +6002,7 @@ BEGIN
|| ' WHERE left_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update right_face for all edges still referencing old faces
@@ -5925,6 +6011,7 @@ BEGIN
|| ' WHERE right_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update containing_face for all nodes still referencing old faces
@@ -5933,6 +6020,7 @@ BEGIN
|| ' WHERE containing_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- NOT IN THE SPECS:
@@ -5945,6 +6033,7 @@ BEGIN
|| ' AND l.topology_id = ' || topoid
|| ' AND l.layer_id = r.layer_id AND abs(r.element_id) = '
|| e1rec.left_face;
+
EXECUTE sql;
sql := 'UPDATE ' || quote_ident(toponame)
|| '.relation r '
@@ -5953,6 +6042,7 @@ BEGIN
|| ' AND l.topology_id = ' || topoid
|| ' AND l.layer_id = r.layer_id AND r.element_id = '
|| e1rec.right_face;
+
EXECUTE sql;
END IF; -- } two faces healed...
@@ -5960,6 +6050,7 @@ BEGIN
-- Delete the edge
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.edge_data WHERE edge_id = ' || e1id;
+
EXECUTE sql;
-- Check if any of the edge nodes remains isolated,
@@ -5971,6 +6062,7 @@ BEGIN
|| e1rec.end_node || ') AND NOT EXISTS (SELECT edge_id FROM '
|| quote_ident(toponame)
|| '.edge_data WHERE start_node = n.node_id OR end_node = n.node_id)';
+
EXECUTE sql;
IF e1rec.right_face != e1rec.left_face THEN -- {
@@ -5979,6 +6071,7 @@ BEGIN
IF e1rec.left_face != 0 THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.left_face;
+
EXECUTE sql;
END IF;
@@ -5987,6 +6080,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.right_face;
+
EXECUTE sql;
END IF;
@@ -6071,6 +6165,7 @@ BEGIN
|| 'WHERE l.level = 0 AND l.feature_type = 2 '
|| ' AND l.topology_id = ' || topoid
|| ' AND abs(r.element_id) = ' || e1id ;
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented dropping edge %',
rec.topogeo_id, rec.layer_id,
@@ -6095,6 +6190,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge < 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -6112,6 +6208,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge > 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -6127,6 +6224,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge < 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -6144,6 +6242,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge > 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -6187,6 +6286,7 @@ BEGIN
END IF; -- }
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented healing faces % and %',
rec.topogeo_id, rec.layer_id,
@@ -6219,6 +6319,7 @@ BEGIN
|| '.face WHERE face_id IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ') ) WHERE face_id = ' || floodfaceid ;
+
EXECUTE sql;
END IF; -- }
@@ -6229,6 +6330,7 @@ BEGIN
|| ' WHERE left_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update right_face for all edges still referencing old faces
@@ -6237,6 +6339,7 @@ BEGIN
|| ' WHERE right_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update containing_face for all nodes still referencing old faces
@@ -6245,6 +6348,7 @@ BEGIN
|| ' WHERE containing_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- NOT IN THE SPECS:
@@ -6259,6 +6363,7 @@ BEGIN
|| e1rec.left_face || ',' || e1rec.right_face
|| ') AND abs(r.element_id) != '
|| floodfaceid; -- could be optimized..
+
EXECUTE sql;
END IF; -- } two faces healed...
@@ -6266,6 +6371,7 @@ BEGIN
-- Delete the edge
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.edge_data WHERE edge_id = ' || e1id;
+
EXECUTE sql;
-- Check if any of the edge nodes remains isolated,
@@ -6277,6 +6383,7 @@ BEGIN
|| e1rec.end_node || ') AND NOT EXISTS (SELECT edge_id FROM '
|| quote_ident(toponame)
|| '.edge_data WHERE start_node = n.node_id OR end_node = n.node_id)';
+
EXECUTE sql;
IF e1rec.right_face != e1rec.left_face THEN -- {
@@ -6286,6 +6393,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.left_face;
+
EXECUTE sql;
END IF;
@@ -6294,6 +6402,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.right_face;
+
EXECUTE sql;
END IF;
@@ -6451,6 +6560,7 @@ BEGIN
sql := sql || ' AND f.face_id = ' || aface;
END IF;
+
EXECUTE sql INTO containingface;
-- If aface was specified, check that it was correct
@@ -6484,6 +6594,7 @@ BEGIN
|| '::geometry,' || containingface
|| ' RETURNING node_id';
+
EXECUTE sql INTO nodeid;
RETURN nodeid;
@@ -6624,7 +6735,7 @@ LANGUAGE 'plpgsql' VOLATILE;
--} ST_RemoveIsoNode
--{
--- According to http://trac.osgeo.org/postgis/ticket/798
+-- According to http:
-- ST_RemoveIsoNode was renamed to ST_RemIsoNode in the final ISO
-- document
--
@@ -6826,6 +6937,7 @@ BEGIN
END LOOP;
+
--RAISE NOTICE 'EdgeId1 % EdgeId2 %', edgeid1, edgeid2;
--RAISE DEBUG 'oldedge.next_left_edge: %', oldedge.next_left_edge;
@@ -7111,6 +7223,7 @@ BEGIN
END LOOP;
+
--
-- Insert the new edge
--
@@ -7618,25 +7731,32 @@ BEGIN
tmp1 := ST_MakeLine(ST_EndPoint(oldedge.geom), ST_StartPoint(oldedge.geom));
+
tmp2 := ST_MakeLine(oldedge.geom, tmp1);
IF ST_NumPoints(tmp2) < 4 THEN
tmp2 := ST_AddPoint(tmp2, ST_StartPoint(oldedge.geom));
END IF;
+
tmp2 := ST_CollectionExtract(ST_MakeValid(ST_MakePolygon(tmp2)), 3);
+
range := ST_MakeLine(acurve, tmp1);
IF ST_NumPoints(range) < 4 THEN
range := ST_AddPoint(range, ST_StartPoint(oldedge.geom));
END IF;
+
range := ST_CollectionExtract(ST_MakeValid(ST_MakePolygon(range)), 3);
+
range := ST_SymDifference(range, tmp2);
+
sql := 'SELECT node_id, geom FROM '
|| quote_ident(atopology)
|| '.node WHERE ST_Contains('
|| quote_literal(range::text)
|| '::geometry, geom) LIMIT 1';
+
FOR rec IN EXECUTE sql LOOP -- {
RAISE EXCEPTION 'Edge motion collision at %', ST_AsText(rec.geom);
END LOOP; -- }
@@ -7652,11 +7772,13 @@ BEGIN
) as pre, NULL::integer[] as post
INTO STRICT snode_info;
+
SELECT topology._ST_AdjacentEdges(
atopology, oldedge.end_node, -anedge
) as pre, NULL::integer[] as post
INTO STRICT enode_info;
+
--}
--
@@ -7674,10 +7796,12 @@ BEGIN
atopology, oldedge.start_node, anedge
);
+
enode_info.post := topology._ST_AdjacentEdges(
atopology, oldedge.end_node, -anedge
);
+
IF snode_info.pre != snode_info.post THEN
RAISE EXCEPTION 'Edge changed disposition around start node %',
oldedge.start_node;
@@ -7754,6 +7878,7 @@ DECLARE
BEGIN
IF oface = 0 AND mbr_only THEN
+
RETURN NULL;
END IF;
@@ -7766,24 +7891,31 @@ BEGIN
INTO STRICT fan.newring_edges;
+
-- You can't get to the other side of an edge forming a ring
IF fan.newring_edges @> ARRAY[-anedge] THEN
+
RETURN 0;
END IF;
+
sql := 'WITH ids as ( select row_number() over () as seq, edge from unnest('
|| quote_literal(fan.newring_edges::text)
|| '::int[] ) u(edge) ), edges AS ( select CASE WHEN i.edge < 0 THEN ST_Reverse(e.geom) ELSE e.geom END as g FROM ids i left join '
|| quote_ident(atopology) || '.edge_data e ON(e.edge_id = abs(i.edge)) ORDER BY seq) SELECT ST_MakePolygon(ST_MakeLine(g.g)) FROM edges g;';
+
EXECUTE sql INTO fan.shell;
+
isccw := NOT ST_OrderingEquals(fan.shell, ST_ForceRHR(fan.shell));
+
IF oface = 0 THEN
IF NOT isccw THEN
+
RETURN NULL;
END IF;
END IF;
@@ -7795,6 +7927,7 @@ BEGIN
|| quote_ident(atopology) || '.face SET mbr = '
|| quote_literal(ST_Envelope(fan.shell)::text)
|| '::geometry WHERE face_id = ' || oface;
+
EXECUTE sql;
END IF; -- }
RETURN NULL;
@@ -7815,6 +7948,7 @@ BEGIN
END IF; -- }
-- Insert new face
+
EXECUTE sql INTO STRICT newface;
-- Update forward edges
@@ -7823,6 +7957,7 @@ BEGIN
|| ' WHERE left_face = ' || oface || ' AND edge_id = ANY ('
|| quote_literal(array( select +(x) from unnest(fan.newring_edges) u(x) )::text)
|| ')';
+
EXECUTE sql;
-- Update backward edges
@@ -7831,12 +7966,15 @@ BEGIN
|| ' WHERE right_face = ' || oface || ' AND edge_id = ANY ('
|| quote_literal(array( select -(x) from unnest(fan.newring_edges) u(x) )::text)
|| ')';
+
EXECUTE sql;
IF oface != 0 AND NOT isccw THEN -- {
-- face shrinked, must update all non-contained edges and nodes
+
ishole := true;
ELSE
+
ishole := false;
END IF; -- }
@@ -7858,6 +7996,7 @@ BEGIN
sql := sql || 'ST_Contains(' || quote_literal(fan.shell::text)
-- We only need to check a single point, but must not be an endpoint
|| '::geometry, ST_Line_Interpolate_Point(geom, 0.2))';
+
EXECUTE sql;
-- Update isolated nodes in new new face
@@ -7867,6 +8006,7 @@ BEGIN
|| ' AND ';
IF ishole THEN sql := sql || 'NOT '; END IF;
sql := sql || 'ST_Contains(' || quote_literal(fan.shell::text) || '::geometry, geom)';
+
EXECUTE sql;
RETURN newface;
@@ -7990,6 +8130,7 @@ BEGIN
|| ')'
LOOP
IF rec.containing_face IS NOT NULL THEN
+
IF newedge.left_face IS NULL THEN
newedge.left_face := rec.containing_face;
newedge.right_face := rec.containing_face;
@@ -8097,6 +8238,7 @@ BEGIN
-- Find links on start node -- {
+
sql :=
'SELECT edge_id, -1 AS end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8142,6 +8284,7 @@ BEGIN
END IF;
+
az = az - span.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8181,6 +8324,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN span.was_isolated = true; END IF;
ELSE
@@ -8197,12 +8341,16 @@ BEGIN
END IF;
+
+
+
-- } start_node analysis
-- Find links on end_node {
+
sql :=
'SELECT edge_id, -1 as end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8244,6 +8392,7 @@ BEGIN
END IF;
+
az := az - epan.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8283,6 +8432,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN epan.was_isolated = true; END IF;
ELSE
@@ -8301,6 +8451,9 @@ BEGIN
-- } end_node analysis
+
+
+
----------------------------------------------------------------------
--
-- If we don't have faces setup by now we must have encountered
@@ -8396,15 +8549,18 @@ BEGIN
--------------------------------------------
+
SELECT topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, false)
INTO newface;
IF newface = 0 THEN
+
RETURN newedge.edge_id;
END IF;
newfaces[1] := newface;
+
SELECT topology._ST_AddFaceSplit(atopology, newedge.edge_id, newedge.left_face, false)
INTO newface;
@@ -8427,6 +8583,7 @@ BEGIN
FOR rec IN EXECUTE sql
LOOP
+
-- Add reference to the other face
sql := 'INSERT INTO ' || quote_ident(atopology)
|| '.relation VALUES( ' || rec.topogeo_id
@@ -8564,6 +8721,7 @@ BEGIN
|| ')'
LOOP
IF rec.containing_face IS NOT NULL THEN
+
IF newedge.left_face IS NULL THEN
newedge.left_face := rec.containing_face;
newedge.right_face := rec.containing_face;
@@ -8669,6 +8827,7 @@ BEGIN
-- Find links on start node -- {
+
sql :=
'SELECT edge_id, -1 AS end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8714,6 +8873,7 @@ BEGIN
END IF;
+
az = az - span.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8753,6 +8913,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN span.was_isolated = true; END IF;
ELSE
@@ -8769,12 +8930,16 @@ BEGIN
END IF;
+
+
+
-- } start_node analysis
-- Find links on end_node {
+
sql :=
'SELECT edge_id, -1 as end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8816,6 +8981,7 @@ BEGIN
END IF;
+
az := az - epan.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8855,6 +9021,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN epan.was_isolated = true; END IF;
ELSE
@@ -8873,6 +9040,9 @@ BEGIN
-- } end_node analysis
+
+
+
----------------------------------------------------------------------
--
-- If we don't have faces setup by now we must have encountered
@@ -8967,20 +9137,25 @@ BEGIN
-- Check face splitting
--------------------------------------------
+
SELECT topology._ST_AddFaceSplit(atopology, newedge.edge_id, newedge.left_face, false)
INTO newface;
IF newface = 0 THEN
+
RETURN newedge.edge_id;
END IF;
IF newface IS NULL THEN -- must be forming a maximal ring in universal face
+
SELECT topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, false)
INTO newface;
ELSE
+
PERFORM topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, true);
END IF;
IF newface IS NULL THEN
+
RETURN newedge.edge_id;
END IF;
@@ -9004,6 +9179,7 @@ BEGIN
FOR rec IN EXECUTE sql
LOOP
+
-- Add reference to the other face
sql := 'INSERT INTO ' || quote_ident(atopology)
|| '.relation VALUES( ' || rec.topogeo_id
@@ -9134,6 +9310,7 @@ BEGIN
END; -- }
+
--
-- Node input linework with itself
--
@@ -9147,6 +9324,7 @@ BEGIN
) as linework INTO STRICT nodededges;
+
--
-- Linemerge the resulting edges, to reduce the working set
-- NOTE: this is more of a workaround for GEOS splitting overlapping
@@ -9156,6 +9334,7 @@ BEGIN
+
--
-- Collect input points and input lines endpoints
--
@@ -9169,6 +9348,7 @@ BEGIN
) as nodes INTO STRICT points;
+
--
-- Further split edges by points
-- TODO: optimize this adding ST_Split support for multiline/multipoint
@@ -9183,6 +9363,7 @@ BEGIN
SELECT ST_UnaryUnion(nodededges) INTO STRICT nodededges;
+
--
-- Collect all nodes (from points and noded linework endpoints)
--
@@ -9201,6 +9382,7 @@ BEGIN
) as endpoints INTO points;
+
--
-- Add all nodes as isolated so that
-- later calls to AddEdgeModFace will tweak their being
@@ -9231,11 +9413,12 @@ LANGUAGE 'plpgsql' VOLATILE;
--=} SQL/MM block
+
-- The following files needs getfaceedges_returntype, defined in sqlmm.sql
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 2012 Sandro Santilli <strk@keybit.net>
--
@@ -9245,7 +9428,7 @@ LANGUAGE 'plpgsql' VOLATILE;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -9312,10 +9495,11 @@ END
$$
LANGUAGE 'plpgsql' STABLE;
--} GetRingEdges
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2012 Sandro Santilli <strk@keybit.net>
--
@@ -9356,9 +9540,11 @@ BEGIN
|| ' UNION ALL SELECT -edge_id, ST_Azimuth(ST_EndPoint(geom), ST_PointN(geom, ST_NumPoints(geom)-1)) FROM incident_edges WHERE end_node = ' || anode
|| ' ORDER BY az';
+
FOR rec IN EXECUTE sql
LOOP -- incident edges {
+
n := n + 1;
retrec.sequence := n;
retrec.edge := rec.edge_id;
@@ -9370,11 +9556,12 @@ $$
LANGUAGE 'plpgsql' STABLE;
--} GetRingEdges
+
--general management --
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://www.postgis.org
+-- http:
--
-- Copyright (C) 2011 Regina Obe <lr@pcorp.us>
--
@@ -9413,6 +9600,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
--} AddToSearchPath
+
CREATE OR REPLACE FUNCTION postgis_topology_scripts_installed() RETURNS text
AS $$ SELECT '2.0.2'::text || ' r' || 10789::text AS version $$
LANGUAGE 'sql' IMMUTABLE;
diff --git a/gcc/postgis_extension/postgis_topology--2.0.0beta2--2.0.2.sql b/gpp/postgis_extension/postgis_topology--2.0.0beta2--2.0.2.sql
index 80c44f9..a257064 100644
--- a/gcc/postgis_extension/postgis_topology--2.0.0beta2--2.0.2.sql
+++ b/gpp/postgis_extension/postgis_topology--2.0.0beta2--2.0.2.sql
@@ -100,14 +100,12 @@ LANGUAGE plpgsql VOLATILE;
-- during upgrade
SELECT postgis_extension_remove_objects('postgis_topology', 'FUNCTION');
SELECT postgis_extension_remove_objects('postgis_topology', 'AGGREGATE');
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: topology.sql.in.c 10643 2012-11-05 10:25:41Z strk $
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -306,6 +304,23 @@ SELECT postgis_extension_remove_objects('postgis_topology', 'AGGREGATE');
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-- Doing everything outside of a transaction helps
-- upgrading in the best case.
@@ -481,7 +496,9 @@ ALTER DOMAIN topology.TopoElement ADD
array_lower(VALUE, 1) = 1
);
ALTER DOMAIN topology.TopoElement DROP CONSTRAINT
+
IF EXISTS
+
type_range;
ALTER DOMAIN topology.TopoElement ADD
CONSTRAINT type_range CHECK (
@@ -777,6 +794,7 @@ BEGIN
-- corrupting the topology anyway ...
--
+
RETURN newlayer_id;
END;
$$
@@ -1120,6 +1138,7 @@ BEGIN
|| ') as obj ORDER BY obj';
+
-- TODO: why not using array_agg here ?
i = 1;
@@ -1517,7 +1536,7 @@ BEGIN
--
-- Closed lines have no boundary, so endpoint
-- intersection would be considered interior
- -- See http://trac.osgeo.org/postgis/ticket/770
+ -- See http:
-- See also full explanation in topology.AddEdge
--
@@ -1681,6 +1700,7 @@ BEGIN
END LOOP;
+
DROP TABLE face_check;
RETURN;
@@ -1910,7 +1930,7 @@ BEGIN
------- Indexes on left_face and right_face of edge_data
------- NOTE: these indexes speed up GetFaceGeometry (and thus
------- TopoGeometry::Geometry) by a factor of 10 !
- ------- See http://trac.osgeo.org/postgis/ticket/806
+ ------- See http:
EXECUTE 'CREATE INDEX edge_left_face_idx ON '
|| quote_ident(atopology)
|| '.edge_data (left_face);';
@@ -1921,7 +1941,7 @@ BEGIN
------- Indexes on start_node and end_node of edge_data
------- NOTE: this indexes speed up node deletion
------- by a factor of 1000 !
- ------- See http://trac.osgeo.org/postgis/ticket/2082
+ ------- See http:
EXECUTE 'CREATE INDEX edge_start_node_idx ON '
|| quote_ident(atopology)
|| '.edge_data (start_node);';
@@ -2029,7 +2049,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -2180,10 +2200,11 @@ $$
LANGUAGE 'plpgsql' STABLE STRICT;
--} TopologySummary
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -2280,11 +2301,12 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
--} TopologySummary
+
-- Spatial predicates
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011-2012 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -2798,11 +2820,12 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--} equals(TopoGeometry, TopoGeometry)
+
-- Querying
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -2888,10 +2911,11 @@ $$
LANGUAGE 'plpgsql' STABLE STRICT;
--} GetNodeByPoint
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -2979,10 +3003,11 @@ END
$$
LANGUAGE 'plpgsql' STABLE STRICT;
--} GetEdgeByPoint
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -3138,11 +3163,12 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--} GetFaceByPoint
+
-- Populating
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010-2012 Sandro Santilli <strk@keybit.net>
--
@@ -3163,7 +3189,7 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--
--
-- A pragmatic test conducted using algoritm shown here:
--- http://stackoverflow.com/questions/7408407/generate-next-largest-or-smallest-representable-floating-point-number-without-bi
+-- http:
-- showed the "tolerance" growing by an order of magnitude proportionally
-- with the order of magnitude of the input, starting with something like
-- 3.5527136788005009294e-15 for the starting value of 9.0
@@ -3219,7 +3245,7 @@ $$ LANGUAGE 'plpgsql' STABLE STRICT;
-- The newly added nodes have no containing face.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3287,6 +3313,7 @@ BEGIN
IF setContainingFace THEN
containing_face := topology.GetFaceByPoint(atopology, apoint, 0);
+
ELSE
containing_face := NULL;
END IF;
@@ -3346,7 +3373,7 @@ LANGUAGE 'sql' VOLATILE;
-- Calling code is expected to do further linking.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3435,6 +3462,7 @@ BEGIN
-- Reuse an EQUAL edge (be it closed or not)
IF ST_RelateMatch(rec.im, '1FFF*FFF2') THEN
+
RETURN rec.edge_id;
END IF;
@@ -3539,7 +3567,7 @@ LANGUAGE 'plpgsql' VOLATILE;
-- o The polygon overlaps an existing face.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3661,6 +3689,7 @@ BEGIN
ST_Line_Locate_Point(bounds, p2);
+
IF right_side THEN
right_edges := array_append(right_edges, rec.edge_id);
old_faceid = rec.right_face;
@@ -3687,6 +3716,8 @@ BEGIN
END IF;
+
+
--
-- Check that all edges found, taken togheter,
-- fully match the ring boundary and nothing more
@@ -3706,8 +3737,10 @@ BEGIN
IF faceid IS NOT NULL AND faceid != 0 THEN
IF NOT force_new THEN
+
RETURN faceid;
ELSE
+
END IF;
END IF;
@@ -3834,12 +3867,14 @@ BEGIN
|| tol || ') ORDER BY ST_Distance('
|| quote_literal(apoint::text)
|| '::geometry, a.geom) LIMIT 1;';
+
EXECUTE sql INTO id;
IF id IS NOT NULL THEN
RETURN id;
END IF;
+
-- 2. Check if any existing edge falls within tolerance
-- and if so split it by a point projected on it
sql := 'SELECT a.edge_id, a.geom FROM '
@@ -3849,35 +3884,42 @@ BEGIN
|| tol || ') ORDER BY ST_Distance('
|| quote_literal(apoint::text)
|| '::geometry, a.geom) LIMIT 1;';
+
EXECUTE sql INTO rec;
IF rec IS NOT NULL THEN
-- project point to line, split edge by point
prj := ST_ClosestPoint(rec.geom, apoint);
-- This is a workaround for ClosestPoint lack of Z support:
- -- http://trac.osgeo.org/postgis/ticket/2033
+ -- http:
z := ST_Z(apoint);
IF z IS NOT NULL THEN
prj := ST_Translate(ST_Force_3DZ(prj), 0, 0, z); -- no ST_SetZ ...
END IF;
+
IF NOT ST_Contains(rec.geom, prj) THEN
+
-- The tolerance must be big enough for snapping to happen
-- and small enough to snap only to the projected point.
-- Unfortunately ST_Distance returns 0 because it also uses
-- a projected point internally, so we need another way.
snaptol := topology._st_mintolerance(prj);
+
snapedge := ST_Snap(rec.geom, prj, snaptol);
-- Snapping currently snaps the first point below tolerance
-- so may possibly move first point. See ticket #1631
IF NOT ST_Equals(ST_StartPoint(rec.geom), ST_StartPoint(snapedge))
THEN
+
snapedge := ST_MakeLine(ST_StartPoint(rec.geom), snapedge);
END IF;
+
PERFORM ST_ChangeEdgeGeom(atopology, rec.edge_id, snapedge);
END IF;
id := topology.ST_ModEdgeSplit(atopology, rec.edge_id, prj);
ELSE
+
id := topology.ST_AddIsoNode(atopology, NULL, apoint);
END IF;
@@ -3923,6 +3965,7 @@ BEGIN
-- 1. Self-node
noded := ST_UnaryUnion(aline);
+
-- 2. Node to edges falling within tol distance
sql := 'WITH nearby AS ( SELECT e.geom FROM '
|| quote_ident(atopology)
@@ -3930,20 +3973,27 @@ BEGIN
|| quote_literal(noded::text)
|| '::geometry, '
|| tol || ') ) SELECT st_collect(geom) FROM nearby;';
+
EXECUTE sql INTO iedges;
IF iedges IS NOT NULL THEN
+
snapped := ST_Snap(noded, iedges, tol);
+
noded := ST_Difference(snapped, iedges);
+
set1 := ST_Intersection(snapped, iedges);
+
set2 := ST_LineMerge(set1);
+
noded := ST_Union(noded, set2);
+
END IF;
-- 2.1. Node with existing nodes within tol
@@ -3954,26 +4004,32 @@ BEGIN
|| quote_literal(noded::text)
|| '::geometry, '
|| tol || ') ) SELECT st_collect(geom) FROM nearby;';
+
EXECUTE sql INTO inodes;
IF inodes IS NOT NULL THEN -- {
+
-- TODO: consider snapping once against all elements
--- (rather than once with edges and once with nodes)
noded := ST_Snap(noded, inodes, tol);
+
FOR rec IN SELECT (ST_Dump(inodes)).*
LOOP
-- Use the node to split edges
SELECT ST_Collect(geom)
FROM ST_Dump(ST_Split(noded, rec.geom))
INTO STRICT noded;
+
END LOOP;
+
-- re-node to account for ST_Snap introduced self-intersections
- -- See http://trac.osgeo.org/postgis/ticket/1714
+ -- See http:
-- TODO: consider running UnaryUnion once after all noding
noded := ST_UnaryUnion(noded);
+
END IF; -- }
-- 3. For each (now-noded) segment, insert an edge
@@ -3982,14 +4038,17 @@ BEGIN
-- TODO: skip point elements ?
+
start_node := topology.TopoGeo_AddPoint(atopology,
ST_StartPoint(rec.geom),
tol);
+
end_node := topology.TopoGeo_AddPoint(atopology,
ST_EndPoint(rec.geom),
tol);
+
-- Added endpoints may have drifted due to tolerance, so
-- we need to re-snap the edge to the new nodes before adding it
sql := 'SELECT n1.geom as sn, n2.geom as en FROM ' || quote_ident(atopology)
@@ -3997,6 +4056,7 @@ BEGIN
|| '.node n2 WHERE n1.node_id = '
|| start_node || ' AND n2.node_id = ' || end_node;
+
EXECUTE sql INTO STRICT rec2;
snapped := ST_SetPoint(
@@ -4007,8 +4067,10 @@ BEGIN
snapped := ST_CollectionExtract(ST_MakeValid(snapped), 2);
+
-- Check if the so-snapped edge collapsed (see #1650)
IF ST_IsEmpty(snapped) THEN
+
CONTINUE;
END IF;
@@ -4016,11 +4078,14 @@ BEGIN
sql := 'SELECT edge_id FROM ' || quote_ident(atopology)
|| '.edge_data WHERE ST_Equals(geom, ' || quote_literal(snapped::text)
|| '::geometry)';
+
EXECUTE sql INTO id;
IF id IS NULL THEN
id := topology.ST_AddEdgeModFace(atopology, start_node, end_node,
snapped);
+
ELSE
+
END IF;
RETURN NEXT id;
@@ -4062,9 +4127,11 @@ BEGIN
-- 1. Extract boundary
boundary := ST_Boundary(apoly);
+
-- 2. Add boundaries as edges
FOR rec IN SELECT (ST_Dump(boundary)).geom LOOP
edges := array_cat(edges, array_agg(x)) FROM ( select topology.TopoGeo_addLinestring(atopology, rec.geom, tol) as x ) as foo;
+
END LOOP;
-- 3. Find faces covered by input polygon
@@ -4073,10 +4140,12 @@ BEGIN
|| '.face f WHERE f.mbr && '
|| quote_literal(apoly::text)
|| '::geometry';
+
FOR rec IN EXECUTE sql LOOP
-- check for actual containment
fgeom := ST_PointOnSurface(ST_GetFaceGeometry(atopology, rec.face_id));
IF NOT ST_Covers(apoly, fgeom) THEN
+
CONTINUE;
END IF;
RETURN NEXT rec.face_id;
@@ -4102,10 +4171,11 @@ END
$$
LANGUAGE 'plpgsql';
--} TopoGeo_AddGeometry
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4154,11 +4224,12 @@ $$
LANGUAGE 'plpgsql';
--} Polygonize(toponame)
+
-- TopoElement
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4172,7 +4243,7 @@ LANGUAGE 'plpgsql';
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -4214,11 +4285,12 @@ CREATE AGGREGATE topology.TopoElementArray_agg(
);
--} TopoElementArray_agg
+
-- TopoGeometry
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4274,10 +4346,11 @@ $$
$$
LANGUAGE 'sql' STABLE STRICT;
-- }
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011-2012 Sandro Santilli <strk@keybit.net>
--
@@ -4289,7 +4362,7 @@ LANGUAGE 'sql' STABLE STRICT;
-- {
-- Convert a simple geometry to a topologically-defined one
--
--- See http://trac.osgeo.org/postgis/ticket/1017
+-- See http:
--
-- }{
CREATE OR REPLACE FUNCTION topology.toTopoGeom(ageom Geometry, atopology varchar, alayer int, atolerance float8 DEFAULT 0)
@@ -4414,6 +4487,7 @@ BEGIN
|| '.relation(topogeo_id, layer_id, element_type, element_id) VALUES ('
|| rec.id || ',' || rec.lyr || ',' || rec.type
|| ',' || rec.primitive || ')';
+
EXECUTE sql;
END LOOP;
@@ -4424,11 +4498,12 @@ $$
LANGUAGE 'plpgsql' VOLATILE STRICT;
-- }
+
-- GML
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4442,7 +4517,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -4989,13 +5064,14 @@ $$ LANGUAGE 'sql' STABLE; -- does NOT write into visited table
-- } AsGML(TopoGeometry)
+
--=} POSTGIS-SPECIFIC block
-- SQL/MM block
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011, 2012 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -5101,6 +5177,7 @@ BEGIN
LOOP
+
retrec.sequence = n;
retrec.edge = rec.edge_id;
@@ -5399,6 +5476,7 @@ BEGIN
|| ' AND l.layer_id = r.layer_id AND abs(r.element_id) = '
|| e1id
;
+
EXECUTE sql;
@@ -5747,6 +5825,7 @@ BEGIN
|| 'WHERE l.level = 0 AND l.feature_type = 2 '
|| ' AND l.topology_id = ' || topoid
|| ' AND abs(r.element_id) = ' || e1id ;
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented dropping edge %',
rec.topogeo_id, rec.layer_id,
@@ -5771,6 +5850,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge < 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -5788,6 +5868,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge > 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -5803,6 +5884,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge < 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -5820,6 +5902,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge > 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -5865,6 +5948,7 @@ BEGIN
END IF; -- }
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented healing faces % and %',
rec.topogeo_id, rec.layer_id,
@@ -5907,6 +5991,7 @@ BEGIN
|| '.face WHERE face_id IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
END IF; -- }
@@ -5917,6 +6002,7 @@ BEGIN
|| ' WHERE left_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update right_face for all edges still referencing old faces
@@ -5925,6 +6011,7 @@ BEGIN
|| ' WHERE right_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update containing_face for all nodes still referencing old faces
@@ -5933,6 +6020,7 @@ BEGIN
|| ' WHERE containing_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- NOT IN THE SPECS:
@@ -5945,6 +6033,7 @@ BEGIN
|| ' AND l.topology_id = ' || topoid
|| ' AND l.layer_id = r.layer_id AND abs(r.element_id) = '
|| e1rec.left_face;
+
EXECUTE sql;
sql := 'UPDATE ' || quote_ident(toponame)
|| '.relation r '
@@ -5953,6 +6042,7 @@ BEGIN
|| ' AND l.topology_id = ' || topoid
|| ' AND l.layer_id = r.layer_id AND r.element_id = '
|| e1rec.right_face;
+
EXECUTE sql;
END IF; -- } two faces healed...
@@ -5960,6 +6050,7 @@ BEGIN
-- Delete the edge
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.edge_data WHERE edge_id = ' || e1id;
+
EXECUTE sql;
-- Check if any of the edge nodes remains isolated,
@@ -5971,6 +6062,7 @@ BEGIN
|| e1rec.end_node || ') AND NOT EXISTS (SELECT edge_id FROM '
|| quote_ident(toponame)
|| '.edge_data WHERE start_node = n.node_id OR end_node = n.node_id)';
+
EXECUTE sql;
IF e1rec.right_face != e1rec.left_face THEN -- {
@@ -5979,6 +6071,7 @@ BEGIN
IF e1rec.left_face != 0 THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.left_face;
+
EXECUTE sql;
END IF;
@@ -5987,6 +6080,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.right_face;
+
EXECUTE sql;
END IF;
@@ -6071,6 +6165,7 @@ BEGIN
|| 'WHERE l.level = 0 AND l.feature_type = 2 '
|| ' AND l.topology_id = ' || topoid
|| ' AND abs(r.element_id) = ' || e1id ;
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented dropping edge %',
rec.topogeo_id, rec.layer_id,
@@ -6095,6 +6190,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge < 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -6112,6 +6208,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge > 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -6127,6 +6224,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge < 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -6144,6 +6242,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge > 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -6187,6 +6286,7 @@ BEGIN
END IF; -- }
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented healing faces % and %',
rec.topogeo_id, rec.layer_id,
@@ -6219,6 +6319,7 @@ BEGIN
|| '.face WHERE face_id IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ') ) WHERE face_id = ' || floodfaceid ;
+
EXECUTE sql;
END IF; -- }
@@ -6229,6 +6330,7 @@ BEGIN
|| ' WHERE left_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update right_face for all edges still referencing old faces
@@ -6237,6 +6339,7 @@ BEGIN
|| ' WHERE right_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update containing_face for all nodes still referencing old faces
@@ -6245,6 +6348,7 @@ BEGIN
|| ' WHERE containing_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- NOT IN THE SPECS:
@@ -6259,6 +6363,7 @@ BEGIN
|| e1rec.left_face || ',' || e1rec.right_face
|| ') AND abs(r.element_id) != '
|| floodfaceid; -- could be optimized..
+
EXECUTE sql;
END IF; -- } two faces healed...
@@ -6266,6 +6371,7 @@ BEGIN
-- Delete the edge
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.edge_data WHERE edge_id = ' || e1id;
+
EXECUTE sql;
-- Check if any of the edge nodes remains isolated,
@@ -6277,6 +6383,7 @@ BEGIN
|| e1rec.end_node || ') AND NOT EXISTS (SELECT edge_id FROM '
|| quote_ident(toponame)
|| '.edge_data WHERE start_node = n.node_id OR end_node = n.node_id)';
+
EXECUTE sql;
IF e1rec.right_face != e1rec.left_face THEN -- {
@@ -6286,6 +6393,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.left_face;
+
EXECUTE sql;
END IF;
@@ -6294,6 +6402,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.right_face;
+
EXECUTE sql;
END IF;
@@ -6451,6 +6560,7 @@ BEGIN
sql := sql || ' AND f.face_id = ' || aface;
END IF;
+
EXECUTE sql INTO containingface;
-- If aface was specified, check that it was correct
@@ -6484,6 +6594,7 @@ BEGIN
|| '::geometry,' || containingface
|| ' RETURNING node_id';
+
EXECUTE sql INTO nodeid;
RETURN nodeid;
@@ -6624,7 +6735,7 @@ LANGUAGE 'plpgsql' VOLATILE;
--} ST_RemoveIsoNode
--{
--- According to http://trac.osgeo.org/postgis/ticket/798
+-- According to http:
-- ST_RemoveIsoNode was renamed to ST_RemIsoNode in the final ISO
-- document
--
@@ -6826,6 +6937,7 @@ BEGIN
END LOOP;
+
--RAISE NOTICE 'EdgeId1 % EdgeId2 %', edgeid1, edgeid2;
--RAISE DEBUG 'oldedge.next_left_edge: %', oldedge.next_left_edge;
@@ -7111,6 +7223,7 @@ BEGIN
END LOOP;
+
--
-- Insert the new edge
--
@@ -7618,25 +7731,32 @@ BEGIN
tmp1 := ST_MakeLine(ST_EndPoint(oldedge.geom), ST_StartPoint(oldedge.geom));
+
tmp2 := ST_MakeLine(oldedge.geom, tmp1);
IF ST_NumPoints(tmp2) < 4 THEN
tmp2 := ST_AddPoint(tmp2, ST_StartPoint(oldedge.geom));
END IF;
+
tmp2 := ST_CollectionExtract(ST_MakeValid(ST_MakePolygon(tmp2)), 3);
+
range := ST_MakeLine(acurve, tmp1);
IF ST_NumPoints(range) < 4 THEN
range := ST_AddPoint(range, ST_StartPoint(oldedge.geom));
END IF;
+
range := ST_CollectionExtract(ST_MakeValid(ST_MakePolygon(range)), 3);
+
range := ST_SymDifference(range, tmp2);
+
sql := 'SELECT node_id, geom FROM '
|| quote_ident(atopology)
|| '.node WHERE ST_Contains('
|| quote_literal(range::text)
|| '::geometry, geom) LIMIT 1';
+
FOR rec IN EXECUTE sql LOOP -- {
RAISE EXCEPTION 'Edge motion collision at %', ST_AsText(rec.geom);
END LOOP; -- }
@@ -7652,11 +7772,13 @@ BEGIN
) as pre, NULL::integer[] as post
INTO STRICT snode_info;
+
SELECT topology._ST_AdjacentEdges(
atopology, oldedge.end_node, -anedge
) as pre, NULL::integer[] as post
INTO STRICT enode_info;
+
--}
--
@@ -7674,10 +7796,12 @@ BEGIN
atopology, oldedge.start_node, anedge
);
+
enode_info.post := topology._ST_AdjacentEdges(
atopology, oldedge.end_node, -anedge
);
+
IF snode_info.pre != snode_info.post THEN
RAISE EXCEPTION 'Edge changed disposition around start node %',
oldedge.start_node;
@@ -7754,6 +7878,7 @@ DECLARE
BEGIN
IF oface = 0 AND mbr_only THEN
+
RETURN NULL;
END IF;
@@ -7766,24 +7891,31 @@ BEGIN
INTO STRICT fan.newring_edges;
+
-- You can't get to the other side of an edge forming a ring
IF fan.newring_edges @> ARRAY[-anedge] THEN
+
RETURN 0;
END IF;
+
sql := 'WITH ids as ( select row_number() over () as seq, edge from unnest('
|| quote_literal(fan.newring_edges::text)
|| '::int[] ) u(edge) ), edges AS ( select CASE WHEN i.edge < 0 THEN ST_Reverse(e.geom) ELSE e.geom END as g FROM ids i left join '
|| quote_ident(atopology) || '.edge_data e ON(e.edge_id = abs(i.edge)) ORDER BY seq) SELECT ST_MakePolygon(ST_MakeLine(g.g)) FROM edges g;';
+
EXECUTE sql INTO fan.shell;
+
isccw := NOT ST_OrderingEquals(fan.shell, ST_ForceRHR(fan.shell));
+
IF oface = 0 THEN
IF NOT isccw THEN
+
RETURN NULL;
END IF;
END IF;
@@ -7795,6 +7927,7 @@ BEGIN
|| quote_ident(atopology) || '.face SET mbr = '
|| quote_literal(ST_Envelope(fan.shell)::text)
|| '::geometry WHERE face_id = ' || oface;
+
EXECUTE sql;
END IF; -- }
RETURN NULL;
@@ -7815,6 +7948,7 @@ BEGIN
END IF; -- }
-- Insert new face
+
EXECUTE sql INTO STRICT newface;
-- Update forward edges
@@ -7823,6 +7957,7 @@ BEGIN
|| ' WHERE left_face = ' || oface || ' AND edge_id = ANY ('
|| quote_literal(array( select +(x) from unnest(fan.newring_edges) u(x) )::text)
|| ')';
+
EXECUTE sql;
-- Update backward edges
@@ -7831,12 +7966,15 @@ BEGIN
|| ' WHERE right_face = ' || oface || ' AND edge_id = ANY ('
|| quote_literal(array( select -(x) from unnest(fan.newring_edges) u(x) )::text)
|| ')';
+
EXECUTE sql;
IF oface != 0 AND NOT isccw THEN -- {
-- face shrinked, must update all non-contained edges and nodes
+
ishole := true;
ELSE
+
ishole := false;
END IF; -- }
@@ -7858,6 +7996,7 @@ BEGIN
sql := sql || 'ST_Contains(' || quote_literal(fan.shell::text)
-- We only need to check a single point, but must not be an endpoint
|| '::geometry, ST_Line_Interpolate_Point(geom, 0.2))';
+
EXECUTE sql;
-- Update isolated nodes in new new face
@@ -7867,6 +8006,7 @@ BEGIN
|| ' AND ';
IF ishole THEN sql := sql || 'NOT '; END IF;
sql := sql || 'ST_Contains(' || quote_literal(fan.shell::text) || '::geometry, geom)';
+
EXECUTE sql;
RETURN newface;
@@ -7990,6 +8130,7 @@ BEGIN
|| ')'
LOOP
IF rec.containing_face IS NOT NULL THEN
+
IF newedge.left_face IS NULL THEN
newedge.left_face := rec.containing_face;
newedge.right_face := rec.containing_face;
@@ -8097,6 +8238,7 @@ BEGIN
-- Find links on start node -- {
+
sql :=
'SELECT edge_id, -1 AS end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8142,6 +8284,7 @@ BEGIN
END IF;
+
az = az - span.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8181,6 +8324,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN span.was_isolated = true; END IF;
ELSE
@@ -8197,12 +8341,16 @@ BEGIN
END IF;
+
+
+
-- } start_node analysis
-- Find links on end_node {
+
sql :=
'SELECT edge_id, -1 as end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8244,6 +8392,7 @@ BEGIN
END IF;
+
az := az - epan.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8283,6 +8432,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN epan.was_isolated = true; END IF;
ELSE
@@ -8301,6 +8451,9 @@ BEGIN
-- } end_node analysis
+
+
+
----------------------------------------------------------------------
--
-- If we don't have faces setup by now we must have encountered
@@ -8396,15 +8549,18 @@ BEGIN
--------------------------------------------
+
SELECT topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, false)
INTO newface;
IF newface = 0 THEN
+
RETURN newedge.edge_id;
END IF;
newfaces[1] := newface;
+
SELECT topology._ST_AddFaceSplit(atopology, newedge.edge_id, newedge.left_face, false)
INTO newface;
@@ -8427,6 +8583,7 @@ BEGIN
FOR rec IN EXECUTE sql
LOOP
+
-- Add reference to the other face
sql := 'INSERT INTO ' || quote_ident(atopology)
|| '.relation VALUES( ' || rec.topogeo_id
@@ -8564,6 +8721,7 @@ BEGIN
|| ')'
LOOP
IF rec.containing_face IS NOT NULL THEN
+
IF newedge.left_face IS NULL THEN
newedge.left_face := rec.containing_face;
newedge.right_face := rec.containing_face;
@@ -8669,6 +8827,7 @@ BEGIN
-- Find links on start node -- {
+
sql :=
'SELECT edge_id, -1 AS end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8714,6 +8873,7 @@ BEGIN
END IF;
+
az = az - span.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8753,6 +8913,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN span.was_isolated = true; END IF;
ELSE
@@ -8769,12 +8930,16 @@ BEGIN
END IF;
+
+
+
-- } start_node analysis
-- Find links on end_node {
+
sql :=
'SELECT edge_id, -1 as end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8816,6 +8981,7 @@ BEGIN
END IF;
+
az := az - epan.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8855,6 +9021,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN epan.was_isolated = true; END IF;
ELSE
@@ -8873,6 +9040,9 @@ BEGIN
-- } end_node analysis
+
+
+
----------------------------------------------------------------------
--
-- If we don't have faces setup by now we must have encountered
@@ -8967,20 +9137,25 @@ BEGIN
-- Check face splitting
--------------------------------------------
+
SELECT topology._ST_AddFaceSplit(atopology, newedge.edge_id, newedge.left_face, false)
INTO newface;
IF newface = 0 THEN
+
RETURN newedge.edge_id;
END IF;
IF newface IS NULL THEN -- must be forming a maximal ring in universal face
+
SELECT topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, false)
INTO newface;
ELSE
+
PERFORM topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, true);
END IF;
IF newface IS NULL THEN
+
RETURN newedge.edge_id;
END IF;
@@ -9004,6 +9179,7 @@ BEGIN
FOR rec IN EXECUTE sql
LOOP
+
-- Add reference to the other face
sql := 'INSERT INTO ' || quote_ident(atopology)
|| '.relation VALUES( ' || rec.topogeo_id
@@ -9134,6 +9310,7 @@ BEGIN
END; -- }
+
--
-- Node input linework with itself
--
@@ -9147,6 +9324,7 @@ BEGIN
) as linework INTO STRICT nodededges;
+
--
-- Linemerge the resulting edges, to reduce the working set
-- NOTE: this is more of a workaround for GEOS splitting overlapping
@@ -9156,6 +9334,7 @@ BEGIN
+
--
-- Collect input points and input lines endpoints
--
@@ -9169,6 +9348,7 @@ BEGIN
) as nodes INTO STRICT points;
+
--
-- Further split edges by points
-- TODO: optimize this adding ST_Split support for multiline/multipoint
@@ -9183,6 +9363,7 @@ BEGIN
SELECT ST_UnaryUnion(nodededges) INTO STRICT nodededges;
+
--
-- Collect all nodes (from points and noded linework endpoints)
--
@@ -9201,6 +9382,7 @@ BEGIN
) as endpoints INTO points;
+
--
-- Add all nodes as isolated so that
-- later calls to AddEdgeModFace will tweak their being
@@ -9231,11 +9413,12 @@ LANGUAGE 'plpgsql' VOLATILE;
--=} SQL/MM block
+
-- The following files needs getfaceedges_returntype, defined in sqlmm.sql
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 2012 Sandro Santilli <strk@keybit.net>
--
@@ -9245,7 +9428,7 @@ LANGUAGE 'plpgsql' VOLATILE;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -9312,10 +9495,11 @@ END
$$
LANGUAGE 'plpgsql' STABLE;
--} GetRingEdges
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2012 Sandro Santilli <strk@keybit.net>
--
@@ -9356,9 +9540,11 @@ BEGIN
|| ' UNION ALL SELECT -edge_id, ST_Azimuth(ST_EndPoint(geom), ST_PointN(geom, ST_NumPoints(geom)-1)) FROM incident_edges WHERE end_node = ' || anode
|| ' ORDER BY az';
+
FOR rec IN EXECUTE sql
LOOP -- incident edges {
+
n := n + 1;
retrec.sequence := n;
retrec.edge := rec.edge_id;
@@ -9370,11 +9556,12 @@ $$
LANGUAGE 'plpgsql' STABLE;
--} GetRingEdges
+
--general management --
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://www.postgis.org
+-- http:
--
-- Copyright (C) 2011 Regina Obe <lr@pcorp.us>
--
@@ -9413,6 +9600,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
--} AddToSearchPath
+
CREATE OR REPLACE FUNCTION postgis_topology_scripts_installed() RETURNS text
AS $$ SELECT '2.0.2'::text || ' r' || 10789::text AS version $$
LANGUAGE 'sql' IMMUTABLE;
diff --git a/gcc/postgis_extension/postgis_topology--2.0.0beta3--2.0.2.sql b/gpp/postgis_extension/postgis_topology--2.0.0beta3--2.0.2.sql
index 80c44f9..a257064 100644
--- a/gcc/postgis_extension/postgis_topology--2.0.0beta3--2.0.2.sql
+++ b/gpp/postgis_extension/postgis_topology--2.0.0beta3--2.0.2.sql
@@ -100,14 +100,12 @@ LANGUAGE plpgsql VOLATILE;
-- during upgrade
SELECT postgis_extension_remove_objects('postgis_topology', 'FUNCTION');
SELECT postgis_extension_remove_objects('postgis_topology', 'AGGREGATE');
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: topology.sql.in.c 10643 2012-11-05 10:25:41Z strk $
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -306,6 +304,23 @@ SELECT postgis_extension_remove_objects('postgis_topology', 'AGGREGATE');
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-- Doing everything outside of a transaction helps
-- upgrading in the best case.
@@ -481,7 +496,9 @@ ALTER DOMAIN topology.TopoElement ADD
array_lower(VALUE, 1) = 1
);
ALTER DOMAIN topology.TopoElement DROP CONSTRAINT
+
IF EXISTS
+
type_range;
ALTER DOMAIN topology.TopoElement ADD
CONSTRAINT type_range CHECK (
@@ -777,6 +794,7 @@ BEGIN
-- corrupting the topology anyway ...
--
+
RETURN newlayer_id;
END;
$$
@@ -1120,6 +1138,7 @@ BEGIN
|| ') as obj ORDER BY obj';
+
-- TODO: why not using array_agg here ?
i = 1;
@@ -1517,7 +1536,7 @@ BEGIN
--
-- Closed lines have no boundary, so endpoint
-- intersection would be considered interior
- -- See http://trac.osgeo.org/postgis/ticket/770
+ -- See http:
-- See also full explanation in topology.AddEdge
--
@@ -1681,6 +1700,7 @@ BEGIN
END LOOP;
+
DROP TABLE face_check;
RETURN;
@@ -1910,7 +1930,7 @@ BEGIN
------- Indexes on left_face and right_face of edge_data
------- NOTE: these indexes speed up GetFaceGeometry (and thus
------- TopoGeometry::Geometry) by a factor of 10 !
- ------- See http://trac.osgeo.org/postgis/ticket/806
+ ------- See http:
EXECUTE 'CREATE INDEX edge_left_face_idx ON '
|| quote_ident(atopology)
|| '.edge_data (left_face);';
@@ -1921,7 +1941,7 @@ BEGIN
------- Indexes on start_node and end_node of edge_data
------- NOTE: this indexes speed up node deletion
------- by a factor of 1000 !
- ------- See http://trac.osgeo.org/postgis/ticket/2082
+ ------- See http:
EXECUTE 'CREATE INDEX edge_start_node_idx ON '
|| quote_ident(atopology)
|| '.edge_data (start_node);';
@@ -2029,7 +2049,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -2180,10 +2200,11 @@ $$
LANGUAGE 'plpgsql' STABLE STRICT;
--} TopologySummary
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -2280,11 +2301,12 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
--} TopologySummary
+
-- Spatial predicates
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011-2012 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -2798,11 +2820,12 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--} equals(TopoGeometry, TopoGeometry)
+
-- Querying
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -2888,10 +2911,11 @@ $$
LANGUAGE 'plpgsql' STABLE STRICT;
--} GetNodeByPoint
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -2979,10 +3003,11 @@ END
$$
LANGUAGE 'plpgsql' STABLE STRICT;
--} GetEdgeByPoint
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -3138,11 +3163,12 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--} GetFaceByPoint
+
-- Populating
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010-2012 Sandro Santilli <strk@keybit.net>
--
@@ -3163,7 +3189,7 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--
--
-- A pragmatic test conducted using algoritm shown here:
--- http://stackoverflow.com/questions/7408407/generate-next-largest-or-smallest-representable-floating-point-number-without-bi
+-- http:
-- showed the "tolerance" growing by an order of magnitude proportionally
-- with the order of magnitude of the input, starting with something like
-- 3.5527136788005009294e-15 for the starting value of 9.0
@@ -3219,7 +3245,7 @@ $$ LANGUAGE 'plpgsql' STABLE STRICT;
-- The newly added nodes have no containing face.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3287,6 +3313,7 @@ BEGIN
IF setContainingFace THEN
containing_face := topology.GetFaceByPoint(atopology, apoint, 0);
+
ELSE
containing_face := NULL;
END IF;
@@ -3346,7 +3373,7 @@ LANGUAGE 'sql' VOLATILE;
-- Calling code is expected to do further linking.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3435,6 +3462,7 @@ BEGIN
-- Reuse an EQUAL edge (be it closed or not)
IF ST_RelateMatch(rec.im, '1FFF*FFF2') THEN
+
RETURN rec.edge_id;
END IF;
@@ -3539,7 +3567,7 @@ LANGUAGE 'plpgsql' VOLATILE;
-- o The polygon overlaps an existing face.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3661,6 +3689,7 @@ BEGIN
ST_Line_Locate_Point(bounds, p2);
+
IF right_side THEN
right_edges := array_append(right_edges, rec.edge_id);
old_faceid = rec.right_face;
@@ -3687,6 +3716,8 @@ BEGIN
END IF;
+
+
--
-- Check that all edges found, taken togheter,
-- fully match the ring boundary and nothing more
@@ -3706,8 +3737,10 @@ BEGIN
IF faceid IS NOT NULL AND faceid != 0 THEN
IF NOT force_new THEN
+
RETURN faceid;
ELSE
+
END IF;
END IF;
@@ -3834,12 +3867,14 @@ BEGIN
|| tol || ') ORDER BY ST_Distance('
|| quote_literal(apoint::text)
|| '::geometry, a.geom) LIMIT 1;';
+
EXECUTE sql INTO id;
IF id IS NOT NULL THEN
RETURN id;
END IF;
+
-- 2. Check if any existing edge falls within tolerance
-- and if so split it by a point projected on it
sql := 'SELECT a.edge_id, a.geom FROM '
@@ -3849,35 +3884,42 @@ BEGIN
|| tol || ') ORDER BY ST_Distance('
|| quote_literal(apoint::text)
|| '::geometry, a.geom) LIMIT 1;';
+
EXECUTE sql INTO rec;
IF rec IS NOT NULL THEN
-- project point to line, split edge by point
prj := ST_ClosestPoint(rec.geom, apoint);
-- This is a workaround for ClosestPoint lack of Z support:
- -- http://trac.osgeo.org/postgis/ticket/2033
+ -- http:
z := ST_Z(apoint);
IF z IS NOT NULL THEN
prj := ST_Translate(ST_Force_3DZ(prj), 0, 0, z); -- no ST_SetZ ...
END IF;
+
IF NOT ST_Contains(rec.geom, prj) THEN
+
-- The tolerance must be big enough for snapping to happen
-- and small enough to snap only to the projected point.
-- Unfortunately ST_Distance returns 0 because it also uses
-- a projected point internally, so we need another way.
snaptol := topology._st_mintolerance(prj);
+
snapedge := ST_Snap(rec.geom, prj, snaptol);
-- Snapping currently snaps the first point below tolerance
-- so may possibly move first point. See ticket #1631
IF NOT ST_Equals(ST_StartPoint(rec.geom), ST_StartPoint(snapedge))
THEN
+
snapedge := ST_MakeLine(ST_StartPoint(rec.geom), snapedge);
END IF;
+
PERFORM ST_ChangeEdgeGeom(atopology, rec.edge_id, snapedge);
END IF;
id := topology.ST_ModEdgeSplit(atopology, rec.edge_id, prj);
ELSE
+
id := topology.ST_AddIsoNode(atopology, NULL, apoint);
END IF;
@@ -3923,6 +3965,7 @@ BEGIN
-- 1. Self-node
noded := ST_UnaryUnion(aline);
+
-- 2. Node to edges falling within tol distance
sql := 'WITH nearby AS ( SELECT e.geom FROM '
|| quote_ident(atopology)
@@ -3930,20 +3973,27 @@ BEGIN
|| quote_literal(noded::text)
|| '::geometry, '
|| tol || ') ) SELECT st_collect(geom) FROM nearby;';
+
EXECUTE sql INTO iedges;
IF iedges IS NOT NULL THEN
+
snapped := ST_Snap(noded, iedges, tol);
+
noded := ST_Difference(snapped, iedges);
+
set1 := ST_Intersection(snapped, iedges);
+
set2 := ST_LineMerge(set1);
+
noded := ST_Union(noded, set2);
+
END IF;
-- 2.1. Node with existing nodes within tol
@@ -3954,26 +4004,32 @@ BEGIN
|| quote_literal(noded::text)
|| '::geometry, '
|| tol || ') ) SELECT st_collect(geom) FROM nearby;';
+
EXECUTE sql INTO inodes;
IF inodes IS NOT NULL THEN -- {
+
-- TODO: consider snapping once against all elements
--- (rather than once with edges and once with nodes)
noded := ST_Snap(noded, inodes, tol);
+
FOR rec IN SELECT (ST_Dump(inodes)).*
LOOP
-- Use the node to split edges
SELECT ST_Collect(geom)
FROM ST_Dump(ST_Split(noded, rec.geom))
INTO STRICT noded;
+
END LOOP;
+
-- re-node to account for ST_Snap introduced self-intersections
- -- See http://trac.osgeo.org/postgis/ticket/1714
+ -- See http:
-- TODO: consider running UnaryUnion once after all noding
noded := ST_UnaryUnion(noded);
+
END IF; -- }
-- 3. For each (now-noded) segment, insert an edge
@@ -3982,14 +4038,17 @@ BEGIN
-- TODO: skip point elements ?
+
start_node := topology.TopoGeo_AddPoint(atopology,
ST_StartPoint(rec.geom),
tol);
+
end_node := topology.TopoGeo_AddPoint(atopology,
ST_EndPoint(rec.geom),
tol);
+
-- Added endpoints may have drifted due to tolerance, so
-- we need to re-snap the edge to the new nodes before adding it
sql := 'SELECT n1.geom as sn, n2.geom as en FROM ' || quote_ident(atopology)
@@ -3997,6 +4056,7 @@ BEGIN
|| '.node n2 WHERE n1.node_id = '
|| start_node || ' AND n2.node_id = ' || end_node;
+
EXECUTE sql INTO STRICT rec2;
snapped := ST_SetPoint(
@@ -4007,8 +4067,10 @@ BEGIN
snapped := ST_CollectionExtract(ST_MakeValid(snapped), 2);
+
-- Check if the so-snapped edge collapsed (see #1650)
IF ST_IsEmpty(snapped) THEN
+
CONTINUE;
END IF;
@@ -4016,11 +4078,14 @@ BEGIN
sql := 'SELECT edge_id FROM ' || quote_ident(atopology)
|| '.edge_data WHERE ST_Equals(geom, ' || quote_literal(snapped::text)
|| '::geometry)';
+
EXECUTE sql INTO id;
IF id IS NULL THEN
id := topology.ST_AddEdgeModFace(atopology, start_node, end_node,
snapped);
+
ELSE
+
END IF;
RETURN NEXT id;
@@ -4062,9 +4127,11 @@ BEGIN
-- 1. Extract boundary
boundary := ST_Boundary(apoly);
+
-- 2. Add boundaries as edges
FOR rec IN SELECT (ST_Dump(boundary)).geom LOOP
edges := array_cat(edges, array_agg(x)) FROM ( select topology.TopoGeo_addLinestring(atopology, rec.geom, tol) as x ) as foo;
+
END LOOP;
-- 3. Find faces covered by input polygon
@@ -4073,10 +4140,12 @@ BEGIN
|| '.face f WHERE f.mbr && '
|| quote_literal(apoly::text)
|| '::geometry';
+
FOR rec IN EXECUTE sql LOOP
-- check for actual containment
fgeom := ST_PointOnSurface(ST_GetFaceGeometry(atopology, rec.face_id));
IF NOT ST_Covers(apoly, fgeom) THEN
+
CONTINUE;
END IF;
RETURN NEXT rec.face_id;
@@ -4102,10 +4171,11 @@ END
$$
LANGUAGE 'plpgsql';
--} TopoGeo_AddGeometry
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4154,11 +4224,12 @@ $$
LANGUAGE 'plpgsql';
--} Polygonize(toponame)
+
-- TopoElement
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4172,7 +4243,7 @@ LANGUAGE 'plpgsql';
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -4214,11 +4285,12 @@ CREATE AGGREGATE topology.TopoElementArray_agg(
);
--} TopoElementArray_agg
+
-- TopoGeometry
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4274,10 +4346,11 @@ $$
$$
LANGUAGE 'sql' STABLE STRICT;
-- }
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011-2012 Sandro Santilli <strk@keybit.net>
--
@@ -4289,7 +4362,7 @@ LANGUAGE 'sql' STABLE STRICT;
-- {
-- Convert a simple geometry to a topologically-defined one
--
--- See http://trac.osgeo.org/postgis/ticket/1017
+-- See http:
--
-- }{
CREATE OR REPLACE FUNCTION topology.toTopoGeom(ageom Geometry, atopology varchar, alayer int, atolerance float8 DEFAULT 0)
@@ -4414,6 +4487,7 @@ BEGIN
|| '.relation(topogeo_id, layer_id, element_type, element_id) VALUES ('
|| rec.id || ',' || rec.lyr || ',' || rec.type
|| ',' || rec.primitive || ')';
+
EXECUTE sql;
END LOOP;
@@ -4424,11 +4498,12 @@ $$
LANGUAGE 'plpgsql' VOLATILE STRICT;
-- }
+
-- GML
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4442,7 +4517,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -4989,13 +5064,14 @@ $$ LANGUAGE 'sql' STABLE; -- does NOT write into visited table
-- } AsGML(TopoGeometry)
+
--=} POSTGIS-SPECIFIC block
-- SQL/MM block
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011, 2012 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -5101,6 +5177,7 @@ BEGIN
LOOP
+
retrec.sequence = n;
retrec.edge = rec.edge_id;
@@ -5399,6 +5476,7 @@ BEGIN
|| ' AND l.layer_id = r.layer_id AND abs(r.element_id) = '
|| e1id
;
+
EXECUTE sql;
@@ -5747,6 +5825,7 @@ BEGIN
|| 'WHERE l.level = 0 AND l.feature_type = 2 '
|| ' AND l.topology_id = ' || topoid
|| ' AND abs(r.element_id) = ' || e1id ;
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented dropping edge %',
rec.topogeo_id, rec.layer_id,
@@ -5771,6 +5850,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge < 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -5788,6 +5868,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge > 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -5803,6 +5884,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge < 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -5820,6 +5902,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge > 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -5865,6 +5948,7 @@ BEGIN
END IF; -- }
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented healing faces % and %',
rec.topogeo_id, rec.layer_id,
@@ -5907,6 +5991,7 @@ BEGIN
|| '.face WHERE face_id IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
END IF; -- }
@@ -5917,6 +6002,7 @@ BEGIN
|| ' WHERE left_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update right_face for all edges still referencing old faces
@@ -5925,6 +6011,7 @@ BEGIN
|| ' WHERE right_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update containing_face for all nodes still referencing old faces
@@ -5933,6 +6020,7 @@ BEGIN
|| ' WHERE containing_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- NOT IN THE SPECS:
@@ -5945,6 +6033,7 @@ BEGIN
|| ' AND l.topology_id = ' || topoid
|| ' AND l.layer_id = r.layer_id AND abs(r.element_id) = '
|| e1rec.left_face;
+
EXECUTE sql;
sql := 'UPDATE ' || quote_ident(toponame)
|| '.relation r '
@@ -5953,6 +6042,7 @@ BEGIN
|| ' AND l.topology_id = ' || topoid
|| ' AND l.layer_id = r.layer_id AND r.element_id = '
|| e1rec.right_face;
+
EXECUTE sql;
END IF; -- } two faces healed...
@@ -5960,6 +6050,7 @@ BEGIN
-- Delete the edge
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.edge_data WHERE edge_id = ' || e1id;
+
EXECUTE sql;
-- Check if any of the edge nodes remains isolated,
@@ -5971,6 +6062,7 @@ BEGIN
|| e1rec.end_node || ') AND NOT EXISTS (SELECT edge_id FROM '
|| quote_ident(toponame)
|| '.edge_data WHERE start_node = n.node_id OR end_node = n.node_id)';
+
EXECUTE sql;
IF e1rec.right_face != e1rec.left_face THEN -- {
@@ -5979,6 +6071,7 @@ BEGIN
IF e1rec.left_face != 0 THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.left_face;
+
EXECUTE sql;
END IF;
@@ -5987,6 +6080,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.right_face;
+
EXECUTE sql;
END IF;
@@ -6071,6 +6165,7 @@ BEGIN
|| 'WHERE l.level = 0 AND l.feature_type = 2 '
|| ' AND l.topology_id = ' || topoid
|| ' AND abs(r.element_id) = ' || e1id ;
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented dropping edge %',
rec.topogeo_id, rec.layer_id,
@@ -6095,6 +6190,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge < 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -6112,6 +6208,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge > 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -6127,6 +6224,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge < 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -6144,6 +6242,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge > 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -6187,6 +6286,7 @@ BEGIN
END IF; -- }
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented healing faces % and %',
rec.topogeo_id, rec.layer_id,
@@ -6219,6 +6319,7 @@ BEGIN
|| '.face WHERE face_id IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ') ) WHERE face_id = ' || floodfaceid ;
+
EXECUTE sql;
END IF; -- }
@@ -6229,6 +6330,7 @@ BEGIN
|| ' WHERE left_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update right_face for all edges still referencing old faces
@@ -6237,6 +6339,7 @@ BEGIN
|| ' WHERE right_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update containing_face for all nodes still referencing old faces
@@ -6245,6 +6348,7 @@ BEGIN
|| ' WHERE containing_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- NOT IN THE SPECS:
@@ -6259,6 +6363,7 @@ BEGIN
|| e1rec.left_face || ',' || e1rec.right_face
|| ') AND abs(r.element_id) != '
|| floodfaceid; -- could be optimized..
+
EXECUTE sql;
END IF; -- } two faces healed...
@@ -6266,6 +6371,7 @@ BEGIN
-- Delete the edge
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.edge_data WHERE edge_id = ' || e1id;
+
EXECUTE sql;
-- Check if any of the edge nodes remains isolated,
@@ -6277,6 +6383,7 @@ BEGIN
|| e1rec.end_node || ') AND NOT EXISTS (SELECT edge_id FROM '
|| quote_ident(toponame)
|| '.edge_data WHERE start_node = n.node_id OR end_node = n.node_id)';
+
EXECUTE sql;
IF e1rec.right_face != e1rec.left_face THEN -- {
@@ -6286,6 +6393,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.left_face;
+
EXECUTE sql;
END IF;
@@ -6294,6 +6402,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.right_face;
+
EXECUTE sql;
END IF;
@@ -6451,6 +6560,7 @@ BEGIN
sql := sql || ' AND f.face_id = ' || aface;
END IF;
+
EXECUTE sql INTO containingface;
-- If aface was specified, check that it was correct
@@ -6484,6 +6594,7 @@ BEGIN
|| '::geometry,' || containingface
|| ' RETURNING node_id';
+
EXECUTE sql INTO nodeid;
RETURN nodeid;
@@ -6624,7 +6735,7 @@ LANGUAGE 'plpgsql' VOLATILE;
--} ST_RemoveIsoNode
--{
--- According to http://trac.osgeo.org/postgis/ticket/798
+-- According to http:
-- ST_RemoveIsoNode was renamed to ST_RemIsoNode in the final ISO
-- document
--
@@ -6826,6 +6937,7 @@ BEGIN
END LOOP;
+
--RAISE NOTICE 'EdgeId1 % EdgeId2 %', edgeid1, edgeid2;
--RAISE DEBUG 'oldedge.next_left_edge: %', oldedge.next_left_edge;
@@ -7111,6 +7223,7 @@ BEGIN
END LOOP;
+
--
-- Insert the new edge
--
@@ -7618,25 +7731,32 @@ BEGIN
tmp1 := ST_MakeLine(ST_EndPoint(oldedge.geom), ST_StartPoint(oldedge.geom));
+
tmp2 := ST_MakeLine(oldedge.geom, tmp1);
IF ST_NumPoints(tmp2) < 4 THEN
tmp2 := ST_AddPoint(tmp2, ST_StartPoint(oldedge.geom));
END IF;
+
tmp2 := ST_CollectionExtract(ST_MakeValid(ST_MakePolygon(tmp2)), 3);
+
range := ST_MakeLine(acurve, tmp1);
IF ST_NumPoints(range) < 4 THEN
range := ST_AddPoint(range, ST_StartPoint(oldedge.geom));
END IF;
+
range := ST_CollectionExtract(ST_MakeValid(ST_MakePolygon(range)), 3);
+
range := ST_SymDifference(range, tmp2);
+
sql := 'SELECT node_id, geom FROM '
|| quote_ident(atopology)
|| '.node WHERE ST_Contains('
|| quote_literal(range::text)
|| '::geometry, geom) LIMIT 1';
+
FOR rec IN EXECUTE sql LOOP -- {
RAISE EXCEPTION 'Edge motion collision at %', ST_AsText(rec.geom);
END LOOP; -- }
@@ -7652,11 +7772,13 @@ BEGIN
) as pre, NULL::integer[] as post
INTO STRICT snode_info;
+
SELECT topology._ST_AdjacentEdges(
atopology, oldedge.end_node, -anedge
) as pre, NULL::integer[] as post
INTO STRICT enode_info;
+
--}
--
@@ -7674,10 +7796,12 @@ BEGIN
atopology, oldedge.start_node, anedge
);
+
enode_info.post := topology._ST_AdjacentEdges(
atopology, oldedge.end_node, -anedge
);
+
IF snode_info.pre != snode_info.post THEN
RAISE EXCEPTION 'Edge changed disposition around start node %',
oldedge.start_node;
@@ -7754,6 +7878,7 @@ DECLARE
BEGIN
IF oface = 0 AND mbr_only THEN
+
RETURN NULL;
END IF;
@@ -7766,24 +7891,31 @@ BEGIN
INTO STRICT fan.newring_edges;
+
-- You can't get to the other side of an edge forming a ring
IF fan.newring_edges @> ARRAY[-anedge] THEN
+
RETURN 0;
END IF;
+
sql := 'WITH ids as ( select row_number() over () as seq, edge from unnest('
|| quote_literal(fan.newring_edges::text)
|| '::int[] ) u(edge) ), edges AS ( select CASE WHEN i.edge < 0 THEN ST_Reverse(e.geom) ELSE e.geom END as g FROM ids i left join '
|| quote_ident(atopology) || '.edge_data e ON(e.edge_id = abs(i.edge)) ORDER BY seq) SELECT ST_MakePolygon(ST_MakeLine(g.g)) FROM edges g;';
+
EXECUTE sql INTO fan.shell;
+
isccw := NOT ST_OrderingEquals(fan.shell, ST_ForceRHR(fan.shell));
+
IF oface = 0 THEN
IF NOT isccw THEN
+
RETURN NULL;
END IF;
END IF;
@@ -7795,6 +7927,7 @@ BEGIN
|| quote_ident(atopology) || '.face SET mbr = '
|| quote_literal(ST_Envelope(fan.shell)::text)
|| '::geometry WHERE face_id = ' || oface;
+
EXECUTE sql;
END IF; -- }
RETURN NULL;
@@ -7815,6 +7948,7 @@ BEGIN
END IF; -- }
-- Insert new face
+
EXECUTE sql INTO STRICT newface;
-- Update forward edges
@@ -7823,6 +7957,7 @@ BEGIN
|| ' WHERE left_face = ' || oface || ' AND edge_id = ANY ('
|| quote_literal(array( select +(x) from unnest(fan.newring_edges) u(x) )::text)
|| ')';
+
EXECUTE sql;
-- Update backward edges
@@ -7831,12 +7966,15 @@ BEGIN
|| ' WHERE right_face = ' || oface || ' AND edge_id = ANY ('
|| quote_literal(array( select -(x) from unnest(fan.newring_edges) u(x) )::text)
|| ')';
+
EXECUTE sql;
IF oface != 0 AND NOT isccw THEN -- {
-- face shrinked, must update all non-contained edges and nodes
+
ishole := true;
ELSE
+
ishole := false;
END IF; -- }
@@ -7858,6 +7996,7 @@ BEGIN
sql := sql || 'ST_Contains(' || quote_literal(fan.shell::text)
-- We only need to check a single point, but must not be an endpoint
|| '::geometry, ST_Line_Interpolate_Point(geom, 0.2))';
+
EXECUTE sql;
-- Update isolated nodes in new new face
@@ -7867,6 +8006,7 @@ BEGIN
|| ' AND ';
IF ishole THEN sql := sql || 'NOT '; END IF;
sql := sql || 'ST_Contains(' || quote_literal(fan.shell::text) || '::geometry, geom)';
+
EXECUTE sql;
RETURN newface;
@@ -7990,6 +8130,7 @@ BEGIN
|| ')'
LOOP
IF rec.containing_face IS NOT NULL THEN
+
IF newedge.left_face IS NULL THEN
newedge.left_face := rec.containing_face;
newedge.right_face := rec.containing_face;
@@ -8097,6 +8238,7 @@ BEGIN
-- Find links on start node -- {
+
sql :=
'SELECT edge_id, -1 AS end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8142,6 +8284,7 @@ BEGIN
END IF;
+
az = az - span.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8181,6 +8324,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN span.was_isolated = true; END IF;
ELSE
@@ -8197,12 +8341,16 @@ BEGIN
END IF;
+
+
+
-- } start_node analysis
-- Find links on end_node {
+
sql :=
'SELECT edge_id, -1 as end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8244,6 +8392,7 @@ BEGIN
END IF;
+
az := az - epan.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8283,6 +8432,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN epan.was_isolated = true; END IF;
ELSE
@@ -8301,6 +8451,9 @@ BEGIN
-- } end_node analysis
+
+
+
----------------------------------------------------------------------
--
-- If we don't have faces setup by now we must have encountered
@@ -8396,15 +8549,18 @@ BEGIN
--------------------------------------------
+
SELECT topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, false)
INTO newface;
IF newface = 0 THEN
+
RETURN newedge.edge_id;
END IF;
newfaces[1] := newface;
+
SELECT topology._ST_AddFaceSplit(atopology, newedge.edge_id, newedge.left_face, false)
INTO newface;
@@ -8427,6 +8583,7 @@ BEGIN
FOR rec IN EXECUTE sql
LOOP
+
-- Add reference to the other face
sql := 'INSERT INTO ' || quote_ident(atopology)
|| '.relation VALUES( ' || rec.topogeo_id
@@ -8564,6 +8721,7 @@ BEGIN
|| ')'
LOOP
IF rec.containing_face IS NOT NULL THEN
+
IF newedge.left_face IS NULL THEN
newedge.left_face := rec.containing_face;
newedge.right_face := rec.containing_face;
@@ -8669,6 +8827,7 @@ BEGIN
-- Find links on start node -- {
+
sql :=
'SELECT edge_id, -1 AS end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8714,6 +8873,7 @@ BEGIN
END IF;
+
az = az - span.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8753,6 +8913,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN span.was_isolated = true; END IF;
ELSE
@@ -8769,12 +8930,16 @@ BEGIN
END IF;
+
+
+
-- } start_node analysis
-- Find links on end_node {
+
sql :=
'SELECT edge_id, -1 as end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8816,6 +8981,7 @@ BEGIN
END IF;
+
az := az - epan.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8855,6 +9021,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN epan.was_isolated = true; END IF;
ELSE
@@ -8873,6 +9040,9 @@ BEGIN
-- } end_node analysis
+
+
+
----------------------------------------------------------------------
--
-- If we don't have faces setup by now we must have encountered
@@ -8967,20 +9137,25 @@ BEGIN
-- Check face splitting
--------------------------------------------
+
SELECT topology._ST_AddFaceSplit(atopology, newedge.edge_id, newedge.left_face, false)
INTO newface;
IF newface = 0 THEN
+
RETURN newedge.edge_id;
END IF;
IF newface IS NULL THEN -- must be forming a maximal ring in universal face
+
SELECT topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, false)
INTO newface;
ELSE
+
PERFORM topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, true);
END IF;
IF newface IS NULL THEN
+
RETURN newedge.edge_id;
END IF;
@@ -9004,6 +9179,7 @@ BEGIN
FOR rec IN EXECUTE sql
LOOP
+
-- Add reference to the other face
sql := 'INSERT INTO ' || quote_ident(atopology)
|| '.relation VALUES( ' || rec.topogeo_id
@@ -9134,6 +9310,7 @@ BEGIN
END; -- }
+
--
-- Node input linework with itself
--
@@ -9147,6 +9324,7 @@ BEGIN
) as linework INTO STRICT nodededges;
+
--
-- Linemerge the resulting edges, to reduce the working set
-- NOTE: this is more of a workaround for GEOS splitting overlapping
@@ -9156,6 +9334,7 @@ BEGIN
+
--
-- Collect input points and input lines endpoints
--
@@ -9169,6 +9348,7 @@ BEGIN
) as nodes INTO STRICT points;
+
--
-- Further split edges by points
-- TODO: optimize this adding ST_Split support for multiline/multipoint
@@ -9183,6 +9363,7 @@ BEGIN
SELECT ST_UnaryUnion(nodededges) INTO STRICT nodededges;
+
--
-- Collect all nodes (from points and noded linework endpoints)
--
@@ -9201,6 +9382,7 @@ BEGIN
) as endpoints INTO points;
+
--
-- Add all nodes as isolated so that
-- later calls to AddEdgeModFace will tweak their being
@@ -9231,11 +9413,12 @@ LANGUAGE 'plpgsql' VOLATILE;
--=} SQL/MM block
+
-- The following files needs getfaceedges_returntype, defined in sqlmm.sql
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 2012 Sandro Santilli <strk@keybit.net>
--
@@ -9245,7 +9428,7 @@ LANGUAGE 'plpgsql' VOLATILE;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -9312,10 +9495,11 @@ END
$$
LANGUAGE 'plpgsql' STABLE;
--} GetRingEdges
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2012 Sandro Santilli <strk@keybit.net>
--
@@ -9356,9 +9540,11 @@ BEGIN
|| ' UNION ALL SELECT -edge_id, ST_Azimuth(ST_EndPoint(geom), ST_PointN(geom, ST_NumPoints(geom)-1)) FROM incident_edges WHERE end_node = ' || anode
|| ' ORDER BY az';
+
FOR rec IN EXECUTE sql
LOOP -- incident edges {
+
n := n + 1;
retrec.sequence := n;
retrec.edge := rec.edge_id;
@@ -9370,11 +9556,12 @@ $$
LANGUAGE 'plpgsql' STABLE;
--} GetRingEdges
+
--general management --
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://www.postgis.org
+-- http:
--
-- Copyright (C) 2011 Regina Obe <lr@pcorp.us>
--
@@ -9413,6 +9600,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
--} AddToSearchPath
+
CREATE OR REPLACE FUNCTION postgis_topology_scripts_installed() RETURNS text
AS $$ SELECT '2.0.2'::text || ' r' || 10789::text AS version $$
LANGUAGE 'sql' IMMUTABLE;
diff --git a/gcc/postgis_extension/postgis_topology--2.0.0beta4--2.0.2.sql b/gpp/postgis_extension/postgis_topology--2.0.0beta4--2.0.2.sql
index 80c44f9..a257064 100644
--- a/gcc/postgis_extension/postgis_topology--2.0.0beta4--2.0.2.sql
+++ b/gpp/postgis_extension/postgis_topology--2.0.0beta4--2.0.2.sql
@@ -100,14 +100,12 @@ LANGUAGE plpgsql VOLATILE;
-- during upgrade
SELECT postgis_extension_remove_objects('postgis_topology', 'FUNCTION');
SELECT postgis_extension_remove_objects('postgis_topology', 'AGGREGATE');
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: topology.sql.in.c 10643 2012-11-05 10:25:41Z strk $
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -306,6 +304,23 @@ SELECT postgis_extension_remove_objects('postgis_topology', 'AGGREGATE');
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-- Doing everything outside of a transaction helps
-- upgrading in the best case.
@@ -481,7 +496,9 @@ ALTER DOMAIN topology.TopoElement ADD
array_lower(VALUE, 1) = 1
);
ALTER DOMAIN topology.TopoElement DROP CONSTRAINT
+
IF EXISTS
+
type_range;
ALTER DOMAIN topology.TopoElement ADD
CONSTRAINT type_range CHECK (
@@ -777,6 +794,7 @@ BEGIN
-- corrupting the topology anyway ...
--
+
RETURN newlayer_id;
END;
$$
@@ -1120,6 +1138,7 @@ BEGIN
|| ') as obj ORDER BY obj';
+
-- TODO: why not using array_agg here ?
i = 1;
@@ -1517,7 +1536,7 @@ BEGIN
--
-- Closed lines have no boundary, so endpoint
-- intersection would be considered interior
- -- See http://trac.osgeo.org/postgis/ticket/770
+ -- See http:
-- See also full explanation in topology.AddEdge
--
@@ -1681,6 +1700,7 @@ BEGIN
END LOOP;
+
DROP TABLE face_check;
RETURN;
@@ -1910,7 +1930,7 @@ BEGIN
------- Indexes on left_face and right_face of edge_data
------- NOTE: these indexes speed up GetFaceGeometry (and thus
------- TopoGeometry::Geometry) by a factor of 10 !
- ------- See http://trac.osgeo.org/postgis/ticket/806
+ ------- See http:
EXECUTE 'CREATE INDEX edge_left_face_idx ON '
|| quote_ident(atopology)
|| '.edge_data (left_face);';
@@ -1921,7 +1941,7 @@ BEGIN
------- Indexes on start_node and end_node of edge_data
------- NOTE: this indexes speed up node deletion
------- by a factor of 1000 !
- ------- See http://trac.osgeo.org/postgis/ticket/2082
+ ------- See http:
EXECUTE 'CREATE INDEX edge_start_node_idx ON '
|| quote_ident(atopology)
|| '.edge_data (start_node);';
@@ -2029,7 +2049,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -2180,10 +2200,11 @@ $$
LANGUAGE 'plpgsql' STABLE STRICT;
--} TopologySummary
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -2280,11 +2301,12 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
--} TopologySummary
+
-- Spatial predicates
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011-2012 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -2798,11 +2820,12 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--} equals(TopoGeometry, TopoGeometry)
+
-- Querying
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -2888,10 +2911,11 @@ $$
LANGUAGE 'plpgsql' STABLE STRICT;
--} GetNodeByPoint
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -2979,10 +3003,11 @@ END
$$
LANGUAGE 'plpgsql' STABLE STRICT;
--} GetEdgeByPoint
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -3138,11 +3163,12 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--} GetFaceByPoint
+
-- Populating
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010-2012 Sandro Santilli <strk@keybit.net>
--
@@ -3163,7 +3189,7 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--
--
-- A pragmatic test conducted using algoritm shown here:
--- http://stackoverflow.com/questions/7408407/generate-next-largest-or-smallest-representable-floating-point-number-without-bi
+-- http:
-- showed the "tolerance" growing by an order of magnitude proportionally
-- with the order of magnitude of the input, starting with something like
-- 3.5527136788005009294e-15 for the starting value of 9.0
@@ -3219,7 +3245,7 @@ $$ LANGUAGE 'plpgsql' STABLE STRICT;
-- The newly added nodes have no containing face.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3287,6 +3313,7 @@ BEGIN
IF setContainingFace THEN
containing_face := topology.GetFaceByPoint(atopology, apoint, 0);
+
ELSE
containing_face := NULL;
END IF;
@@ -3346,7 +3373,7 @@ LANGUAGE 'sql' VOLATILE;
-- Calling code is expected to do further linking.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3435,6 +3462,7 @@ BEGIN
-- Reuse an EQUAL edge (be it closed or not)
IF ST_RelateMatch(rec.im, '1FFF*FFF2') THEN
+
RETURN rec.edge_id;
END IF;
@@ -3539,7 +3567,7 @@ LANGUAGE 'plpgsql' VOLATILE;
-- o The polygon overlaps an existing face.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3661,6 +3689,7 @@ BEGIN
ST_Line_Locate_Point(bounds, p2);
+
IF right_side THEN
right_edges := array_append(right_edges, rec.edge_id);
old_faceid = rec.right_face;
@@ -3687,6 +3716,8 @@ BEGIN
END IF;
+
+
--
-- Check that all edges found, taken togheter,
-- fully match the ring boundary and nothing more
@@ -3706,8 +3737,10 @@ BEGIN
IF faceid IS NOT NULL AND faceid != 0 THEN
IF NOT force_new THEN
+
RETURN faceid;
ELSE
+
END IF;
END IF;
@@ -3834,12 +3867,14 @@ BEGIN
|| tol || ') ORDER BY ST_Distance('
|| quote_literal(apoint::text)
|| '::geometry, a.geom) LIMIT 1;';
+
EXECUTE sql INTO id;
IF id IS NOT NULL THEN
RETURN id;
END IF;
+
-- 2. Check if any existing edge falls within tolerance
-- and if so split it by a point projected on it
sql := 'SELECT a.edge_id, a.geom FROM '
@@ -3849,35 +3884,42 @@ BEGIN
|| tol || ') ORDER BY ST_Distance('
|| quote_literal(apoint::text)
|| '::geometry, a.geom) LIMIT 1;';
+
EXECUTE sql INTO rec;
IF rec IS NOT NULL THEN
-- project point to line, split edge by point
prj := ST_ClosestPoint(rec.geom, apoint);
-- This is a workaround for ClosestPoint lack of Z support:
- -- http://trac.osgeo.org/postgis/ticket/2033
+ -- http:
z := ST_Z(apoint);
IF z IS NOT NULL THEN
prj := ST_Translate(ST_Force_3DZ(prj), 0, 0, z); -- no ST_SetZ ...
END IF;
+
IF NOT ST_Contains(rec.geom, prj) THEN
+
-- The tolerance must be big enough for snapping to happen
-- and small enough to snap only to the projected point.
-- Unfortunately ST_Distance returns 0 because it also uses
-- a projected point internally, so we need another way.
snaptol := topology._st_mintolerance(prj);
+
snapedge := ST_Snap(rec.geom, prj, snaptol);
-- Snapping currently snaps the first point below tolerance
-- so may possibly move first point. See ticket #1631
IF NOT ST_Equals(ST_StartPoint(rec.geom), ST_StartPoint(snapedge))
THEN
+
snapedge := ST_MakeLine(ST_StartPoint(rec.geom), snapedge);
END IF;
+
PERFORM ST_ChangeEdgeGeom(atopology, rec.edge_id, snapedge);
END IF;
id := topology.ST_ModEdgeSplit(atopology, rec.edge_id, prj);
ELSE
+
id := topology.ST_AddIsoNode(atopology, NULL, apoint);
END IF;
@@ -3923,6 +3965,7 @@ BEGIN
-- 1. Self-node
noded := ST_UnaryUnion(aline);
+
-- 2. Node to edges falling within tol distance
sql := 'WITH nearby AS ( SELECT e.geom FROM '
|| quote_ident(atopology)
@@ -3930,20 +3973,27 @@ BEGIN
|| quote_literal(noded::text)
|| '::geometry, '
|| tol || ') ) SELECT st_collect(geom) FROM nearby;';
+
EXECUTE sql INTO iedges;
IF iedges IS NOT NULL THEN
+
snapped := ST_Snap(noded, iedges, tol);
+
noded := ST_Difference(snapped, iedges);
+
set1 := ST_Intersection(snapped, iedges);
+
set2 := ST_LineMerge(set1);
+
noded := ST_Union(noded, set2);
+
END IF;
-- 2.1. Node with existing nodes within tol
@@ -3954,26 +4004,32 @@ BEGIN
|| quote_literal(noded::text)
|| '::geometry, '
|| tol || ') ) SELECT st_collect(geom) FROM nearby;';
+
EXECUTE sql INTO inodes;
IF inodes IS NOT NULL THEN -- {
+
-- TODO: consider snapping once against all elements
--- (rather than once with edges and once with nodes)
noded := ST_Snap(noded, inodes, tol);
+
FOR rec IN SELECT (ST_Dump(inodes)).*
LOOP
-- Use the node to split edges
SELECT ST_Collect(geom)
FROM ST_Dump(ST_Split(noded, rec.geom))
INTO STRICT noded;
+
END LOOP;
+
-- re-node to account for ST_Snap introduced self-intersections
- -- See http://trac.osgeo.org/postgis/ticket/1714
+ -- See http:
-- TODO: consider running UnaryUnion once after all noding
noded := ST_UnaryUnion(noded);
+
END IF; -- }
-- 3. For each (now-noded) segment, insert an edge
@@ -3982,14 +4038,17 @@ BEGIN
-- TODO: skip point elements ?
+
start_node := topology.TopoGeo_AddPoint(atopology,
ST_StartPoint(rec.geom),
tol);
+
end_node := topology.TopoGeo_AddPoint(atopology,
ST_EndPoint(rec.geom),
tol);
+
-- Added endpoints may have drifted due to tolerance, so
-- we need to re-snap the edge to the new nodes before adding it
sql := 'SELECT n1.geom as sn, n2.geom as en FROM ' || quote_ident(atopology)
@@ -3997,6 +4056,7 @@ BEGIN
|| '.node n2 WHERE n1.node_id = '
|| start_node || ' AND n2.node_id = ' || end_node;
+
EXECUTE sql INTO STRICT rec2;
snapped := ST_SetPoint(
@@ -4007,8 +4067,10 @@ BEGIN
snapped := ST_CollectionExtract(ST_MakeValid(snapped), 2);
+
-- Check if the so-snapped edge collapsed (see #1650)
IF ST_IsEmpty(snapped) THEN
+
CONTINUE;
END IF;
@@ -4016,11 +4078,14 @@ BEGIN
sql := 'SELECT edge_id FROM ' || quote_ident(atopology)
|| '.edge_data WHERE ST_Equals(geom, ' || quote_literal(snapped::text)
|| '::geometry)';
+
EXECUTE sql INTO id;
IF id IS NULL THEN
id := topology.ST_AddEdgeModFace(atopology, start_node, end_node,
snapped);
+
ELSE
+
END IF;
RETURN NEXT id;
@@ -4062,9 +4127,11 @@ BEGIN
-- 1. Extract boundary
boundary := ST_Boundary(apoly);
+
-- 2. Add boundaries as edges
FOR rec IN SELECT (ST_Dump(boundary)).geom LOOP
edges := array_cat(edges, array_agg(x)) FROM ( select topology.TopoGeo_addLinestring(atopology, rec.geom, tol) as x ) as foo;
+
END LOOP;
-- 3. Find faces covered by input polygon
@@ -4073,10 +4140,12 @@ BEGIN
|| '.face f WHERE f.mbr && '
|| quote_literal(apoly::text)
|| '::geometry';
+
FOR rec IN EXECUTE sql LOOP
-- check for actual containment
fgeom := ST_PointOnSurface(ST_GetFaceGeometry(atopology, rec.face_id));
IF NOT ST_Covers(apoly, fgeom) THEN
+
CONTINUE;
END IF;
RETURN NEXT rec.face_id;
@@ -4102,10 +4171,11 @@ END
$$
LANGUAGE 'plpgsql';
--} TopoGeo_AddGeometry
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4154,11 +4224,12 @@ $$
LANGUAGE 'plpgsql';
--} Polygonize(toponame)
+
-- TopoElement
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4172,7 +4243,7 @@ LANGUAGE 'plpgsql';
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -4214,11 +4285,12 @@ CREATE AGGREGATE topology.TopoElementArray_agg(
);
--} TopoElementArray_agg
+
-- TopoGeometry
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4274,10 +4346,11 @@ $$
$$
LANGUAGE 'sql' STABLE STRICT;
-- }
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011-2012 Sandro Santilli <strk@keybit.net>
--
@@ -4289,7 +4362,7 @@ LANGUAGE 'sql' STABLE STRICT;
-- {
-- Convert a simple geometry to a topologically-defined one
--
--- See http://trac.osgeo.org/postgis/ticket/1017
+-- See http:
--
-- }{
CREATE OR REPLACE FUNCTION topology.toTopoGeom(ageom Geometry, atopology varchar, alayer int, atolerance float8 DEFAULT 0)
@@ -4414,6 +4487,7 @@ BEGIN
|| '.relation(topogeo_id, layer_id, element_type, element_id) VALUES ('
|| rec.id || ',' || rec.lyr || ',' || rec.type
|| ',' || rec.primitive || ')';
+
EXECUTE sql;
END LOOP;
@@ -4424,11 +4498,12 @@ $$
LANGUAGE 'plpgsql' VOLATILE STRICT;
-- }
+
-- GML
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4442,7 +4517,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -4989,13 +5064,14 @@ $$ LANGUAGE 'sql' STABLE; -- does NOT write into visited table
-- } AsGML(TopoGeometry)
+
--=} POSTGIS-SPECIFIC block
-- SQL/MM block
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011, 2012 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -5101,6 +5177,7 @@ BEGIN
LOOP
+
retrec.sequence = n;
retrec.edge = rec.edge_id;
@@ -5399,6 +5476,7 @@ BEGIN
|| ' AND l.layer_id = r.layer_id AND abs(r.element_id) = '
|| e1id
;
+
EXECUTE sql;
@@ -5747,6 +5825,7 @@ BEGIN
|| 'WHERE l.level = 0 AND l.feature_type = 2 '
|| ' AND l.topology_id = ' || topoid
|| ' AND abs(r.element_id) = ' || e1id ;
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented dropping edge %',
rec.topogeo_id, rec.layer_id,
@@ -5771,6 +5850,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge < 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -5788,6 +5868,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge > 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -5803,6 +5884,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge < 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -5820,6 +5902,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge > 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -5865,6 +5948,7 @@ BEGIN
END IF; -- }
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented healing faces % and %',
rec.topogeo_id, rec.layer_id,
@@ -5907,6 +5991,7 @@ BEGIN
|| '.face WHERE face_id IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
END IF; -- }
@@ -5917,6 +6002,7 @@ BEGIN
|| ' WHERE left_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update right_face for all edges still referencing old faces
@@ -5925,6 +6011,7 @@ BEGIN
|| ' WHERE right_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update containing_face for all nodes still referencing old faces
@@ -5933,6 +6020,7 @@ BEGIN
|| ' WHERE containing_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- NOT IN THE SPECS:
@@ -5945,6 +6033,7 @@ BEGIN
|| ' AND l.topology_id = ' || topoid
|| ' AND l.layer_id = r.layer_id AND abs(r.element_id) = '
|| e1rec.left_face;
+
EXECUTE sql;
sql := 'UPDATE ' || quote_ident(toponame)
|| '.relation r '
@@ -5953,6 +6042,7 @@ BEGIN
|| ' AND l.topology_id = ' || topoid
|| ' AND l.layer_id = r.layer_id AND r.element_id = '
|| e1rec.right_face;
+
EXECUTE sql;
END IF; -- } two faces healed...
@@ -5960,6 +6050,7 @@ BEGIN
-- Delete the edge
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.edge_data WHERE edge_id = ' || e1id;
+
EXECUTE sql;
-- Check if any of the edge nodes remains isolated,
@@ -5971,6 +6062,7 @@ BEGIN
|| e1rec.end_node || ') AND NOT EXISTS (SELECT edge_id FROM '
|| quote_ident(toponame)
|| '.edge_data WHERE start_node = n.node_id OR end_node = n.node_id)';
+
EXECUTE sql;
IF e1rec.right_face != e1rec.left_face THEN -- {
@@ -5979,6 +6071,7 @@ BEGIN
IF e1rec.left_face != 0 THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.left_face;
+
EXECUTE sql;
END IF;
@@ -5987,6 +6080,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.right_face;
+
EXECUTE sql;
END IF;
@@ -6071,6 +6165,7 @@ BEGIN
|| 'WHERE l.level = 0 AND l.feature_type = 2 '
|| ' AND l.topology_id = ' || topoid
|| ' AND abs(r.element_id) = ' || e1id ;
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented dropping edge %',
rec.topogeo_id, rec.layer_id,
@@ -6095,6 +6190,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge < 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -6112,6 +6208,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge > 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -6127,6 +6224,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge < 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -6144,6 +6242,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge > 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -6187,6 +6286,7 @@ BEGIN
END IF; -- }
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented healing faces % and %',
rec.topogeo_id, rec.layer_id,
@@ -6219,6 +6319,7 @@ BEGIN
|| '.face WHERE face_id IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ') ) WHERE face_id = ' || floodfaceid ;
+
EXECUTE sql;
END IF; -- }
@@ -6229,6 +6330,7 @@ BEGIN
|| ' WHERE left_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update right_face for all edges still referencing old faces
@@ -6237,6 +6339,7 @@ BEGIN
|| ' WHERE right_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update containing_face for all nodes still referencing old faces
@@ -6245,6 +6348,7 @@ BEGIN
|| ' WHERE containing_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- NOT IN THE SPECS:
@@ -6259,6 +6363,7 @@ BEGIN
|| e1rec.left_face || ',' || e1rec.right_face
|| ') AND abs(r.element_id) != '
|| floodfaceid; -- could be optimized..
+
EXECUTE sql;
END IF; -- } two faces healed...
@@ -6266,6 +6371,7 @@ BEGIN
-- Delete the edge
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.edge_data WHERE edge_id = ' || e1id;
+
EXECUTE sql;
-- Check if any of the edge nodes remains isolated,
@@ -6277,6 +6383,7 @@ BEGIN
|| e1rec.end_node || ') AND NOT EXISTS (SELECT edge_id FROM '
|| quote_ident(toponame)
|| '.edge_data WHERE start_node = n.node_id OR end_node = n.node_id)';
+
EXECUTE sql;
IF e1rec.right_face != e1rec.left_face THEN -- {
@@ -6286,6 +6393,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.left_face;
+
EXECUTE sql;
END IF;
@@ -6294,6 +6402,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.right_face;
+
EXECUTE sql;
END IF;
@@ -6451,6 +6560,7 @@ BEGIN
sql := sql || ' AND f.face_id = ' || aface;
END IF;
+
EXECUTE sql INTO containingface;
-- If aface was specified, check that it was correct
@@ -6484,6 +6594,7 @@ BEGIN
|| '::geometry,' || containingface
|| ' RETURNING node_id';
+
EXECUTE sql INTO nodeid;
RETURN nodeid;
@@ -6624,7 +6735,7 @@ LANGUAGE 'plpgsql' VOLATILE;
--} ST_RemoveIsoNode
--{
--- According to http://trac.osgeo.org/postgis/ticket/798
+-- According to http:
-- ST_RemoveIsoNode was renamed to ST_RemIsoNode in the final ISO
-- document
--
@@ -6826,6 +6937,7 @@ BEGIN
END LOOP;
+
--RAISE NOTICE 'EdgeId1 % EdgeId2 %', edgeid1, edgeid2;
--RAISE DEBUG 'oldedge.next_left_edge: %', oldedge.next_left_edge;
@@ -7111,6 +7223,7 @@ BEGIN
END LOOP;
+
--
-- Insert the new edge
--
@@ -7618,25 +7731,32 @@ BEGIN
tmp1 := ST_MakeLine(ST_EndPoint(oldedge.geom), ST_StartPoint(oldedge.geom));
+
tmp2 := ST_MakeLine(oldedge.geom, tmp1);
IF ST_NumPoints(tmp2) < 4 THEN
tmp2 := ST_AddPoint(tmp2, ST_StartPoint(oldedge.geom));
END IF;
+
tmp2 := ST_CollectionExtract(ST_MakeValid(ST_MakePolygon(tmp2)), 3);
+
range := ST_MakeLine(acurve, tmp1);
IF ST_NumPoints(range) < 4 THEN
range := ST_AddPoint(range, ST_StartPoint(oldedge.geom));
END IF;
+
range := ST_CollectionExtract(ST_MakeValid(ST_MakePolygon(range)), 3);
+
range := ST_SymDifference(range, tmp2);
+
sql := 'SELECT node_id, geom FROM '
|| quote_ident(atopology)
|| '.node WHERE ST_Contains('
|| quote_literal(range::text)
|| '::geometry, geom) LIMIT 1';
+
FOR rec IN EXECUTE sql LOOP -- {
RAISE EXCEPTION 'Edge motion collision at %', ST_AsText(rec.geom);
END LOOP; -- }
@@ -7652,11 +7772,13 @@ BEGIN
) as pre, NULL::integer[] as post
INTO STRICT snode_info;
+
SELECT topology._ST_AdjacentEdges(
atopology, oldedge.end_node, -anedge
) as pre, NULL::integer[] as post
INTO STRICT enode_info;
+
--}
--
@@ -7674,10 +7796,12 @@ BEGIN
atopology, oldedge.start_node, anedge
);
+
enode_info.post := topology._ST_AdjacentEdges(
atopology, oldedge.end_node, -anedge
);
+
IF snode_info.pre != snode_info.post THEN
RAISE EXCEPTION 'Edge changed disposition around start node %',
oldedge.start_node;
@@ -7754,6 +7878,7 @@ DECLARE
BEGIN
IF oface = 0 AND mbr_only THEN
+
RETURN NULL;
END IF;
@@ -7766,24 +7891,31 @@ BEGIN
INTO STRICT fan.newring_edges;
+
-- You can't get to the other side of an edge forming a ring
IF fan.newring_edges @> ARRAY[-anedge] THEN
+
RETURN 0;
END IF;
+
sql := 'WITH ids as ( select row_number() over () as seq, edge from unnest('
|| quote_literal(fan.newring_edges::text)
|| '::int[] ) u(edge) ), edges AS ( select CASE WHEN i.edge < 0 THEN ST_Reverse(e.geom) ELSE e.geom END as g FROM ids i left join '
|| quote_ident(atopology) || '.edge_data e ON(e.edge_id = abs(i.edge)) ORDER BY seq) SELECT ST_MakePolygon(ST_MakeLine(g.g)) FROM edges g;';
+
EXECUTE sql INTO fan.shell;
+
isccw := NOT ST_OrderingEquals(fan.shell, ST_ForceRHR(fan.shell));
+
IF oface = 0 THEN
IF NOT isccw THEN
+
RETURN NULL;
END IF;
END IF;
@@ -7795,6 +7927,7 @@ BEGIN
|| quote_ident(atopology) || '.face SET mbr = '
|| quote_literal(ST_Envelope(fan.shell)::text)
|| '::geometry WHERE face_id = ' || oface;
+
EXECUTE sql;
END IF; -- }
RETURN NULL;
@@ -7815,6 +7948,7 @@ BEGIN
END IF; -- }
-- Insert new face
+
EXECUTE sql INTO STRICT newface;
-- Update forward edges
@@ -7823,6 +7957,7 @@ BEGIN
|| ' WHERE left_face = ' || oface || ' AND edge_id = ANY ('
|| quote_literal(array( select +(x) from unnest(fan.newring_edges) u(x) )::text)
|| ')';
+
EXECUTE sql;
-- Update backward edges
@@ -7831,12 +7966,15 @@ BEGIN
|| ' WHERE right_face = ' || oface || ' AND edge_id = ANY ('
|| quote_literal(array( select -(x) from unnest(fan.newring_edges) u(x) )::text)
|| ')';
+
EXECUTE sql;
IF oface != 0 AND NOT isccw THEN -- {
-- face shrinked, must update all non-contained edges and nodes
+
ishole := true;
ELSE
+
ishole := false;
END IF; -- }
@@ -7858,6 +7996,7 @@ BEGIN
sql := sql || 'ST_Contains(' || quote_literal(fan.shell::text)
-- We only need to check a single point, but must not be an endpoint
|| '::geometry, ST_Line_Interpolate_Point(geom, 0.2))';
+
EXECUTE sql;
-- Update isolated nodes in new new face
@@ -7867,6 +8006,7 @@ BEGIN
|| ' AND ';
IF ishole THEN sql := sql || 'NOT '; END IF;
sql := sql || 'ST_Contains(' || quote_literal(fan.shell::text) || '::geometry, geom)';
+
EXECUTE sql;
RETURN newface;
@@ -7990,6 +8130,7 @@ BEGIN
|| ')'
LOOP
IF rec.containing_face IS NOT NULL THEN
+
IF newedge.left_face IS NULL THEN
newedge.left_face := rec.containing_face;
newedge.right_face := rec.containing_face;
@@ -8097,6 +8238,7 @@ BEGIN
-- Find links on start node -- {
+
sql :=
'SELECT edge_id, -1 AS end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8142,6 +8284,7 @@ BEGIN
END IF;
+
az = az - span.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8181,6 +8324,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN span.was_isolated = true; END IF;
ELSE
@@ -8197,12 +8341,16 @@ BEGIN
END IF;
+
+
+
-- } start_node analysis
-- Find links on end_node {
+
sql :=
'SELECT edge_id, -1 as end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8244,6 +8392,7 @@ BEGIN
END IF;
+
az := az - epan.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8283,6 +8432,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN epan.was_isolated = true; END IF;
ELSE
@@ -8301,6 +8451,9 @@ BEGIN
-- } end_node analysis
+
+
+
----------------------------------------------------------------------
--
-- If we don't have faces setup by now we must have encountered
@@ -8396,15 +8549,18 @@ BEGIN
--------------------------------------------
+
SELECT topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, false)
INTO newface;
IF newface = 0 THEN
+
RETURN newedge.edge_id;
END IF;
newfaces[1] := newface;
+
SELECT topology._ST_AddFaceSplit(atopology, newedge.edge_id, newedge.left_face, false)
INTO newface;
@@ -8427,6 +8583,7 @@ BEGIN
FOR rec IN EXECUTE sql
LOOP
+
-- Add reference to the other face
sql := 'INSERT INTO ' || quote_ident(atopology)
|| '.relation VALUES( ' || rec.topogeo_id
@@ -8564,6 +8721,7 @@ BEGIN
|| ')'
LOOP
IF rec.containing_face IS NOT NULL THEN
+
IF newedge.left_face IS NULL THEN
newedge.left_face := rec.containing_face;
newedge.right_face := rec.containing_face;
@@ -8669,6 +8827,7 @@ BEGIN
-- Find links on start node -- {
+
sql :=
'SELECT edge_id, -1 AS end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8714,6 +8873,7 @@ BEGIN
END IF;
+
az = az - span.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8753,6 +8913,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN span.was_isolated = true; END IF;
ELSE
@@ -8769,12 +8930,16 @@ BEGIN
END IF;
+
+
+
-- } start_node analysis
-- Find links on end_node {
+
sql :=
'SELECT edge_id, -1 as end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8816,6 +8981,7 @@ BEGIN
END IF;
+
az := az - epan.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8855,6 +9021,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN epan.was_isolated = true; END IF;
ELSE
@@ -8873,6 +9040,9 @@ BEGIN
-- } end_node analysis
+
+
+
----------------------------------------------------------------------
--
-- If we don't have faces setup by now we must have encountered
@@ -8967,20 +9137,25 @@ BEGIN
-- Check face splitting
--------------------------------------------
+
SELECT topology._ST_AddFaceSplit(atopology, newedge.edge_id, newedge.left_face, false)
INTO newface;
IF newface = 0 THEN
+
RETURN newedge.edge_id;
END IF;
IF newface IS NULL THEN -- must be forming a maximal ring in universal face
+
SELECT topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, false)
INTO newface;
ELSE
+
PERFORM topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, true);
END IF;
IF newface IS NULL THEN
+
RETURN newedge.edge_id;
END IF;
@@ -9004,6 +9179,7 @@ BEGIN
FOR rec IN EXECUTE sql
LOOP
+
-- Add reference to the other face
sql := 'INSERT INTO ' || quote_ident(atopology)
|| '.relation VALUES( ' || rec.topogeo_id
@@ -9134,6 +9310,7 @@ BEGIN
END; -- }
+
--
-- Node input linework with itself
--
@@ -9147,6 +9324,7 @@ BEGIN
) as linework INTO STRICT nodededges;
+
--
-- Linemerge the resulting edges, to reduce the working set
-- NOTE: this is more of a workaround for GEOS splitting overlapping
@@ -9156,6 +9334,7 @@ BEGIN
+
--
-- Collect input points and input lines endpoints
--
@@ -9169,6 +9348,7 @@ BEGIN
) as nodes INTO STRICT points;
+
--
-- Further split edges by points
-- TODO: optimize this adding ST_Split support for multiline/multipoint
@@ -9183,6 +9363,7 @@ BEGIN
SELECT ST_UnaryUnion(nodededges) INTO STRICT nodededges;
+
--
-- Collect all nodes (from points and noded linework endpoints)
--
@@ -9201,6 +9382,7 @@ BEGIN
) as endpoints INTO points;
+
--
-- Add all nodes as isolated so that
-- later calls to AddEdgeModFace will tweak their being
@@ -9231,11 +9413,12 @@ LANGUAGE 'plpgsql' VOLATILE;
--=} SQL/MM block
+
-- The following files needs getfaceedges_returntype, defined in sqlmm.sql
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 2012 Sandro Santilli <strk@keybit.net>
--
@@ -9245,7 +9428,7 @@ LANGUAGE 'plpgsql' VOLATILE;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -9312,10 +9495,11 @@ END
$$
LANGUAGE 'plpgsql' STABLE;
--} GetRingEdges
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2012 Sandro Santilli <strk@keybit.net>
--
@@ -9356,9 +9540,11 @@ BEGIN
|| ' UNION ALL SELECT -edge_id, ST_Azimuth(ST_EndPoint(geom), ST_PointN(geom, ST_NumPoints(geom)-1)) FROM incident_edges WHERE end_node = ' || anode
|| ' ORDER BY az';
+
FOR rec IN EXECUTE sql
LOOP -- incident edges {
+
n := n + 1;
retrec.sequence := n;
retrec.edge := rec.edge_id;
@@ -9370,11 +9556,12 @@ $$
LANGUAGE 'plpgsql' STABLE;
--} GetRingEdges
+
--general management --
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://www.postgis.org
+-- http:
--
-- Copyright (C) 2011 Regina Obe <lr@pcorp.us>
--
@@ -9413,6 +9600,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
--} AddToSearchPath
+
CREATE OR REPLACE FUNCTION postgis_topology_scripts_installed() RETURNS text
AS $$ SELECT '2.0.2'::text || ' r' || 10789::text AS version $$
LANGUAGE 'sql' IMMUTABLE;
diff --git a/gcc/postgis_extension/postgis_topology--2.0.0rc1--2.0.2.sql b/gpp/postgis_extension/postgis_topology--2.0.0rc1--2.0.2.sql
index 80c44f9..a257064 100644
--- a/gcc/postgis_extension/postgis_topology--2.0.0rc1--2.0.2.sql
+++ b/gpp/postgis_extension/postgis_topology--2.0.0rc1--2.0.2.sql
@@ -100,14 +100,12 @@ LANGUAGE plpgsql VOLATILE;
-- during upgrade
SELECT postgis_extension_remove_objects('postgis_topology', 'FUNCTION');
SELECT postgis_extension_remove_objects('postgis_topology', 'AGGREGATE');
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: topology.sql.in.c 10643 2012-11-05 10:25:41Z strk $
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -306,6 +304,23 @@ SELECT postgis_extension_remove_objects('postgis_topology', 'AGGREGATE');
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-- Doing everything outside of a transaction helps
-- upgrading in the best case.
@@ -481,7 +496,9 @@ ALTER DOMAIN topology.TopoElement ADD
array_lower(VALUE, 1) = 1
);
ALTER DOMAIN topology.TopoElement DROP CONSTRAINT
+
IF EXISTS
+
type_range;
ALTER DOMAIN topology.TopoElement ADD
CONSTRAINT type_range CHECK (
@@ -777,6 +794,7 @@ BEGIN
-- corrupting the topology anyway ...
--
+
RETURN newlayer_id;
END;
$$
@@ -1120,6 +1138,7 @@ BEGIN
|| ') as obj ORDER BY obj';
+
-- TODO: why not using array_agg here ?
i = 1;
@@ -1517,7 +1536,7 @@ BEGIN
--
-- Closed lines have no boundary, so endpoint
-- intersection would be considered interior
- -- See http://trac.osgeo.org/postgis/ticket/770
+ -- See http:
-- See also full explanation in topology.AddEdge
--
@@ -1681,6 +1700,7 @@ BEGIN
END LOOP;
+
DROP TABLE face_check;
RETURN;
@@ -1910,7 +1930,7 @@ BEGIN
------- Indexes on left_face and right_face of edge_data
------- NOTE: these indexes speed up GetFaceGeometry (and thus
------- TopoGeometry::Geometry) by a factor of 10 !
- ------- See http://trac.osgeo.org/postgis/ticket/806
+ ------- See http:
EXECUTE 'CREATE INDEX edge_left_face_idx ON '
|| quote_ident(atopology)
|| '.edge_data (left_face);';
@@ -1921,7 +1941,7 @@ BEGIN
------- Indexes on start_node and end_node of edge_data
------- NOTE: this indexes speed up node deletion
------- by a factor of 1000 !
- ------- See http://trac.osgeo.org/postgis/ticket/2082
+ ------- See http:
EXECUTE 'CREATE INDEX edge_start_node_idx ON '
|| quote_ident(atopology)
|| '.edge_data (start_node);';
@@ -2029,7 +2049,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -2180,10 +2200,11 @@ $$
LANGUAGE 'plpgsql' STABLE STRICT;
--} TopologySummary
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -2280,11 +2301,12 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
--} TopologySummary
+
-- Spatial predicates
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011-2012 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -2798,11 +2820,12 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--} equals(TopoGeometry, TopoGeometry)
+
-- Querying
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -2888,10 +2911,11 @@ $$
LANGUAGE 'plpgsql' STABLE STRICT;
--} GetNodeByPoint
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -2979,10 +3003,11 @@ END
$$
LANGUAGE 'plpgsql' STABLE STRICT;
--} GetEdgeByPoint
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -3138,11 +3163,12 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--} GetFaceByPoint
+
-- Populating
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010-2012 Sandro Santilli <strk@keybit.net>
--
@@ -3163,7 +3189,7 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--
--
-- A pragmatic test conducted using algoritm shown here:
--- http://stackoverflow.com/questions/7408407/generate-next-largest-or-smallest-representable-floating-point-number-without-bi
+-- http:
-- showed the "tolerance" growing by an order of magnitude proportionally
-- with the order of magnitude of the input, starting with something like
-- 3.5527136788005009294e-15 for the starting value of 9.0
@@ -3219,7 +3245,7 @@ $$ LANGUAGE 'plpgsql' STABLE STRICT;
-- The newly added nodes have no containing face.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3287,6 +3313,7 @@ BEGIN
IF setContainingFace THEN
containing_face := topology.GetFaceByPoint(atopology, apoint, 0);
+
ELSE
containing_face := NULL;
END IF;
@@ -3346,7 +3373,7 @@ LANGUAGE 'sql' VOLATILE;
-- Calling code is expected to do further linking.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3435,6 +3462,7 @@ BEGIN
-- Reuse an EQUAL edge (be it closed or not)
IF ST_RelateMatch(rec.im, '1FFF*FFF2') THEN
+
RETURN rec.edge_id;
END IF;
@@ -3539,7 +3567,7 @@ LANGUAGE 'plpgsql' VOLATILE;
-- o The polygon overlaps an existing face.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3661,6 +3689,7 @@ BEGIN
ST_Line_Locate_Point(bounds, p2);
+
IF right_side THEN
right_edges := array_append(right_edges, rec.edge_id);
old_faceid = rec.right_face;
@@ -3687,6 +3716,8 @@ BEGIN
END IF;
+
+
--
-- Check that all edges found, taken togheter,
-- fully match the ring boundary and nothing more
@@ -3706,8 +3737,10 @@ BEGIN
IF faceid IS NOT NULL AND faceid != 0 THEN
IF NOT force_new THEN
+
RETURN faceid;
ELSE
+
END IF;
END IF;
@@ -3834,12 +3867,14 @@ BEGIN
|| tol || ') ORDER BY ST_Distance('
|| quote_literal(apoint::text)
|| '::geometry, a.geom) LIMIT 1;';
+
EXECUTE sql INTO id;
IF id IS NOT NULL THEN
RETURN id;
END IF;
+
-- 2. Check if any existing edge falls within tolerance
-- and if so split it by a point projected on it
sql := 'SELECT a.edge_id, a.geom FROM '
@@ -3849,35 +3884,42 @@ BEGIN
|| tol || ') ORDER BY ST_Distance('
|| quote_literal(apoint::text)
|| '::geometry, a.geom) LIMIT 1;';
+
EXECUTE sql INTO rec;
IF rec IS NOT NULL THEN
-- project point to line, split edge by point
prj := ST_ClosestPoint(rec.geom, apoint);
-- This is a workaround for ClosestPoint lack of Z support:
- -- http://trac.osgeo.org/postgis/ticket/2033
+ -- http:
z := ST_Z(apoint);
IF z IS NOT NULL THEN
prj := ST_Translate(ST_Force_3DZ(prj), 0, 0, z); -- no ST_SetZ ...
END IF;
+
IF NOT ST_Contains(rec.geom, prj) THEN
+
-- The tolerance must be big enough for snapping to happen
-- and small enough to snap only to the projected point.
-- Unfortunately ST_Distance returns 0 because it also uses
-- a projected point internally, so we need another way.
snaptol := topology._st_mintolerance(prj);
+
snapedge := ST_Snap(rec.geom, prj, snaptol);
-- Snapping currently snaps the first point below tolerance
-- so may possibly move first point. See ticket #1631
IF NOT ST_Equals(ST_StartPoint(rec.geom), ST_StartPoint(snapedge))
THEN
+
snapedge := ST_MakeLine(ST_StartPoint(rec.geom), snapedge);
END IF;
+
PERFORM ST_ChangeEdgeGeom(atopology, rec.edge_id, snapedge);
END IF;
id := topology.ST_ModEdgeSplit(atopology, rec.edge_id, prj);
ELSE
+
id := topology.ST_AddIsoNode(atopology, NULL, apoint);
END IF;
@@ -3923,6 +3965,7 @@ BEGIN
-- 1. Self-node
noded := ST_UnaryUnion(aline);
+
-- 2. Node to edges falling within tol distance
sql := 'WITH nearby AS ( SELECT e.geom FROM '
|| quote_ident(atopology)
@@ -3930,20 +3973,27 @@ BEGIN
|| quote_literal(noded::text)
|| '::geometry, '
|| tol || ') ) SELECT st_collect(geom) FROM nearby;';
+
EXECUTE sql INTO iedges;
IF iedges IS NOT NULL THEN
+
snapped := ST_Snap(noded, iedges, tol);
+
noded := ST_Difference(snapped, iedges);
+
set1 := ST_Intersection(snapped, iedges);
+
set2 := ST_LineMerge(set1);
+
noded := ST_Union(noded, set2);
+
END IF;
-- 2.1. Node with existing nodes within tol
@@ -3954,26 +4004,32 @@ BEGIN
|| quote_literal(noded::text)
|| '::geometry, '
|| tol || ') ) SELECT st_collect(geom) FROM nearby;';
+
EXECUTE sql INTO inodes;
IF inodes IS NOT NULL THEN -- {
+
-- TODO: consider snapping once against all elements
--- (rather than once with edges and once with nodes)
noded := ST_Snap(noded, inodes, tol);
+
FOR rec IN SELECT (ST_Dump(inodes)).*
LOOP
-- Use the node to split edges
SELECT ST_Collect(geom)
FROM ST_Dump(ST_Split(noded, rec.geom))
INTO STRICT noded;
+
END LOOP;
+
-- re-node to account for ST_Snap introduced self-intersections
- -- See http://trac.osgeo.org/postgis/ticket/1714
+ -- See http:
-- TODO: consider running UnaryUnion once after all noding
noded := ST_UnaryUnion(noded);
+
END IF; -- }
-- 3. For each (now-noded) segment, insert an edge
@@ -3982,14 +4038,17 @@ BEGIN
-- TODO: skip point elements ?
+
start_node := topology.TopoGeo_AddPoint(atopology,
ST_StartPoint(rec.geom),
tol);
+
end_node := topology.TopoGeo_AddPoint(atopology,
ST_EndPoint(rec.geom),
tol);
+
-- Added endpoints may have drifted due to tolerance, so
-- we need to re-snap the edge to the new nodes before adding it
sql := 'SELECT n1.geom as sn, n2.geom as en FROM ' || quote_ident(atopology)
@@ -3997,6 +4056,7 @@ BEGIN
|| '.node n2 WHERE n1.node_id = '
|| start_node || ' AND n2.node_id = ' || end_node;
+
EXECUTE sql INTO STRICT rec2;
snapped := ST_SetPoint(
@@ -4007,8 +4067,10 @@ BEGIN
snapped := ST_CollectionExtract(ST_MakeValid(snapped), 2);
+
-- Check if the so-snapped edge collapsed (see #1650)
IF ST_IsEmpty(snapped) THEN
+
CONTINUE;
END IF;
@@ -4016,11 +4078,14 @@ BEGIN
sql := 'SELECT edge_id FROM ' || quote_ident(atopology)
|| '.edge_data WHERE ST_Equals(geom, ' || quote_literal(snapped::text)
|| '::geometry)';
+
EXECUTE sql INTO id;
IF id IS NULL THEN
id := topology.ST_AddEdgeModFace(atopology, start_node, end_node,
snapped);
+
ELSE
+
END IF;
RETURN NEXT id;
@@ -4062,9 +4127,11 @@ BEGIN
-- 1. Extract boundary
boundary := ST_Boundary(apoly);
+
-- 2. Add boundaries as edges
FOR rec IN SELECT (ST_Dump(boundary)).geom LOOP
edges := array_cat(edges, array_agg(x)) FROM ( select topology.TopoGeo_addLinestring(atopology, rec.geom, tol) as x ) as foo;
+
END LOOP;
-- 3. Find faces covered by input polygon
@@ -4073,10 +4140,12 @@ BEGIN
|| '.face f WHERE f.mbr && '
|| quote_literal(apoly::text)
|| '::geometry';
+
FOR rec IN EXECUTE sql LOOP
-- check for actual containment
fgeom := ST_PointOnSurface(ST_GetFaceGeometry(atopology, rec.face_id));
IF NOT ST_Covers(apoly, fgeom) THEN
+
CONTINUE;
END IF;
RETURN NEXT rec.face_id;
@@ -4102,10 +4171,11 @@ END
$$
LANGUAGE 'plpgsql';
--} TopoGeo_AddGeometry
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4154,11 +4224,12 @@ $$
LANGUAGE 'plpgsql';
--} Polygonize(toponame)
+
-- TopoElement
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4172,7 +4243,7 @@ LANGUAGE 'plpgsql';
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -4214,11 +4285,12 @@ CREATE AGGREGATE topology.TopoElementArray_agg(
);
--} TopoElementArray_agg
+
-- TopoGeometry
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4274,10 +4346,11 @@ $$
$$
LANGUAGE 'sql' STABLE STRICT;
-- }
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011-2012 Sandro Santilli <strk@keybit.net>
--
@@ -4289,7 +4362,7 @@ LANGUAGE 'sql' STABLE STRICT;
-- {
-- Convert a simple geometry to a topologically-defined one
--
--- See http://trac.osgeo.org/postgis/ticket/1017
+-- See http:
--
-- }{
CREATE OR REPLACE FUNCTION topology.toTopoGeom(ageom Geometry, atopology varchar, alayer int, atolerance float8 DEFAULT 0)
@@ -4414,6 +4487,7 @@ BEGIN
|| '.relation(topogeo_id, layer_id, element_type, element_id) VALUES ('
|| rec.id || ',' || rec.lyr || ',' || rec.type
|| ',' || rec.primitive || ')';
+
EXECUTE sql;
END LOOP;
@@ -4424,11 +4498,12 @@ $$
LANGUAGE 'plpgsql' VOLATILE STRICT;
-- }
+
-- GML
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4442,7 +4517,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -4989,13 +5064,14 @@ $$ LANGUAGE 'sql' STABLE; -- does NOT write into visited table
-- } AsGML(TopoGeometry)
+
--=} POSTGIS-SPECIFIC block
-- SQL/MM block
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011, 2012 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -5101,6 +5177,7 @@ BEGIN
LOOP
+
retrec.sequence = n;
retrec.edge = rec.edge_id;
@@ -5399,6 +5476,7 @@ BEGIN
|| ' AND l.layer_id = r.layer_id AND abs(r.element_id) = '
|| e1id
;
+
EXECUTE sql;
@@ -5747,6 +5825,7 @@ BEGIN
|| 'WHERE l.level = 0 AND l.feature_type = 2 '
|| ' AND l.topology_id = ' || topoid
|| ' AND abs(r.element_id) = ' || e1id ;
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented dropping edge %',
rec.topogeo_id, rec.layer_id,
@@ -5771,6 +5850,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge < 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -5788,6 +5868,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge > 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -5803,6 +5884,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge < 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -5820,6 +5902,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge > 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -5865,6 +5948,7 @@ BEGIN
END IF; -- }
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented healing faces % and %',
rec.topogeo_id, rec.layer_id,
@@ -5907,6 +5991,7 @@ BEGIN
|| '.face WHERE face_id IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
END IF; -- }
@@ -5917,6 +6002,7 @@ BEGIN
|| ' WHERE left_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update right_face for all edges still referencing old faces
@@ -5925,6 +6011,7 @@ BEGIN
|| ' WHERE right_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update containing_face for all nodes still referencing old faces
@@ -5933,6 +6020,7 @@ BEGIN
|| ' WHERE containing_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- NOT IN THE SPECS:
@@ -5945,6 +6033,7 @@ BEGIN
|| ' AND l.topology_id = ' || topoid
|| ' AND l.layer_id = r.layer_id AND abs(r.element_id) = '
|| e1rec.left_face;
+
EXECUTE sql;
sql := 'UPDATE ' || quote_ident(toponame)
|| '.relation r '
@@ -5953,6 +6042,7 @@ BEGIN
|| ' AND l.topology_id = ' || topoid
|| ' AND l.layer_id = r.layer_id AND r.element_id = '
|| e1rec.right_face;
+
EXECUTE sql;
END IF; -- } two faces healed...
@@ -5960,6 +6050,7 @@ BEGIN
-- Delete the edge
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.edge_data WHERE edge_id = ' || e1id;
+
EXECUTE sql;
-- Check if any of the edge nodes remains isolated,
@@ -5971,6 +6062,7 @@ BEGIN
|| e1rec.end_node || ') AND NOT EXISTS (SELECT edge_id FROM '
|| quote_ident(toponame)
|| '.edge_data WHERE start_node = n.node_id OR end_node = n.node_id)';
+
EXECUTE sql;
IF e1rec.right_face != e1rec.left_face THEN -- {
@@ -5979,6 +6071,7 @@ BEGIN
IF e1rec.left_face != 0 THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.left_face;
+
EXECUTE sql;
END IF;
@@ -5987,6 +6080,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.right_face;
+
EXECUTE sql;
END IF;
@@ -6071,6 +6165,7 @@ BEGIN
|| 'WHERE l.level = 0 AND l.feature_type = 2 '
|| ' AND l.topology_id = ' || topoid
|| ' AND abs(r.element_id) = ' || e1id ;
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented dropping edge %',
rec.topogeo_id, rec.layer_id,
@@ -6095,6 +6190,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge < 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -6112,6 +6208,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge > 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -6127,6 +6224,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge < 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -6144,6 +6242,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge > 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -6187,6 +6286,7 @@ BEGIN
END IF; -- }
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented healing faces % and %',
rec.topogeo_id, rec.layer_id,
@@ -6219,6 +6319,7 @@ BEGIN
|| '.face WHERE face_id IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ') ) WHERE face_id = ' || floodfaceid ;
+
EXECUTE sql;
END IF; -- }
@@ -6229,6 +6330,7 @@ BEGIN
|| ' WHERE left_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update right_face for all edges still referencing old faces
@@ -6237,6 +6339,7 @@ BEGIN
|| ' WHERE right_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update containing_face for all nodes still referencing old faces
@@ -6245,6 +6348,7 @@ BEGIN
|| ' WHERE containing_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- NOT IN THE SPECS:
@@ -6259,6 +6363,7 @@ BEGIN
|| e1rec.left_face || ',' || e1rec.right_face
|| ') AND abs(r.element_id) != '
|| floodfaceid; -- could be optimized..
+
EXECUTE sql;
END IF; -- } two faces healed...
@@ -6266,6 +6371,7 @@ BEGIN
-- Delete the edge
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.edge_data WHERE edge_id = ' || e1id;
+
EXECUTE sql;
-- Check if any of the edge nodes remains isolated,
@@ -6277,6 +6383,7 @@ BEGIN
|| e1rec.end_node || ') AND NOT EXISTS (SELECT edge_id FROM '
|| quote_ident(toponame)
|| '.edge_data WHERE start_node = n.node_id OR end_node = n.node_id)';
+
EXECUTE sql;
IF e1rec.right_face != e1rec.left_face THEN -- {
@@ -6286,6 +6393,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.left_face;
+
EXECUTE sql;
END IF;
@@ -6294,6 +6402,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.right_face;
+
EXECUTE sql;
END IF;
@@ -6451,6 +6560,7 @@ BEGIN
sql := sql || ' AND f.face_id = ' || aface;
END IF;
+
EXECUTE sql INTO containingface;
-- If aface was specified, check that it was correct
@@ -6484,6 +6594,7 @@ BEGIN
|| '::geometry,' || containingface
|| ' RETURNING node_id';
+
EXECUTE sql INTO nodeid;
RETURN nodeid;
@@ -6624,7 +6735,7 @@ LANGUAGE 'plpgsql' VOLATILE;
--} ST_RemoveIsoNode
--{
--- According to http://trac.osgeo.org/postgis/ticket/798
+-- According to http:
-- ST_RemoveIsoNode was renamed to ST_RemIsoNode in the final ISO
-- document
--
@@ -6826,6 +6937,7 @@ BEGIN
END LOOP;
+
--RAISE NOTICE 'EdgeId1 % EdgeId2 %', edgeid1, edgeid2;
--RAISE DEBUG 'oldedge.next_left_edge: %', oldedge.next_left_edge;
@@ -7111,6 +7223,7 @@ BEGIN
END LOOP;
+
--
-- Insert the new edge
--
@@ -7618,25 +7731,32 @@ BEGIN
tmp1 := ST_MakeLine(ST_EndPoint(oldedge.geom), ST_StartPoint(oldedge.geom));
+
tmp2 := ST_MakeLine(oldedge.geom, tmp1);
IF ST_NumPoints(tmp2) < 4 THEN
tmp2 := ST_AddPoint(tmp2, ST_StartPoint(oldedge.geom));
END IF;
+
tmp2 := ST_CollectionExtract(ST_MakeValid(ST_MakePolygon(tmp2)), 3);
+
range := ST_MakeLine(acurve, tmp1);
IF ST_NumPoints(range) < 4 THEN
range := ST_AddPoint(range, ST_StartPoint(oldedge.geom));
END IF;
+
range := ST_CollectionExtract(ST_MakeValid(ST_MakePolygon(range)), 3);
+
range := ST_SymDifference(range, tmp2);
+
sql := 'SELECT node_id, geom FROM '
|| quote_ident(atopology)
|| '.node WHERE ST_Contains('
|| quote_literal(range::text)
|| '::geometry, geom) LIMIT 1';
+
FOR rec IN EXECUTE sql LOOP -- {
RAISE EXCEPTION 'Edge motion collision at %', ST_AsText(rec.geom);
END LOOP; -- }
@@ -7652,11 +7772,13 @@ BEGIN
) as pre, NULL::integer[] as post
INTO STRICT snode_info;
+
SELECT topology._ST_AdjacentEdges(
atopology, oldedge.end_node, -anedge
) as pre, NULL::integer[] as post
INTO STRICT enode_info;
+
--}
--
@@ -7674,10 +7796,12 @@ BEGIN
atopology, oldedge.start_node, anedge
);
+
enode_info.post := topology._ST_AdjacentEdges(
atopology, oldedge.end_node, -anedge
);
+
IF snode_info.pre != snode_info.post THEN
RAISE EXCEPTION 'Edge changed disposition around start node %',
oldedge.start_node;
@@ -7754,6 +7878,7 @@ DECLARE
BEGIN
IF oface = 0 AND mbr_only THEN
+
RETURN NULL;
END IF;
@@ -7766,24 +7891,31 @@ BEGIN
INTO STRICT fan.newring_edges;
+
-- You can't get to the other side of an edge forming a ring
IF fan.newring_edges @> ARRAY[-anedge] THEN
+
RETURN 0;
END IF;
+
sql := 'WITH ids as ( select row_number() over () as seq, edge from unnest('
|| quote_literal(fan.newring_edges::text)
|| '::int[] ) u(edge) ), edges AS ( select CASE WHEN i.edge < 0 THEN ST_Reverse(e.geom) ELSE e.geom END as g FROM ids i left join '
|| quote_ident(atopology) || '.edge_data e ON(e.edge_id = abs(i.edge)) ORDER BY seq) SELECT ST_MakePolygon(ST_MakeLine(g.g)) FROM edges g;';
+
EXECUTE sql INTO fan.shell;
+
isccw := NOT ST_OrderingEquals(fan.shell, ST_ForceRHR(fan.shell));
+
IF oface = 0 THEN
IF NOT isccw THEN
+
RETURN NULL;
END IF;
END IF;
@@ -7795,6 +7927,7 @@ BEGIN
|| quote_ident(atopology) || '.face SET mbr = '
|| quote_literal(ST_Envelope(fan.shell)::text)
|| '::geometry WHERE face_id = ' || oface;
+
EXECUTE sql;
END IF; -- }
RETURN NULL;
@@ -7815,6 +7948,7 @@ BEGIN
END IF; -- }
-- Insert new face
+
EXECUTE sql INTO STRICT newface;
-- Update forward edges
@@ -7823,6 +7957,7 @@ BEGIN
|| ' WHERE left_face = ' || oface || ' AND edge_id = ANY ('
|| quote_literal(array( select +(x) from unnest(fan.newring_edges) u(x) )::text)
|| ')';
+
EXECUTE sql;
-- Update backward edges
@@ -7831,12 +7966,15 @@ BEGIN
|| ' WHERE right_face = ' || oface || ' AND edge_id = ANY ('
|| quote_literal(array( select -(x) from unnest(fan.newring_edges) u(x) )::text)
|| ')';
+
EXECUTE sql;
IF oface != 0 AND NOT isccw THEN -- {
-- face shrinked, must update all non-contained edges and nodes
+
ishole := true;
ELSE
+
ishole := false;
END IF; -- }
@@ -7858,6 +7996,7 @@ BEGIN
sql := sql || 'ST_Contains(' || quote_literal(fan.shell::text)
-- We only need to check a single point, but must not be an endpoint
|| '::geometry, ST_Line_Interpolate_Point(geom, 0.2))';
+
EXECUTE sql;
-- Update isolated nodes in new new face
@@ -7867,6 +8006,7 @@ BEGIN
|| ' AND ';
IF ishole THEN sql := sql || 'NOT '; END IF;
sql := sql || 'ST_Contains(' || quote_literal(fan.shell::text) || '::geometry, geom)';
+
EXECUTE sql;
RETURN newface;
@@ -7990,6 +8130,7 @@ BEGIN
|| ')'
LOOP
IF rec.containing_face IS NOT NULL THEN
+
IF newedge.left_face IS NULL THEN
newedge.left_face := rec.containing_face;
newedge.right_face := rec.containing_face;
@@ -8097,6 +8238,7 @@ BEGIN
-- Find links on start node -- {
+
sql :=
'SELECT edge_id, -1 AS end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8142,6 +8284,7 @@ BEGIN
END IF;
+
az = az - span.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8181,6 +8324,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN span.was_isolated = true; END IF;
ELSE
@@ -8197,12 +8341,16 @@ BEGIN
END IF;
+
+
+
-- } start_node analysis
-- Find links on end_node {
+
sql :=
'SELECT edge_id, -1 as end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8244,6 +8392,7 @@ BEGIN
END IF;
+
az := az - epan.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8283,6 +8432,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN epan.was_isolated = true; END IF;
ELSE
@@ -8301,6 +8451,9 @@ BEGIN
-- } end_node analysis
+
+
+
----------------------------------------------------------------------
--
-- If we don't have faces setup by now we must have encountered
@@ -8396,15 +8549,18 @@ BEGIN
--------------------------------------------
+
SELECT topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, false)
INTO newface;
IF newface = 0 THEN
+
RETURN newedge.edge_id;
END IF;
newfaces[1] := newface;
+
SELECT topology._ST_AddFaceSplit(atopology, newedge.edge_id, newedge.left_face, false)
INTO newface;
@@ -8427,6 +8583,7 @@ BEGIN
FOR rec IN EXECUTE sql
LOOP
+
-- Add reference to the other face
sql := 'INSERT INTO ' || quote_ident(atopology)
|| '.relation VALUES( ' || rec.topogeo_id
@@ -8564,6 +8721,7 @@ BEGIN
|| ')'
LOOP
IF rec.containing_face IS NOT NULL THEN
+
IF newedge.left_face IS NULL THEN
newedge.left_face := rec.containing_face;
newedge.right_face := rec.containing_face;
@@ -8669,6 +8827,7 @@ BEGIN
-- Find links on start node -- {
+
sql :=
'SELECT edge_id, -1 AS end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8714,6 +8873,7 @@ BEGIN
END IF;
+
az = az - span.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8753,6 +8913,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN span.was_isolated = true; END IF;
ELSE
@@ -8769,12 +8930,16 @@ BEGIN
END IF;
+
+
+
-- } start_node analysis
-- Find links on end_node {
+
sql :=
'SELECT edge_id, -1 as end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8816,6 +8981,7 @@ BEGIN
END IF;
+
az := az - epan.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8855,6 +9021,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN epan.was_isolated = true; END IF;
ELSE
@@ -8873,6 +9040,9 @@ BEGIN
-- } end_node analysis
+
+
+
----------------------------------------------------------------------
--
-- If we don't have faces setup by now we must have encountered
@@ -8967,20 +9137,25 @@ BEGIN
-- Check face splitting
--------------------------------------------
+
SELECT topology._ST_AddFaceSplit(atopology, newedge.edge_id, newedge.left_face, false)
INTO newface;
IF newface = 0 THEN
+
RETURN newedge.edge_id;
END IF;
IF newface IS NULL THEN -- must be forming a maximal ring in universal face
+
SELECT topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, false)
INTO newface;
ELSE
+
PERFORM topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, true);
END IF;
IF newface IS NULL THEN
+
RETURN newedge.edge_id;
END IF;
@@ -9004,6 +9179,7 @@ BEGIN
FOR rec IN EXECUTE sql
LOOP
+
-- Add reference to the other face
sql := 'INSERT INTO ' || quote_ident(atopology)
|| '.relation VALUES( ' || rec.topogeo_id
@@ -9134,6 +9310,7 @@ BEGIN
END; -- }
+
--
-- Node input linework with itself
--
@@ -9147,6 +9324,7 @@ BEGIN
) as linework INTO STRICT nodededges;
+
--
-- Linemerge the resulting edges, to reduce the working set
-- NOTE: this is more of a workaround for GEOS splitting overlapping
@@ -9156,6 +9334,7 @@ BEGIN
+
--
-- Collect input points and input lines endpoints
--
@@ -9169,6 +9348,7 @@ BEGIN
) as nodes INTO STRICT points;
+
--
-- Further split edges by points
-- TODO: optimize this adding ST_Split support for multiline/multipoint
@@ -9183,6 +9363,7 @@ BEGIN
SELECT ST_UnaryUnion(nodededges) INTO STRICT nodededges;
+
--
-- Collect all nodes (from points and noded linework endpoints)
--
@@ -9201,6 +9382,7 @@ BEGIN
) as endpoints INTO points;
+
--
-- Add all nodes as isolated so that
-- later calls to AddEdgeModFace will tweak their being
@@ -9231,11 +9413,12 @@ LANGUAGE 'plpgsql' VOLATILE;
--=} SQL/MM block
+
-- The following files needs getfaceedges_returntype, defined in sqlmm.sql
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 2012 Sandro Santilli <strk@keybit.net>
--
@@ -9245,7 +9428,7 @@ LANGUAGE 'plpgsql' VOLATILE;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -9312,10 +9495,11 @@ END
$$
LANGUAGE 'plpgsql' STABLE;
--} GetRingEdges
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2012 Sandro Santilli <strk@keybit.net>
--
@@ -9356,9 +9540,11 @@ BEGIN
|| ' UNION ALL SELECT -edge_id, ST_Azimuth(ST_EndPoint(geom), ST_PointN(geom, ST_NumPoints(geom)-1)) FROM incident_edges WHERE end_node = ' || anode
|| ' ORDER BY az';
+
FOR rec IN EXECUTE sql
LOOP -- incident edges {
+
n := n + 1;
retrec.sequence := n;
retrec.edge := rec.edge_id;
@@ -9370,11 +9556,12 @@ $$
LANGUAGE 'plpgsql' STABLE;
--} GetRingEdges
+
--general management --
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://www.postgis.org
+-- http:
--
-- Copyright (C) 2011 Regina Obe <lr@pcorp.us>
--
@@ -9413,6 +9600,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
--} AddToSearchPath
+
CREATE OR REPLACE FUNCTION postgis_topology_scripts_installed() RETURNS text
AS $$ SELECT '2.0.2'::text || ' r' || 10789::text AS version $$
LANGUAGE 'sql' IMMUTABLE;
diff --git a/gcc/postgis_extension/postgis_topology--2.0.0rc2--2.0.2.sql b/gpp/postgis_extension/postgis_topology--2.0.0rc2--2.0.2.sql
index 80c44f9..a257064 100644
--- a/gcc/postgis_extension/postgis_topology--2.0.0rc2--2.0.2.sql
+++ b/gpp/postgis_extension/postgis_topology--2.0.0rc2--2.0.2.sql
@@ -100,14 +100,12 @@ LANGUAGE plpgsql VOLATILE;
-- during upgrade
SELECT postgis_extension_remove_objects('postgis_topology', 'FUNCTION');
SELECT postgis_extension_remove_objects('postgis_topology', 'AGGREGATE');
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: topology.sql.in.c 10643 2012-11-05 10:25:41Z strk $
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -306,6 +304,23 @@ SELECT postgis_extension_remove_objects('postgis_topology', 'AGGREGATE');
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-- Doing everything outside of a transaction helps
-- upgrading in the best case.
@@ -481,7 +496,9 @@ ALTER DOMAIN topology.TopoElement ADD
array_lower(VALUE, 1) = 1
);
ALTER DOMAIN topology.TopoElement DROP CONSTRAINT
+
IF EXISTS
+
type_range;
ALTER DOMAIN topology.TopoElement ADD
CONSTRAINT type_range CHECK (
@@ -777,6 +794,7 @@ BEGIN
-- corrupting the topology anyway ...
--
+
RETURN newlayer_id;
END;
$$
@@ -1120,6 +1138,7 @@ BEGIN
|| ') as obj ORDER BY obj';
+
-- TODO: why not using array_agg here ?
i = 1;
@@ -1517,7 +1536,7 @@ BEGIN
--
-- Closed lines have no boundary, so endpoint
-- intersection would be considered interior
- -- See http://trac.osgeo.org/postgis/ticket/770
+ -- See http:
-- See also full explanation in topology.AddEdge
--
@@ -1681,6 +1700,7 @@ BEGIN
END LOOP;
+
DROP TABLE face_check;
RETURN;
@@ -1910,7 +1930,7 @@ BEGIN
------- Indexes on left_face and right_face of edge_data
------- NOTE: these indexes speed up GetFaceGeometry (and thus
------- TopoGeometry::Geometry) by a factor of 10 !
- ------- See http://trac.osgeo.org/postgis/ticket/806
+ ------- See http:
EXECUTE 'CREATE INDEX edge_left_face_idx ON '
|| quote_ident(atopology)
|| '.edge_data (left_face);';
@@ -1921,7 +1941,7 @@ BEGIN
------- Indexes on start_node and end_node of edge_data
------- NOTE: this indexes speed up node deletion
------- by a factor of 1000 !
- ------- See http://trac.osgeo.org/postgis/ticket/2082
+ ------- See http:
EXECUTE 'CREATE INDEX edge_start_node_idx ON '
|| quote_ident(atopology)
|| '.edge_data (start_node);';
@@ -2029,7 +2049,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -2180,10 +2200,11 @@ $$
LANGUAGE 'plpgsql' STABLE STRICT;
--} TopologySummary
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -2280,11 +2301,12 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
--} TopologySummary
+
-- Spatial predicates
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011-2012 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -2798,11 +2820,12 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--} equals(TopoGeometry, TopoGeometry)
+
-- Querying
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -2888,10 +2911,11 @@ $$
LANGUAGE 'plpgsql' STABLE STRICT;
--} GetNodeByPoint
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -2979,10 +3003,11 @@ END
$$
LANGUAGE 'plpgsql' STABLE STRICT;
--} GetEdgeByPoint
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -3138,11 +3163,12 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--} GetFaceByPoint
+
-- Populating
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010-2012 Sandro Santilli <strk@keybit.net>
--
@@ -3163,7 +3189,7 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--
--
-- A pragmatic test conducted using algoritm shown here:
--- http://stackoverflow.com/questions/7408407/generate-next-largest-or-smallest-representable-floating-point-number-without-bi
+-- http:
-- showed the "tolerance" growing by an order of magnitude proportionally
-- with the order of magnitude of the input, starting with something like
-- 3.5527136788005009294e-15 for the starting value of 9.0
@@ -3219,7 +3245,7 @@ $$ LANGUAGE 'plpgsql' STABLE STRICT;
-- The newly added nodes have no containing face.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3287,6 +3313,7 @@ BEGIN
IF setContainingFace THEN
containing_face := topology.GetFaceByPoint(atopology, apoint, 0);
+
ELSE
containing_face := NULL;
END IF;
@@ -3346,7 +3373,7 @@ LANGUAGE 'sql' VOLATILE;
-- Calling code is expected to do further linking.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3435,6 +3462,7 @@ BEGIN
-- Reuse an EQUAL edge (be it closed or not)
IF ST_RelateMatch(rec.im, '1FFF*FFF2') THEN
+
RETURN rec.edge_id;
END IF;
@@ -3539,7 +3567,7 @@ LANGUAGE 'plpgsql' VOLATILE;
-- o The polygon overlaps an existing face.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3661,6 +3689,7 @@ BEGIN
ST_Line_Locate_Point(bounds, p2);
+
IF right_side THEN
right_edges := array_append(right_edges, rec.edge_id);
old_faceid = rec.right_face;
@@ -3687,6 +3716,8 @@ BEGIN
END IF;
+
+
--
-- Check that all edges found, taken togheter,
-- fully match the ring boundary and nothing more
@@ -3706,8 +3737,10 @@ BEGIN
IF faceid IS NOT NULL AND faceid != 0 THEN
IF NOT force_new THEN
+
RETURN faceid;
ELSE
+
END IF;
END IF;
@@ -3834,12 +3867,14 @@ BEGIN
|| tol || ') ORDER BY ST_Distance('
|| quote_literal(apoint::text)
|| '::geometry, a.geom) LIMIT 1;';
+
EXECUTE sql INTO id;
IF id IS NOT NULL THEN
RETURN id;
END IF;
+
-- 2. Check if any existing edge falls within tolerance
-- and if so split it by a point projected on it
sql := 'SELECT a.edge_id, a.geom FROM '
@@ -3849,35 +3884,42 @@ BEGIN
|| tol || ') ORDER BY ST_Distance('
|| quote_literal(apoint::text)
|| '::geometry, a.geom) LIMIT 1;';
+
EXECUTE sql INTO rec;
IF rec IS NOT NULL THEN
-- project point to line, split edge by point
prj := ST_ClosestPoint(rec.geom, apoint);
-- This is a workaround for ClosestPoint lack of Z support:
- -- http://trac.osgeo.org/postgis/ticket/2033
+ -- http:
z := ST_Z(apoint);
IF z IS NOT NULL THEN
prj := ST_Translate(ST_Force_3DZ(prj), 0, 0, z); -- no ST_SetZ ...
END IF;
+
IF NOT ST_Contains(rec.geom, prj) THEN
+
-- The tolerance must be big enough for snapping to happen
-- and small enough to snap only to the projected point.
-- Unfortunately ST_Distance returns 0 because it also uses
-- a projected point internally, so we need another way.
snaptol := topology._st_mintolerance(prj);
+
snapedge := ST_Snap(rec.geom, prj, snaptol);
-- Snapping currently snaps the first point below tolerance
-- so may possibly move first point. See ticket #1631
IF NOT ST_Equals(ST_StartPoint(rec.geom), ST_StartPoint(snapedge))
THEN
+
snapedge := ST_MakeLine(ST_StartPoint(rec.geom), snapedge);
END IF;
+
PERFORM ST_ChangeEdgeGeom(atopology, rec.edge_id, snapedge);
END IF;
id := topology.ST_ModEdgeSplit(atopology, rec.edge_id, prj);
ELSE
+
id := topology.ST_AddIsoNode(atopology, NULL, apoint);
END IF;
@@ -3923,6 +3965,7 @@ BEGIN
-- 1. Self-node
noded := ST_UnaryUnion(aline);
+
-- 2. Node to edges falling within tol distance
sql := 'WITH nearby AS ( SELECT e.geom FROM '
|| quote_ident(atopology)
@@ -3930,20 +3973,27 @@ BEGIN
|| quote_literal(noded::text)
|| '::geometry, '
|| tol || ') ) SELECT st_collect(geom) FROM nearby;';
+
EXECUTE sql INTO iedges;
IF iedges IS NOT NULL THEN
+
snapped := ST_Snap(noded, iedges, tol);
+
noded := ST_Difference(snapped, iedges);
+
set1 := ST_Intersection(snapped, iedges);
+
set2 := ST_LineMerge(set1);
+
noded := ST_Union(noded, set2);
+
END IF;
-- 2.1. Node with existing nodes within tol
@@ -3954,26 +4004,32 @@ BEGIN
|| quote_literal(noded::text)
|| '::geometry, '
|| tol || ') ) SELECT st_collect(geom) FROM nearby;';
+
EXECUTE sql INTO inodes;
IF inodes IS NOT NULL THEN -- {
+
-- TODO: consider snapping once against all elements
--- (rather than once with edges and once with nodes)
noded := ST_Snap(noded, inodes, tol);
+
FOR rec IN SELECT (ST_Dump(inodes)).*
LOOP
-- Use the node to split edges
SELECT ST_Collect(geom)
FROM ST_Dump(ST_Split(noded, rec.geom))
INTO STRICT noded;
+
END LOOP;
+
-- re-node to account for ST_Snap introduced self-intersections
- -- See http://trac.osgeo.org/postgis/ticket/1714
+ -- See http:
-- TODO: consider running UnaryUnion once after all noding
noded := ST_UnaryUnion(noded);
+
END IF; -- }
-- 3. For each (now-noded) segment, insert an edge
@@ -3982,14 +4038,17 @@ BEGIN
-- TODO: skip point elements ?
+
start_node := topology.TopoGeo_AddPoint(atopology,
ST_StartPoint(rec.geom),
tol);
+
end_node := topology.TopoGeo_AddPoint(atopology,
ST_EndPoint(rec.geom),
tol);
+
-- Added endpoints may have drifted due to tolerance, so
-- we need to re-snap the edge to the new nodes before adding it
sql := 'SELECT n1.geom as sn, n2.geom as en FROM ' || quote_ident(atopology)
@@ -3997,6 +4056,7 @@ BEGIN
|| '.node n2 WHERE n1.node_id = '
|| start_node || ' AND n2.node_id = ' || end_node;
+
EXECUTE sql INTO STRICT rec2;
snapped := ST_SetPoint(
@@ -4007,8 +4067,10 @@ BEGIN
snapped := ST_CollectionExtract(ST_MakeValid(snapped), 2);
+
-- Check if the so-snapped edge collapsed (see #1650)
IF ST_IsEmpty(snapped) THEN
+
CONTINUE;
END IF;
@@ -4016,11 +4078,14 @@ BEGIN
sql := 'SELECT edge_id FROM ' || quote_ident(atopology)
|| '.edge_data WHERE ST_Equals(geom, ' || quote_literal(snapped::text)
|| '::geometry)';
+
EXECUTE sql INTO id;
IF id IS NULL THEN
id := topology.ST_AddEdgeModFace(atopology, start_node, end_node,
snapped);
+
ELSE
+
END IF;
RETURN NEXT id;
@@ -4062,9 +4127,11 @@ BEGIN
-- 1. Extract boundary
boundary := ST_Boundary(apoly);
+
-- 2. Add boundaries as edges
FOR rec IN SELECT (ST_Dump(boundary)).geom LOOP
edges := array_cat(edges, array_agg(x)) FROM ( select topology.TopoGeo_addLinestring(atopology, rec.geom, tol) as x ) as foo;
+
END LOOP;
-- 3. Find faces covered by input polygon
@@ -4073,10 +4140,12 @@ BEGIN
|| '.face f WHERE f.mbr && '
|| quote_literal(apoly::text)
|| '::geometry';
+
FOR rec IN EXECUTE sql LOOP
-- check for actual containment
fgeom := ST_PointOnSurface(ST_GetFaceGeometry(atopology, rec.face_id));
IF NOT ST_Covers(apoly, fgeom) THEN
+
CONTINUE;
END IF;
RETURN NEXT rec.face_id;
@@ -4102,10 +4171,11 @@ END
$$
LANGUAGE 'plpgsql';
--} TopoGeo_AddGeometry
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4154,11 +4224,12 @@ $$
LANGUAGE 'plpgsql';
--} Polygonize(toponame)
+
-- TopoElement
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4172,7 +4243,7 @@ LANGUAGE 'plpgsql';
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -4214,11 +4285,12 @@ CREATE AGGREGATE topology.TopoElementArray_agg(
);
--} TopoElementArray_agg
+
-- TopoGeometry
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4274,10 +4346,11 @@ $$
$$
LANGUAGE 'sql' STABLE STRICT;
-- }
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011-2012 Sandro Santilli <strk@keybit.net>
--
@@ -4289,7 +4362,7 @@ LANGUAGE 'sql' STABLE STRICT;
-- {
-- Convert a simple geometry to a topologically-defined one
--
--- See http://trac.osgeo.org/postgis/ticket/1017
+-- See http:
--
-- }{
CREATE OR REPLACE FUNCTION topology.toTopoGeom(ageom Geometry, atopology varchar, alayer int, atolerance float8 DEFAULT 0)
@@ -4414,6 +4487,7 @@ BEGIN
|| '.relation(topogeo_id, layer_id, element_type, element_id) VALUES ('
|| rec.id || ',' || rec.lyr || ',' || rec.type
|| ',' || rec.primitive || ')';
+
EXECUTE sql;
END LOOP;
@@ -4424,11 +4498,12 @@ $$
LANGUAGE 'plpgsql' VOLATILE STRICT;
-- }
+
-- GML
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4442,7 +4517,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -4989,13 +5064,14 @@ $$ LANGUAGE 'sql' STABLE; -- does NOT write into visited table
-- } AsGML(TopoGeometry)
+
--=} POSTGIS-SPECIFIC block
-- SQL/MM block
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011, 2012 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -5101,6 +5177,7 @@ BEGIN
LOOP
+
retrec.sequence = n;
retrec.edge = rec.edge_id;
@@ -5399,6 +5476,7 @@ BEGIN
|| ' AND l.layer_id = r.layer_id AND abs(r.element_id) = '
|| e1id
;
+
EXECUTE sql;
@@ -5747,6 +5825,7 @@ BEGIN
|| 'WHERE l.level = 0 AND l.feature_type = 2 '
|| ' AND l.topology_id = ' || topoid
|| ' AND abs(r.element_id) = ' || e1id ;
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented dropping edge %',
rec.topogeo_id, rec.layer_id,
@@ -5771,6 +5850,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge < 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -5788,6 +5868,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge > 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -5803,6 +5884,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge < 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -5820,6 +5902,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge > 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -5865,6 +5948,7 @@ BEGIN
END IF; -- }
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented healing faces % and %',
rec.topogeo_id, rec.layer_id,
@@ -5907,6 +5991,7 @@ BEGIN
|| '.face WHERE face_id IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
END IF; -- }
@@ -5917,6 +6002,7 @@ BEGIN
|| ' WHERE left_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update right_face for all edges still referencing old faces
@@ -5925,6 +6011,7 @@ BEGIN
|| ' WHERE right_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update containing_face for all nodes still referencing old faces
@@ -5933,6 +6020,7 @@ BEGIN
|| ' WHERE containing_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- NOT IN THE SPECS:
@@ -5945,6 +6033,7 @@ BEGIN
|| ' AND l.topology_id = ' || topoid
|| ' AND l.layer_id = r.layer_id AND abs(r.element_id) = '
|| e1rec.left_face;
+
EXECUTE sql;
sql := 'UPDATE ' || quote_ident(toponame)
|| '.relation r '
@@ -5953,6 +6042,7 @@ BEGIN
|| ' AND l.topology_id = ' || topoid
|| ' AND l.layer_id = r.layer_id AND r.element_id = '
|| e1rec.right_face;
+
EXECUTE sql;
END IF; -- } two faces healed...
@@ -5960,6 +6050,7 @@ BEGIN
-- Delete the edge
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.edge_data WHERE edge_id = ' || e1id;
+
EXECUTE sql;
-- Check if any of the edge nodes remains isolated,
@@ -5971,6 +6062,7 @@ BEGIN
|| e1rec.end_node || ') AND NOT EXISTS (SELECT edge_id FROM '
|| quote_ident(toponame)
|| '.edge_data WHERE start_node = n.node_id OR end_node = n.node_id)';
+
EXECUTE sql;
IF e1rec.right_face != e1rec.left_face THEN -- {
@@ -5979,6 +6071,7 @@ BEGIN
IF e1rec.left_face != 0 THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.left_face;
+
EXECUTE sql;
END IF;
@@ -5987,6 +6080,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.right_face;
+
EXECUTE sql;
END IF;
@@ -6071,6 +6165,7 @@ BEGIN
|| 'WHERE l.level = 0 AND l.feature_type = 2 '
|| ' AND l.topology_id = ' || topoid
|| ' AND abs(r.element_id) = ' || e1id ;
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented dropping edge %',
rec.topogeo_id, rec.layer_id,
@@ -6095,6 +6190,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge < 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -6112,6 +6208,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge > 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -6127,6 +6224,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge < 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -6144,6 +6242,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge > 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -6187,6 +6286,7 @@ BEGIN
END IF; -- }
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented healing faces % and %',
rec.topogeo_id, rec.layer_id,
@@ -6219,6 +6319,7 @@ BEGIN
|| '.face WHERE face_id IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ') ) WHERE face_id = ' || floodfaceid ;
+
EXECUTE sql;
END IF; -- }
@@ -6229,6 +6330,7 @@ BEGIN
|| ' WHERE left_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update right_face for all edges still referencing old faces
@@ -6237,6 +6339,7 @@ BEGIN
|| ' WHERE right_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update containing_face for all nodes still referencing old faces
@@ -6245,6 +6348,7 @@ BEGIN
|| ' WHERE containing_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- NOT IN THE SPECS:
@@ -6259,6 +6363,7 @@ BEGIN
|| e1rec.left_face || ',' || e1rec.right_face
|| ') AND abs(r.element_id) != '
|| floodfaceid; -- could be optimized..
+
EXECUTE sql;
END IF; -- } two faces healed...
@@ -6266,6 +6371,7 @@ BEGIN
-- Delete the edge
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.edge_data WHERE edge_id = ' || e1id;
+
EXECUTE sql;
-- Check if any of the edge nodes remains isolated,
@@ -6277,6 +6383,7 @@ BEGIN
|| e1rec.end_node || ') AND NOT EXISTS (SELECT edge_id FROM '
|| quote_ident(toponame)
|| '.edge_data WHERE start_node = n.node_id OR end_node = n.node_id)';
+
EXECUTE sql;
IF e1rec.right_face != e1rec.left_face THEN -- {
@@ -6286,6 +6393,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.left_face;
+
EXECUTE sql;
END IF;
@@ -6294,6 +6402,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.right_face;
+
EXECUTE sql;
END IF;
@@ -6451,6 +6560,7 @@ BEGIN
sql := sql || ' AND f.face_id = ' || aface;
END IF;
+
EXECUTE sql INTO containingface;
-- If aface was specified, check that it was correct
@@ -6484,6 +6594,7 @@ BEGIN
|| '::geometry,' || containingface
|| ' RETURNING node_id';
+
EXECUTE sql INTO nodeid;
RETURN nodeid;
@@ -6624,7 +6735,7 @@ LANGUAGE 'plpgsql' VOLATILE;
--} ST_RemoveIsoNode
--{
--- According to http://trac.osgeo.org/postgis/ticket/798
+-- According to http:
-- ST_RemoveIsoNode was renamed to ST_RemIsoNode in the final ISO
-- document
--
@@ -6826,6 +6937,7 @@ BEGIN
END LOOP;
+
--RAISE NOTICE 'EdgeId1 % EdgeId2 %', edgeid1, edgeid2;
--RAISE DEBUG 'oldedge.next_left_edge: %', oldedge.next_left_edge;
@@ -7111,6 +7223,7 @@ BEGIN
END LOOP;
+
--
-- Insert the new edge
--
@@ -7618,25 +7731,32 @@ BEGIN
tmp1 := ST_MakeLine(ST_EndPoint(oldedge.geom), ST_StartPoint(oldedge.geom));
+
tmp2 := ST_MakeLine(oldedge.geom, tmp1);
IF ST_NumPoints(tmp2) < 4 THEN
tmp2 := ST_AddPoint(tmp2, ST_StartPoint(oldedge.geom));
END IF;
+
tmp2 := ST_CollectionExtract(ST_MakeValid(ST_MakePolygon(tmp2)), 3);
+
range := ST_MakeLine(acurve, tmp1);
IF ST_NumPoints(range) < 4 THEN
range := ST_AddPoint(range, ST_StartPoint(oldedge.geom));
END IF;
+
range := ST_CollectionExtract(ST_MakeValid(ST_MakePolygon(range)), 3);
+
range := ST_SymDifference(range, tmp2);
+
sql := 'SELECT node_id, geom FROM '
|| quote_ident(atopology)
|| '.node WHERE ST_Contains('
|| quote_literal(range::text)
|| '::geometry, geom) LIMIT 1';
+
FOR rec IN EXECUTE sql LOOP -- {
RAISE EXCEPTION 'Edge motion collision at %', ST_AsText(rec.geom);
END LOOP; -- }
@@ -7652,11 +7772,13 @@ BEGIN
) as pre, NULL::integer[] as post
INTO STRICT snode_info;
+
SELECT topology._ST_AdjacentEdges(
atopology, oldedge.end_node, -anedge
) as pre, NULL::integer[] as post
INTO STRICT enode_info;
+
--}
--
@@ -7674,10 +7796,12 @@ BEGIN
atopology, oldedge.start_node, anedge
);
+
enode_info.post := topology._ST_AdjacentEdges(
atopology, oldedge.end_node, -anedge
);
+
IF snode_info.pre != snode_info.post THEN
RAISE EXCEPTION 'Edge changed disposition around start node %',
oldedge.start_node;
@@ -7754,6 +7878,7 @@ DECLARE
BEGIN
IF oface = 0 AND mbr_only THEN
+
RETURN NULL;
END IF;
@@ -7766,24 +7891,31 @@ BEGIN
INTO STRICT fan.newring_edges;
+
-- You can't get to the other side of an edge forming a ring
IF fan.newring_edges @> ARRAY[-anedge] THEN
+
RETURN 0;
END IF;
+
sql := 'WITH ids as ( select row_number() over () as seq, edge from unnest('
|| quote_literal(fan.newring_edges::text)
|| '::int[] ) u(edge) ), edges AS ( select CASE WHEN i.edge < 0 THEN ST_Reverse(e.geom) ELSE e.geom END as g FROM ids i left join '
|| quote_ident(atopology) || '.edge_data e ON(e.edge_id = abs(i.edge)) ORDER BY seq) SELECT ST_MakePolygon(ST_MakeLine(g.g)) FROM edges g;';
+
EXECUTE sql INTO fan.shell;
+
isccw := NOT ST_OrderingEquals(fan.shell, ST_ForceRHR(fan.shell));
+
IF oface = 0 THEN
IF NOT isccw THEN
+
RETURN NULL;
END IF;
END IF;
@@ -7795,6 +7927,7 @@ BEGIN
|| quote_ident(atopology) || '.face SET mbr = '
|| quote_literal(ST_Envelope(fan.shell)::text)
|| '::geometry WHERE face_id = ' || oface;
+
EXECUTE sql;
END IF; -- }
RETURN NULL;
@@ -7815,6 +7948,7 @@ BEGIN
END IF; -- }
-- Insert new face
+
EXECUTE sql INTO STRICT newface;
-- Update forward edges
@@ -7823,6 +7957,7 @@ BEGIN
|| ' WHERE left_face = ' || oface || ' AND edge_id = ANY ('
|| quote_literal(array( select +(x) from unnest(fan.newring_edges) u(x) )::text)
|| ')';
+
EXECUTE sql;
-- Update backward edges
@@ -7831,12 +7966,15 @@ BEGIN
|| ' WHERE right_face = ' || oface || ' AND edge_id = ANY ('
|| quote_literal(array( select -(x) from unnest(fan.newring_edges) u(x) )::text)
|| ')';
+
EXECUTE sql;
IF oface != 0 AND NOT isccw THEN -- {
-- face shrinked, must update all non-contained edges and nodes
+
ishole := true;
ELSE
+
ishole := false;
END IF; -- }
@@ -7858,6 +7996,7 @@ BEGIN
sql := sql || 'ST_Contains(' || quote_literal(fan.shell::text)
-- We only need to check a single point, but must not be an endpoint
|| '::geometry, ST_Line_Interpolate_Point(geom, 0.2))';
+
EXECUTE sql;
-- Update isolated nodes in new new face
@@ -7867,6 +8006,7 @@ BEGIN
|| ' AND ';
IF ishole THEN sql := sql || 'NOT '; END IF;
sql := sql || 'ST_Contains(' || quote_literal(fan.shell::text) || '::geometry, geom)';
+
EXECUTE sql;
RETURN newface;
@@ -7990,6 +8130,7 @@ BEGIN
|| ')'
LOOP
IF rec.containing_face IS NOT NULL THEN
+
IF newedge.left_face IS NULL THEN
newedge.left_face := rec.containing_face;
newedge.right_face := rec.containing_face;
@@ -8097,6 +8238,7 @@ BEGIN
-- Find links on start node -- {
+
sql :=
'SELECT edge_id, -1 AS end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8142,6 +8284,7 @@ BEGIN
END IF;
+
az = az - span.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8181,6 +8324,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN span.was_isolated = true; END IF;
ELSE
@@ -8197,12 +8341,16 @@ BEGIN
END IF;
+
+
+
-- } start_node analysis
-- Find links on end_node {
+
sql :=
'SELECT edge_id, -1 as end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8244,6 +8392,7 @@ BEGIN
END IF;
+
az := az - epan.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8283,6 +8432,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN epan.was_isolated = true; END IF;
ELSE
@@ -8301,6 +8451,9 @@ BEGIN
-- } end_node analysis
+
+
+
----------------------------------------------------------------------
--
-- If we don't have faces setup by now we must have encountered
@@ -8396,15 +8549,18 @@ BEGIN
--------------------------------------------
+
SELECT topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, false)
INTO newface;
IF newface = 0 THEN
+
RETURN newedge.edge_id;
END IF;
newfaces[1] := newface;
+
SELECT topology._ST_AddFaceSplit(atopology, newedge.edge_id, newedge.left_face, false)
INTO newface;
@@ -8427,6 +8583,7 @@ BEGIN
FOR rec IN EXECUTE sql
LOOP
+
-- Add reference to the other face
sql := 'INSERT INTO ' || quote_ident(atopology)
|| '.relation VALUES( ' || rec.topogeo_id
@@ -8564,6 +8721,7 @@ BEGIN
|| ')'
LOOP
IF rec.containing_face IS NOT NULL THEN
+
IF newedge.left_face IS NULL THEN
newedge.left_face := rec.containing_face;
newedge.right_face := rec.containing_face;
@@ -8669,6 +8827,7 @@ BEGIN
-- Find links on start node -- {
+
sql :=
'SELECT edge_id, -1 AS end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8714,6 +8873,7 @@ BEGIN
END IF;
+
az = az - span.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8753,6 +8913,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN span.was_isolated = true; END IF;
ELSE
@@ -8769,12 +8930,16 @@ BEGIN
END IF;
+
+
+
-- } start_node analysis
-- Find links on end_node {
+
sql :=
'SELECT edge_id, -1 as end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8816,6 +8981,7 @@ BEGIN
END IF;
+
az := az - epan.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8855,6 +9021,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN epan.was_isolated = true; END IF;
ELSE
@@ -8873,6 +9040,9 @@ BEGIN
-- } end_node analysis
+
+
+
----------------------------------------------------------------------
--
-- If we don't have faces setup by now we must have encountered
@@ -8967,20 +9137,25 @@ BEGIN
-- Check face splitting
--------------------------------------------
+
SELECT topology._ST_AddFaceSplit(atopology, newedge.edge_id, newedge.left_face, false)
INTO newface;
IF newface = 0 THEN
+
RETURN newedge.edge_id;
END IF;
IF newface IS NULL THEN -- must be forming a maximal ring in universal face
+
SELECT topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, false)
INTO newface;
ELSE
+
PERFORM topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, true);
END IF;
IF newface IS NULL THEN
+
RETURN newedge.edge_id;
END IF;
@@ -9004,6 +9179,7 @@ BEGIN
FOR rec IN EXECUTE sql
LOOP
+
-- Add reference to the other face
sql := 'INSERT INTO ' || quote_ident(atopology)
|| '.relation VALUES( ' || rec.topogeo_id
@@ -9134,6 +9310,7 @@ BEGIN
END; -- }
+
--
-- Node input linework with itself
--
@@ -9147,6 +9324,7 @@ BEGIN
) as linework INTO STRICT nodededges;
+
--
-- Linemerge the resulting edges, to reduce the working set
-- NOTE: this is more of a workaround for GEOS splitting overlapping
@@ -9156,6 +9334,7 @@ BEGIN
+
--
-- Collect input points and input lines endpoints
--
@@ -9169,6 +9348,7 @@ BEGIN
) as nodes INTO STRICT points;
+
--
-- Further split edges by points
-- TODO: optimize this adding ST_Split support for multiline/multipoint
@@ -9183,6 +9363,7 @@ BEGIN
SELECT ST_UnaryUnion(nodededges) INTO STRICT nodededges;
+
--
-- Collect all nodes (from points and noded linework endpoints)
--
@@ -9201,6 +9382,7 @@ BEGIN
) as endpoints INTO points;
+
--
-- Add all nodes as isolated so that
-- later calls to AddEdgeModFace will tweak their being
@@ -9231,11 +9413,12 @@ LANGUAGE 'plpgsql' VOLATILE;
--=} SQL/MM block
+
-- The following files needs getfaceedges_returntype, defined in sqlmm.sql
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 2012 Sandro Santilli <strk@keybit.net>
--
@@ -9245,7 +9428,7 @@ LANGUAGE 'plpgsql' VOLATILE;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -9312,10 +9495,11 @@ END
$$
LANGUAGE 'plpgsql' STABLE;
--} GetRingEdges
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2012 Sandro Santilli <strk@keybit.net>
--
@@ -9356,9 +9540,11 @@ BEGIN
|| ' UNION ALL SELECT -edge_id, ST_Azimuth(ST_EndPoint(geom), ST_PointN(geom, ST_NumPoints(geom)-1)) FROM incident_edges WHERE end_node = ' || anode
|| ' ORDER BY az';
+
FOR rec IN EXECUTE sql
LOOP -- incident edges {
+
n := n + 1;
retrec.sequence := n;
retrec.edge := rec.edge_id;
@@ -9370,11 +9556,12 @@ $$
LANGUAGE 'plpgsql' STABLE;
--} GetRingEdges
+
--general management --
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://www.postgis.org
+-- http:
--
-- Copyright (C) 2011 Regina Obe <lr@pcorp.us>
--
@@ -9413,6 +9600,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
--} AddToSearchPath
+
CREATE OR REPLACE FUNCTION postgis_topology_scripts_installed() RETURNS text
AS $$ SELECT '2.0.2'::text || ' r' || 10789::text AS version $$
LANGUAGE 'sql' IMMUTABLE;
diff --git a/gcc/postgis_extension/postgis_topology--2.0.1--2.0.2.sql b/gpp/postgis_extension/postgis_topology--2.0.1--2.0.2.sql
index 80c44f9..a257064 100644
--- a/gcc/postgis_extension/postgis_topology--2.0.1--2.0.2.sql
+++ b/gpp/postgis_extension/postgis_topology--2.0.1--2.0.2.sql
@@ -100,14 +100,12 @@ LANGUAGE plpgsql VOLATILE;
-- during upgrade
SELECT postgis_extension_remove_objects('postgis_topology', 'FUNCTION');
SELECT postgis_extension_remove_objects('postgis_topology', 'AGGREGATE');
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: topology.sql.in.c 10643 2012-11-05 10:25:41Z strk $
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -306,6 +304,23 @@ SELECT postgis_extension_remove_objects('postgis_topology', 'AGGREGATE');
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-- Doing everything outside of a transaction helps
-- upgrading in the best case.
@@ -481,7 +496,9 @@ ALTER DOMAIN topology.TopoElement ADD
array_lower(VALUE, 1) = 1
);
ALTER DOMAIN topology.TopoElement DROP CONSTRAINT
+
IF EXISTS
+
type_range;
ALTER DOMAIN topology.TopoElement ADD
CONSTRAINT type_range CHECK (
@@ -777,6 +794,7 @@ BEGIN
-- corrupting the topology anyway ...
--
+
RETURN newlayer_id;
END;
$$
@@ -1120,6 +1138,7 @@ BEGIN
|| ') as obj ORDER BY obj';
+
-- TODO: why not using array_agg here ?
i = 1;
@@ -1517,7 +1536,7 @@ BEGIN
--
-- Closed lines have no boundary, so endpoint
-- intersection would be considered interior
- -- See http://trac.osgeo.org/postgis/ticket/770
+ -- See http:
-- See also full explanation in topology.AddEdge
--
@@ -1681,6 +1700,7 @@ BEGIN
END LOOP;
+
DROP TABLE face_check;
RETURN;
@@ -1910,7 +1930,7 @@ BEGIN
------- Indexes on left_face and right_face of edge_data
------- NOTE: these indexes speed up GetFaceGeometry (and thus
------- TopoGeometry::Geometry) by a factor of 10 !
- ------- See http://trac.osgeo.org/postgis/ticket/806
+ ------- See http:
EXECUTE 'CREATE INDEX edge_left_face_idx ON '
|| quote_ident(atopology)
|| '.edge_data (left_face);';
@@ -1921,7 +1941,7 @@ BEGIN
------- Indexes on start_node and end_node of edge_data
------- NOTE: this indexes speed up node deletion
------- by a factor of 1000 !
- ------- See http://trac.osgeo.org/postgis/ticket/2082
+ ------- See http:
EXECUTE 'CREATE INDEX edge_start_node_idx ON '
|| quote_ident(atopology)
|| '.edge_data (start_node);';
@@ -2029,7 +2049,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -2180,10 +2200,11 @@ $$
LANGUAGE 'plpgsql' STABLE STRICT;
--} TopologySummary
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -2280,11 +2301,12 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
--} TopologySummary
+
-- Spatial predicates
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011-2012 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -2798,11 +2820,12 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--} equals(TopoGeometry, TopoGeometry)
+
-- Querying
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -2888,10 +2911,11 @@ $$
LANGUAGE 'plpgsql' STABLE STRICT;
--} GetNodeByPoint
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -2979,10 +3003,11 @@ END
$$
LANGUAGE 'plpgsql' STABLE STRICT;
--} GetEdgeByPoint
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -3138,11 +3163,12 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--} GetFaceByPoint
+
-- Populating
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010-2012 Sandro Santilli <strk@keybit.net>
--
@@ -3163,7 +3189,7 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--
--
-- A pragmatic test conducted using algoritm shown here:
--- http://stackoverflow.com/questions/7408407/generate-next-largest-or-smallest-representable-floating-point-number-without-bi
+-- http:
-- showed the "tolerance" growing by an order of magnitude proportionally
-- with the order of magnitude of the input, starting with something like
-- 3.5527136788005009294e-15 for the starting value of 9.0
@@ -3219,7 +3245,7 @@ $$ LANGUAGE 'plpgsql' STABLE STRICT;
-- The newly added nodes have no containing face.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3287,6 +3313,7 @@ BEGIN
IF setContainingFace THEN
containing_face := topology.GetFaceByPoint(atopology, apoint, 0);
+
ELSE
containing_face := NULL;
END IF;
@@ -3346,7 +3373,7 @@ LANGUAGE 'sql' VOLATILE;
-- Calling code is expected to do further linking.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3435,6 +3462,7 @@ BEGIN
-- Reuse an EQUAL edge (be it closed or not)
IF ST_RelateMatch(rec.im, '1FFF*FFF2') THEN
+
RETURN rec.edge_id;
END IF;
@@ -3539,7 +3567,7 @@ LANGUAGE 'plpgsql' VOLATILE;
-- o The polygon overlaps an existing face.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3661,6 +3689,7 @@ BEGIN
ST_Line_Locate_Point(bounds, p2);
+
IF right_side THEN
right_edges := array_append(right_edges, rec.edge_id);
old_faceid = rec.right_face;
@@ -3687,6 +3716,8 @@ BEGIN
END IF;
+
+
--
-- Check that all edges found, taken togheter,
-- fully match the ring boundary and nothing more
@@ -3706,8 +3737,10 @@ BEGIN
IF faceid IS NOT NULL AND faceid != 0 THEN
IF NOT force_new THEN
+
RETURN faceid;
ELSE
+
END IF;
END IF;
@@ -3834,12 +3867,14 @@ BEGIN
|| tol || ') ORDER BY ST_Distance('
|| quote_literal(apoint::text)
|| '::geometry, a.geom) LIMIT 1;';
+
EXECUTE sql INTO id;
IF id IS NOT NULL THEN
RETURN id;
END IF;
+
-- 2. Check if any existing edge falls within tolerance
-- and if so split it by a point projected on it
sql := 'SELECT a.edge_id, a.geom FROM '
@@ -3849,35 +3884,42 @@ BEGIN
|| tol || ') ORDER BY ST_Distance('
|| quote_literal(apoint::text)
|| '::geometry, a.geom) LIMIT 1;';
+
EXECUTE sql INTO rec;
IF rec IS NOT NULL THEN
-- project point to line, split edge by point
prj := ST_ClosestPoint(rec.geom, apoint);
-- This is a workaround for ClosestPoint lack of Z support:
- -- http://trac.osgeo.org/postgis/ticket/2033
+ -- http:
z := ST_Z(apoint);
IF z IS NOT NULL THEN
prj := ST_Translate(ST_Force_3DZ(prj), 0, 0, z); -- no ST_SetZ ...
END IF;
+
IF NOT ST_Contains(rec.geom, prj) THEN
+
-- The tolerance must be big enough for snapping to happen
-- and small enough to snap only to the projected point.
-- Unfortunately ST_Distance returns 0 because it also uses
-- a projected point internally, so we need another way.
snaptol := topology._st_mintolerance(prj);
+
snapedge := ST_Snap(rec.geom, prj, snaptol);
-- Snapping currently snaps the first point below tolerance
-- so may possibly move first point. See ticket #1631
IF NOT ST_Equals(ST_StartPoint(rec.geom), ST_StartPoint(snapedge))
THEN
+
snapedge := ST_MakeLine(ST_StartPoint(rec.geom), snapedge);
END IF;
+
PERFORM ST_ChangeEdgeGeom(atopology, rec.edge_id, snapedge);
END IF;
id := topology.ST_ModEdgeSplit(atopology, rec.edge_id, prj);
ELSE
+
id := topology.ST_AddIsoNode(atopology, NULL, apoint);
END IF;
@@ -3923,6 +3965,7 @@ BEGIN
-- 1. Self-node
noded := ST_UnaryUnion(aline);
+
-- 2. Node to edges falling within tol distance
sql := 'WITH nearby AS ( SELECT e.geom FROM '
|| quote_ident(atopology)
@@ -3930,20 +3973,27 @@ BEGIN
|| quote_literal(noded::text)
|| '::geometry, '
|| tol || ') ) SELECT st_collect(geom) FROM nearby;';
+
EXECUTE sql INTO iedges;
IF iedges IS NOT NULL THEN
+
snapped := ST_Snap(noded, iedges, tol);
+
noded := ST_Difference(snapped, iedges);
+
set1 := ST_Intersection(snapped, iedges);
+
set2 := ST_LineMerge(set1);
+
noded := ST_Union(noded, set2);
+
END IF;
-- 2.1. Node with existing nodes within tol
@@ -3954,26 +4004,32 @@ BEGIN
|| quote_literal(noded::text)
|| '::geometry, '
|| tol || ') ) SELECT st_collect(geom) FROM nearby;';
+
EXECUTE sql INTO inodes;
IF inodes IS NOT NULL THEN -- {
+
-- TODO: consider snapping once against all elements
--- (rather than once with edges and once with nodes)
noded := ST_Snap(noded, inodes, tol);
+
FOR rec IN SELECT (ST_Dump(inodes)).*
LOOP
-- Use the node to split edges
SELECT ST_Collect(geom)
FROM ST_Dump(ST_Split(noded, rec.geom))
INTO STRICT noded;
+
END LOOP;
+
-- re-node to account for ST_Snap introduced self-intersections
- -- See http://trac.osgeo.org/postgis/ticket/1714
+ -- See http:
-- TODO: consider running UnaryUnion once after all noding
noded := ST_UnaryUnion(noded);
+
END IF; -- }
-- 3. For each (now-noded) segment, insert an edge
@@ -3982,14 +4038,17 @@ BEGIN
-- TODO: skip point elements ?
+
start_node := topology.TopoGeo_AddPoint(atopology,
ST_StartPoint(rec.geom),
tol);
+
end_node := topology.TopoGeo_AddPoint(atopology,
ST_EndPoint(rec.geom),
tol);
+
-- Added endpoints may have drifted due to tolerance, so
-- we need to re-snap the edge to the new nodes before adding it
sql := 'SELECT n1.geom as sn, n2.geom as en FROM ' || quote_ident(atopology)
@@ -3997,6 +4056,7 @@ BEGIN
|| '.node n2 WHERE n1.node_id = '
|| start_node || ' AND n2.node_id = ' || end_node;
+
EXECUTE sql INTO STRICT rec2;
snapped := ST_SetPoint(
@@ -4007,8 +4067,10 @@ BEGIN
snapped := ST_CollectionExtract(ST_MakeValid(snapped), 2);
+
-- Check if the so-snapped edge collapsed (see #1650)
IF ST_IsEmpty(snapped) THEN
+
CONTINUE;
END IF;
@@ -4016,11 +4078,14 @@ BEGIN
sql := 'SELECT edge_id FROM ' || quote_ident(atopology)
|| '.edge_data WHERE ST_Equals(geom, ' || quote_literal(snapped::text)
|| '::geometry)';
+
EXECUTE sql INTO id;
IF id IS NULL THEN
id := topology.ST_AddEdgeModFace(atopology, start_node, end_node,
snapped);
+
ELSE
+
END IF;
RETURN NEXT id;
@@ -4062,9 +4127,11 @@ BEGIN
-- 1. Extract boundary
boundary := ST_Boundary(apoly);
+
-- 2. Add boundaries as edges
FOR rec IN SELECT (ST_Dump(boundary)).geom LOOP
edges := array_cat(edges, array_agg(x)) FROM ( select topology.TopoGeo_addLinestring(atopology, rec.geom, tol) as x ) as foo;
+
END LOOP;
-- 3. Find faces covered by input polygon
@@ -4073,10 +4140,12 @@ BEGIN
|| '.face f WHERE f.mbr && '
|| quote_literal(apoly::text)
|| '::geometry';
+
FOR rec IN EXECUTE sql LOOP
-- check for actual containment
fgeom := ST_PointOnSurface(ST_GetFaceGeometry(atopology, rec.face_id));
IF NOT ST_Covers(apoly, fgeom) THEN
+
CONTINUE;
END IF;
RETURN NEXT rec.face_id;
@@ -4102,10 +4171,11 @@ END
$$
LANGUAGE 'plpgsql';
--} TopoGeo_AddGeometry
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4154,11 +4224,12 @@ $$
LANGUAGE 'plpgsql';
--} Polygonize(toponame)
+
-- TopoElement
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4172,7 +4243,7 @@ LANGUAGE 'plpgsql';
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -4214,11 +4285,12 @@ CREATE AGGREGATE topology.TopoElementArray_agg(
);
--} TopoElementArray_agg
+
-- TopoGeometry
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4274,10 +4346,11 @@ $$
$$
LANGUAGE 'sql' STABLE STRICT;
-- }
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011-2012 Sandro Santilli <strk@keybit.net>
--
@@ -4289,7 +4362,7 @@ LANGUAGE 'sql' STABLE STRICT;
-- {
-- Convert a simple geometry to a topologically-defined one
--
--- See http://trac.osgeo.org/postgis/ticket/1017
+-- See http:
--
-- }{
CREATE OR REPLACE FUNCTION topology.toTopoGeom(ageom Geometry, atopology varchar, alayer int, atolerance float8 DEFAULT 0)
@@ -4414,6 +4487,7 @@ BEGIN
|| '.relation(topogeo_id, layer_id, element_type, element_id) VALUES ('
|| rec.id || ',' || rec.lyr || ',' || rec.type
|| ',' || rec.primitive || ')';
+
EXECUTE sql;
END LOOP;
@@ -4424,11 +4498,12 @@ $$
LANGUAGE 'plpgsql' VOLATILE STRICT;
-- }
+
-- GML
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4442,7 +4517,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -4989,13 +5064,14 @@ $$ LANGUAGE 'sql' STABLE; -- does NOT write into visited table
-- } AsGML(TopoGeometry)
+
--=} POSTGIS-SPECIFIC block
-- SQL/MM block
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011, 2012 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -5101,6 +5177,7 @@ BEGIN
LOOP
+
retrec.sequence = n;
retrec.edge = rec.edge_id;
@@ -5399,6 +5476,7 @@ BEGIN
|| ' AND l.layer_id = r.layer_id AND abs(r.element_id) = '
|| e1id
;
+
EXECUTE sql;
@@ -5747,6 +5825,7 @@ BEGIN
|| 'WHERE l.level = 0 AND l.feature_type = 2 '
|| ' AND l.topology_id = ' || topoid
|| ' AND abs(r.element_id) = ' || e1id ;
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented dropping edge %',
rec.topogeo_id, rec.layer_id,
@@ -5771,6 +5850,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge < 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -5788,6 +5868,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge > 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -5803,6 +5884,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge < 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -5820,6 +5902,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge > 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -5865,6 +5948,7 @@ BEGIN
END IF; -- }
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented healing faces % and %',
rec.topogeo_id, rec.layer_id,
@@ -5907,6 +5991,7 @@ BEGIN
|| '.face WHERE face_id IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
END IF; -- }
@@ -5917,6 +6002,7 @@ BEGIN
|| ' WHERE left_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update right_face for all edges still referencing old faces
@@ -5925,6 +6011,7 @@ BEGIN
|| ' WHERE right_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update containing_face for all nodes still referencing old faces
@@ -5933,6 +6020,7 @@ BEGIN
|| ' WHERE containing_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- NOT IN THE SPECS:
@@ -5945,6 +6033,7 @@ BEGIN
|| ' AND l.topology_id = ' || topoid
|| ' AND l.layer_id = r.layer_id AND abs(r.element_id) = '
|| e1rec.left_face;
+
EXECUTE sql;
sql := 'UPDATE ' || quote_ident(toponame)
|| '.relation r '
@@ -5953,6 +6042,7 @@ BEGIN
|| ' AND l.topology_id = ' || topoid
|| ' AND l.layer_id = r.layer_id AND r.element_id = '
|| e1rec.right_face;
+
EXECUTE sql;
END IF; -- } two faces healed...
@@ -5960,6 +6050,7 @@ BEGIN
-- Delete the edge
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.edge_data WHERE edge_id = ' || e1id;
+
EXECUTE sql;
-- Check if any of the edge nodes remains isolated,
@@ -5971,6 +6062,7 @@ BEGIN
|| e1rec.end_node || ') AND NOT EXISTS (SELECT edge_id FROM '
|| quote_ident(toponame)
|| '.edge_data WHERE start_node = n.node_id OR end_node = n.node_id)';
+
EXECUTE sql;
IF e1rec.right_face != e1rec.left_face THEN -- {
@@ -5979,6 +6071,7 @@ BEGIN
IF e1rec.left_face != 0 THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.left_face;
+
EXECUTE sql;
END IF;
@@ -5987,6 +6080,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.right_face;
+
EXECUTE sql;
END IF;
@@ -6071,6 +6165,7 @@ BEGIN
|| 'WHERE l.level = 0 AND l.feature_type = 2 '
|| ' AND l.topology_id = ' || topoid
|| ' AND abs(r.element_id) = ' || e1id ;
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented dropping edge %',
rec.topogeo_id, rec.layer_id,
@@ -6095,6 +6190,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge < 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -6112,6 +6208,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge > 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -6127,6 +6224,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge < 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -6144,6 +6242,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge > 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -6187,6 +6286,7 @@ BEGIN
END IF; -- }
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented healing faces % and %',
rec.topogeo_id, rec.layer_id,
@@ -6219,6 +6319,7 @@ BEGIN
|| '.face WHERE face_id IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ') ) WHERE face_id = ' || floodfaceid ;
+
EXECUTE sql;
END IF; -- }
@@ -6229,6 +6330,7 @@ BEGIN
|| ' WHERE left_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update right_face for all edges still referencing old faces
@@ -6237,6 +6339,7 @@ BEGIN
|| ' WHERE right_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update containing_face for all nodes still referencing old faces
@@ -6245,6 +6348,7 @@ BEGIN
|| ' WHERE containing_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- NOT IN THE SPECS:
@@ -6259,6 +6363,7 @@ BEGIN
|| e1rec.left_face || ',' || e1rec.right_face
|| ') AND abs(r.element_id) != '
|| floodfaceid; -- could be optimized..
+
EXECUTE sql;
END IF; -- } two faces healed...
@@ -6266,6 +6371,7 @@ BEGIN
-- Delete the edge
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.edge_data WHERE edge_id = ' || e1id;
+
EXECUTE sql;
-- Check if any of the edge nodes remains isolated,
@@ -6277,6 +6383,7 @@ BEGIN
|| e1rec.end_node || ') AND NOT EXISTS (SELECT edge_id FROM '
|| quote_ident(toponame)
|| '.edge_data WHERE start_node = n.node_id OR end_node = n.node_id)';
+
EXECUTE sql;
IF e1rec.right_face != e1rec.left_face THEN -- {
@@ -6286,6 +6393,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.left_face;
+
EXECUTE sql;
END IF;
@@ -6294,6 +6402,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.right_face;
+
EXECUTE sql;
END IF;
@@ -6451,6 +6560,7 @@ BEGIN
sql := sql || ' AND f.face_id = ' || aface;
END IF;
+
EXECUTE sql INTO containingface;
-- If aface was specified, check that it was correct
@@ -6484,6 +6594,7 @@ BEGIN
|| '::geometry,' || containingface
|| ' RETURNING node_id';
+
EXECUTE sql INTO nodeid;
RETURN nodeid;
@@ -6624,7 +6735,7 @@ LANGUAGE 'plpgsql' VOLATILE;
--} ST_RemoveIsoNode
--{
--- According to http://trac.osgeo.org/postgis/ticket/798
+-- According to http:
-- ST_RemoveIsoNode was renamed to ST_RemIsoNode in the final ISO
-- document
--
@@ -6826,6 +6937,7 @@ BEGIN
END LOOP;
+
--RAISE NOTICE 'EdgeId1 % EdgeId2 %', edgeid1, edgeid2;
--RAISE DEBUG 'oldedge.next_left_edge: %', oldedge.next_left_edge;
@@ -7111,6 +7223,7 @@ BEGIN
END LOOP;
+
--
-- Insert the new edge
--
@@ -7618,25 +7731,32 @@ BEGIN
tmp1 := ST_MakeLine(ST_EndPoint(oldedge.geom), ST_StartPoint(oldedge.geom));
+
tmp2 := ST_MakeLine(oldedge.geom, tmp1);
IF ST_NumPoints(tmp2) < 4 THEN
tmp2 := ST_AddPoint(tmp2, ST_StartPoint(oldedge.geom));
END IF;
+
tmp2 := ST_CollectionExtract(ST_MakeValid(ST_MakePolygon(tmp2)), 3);
+
range := ST_MakeLine(acurve, tmp1);
IF ST_NumPoints(range) < 4 THEN
range := ST_AddPoint(range, ST_StartPoint(oldedge.geom));
END IF;
+
range := ST_CollectionExtract(ST_MakeValid(ST_MakePolygon(range)), 3);
+
range := ST_SymDifference(range, tmp2);
+
sql := 'SELECT node_id, geom FROM '
|| quote_ident(atopology)
|| '.node WHERE ST_Contains('
|| quote_literal(range::text)
|| '::geometry, geom) LIMIT 1';
+
FOR rec IN EXECUTE sql LOOP -- {
RAISE EXCEPTION 'Edge motion collision at %', ST_AsText(rec.geom);
END LOOP; -- }
@@ -7652,11 +7772,13 @@ BEGIN
) as pre, NULL::integer[] as post
INTO STRICT snode_info;
+
SELECT topology._ST_AdjacentEdges(
atopology, oldedge.end_node, -anedge
) as pre, NULL::integer[] as post
INTO STRICT enode_info;
+
--}
--
@@ -7674,10 +7796,12 @@ BEGIN
atopology, oldedge.start_node, anedge
);
+
enode_info.post := topology._ST_AdjacentEdges(
atopology, oldedge.end_node, -anedge
);
+
IF snode_info.pre != snode_info.post THEN
RAISE EXCEPTION 'Edge changed disposition around start node %',
oldedge.start_node;
@@ -7754,6 +7878,7 @@ DECLARE
BEGIN
IF oface = 0 AND mbr_only THEN
+
RETURN NULL;
END IF;
@@ -7766,24 +7891,31 @@ BEGIN
INTO STRICT fan.newring_edges;
+
-- You can't get to the other side of an edge forming a ring
IF fan.newring_edges @> ARRAY[-anedge] THEN
+
RETURN 0;
END IF;
+
sql := 'WITH ids as ( select row_number() over () as seq, edge from unnest('
|| quote_literal(fan.newring_edges::text)
|| '::int[] ) u(edge) ), edges AS ( select CASE WHEN i.edge < 0 THEN ST_Reverse(e.geom) ELSE e.geom END as g FROM ids i left join '
|| quote_ident(atopology) || '.edge_data e ON(e.edge_id = abs(i.edge)) ORDER BY seq) SELECT ST_MakePolygon(ST_MakeLine(g.g)) FROM edges g;';
+
EXECUTE sql INTO fan.shell;
+
isccw := NOT ST_OrderingEquals(fan.shell, ST_ForceRHR(fan.shell));
+
IF oface = 0 THEN
IF NOT isccw THEN
+
RETURN NULL;
END IF;
END IF;
@@ -7795,6 +7927,7 @@ BEGIN
|| quote_ident(atopology) || '.face SET mbr = '
|| quote_literal(ST_Envelope(fan.shell)::text)
|| '::geometry WHERE face_id = ' || oface;
+
EXECUTE sql;
END IF; -- }
RETURN NULL;
@@ -7815,6 +7948,7 @@ BEGIN
END IF; -- }
-- Insert new face
+
EXECUTE sql INTO STRICT newface;
-- Update forward edges
@@ -7823,6 +7957,7 @@ BEGIN
|| ' WHERE left_face = ' || oface || ' AND edge_id = ANY ('
|| quote_literal(array( select +(x) from unnest(fan.newring_edges) u(x) )::text)
|| ')';
+
EXECUTE sql;
-- Update backward edges
@@ -7831,12 +7966,15 @@ BEGIN
|| ' WHERE right_face = ' || oface || ' AND edge_id = ANY ('
|| quote_literal(array( select -(x) from unnest(fan.newring_edges) u(x) )::text)
|| ')';
+
EXECUTE sql;
IF oface != 0 AND NOT isccw THEN -- {
-- face shrinked, must update all non-contained edges and nodes
+
ishole := true;
ELSE
+
ishole := false;
END IF; -- }
@@ -7858,6 +7996,7 @@ BEGIN
sql := sql || 'ST_Contains(' || quote_literal(fan.shell::text)
-- We only need to check a single point, but must not be an endpoint
|| '::geometry, ST_Line_Interpolate_Point(geom, 0.2))';
+
EXECUTE sql;
-- Update isolated nodes in new new face
@@ -7867,6 +8006,7 @@ BEGIN
|| ' AND ';
IF ishole THEN sql := sql || 'NOT '; END IF;
sql := sql || 'ST_Contains(' || quote_literal(fan.shell::text) || '::geometry, geom)';
+
EXECUTE sql;
RETURN newface;
@@ -7990,6 +8130,7 @@ BEGIN
|| ')'
LOOP
IF rec.containing_face IS NOT NULL THEN
+
IF newedge.left_face IS NULL THEN
newedge.left_face := rec.containing_face;
newedge.right_face := rec.containing_face;
@@ -8097,6 +8238,7 @@ BEGIN
-- Find links on start node -- {
+
sql :=
'SELECT edge_id, -1 AS end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8142,6 +8284,7 @@ BEGIN
END IF;
+
az = az - span.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8181,6 +8324,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN span.was_isolated = true; END IF;
ELSE
@@ -8197,12 +8341,16 @@ BEGIN
END IF;
+
+
+
-- } start_node analysis
-- Find links on end_node {
+
sql :=
'SELECT edge_id, -1 as end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8244,6 +8392,7 @@ BEGIN
END IF;
+
az := az - epan.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8283,6 +8432,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN epan.was_isolated = true; END IF;
ELSE
@@ -8301,6 +8451,9 @@ BEGIN
-- } end_node analysis
+
+
+
----------------------------------------------------------------------
--
-- If we don't have faces setup by now we must have encountered
@@ -8396,15 +8549,18 @@ BEGIN
--------------------------------------------
+
SELECT topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, false)
INTO newface;
IF newface = 0 THEN
+
RETURN newedge.edge_id;
END IF;
newfaces[1] := newface;
+
SELECT topology._ST_AddFaceSplit(atopology, newedge.edge_id, newedge.left_face, false)
INTO newface;
@@ -8427,6 +8583,7 @@ BEGIN
FOR rec IN EXECUTE sql
LOOP
+
-- Add reference to the other face
sql := 'INSERT INTO ' || quote_ident(atopology)
|| '.relation VALUES( ' || rec.topogeo_id
@@ -8564,6 +8721,7 @@ BEGIN
|| ')'
LOOP
IF rec.containing_face IS NOT NULL THEN
+
IF newedge.left_face IS NULL THEN
newedge.left_face := rec.containing_face;
newedge.right_face := rec.containing_face;
@@ -8669,6 +8827,7 @@ BEGIN
-- Find links on start node -- {
+
sql :=
'SELECT edge_id, -1 AS end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8714,6 +8873,7 @@ BEGIN
END IF;
+
az = az - span.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8753,6 +8913,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN span.was_isolated = true; END IF;
ELSE
@@ -8769,12 +8930,16 @@ BEGIN
END IF;
+
+
+
-- } start_node analysis
-- Find links on end_node {
+
sql :=
'SELECT edge_id, -1 as end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8816,6 +8981,7 @@ BEGIN
END IF;
+
az := az - epan.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8855,6 +9021,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN epan.was_isolated = true; END IF;
ELSE
@@ -8873,6 +9040,9 @@ BEGIN
-- } end_node analysis
+
+
+
----------------------------------------------------------------------
--
-- If we don't have faces setup by now we must have encountered
@@ -8967,20 +9137,25 @@ BEGIN
-- Check face splitting
--------------------------------------------
+
SELECT topology._ST_AddFaceSplit(atopology, newedge.edge_id, newedge.left_face, false)
INTO newface;
IF newface = 0 THEN
+
RETURN newedge.edge_id;
END IF;
IF newface IS NULL THEN -- must be forming a maximal ring in universal face
+
SELECT topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, false)
INTO newface;
ELSE
+
PERFORM topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, true);
END IF;
IF newface IS NULL THEN
+
RETURN newedge.edge_id;
END IF;
@@ -9004,6 +9179,7 @@ BEGIN
FOR rec IN EXECUTE sql
LOOP
+
-- Add reference to the other face
sql := 'INSERT INTO ' || quote_ident(atopology)
|| '.relation VALUES( ' || rec.topogeo_id
@@ -9134,6 +9310,7 @@ BEGIN
END; -- }
+
--
-- Node input linework with itself
--
@@ -9147,6 +9324,7 @@ BEGIN
) as linework INTO STRICT nodededges;
+
--
-- Linemerge the resulting edges, to reduce the working set
-- NOTE: this is more of a workaround for GEOS splitting overlapping
@@ -9156,6 +9334,7 @@ BEGIN
+
--
-- Collect input points and input lines endpoints
--
@@ -9169,6 +9348,7 @@ BEGIN
) as nodes INTO STRICT points;
+
--
-- Further split edges by points
-- TODO: optimize this adding ST_Split support for multiline/multipoint
@@ -9183,6 +9363,7 @@ BEGIN
SELECT ST_UnaryUnion(nodededges) INTO STRICT nodededges;
+
--
-- Collect all nodes (from points and noded linework endpoints)
--
@@ -9201,6 +9382,7 @@ BEGIN
) as endpoints INTO points;
+
--
-- Add all nodes as isolated so that
-- later calls to AddEdgeModFace will tweak their being
@@ -9231,11 +9413,12 @@ LANGUAGE 'plpgsql' VOLATILE;
--=} SQL/MM block
+
-- The following files needs getfaceedges_returntype, defined in sqlmm.sql
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 2012 Sandro Santilli <strk@keybit.net>
--
@@ -9245,7 +9428,7 @@ LANGUAGE 'plpgsql' VOLATILE;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -9312,10 +9495,11 @@ END
$$
LANGUAGE 'plpgsql' STABLE;
--} GetRingEdges
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2012 Sandro Santilli <strk@keybit.net>
--
@@ -9356,9 +9540,11 @@ BEGIN
|| ' UNION ALL SELECT -edge_id, ST_Azimuth(ST_EndPoint(geom), ST_PointN(geom, ST_NumPoints(geom)-1)) FROM incident_edges WHERE end_node = ' || anode
|| ' ORDER BY az';
+
FOR rec IN EXECUTE sql
LOOP -- incident edges {
+
n := n + 1;
retrec.sequence := n;
retrec.edge := rec.edge_id;
@@ -9370,11 +9556,12 @@ $$
LANGUAGE 'plpgsql' STABLE;
--} GetRingEdges
+
--general management --
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://www.postgis.org
+-- http:
--
-- Copyright (C) 2011 Regina Obe <lr@pcorp.us>
--
@@ -9413,6 +9600,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
--} AddToSearchPath
+
CREATE OR REPLACE FUNCTION postgis_topology_scripts_installed() RETURNS text
AS $$ SELECT '2.0.2'::text || ' r' || 10789::text AS version $$
LANGUAGE 'sql' IMMUTABLE;
diff --git a/gcc/postgis_extension/postgis_topology--2.0.2.sql b/gpp/postgis_extension/postgis_topology--2.0.2.sql
index d9212f5..fa0a20a 100644
--- a/gcc/postgis_extension/postgis_topology--2.0.2.sql
+++ b/gpp/postgis_extension/postgis_topology--2.0.2.sql
@@ -1,11 +1,9 @@
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: topology.sql.in.c 10643 2012-11-05 10:25:41Z strk $
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -204,6 +202,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-- Doing everything outside of a transaction helps
-- upgrading in the best case.
@@ -379,7 +394,9 @@ ALTER DOMAIN topology.TopoElement ADD
array_lower(VALUE, 1) = 1
);
ALTER DOMAIN topology.TopoElement DROP CONSTRAINT
+
IF EXISTS
+
type_range;
ALTER DOMAIN topology.TopoElement ADD
CONSTRAINT type_range CHECK (
@@ -675,6 +692,7 @@ BEGIN
-- corrupting the topology anyway ...
--
+
RETURN newlayer_id;
END;
$$
@@ -1018,6 +1036,7 @@ BEGIN
|| ') as obj ORDER BY obj';
+
-- TODO: why not using array_agg here ?
i = 1;
@@ -1415,7 +1434,7 @@ BEGIN
--
-- Closed lines have no boundary, so endpoint
-- intersection would be considered interior
- -- See http://trac.osgeo.org/postgis/ticket/770
+ -- See http:
-- See also full explanation in topology.AddEdge
--
@@ -1579,6 +1598,7 @@ BEGIN
END LOOP;
+
DROP TABLE face_check;
RETURN;
@@ -1808,7 +1828,7 @@ BEGIN
------- Indexes on left_face and right_face of edge_data
------- NOTE: these indexes speed up GetFaceGeometry (and thus
------- TopoGeometry::Geometry) by a factor of 10 !
- ------- See http://trac.osgeo.org/postgis/ticket/806
+ ------- See http:
EXECUTE 'CREATE INDEX edge_left_face_idx ON '
|| quote_ident(atopology)
|| '.edge_data (left_face);';
@@ -1819,7 +1839,7 @@ BEGIN
------- Indexes on start_node and end_node of edge_data
------- NOTE: this indexes speed up node deletion
------- by a factor of 1000 !
- ------- See http://trac.osgeo.org/postgis/ticket/2082
+ ------- See http:
EXECUTE 'CREATE INDEX edge_start_node_idx ON '
|| quote_ident(atopology)
|| '.edge_data (start_node);';
@@ -1927,7 +1947,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -2078,10 +2098,11 @@ $$
LANGUAGE 'plpgsql' STABLE STRICT;
--} TopologySummary
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -2178,11 +2199,12 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
--} TopologySummary
+
-- Spatial predicates
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011-2012 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -2696,11 +2718,12 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--} equals(TopoGeometry, TopoGeometry)
+
-- Querying
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -2786,10 +2809,11 @@ $$
LANGUAGE 'plpgsql' STABLE STRICT;
--} GetNodeByPoint
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -2877,10 +2901,11 @@ END
$$
LANGUAGE 'plpgsql' STABLE STRICT;
--} GetEdgeByPoint
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -3036,11 +3061,12 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--} GetFaceByPoint
+
-- Populating
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010-2012 Sandro Santilli <strk@keybit.net>
--
@@ -3061,7 +3087,7 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--
--
-- A pragmatic test conducted using algoritm shown here:
--- http://stackoverflow.com/questions/7408407/generate-next-largest-or-smallest-representable-floating-point-number-without-bi
+-- http:
-- showed the "tolerance" growing by an order of magnitude proportionally
-- with the order of magnitude of the input, starting with something like
-- 3.5527136788005009294e-15 for the starting value of 9.0
@@ -3117,7 +3143,7 @@ $$ LANGUAGE 'plpgsql' STABLE STRICT;
-- The newly added nodes have no containing face.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3185,6 +3211,7 @@ BEGIN
IF setContainingFace THEN
containing_face := topology.GetFaceByPoint(atopology, apoint, 0);
+
ELSE
containing_face := NULL;
END IF;
@@ -3244,7 +3271,7 @@ LANGUAGE 'sql' VOLATILE;
-- Calling code is expected to do further linking.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3333,6 +3360,7 @@ BEGIN
-- Reuse an EQUAL edge (be it closed or not)
IF ST_RelateMatch(rec.im, '1FFF*FFF2') THEN
+
RETURN rec.edge_id;
END IF;
@@ -3437,7 +3465,7 @@ LANGUAGE 'plpgsql' VOLATILE;
-- o The polygon overlaps an existing face.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3559,6 +3587,7 @@ BEGIN
ST_Line_Locate_Point(bounds, p2);
+
IF right_side THEN
right_edges := array_append(right_edges, rec.edge_id);
old_faceid = rec.right_face;
@@ -3585,6 +3614,8 @@ BEGIN
END IF;
+
+
--
-- Check that all edges found, taken togheter,
-- fully match the ring boundary and nothing more
@@ -3604,8 +3635,10 @@ BEGIN
IF faceid IS NOT NULL AND faceid != 0 THEN
IF NOT force_new THEN
+
RETURN faceid;
ELSE
+
END IF;
END IF;
@@ -3732,12 +3765,14 @@ BEGIN
|| tol || ') ORDER BY ST_Distance('
|| quote_literal(apoint::text)
|| '::geometry, a.geom) LIMIT 1;';
+
EXECUTE sql INTO id;
IF id IS NOT NULL THEN
RETURN id;
END IF;
+
-- 2. Check if any existing edge falls within tolerance
-- and if so split it by a point projected on it
sql := 'SELECT a.edge_id, a.geom FROM '
@@ -3747,35 +3782,42 @@ BEGIN
|| tol || ') ORDER BY ST_Distance('
|| quote_literal(apoint::text)
|| '::geometry, a.geom) LIMIT 1;';
+
EXECUTE sql INTO rec;
IF rec IS NOT NULL THEN
-- project point to line, split edge by point
prj := ST_ClosestPoint(rec.geom, apoint);
-- This is a workaround for ClosestPoint lack of Z support:
- -- http://trac.osgeo.org/postgis/ticket/2033
+ -- http:
z := ST_Z(apoint);
IF z IS NOT NULL THEN
prj := ST_Translate(ST_Force_3DZ(prj), 0, 0, z); -- no ST_SetZ ...
END IF;
+
IF NOT ST_Contains(rec.geom, prj) THEN
+
-- The tolerance must be big enough for snapping to happen
-- and small enough to snap only to the projected point.
-- Unfortunately ST_Distance returns 0 because it also uses
-- a projected point internally, so we need another way.
snaptol := topology._st_mintolerance(prj);
+
snapedge := ST_Snap(rec.geom, prj, snaptol);
-- Snapping currently snaps the first point below tolerance
-- so may possibly move first point. See ticket #1631
IF NOT ST_Equals(ST_StartPoint(rec.geom), ST_StartPoint(snapedge))
THEN
+
snapedge := ST_MakeLine(ST_StartPoint(rec.geom), snapedge);
END IF;
+
PERFORM ST_ChangeEdgeGeom(atopology, rec.edge_id, snapedge);
END IF;
id := topology.ST_ModEdgeSplit(atopology, rec.edge_id, prj);
ELSE
+
id := topology.ST_AddIsoNode(atopology, NULL, apoint);
END IF;
@@ -3821,6 +3863,7 @@ BEGIN
-- 1. Self-node
noded := ST_UnaryUnion(aline);
+
-- 2. Node to edges falling within tol distance
sql := 'WITH nearby AS ( SELECT e.geom FROM '
|| quote_ident(atopology)
@@ -3828,20 +3871,27 @@ BEGIN
|| quote_literal(noded::text)
|| '::geometry, '
|| tol || ') ) SELECT st_collect(geom) FROM nearby;';
+
EXECUTE sql INTO iedges;
IF iedges IS NOT NULL THEN
+
snapped := ST_Snap(noded, iedges, tol);
+
noded := ST_Difference(snapped, iedges);
+
set1 := ST_Intersection(snapped, iedges);
+
set2 := ST_LineMerge(set1);
+
noded := ST_Union(noded, set2);
+
END IF;
-- 2.1. Node with existing nodes within tol
@@ -3852,26 +3902,32 @@ BEGIN
|| quote_literal(noded::text)
|| '::geometry, '
|| tol || ') ) SELECT st_collect(geom) FROM nearby;';
+
EXECUTE sql INTO inodes;
IF inodes IS NOT NULL THEN -- {
+
-- TODO: consider snapping once against all elements
--- (rather than once with edges and once with nodes)
noded := ST_Snap(noded, inodes, tol);
+
FOR rec IN SELECT (ST_Dump(inodes)).*
LOOP
-- Use the node to split edges
SELECT ST_Collect(geom)
FROM ST_Dump(ST_Split(noded, rec.geom))
INTO STRICT noded;
+
END LOOP;
+
-- re-node to account for ST_Snap introduced self-intersections
- -- See http://trac.osgeo.org/postgis/ticket/1714
+ -- See http:
-- TODO: consider running UnaryUnion once after all noding
noded := ST_UnaryUnion(noded);
+
END IF; -- }
-- 3. For each (now-noded) segment, insert an edge
@@ -3880,14 +3936,17 @@ BEGIN
-- TODO: skip point elements ?
+
start_node := topology.TopoGeo_AddPoint(atopology,
ST_StartPoint(rec.geom),
tol);
+
end_node := topology.TopoGeo_AddPoint(atopology,
ST_EndPoint(rec.geom),
tol);
+
-- Added endpoints may have drifted due to tolerance, so
-- we need to re-snap the edge to the new nodes before adding it
sql := 'SELECT n1.geom as sn, n2.geom as en FROM ' || quote_ident(atopology)
@@ -3895,6 +3954,7 @@ BEGIN
|| '.node n2 WHERE n1.node_id = '
|| start_node || ' AND n2.node_id = ' || end_node;
+
EXECUTE sql INTO STRICT rec2;
snapped := ST_SetPoint(
@@ -3905,8 +3965,10 @@ BEGIN
snapped := ST_CollectionExtract(ST_MakeValid(snapped), 2);
+
-- Check if the so-snapped edge collapsed (see #1650)
IF ST_IsEmpty(snapped) THEN
+
CONTINUE;
END IF;
@@ -3914,11 +3976,14 @@ BEGIN
sql := 'SELECT edge_id FROM ' || quote_ident(atopology)
|| '.edge_data WHERE ST_Equals(geom, ' || quote_literal(snapped::text)
|| '::geometry)';
+
EXECUTE sql INTO id;
IF id IS NULL THEN
id := topology.ST_AddEdgeModFace(atopology, start_node, end_node,
snapped);
+
ELSE
+
END IF;
RETURN NEXT id;
@@ -3960,9 +4025,11 @@ BEGIN
-- 1. Extract boundary
boundary := ST_Boundary(apoly);
+
-- 2. Add boundaries as edges
FOR rec IN SELECT (ST_Dump(boundary)).geom LOOP
edges := array_cat(edges, array_agg(x)) FROM ( select topology.TopoGeo_addLinestring(atopology, rec.geom, tol) as x ) as foo;
+
END LOOP;
-- 3. Find faces covered by input polygon
@@ -3971,10 +4038,12 @@ BEGIN
|| '.face f WHERE f.mbr && '
|| quote_literal(apoly::text)
|| '::geometry';
+
FOR rec IN EXECUTE sql LOOP
-- check for actual containment
fgeom := ST_PointOnSurface(ST_GetFaceGeometry(atopology, rec.face_id));
IF NOT ST_Covers(apoly, fgeom) THEN
+
CONTINUE;
END IF;
RETURN NEXT rec.face_id;
@@ -4000,10 +4069,11 @@ END
$$
LANGUAGE 'plpgsql';
--} TopoGeo_AddGeometry
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4052,11 +4122,12 @@ $$
LANGUAGE 'plpgsql';
--} Polygonize(toponame)
+
-- TopoElement
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4070,7 +4141,7 @@ LANGUAGE 'plpgsql';
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -4112,11 +4183,12 @@ CREATE AGGREGATE topology.TopoElementArray_agg(
);
--} TopoElementArray_agg
+
-- TopoGeometry
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4172,10 +4244,11 @@ $$
$$
LANGUAGE 'sql' STABLE STRICT;
-- }
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011-2012 Sandro Santilli <strk@keybit.net>
--
@@ -4187,7 +4260,7 @@ LANGUAGE 'sql' STABLE STRICT;
-- {
-- Convert a simple geometry to a topologically-defined one
--
--- See http://trac.osgeo.org/postgis/ticket/1017
+-- See http:
--
-- }{
CREATE OR REPLACE FUNCTION topology.toTopoGeom(ageom Geometry, atopology varchar, alayer int, atolerance float8 DEFAULT 0)
@@ -4312,6 +4385,7 @@ BEGIN
|| '.relation(topogeo_id, layer_id, element_type, element_id) VALUES ('
|| rec.id || ',' || rec.lyr || ',' || rec.type
|| ',' || rec.primitive || ')';
+
EXECUTE sql;
END LOOP;
@@ -4322,11 +4396,12 @@ $$
LANGUAGE 'plpgsql' VOLATILE STRICT;
-- }
+
-- GML
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4340,7 +4415,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -4887,13 +4962,14 @@ $$ LANGUAGE 'sql' STABLE; -- does NOT write into visited table
-- } AsGML(TopoGeometry)
+
--=} POSTGIS-SPECIFIC block
-- SQL/MM block
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011, 2012 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -4999,6 +5075,7 @@ BEGIN
LOOP
+
retrec.sequence = n;
retrec.edge = rec.edge_id;
@@ -5297,6 +5374,7 @@ BEGIN
|| ' AND l.layer_id = r.layer_id AND abs(r.element_id) = '
|| e1id
;
+
EXECUTE sql;
@@ -5645,6 +5723,7 @@ BEGIN
|| 'WHERE l.level = 0 AND l.feature_type = 2 '
|| ' AND l.topology_id = ' || topoid
|| ' AND abs(r.element_id) = ' || e1id ;
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented dropping edge %',
rec.topogeo_id, rec.layer_id,
@@ -5669,6 +5748,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge < 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -5686,6 +5766,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge > 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -5701,6 +5782,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge < 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -5718,6 +5800,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge > 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -5763,6 +5846,7 @@ BEGIN
END IF; -- }
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented healing faces % and %',
rec.topogeo_id, rec.layer_id,
@@ -5805,6 +5889,7 @@ BEGIN
|| '.face WHERE face_id IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
END IF; -- }
@@ -5815,6 +5900,7 @@ BEGIN
|| ' WHERE left_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update right_face for all edges still referencing old faces
@@ -5823,6 +5909,7 @@ BEGIN
|| ' WHERE right_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update containing_face for all nodes still referencing old faces
@@ -5831,6 +5918,7 @@ BEGIN
|| ' WHERE containing_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- NOT IN THE SPECS:
@@ -5843,6 +5931,7 @@ BEGIN
|| ' AND l.topology_id = ' || topoid
|| ' AND l.layer_id = r.layer_id AND abs(r.element_id) = '
|| e1rec.left_face;
+
EXECUTE sql;
sql := 'UPDATE ' || quote_ident(toponame)
|| '.relation r '
@@ -5851,6 +5940,7 @@ BEGIN
|| ' AND l.topology_id = ' || topoid
|| ' AND l.layer_id = r.layer_id AND r.element_id = '
|| e1rec.right_face;
+
EXECUTE sql;
END IF; -- } two faces healed...
@@ -5858,6 +5948,7 @@ BEGIN
-- Delete the edge
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.edge_data WHERE edge_id = ' || e1id;
+
EXECUTE sql;
-- Check if any of the edge nodes remains isolated,
@@ -5869,6 +5960,7 @@ BEGIN
|| e1rec.end_node || ') AND NOT EXISTS (SELECT edge_id FROM '
|| quote_ident(toponame)
|| '.edge_data WHERE start_node = n.node_id OR end_node = n.node_id)';
+
EXECUTE sql;
IF e1rec.right_face != e1rec.left_face THEN -- {
@@ -5877,6 +5969,7 @@ BEGIN
IF e1rec.left_face != 0 THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.left_face;
+
EXECUTE sql;
END IF;
@@ -5885,6 +5978,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.right_face;
+
EXECUTE sql;
END IF;
@@ -5969,6 +6063,7 @@ BEGIN
|| 'WHERE l.level = 0 AND l.feature_type = 2 '
|| ' AND l.topology_id = ' || topoid
|| ' AND abs(r.element_id) = ' || e1id ;
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented dropping edge %',
rec.topogeo_id, rec.layer_id,
@@ -5993,6 +6088,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge < 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -6010,6 +6106,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge > 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -6025,6 +6122,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge < 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -6042,6 +6140,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge > 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -6085,6 +6184,7 @@ BEGIN
END IF; -- }
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented healing faces % and %',
rec.topogeo_id, rec.layer_id,
@@ -6117,6 +6217,7 @@ BEGIN
|| '.face WHERE face_id IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ') ) WHERE face_id = ' || floodfaceid ;
+
EXECUTE sql;
END IF; -- }
@@ -6127,6 +6228,7 @@ BEGIN
|| ' WHERE left_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update right_face for all edges still referencing old faces
@@ -6135,6 +6237,7 @@ BEGIN
|| ' WHERE right_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update containing_face for all nodes still referencing old faces
@@ -6143,6 +6246,7 @@ BEGIN
|| ' WHERE containing_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- NOT IN THE SPECS:
@@ -6157,6 +6261,7 @@ BEGIN
|| e1rec.left_face || ',' || e1rec.right_face
|| ') AND abs(r.element_id) != '
|| floodfaceid; -- could be optimized..
+
EXECUTE sql;
END IF; -- } two faces healed...
@@ -6164,6 +6269,7 @@ BEGIN
-- Delete the edge
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.edge_data WHERE edge_id = ' || e1id;
+
EXECUTE sql;
-- Check if any of the edge nodes remains isolated,
@@ -6175,6 +6281,7 @@ BEGIN
|| e1rec.end_node || ') AND NOT EXISTS (SELECT edge_id FROM '
|| quote_ident(toponame)
|| '.edge_data WHERE start_node = n.node_id OR end_node = n.node_id)';
+
EXECUTE sql;
IF e1rec.right_face != e1rec.left_face THEN -- {
@@ -6184,6 +6291,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.left_face;
+
EXECUTE sql;
END IF;
@@ -6192,6 +6300,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.right_face;
+
EXECUTE sql;
END IF;
@@ -6349,6 +6458,7 @@ BEGIN
sql := sql || ' AND f.face_id = ' || aface;
END IF;
+
EXECUTE sql INTO containingface;
-- If aface was specified, check that it was correct
@@ -6382,6 +6492,7 @@ BEGIN
|| '::geometry,' || containingface
|| ' RETURNING node_id';
+
EXECUTE sql INTO nodeid;
RETURN nodeid;
@@ -6522,7 +6633,7 @@ LANGUAGE 'plpgsql' VOLATILE;
--} ST_RemoveIsoNode
--{
--- According to http://trac.osgeo.org/postgis/ticket/798
+-- According to http:
-- ST_RemoveIsoNode was renamed to ST_RemIsoNode in the final ISO
-- document
--
@@ -6724,6 +6835,7 @@ BEGIN
END LOOP;
+
--RAISE NOTICE 'EdgeId1 % EdgeId2 %', edgeid1, edgeid2;
--RAISE DEBUG 'oldedge.next_left_edge: %', oldedge.next_left_edge;
@@ -7009,6 +7121,7 @@ BEGIN
END LOOP;
+
--
-- Insert the new edge
--
@@ -7516,25 +7629,32 @@ BEGIN
tmp1 := ST_MakeLine(ST_EndPoint(oldedge.geom), ST_StartPoint(oldedge.geom));
+
tmp2 := ST_MakeLine(oldedge.geom, tmp1);
IF ST_NumPoints(tmp2) < 4 THEN
tmp2 := ST_AddPoint(tmp2, ST_StartPoint(oldedge.geom));
END IF;
+
tmp2 := ST_CollectionExtract(ST_MakeValid(ST_MakePolygon(tmp2)), 3);
+
range := ST_MakeLine(acurve, tmp1);
IF ST_NumPoints(range) < 4 THEN
range := ST_AddPoint(range, ST_StartPoint(oldedge.geom));
END IF;
+
range := ST_CollectionExtract(ST_MakeValid(ST_MakePolygon(range)), 3);
+
range := ST_SymDifference(range, tmp2);
+
sql := 'SELECT node_id, geom FROM '
|| quote_ident(atopology)
|| '.node WHERE ST_Contains('
|| quote_literal(range::text)
|| '::geometry, geom) LIMIT 1';
+
FOR rec IN EXECUTE sql LOOP -- {
RAISE EXCEPTION 'Edge motion collision at %', ST_AsText(rec.geom);
END LOOP; -- }
@@ -7550,11 +7670,13 @@ BEGIN
) as pre, NULL::integer[] as post
INTO STRICT snode_info;
+
SELECT topology._ST_AdjacentEdges(
atopology, oldedge.end_node, -anedge
) as pre, NULL::integer[] as post
INTO STRICT enode_info;
+
--}
--
@@ -7572,10 +7694,12 @@ BEGIN
atopology, oldedge.start_node, anedge
);
+
enode_info.post := topology._ST_AdjacentEdges(
atopology, oldedge.end_node, -anedge
);
+
IF snode_info.pre != snode_info.post THEN
RAISE EXCEPTION 'Edge changed disposition around start node %',
oldedge.start_node;
@@ -7652,6 +7776,7 @@ DECLARE
BEGIN
IF oface = 0 AND mbr_only THEN
+
RETURN NULL;
END IF;
@@ -7664,24 +7789,31 @@ BEGIN
INTO STRICT fan.newring_edges;
+
-- You can't get to the other side of an edge forming a ring
IF fan.newring_edges @> ARRAY[-anedge] THEN
+
RETURN 0;
END IF;
+
sql := 'WITH ids as ( select row_number() over () as seq, edge from unnest('
|| quote_literal(fan.newring_edges::text)
|| '::int[] ) u(edge) ), edges AS ( select CASE WHEN i.edge < 0 THEN ST_Reverse(e.geom) ELSE e.geom END as g FROM ids i left join '
|| quote_ident(atopology) || '.edge_data e ON(e.edge_id = abs(i.edge)) ORDER BY seq) SELECT ST_MakePolygon(ST_MakeLine(g.g)) FROM edges g;';
+
EXECUTE sql INTO fan.shell;
+
isccw := NOT ST_OrderingEquals(fan.shell, ST_ForceRHR(fan.shell));
+
IF oface = 0 THEN
IF NOT isccw THEN
+
RETURN NULL;
END IF;
END IF;
@@ -7693,6 +7825,7 @@ BEGIN
|| quote_ident(atopology) || '.face SET mbr = '
|| quote_literal(ST_Envelope(fan.shell)::text)
|| '::geometry WHERE face_id = ' || oface;
+
EXECUTE sql;
END IF; -- }
RETURN NULL;
@@ -7713,6 +7846,7 @@ BEGIN
END IF; -- }
-- Insert new face
+
EXECUTE sql INTO STRICT newface;
-- Update forward edges
@@ -7721,6 +7855,7 @@ BEGIN
|| ' WHERE left_face = ' || oface || ' AND edge_id = ANY ('
|| quote_literal(array( select +(x) from unnest(fan.newring_edges) u(x) )::text)
|| ')';
+
EXECUTE sql;
-- Update backward edges
@@ -7729,12 +7864,15 @@ BEGIN
|| ' WHERE right_face = ' || oface || ' AND edge_id = ANY ('
|| quote_literal(array( select -(x) from unnest(fan.newring_edges) u(x) )::text)
|| ')';
+
EXECUTE sql;
IF oface != 0 AND NOT isccw THEN -- {
-- face shrinked, must update all non-contained edges and nodes
+
ishole := true;
ELSE
+
ishole := false;
END IF; -- }
@@ -7756,6 +7894,7 @@ BEGIN
sql := sql || 'ST_Contains(' || quote_literal(fan.shell::text)
-- We only need to check a single point, but must not be an endpoint
|| '::geometry, ST_Line_Interpolate_Point(geom, 0.2))';
+
EXECUTE sql;
-- Update isolated nodes in new new face
@@ -7765,6 +7904,7 @@ BEGIN
|| ' AND ';
IF ishole THEN sql := sql || 'NOT '; END IF;
sql := sql || 'ST_Contains(' || quote_literal(fan.shell::text) || '::geometry, geom)';
+
EXECUTE sql;
RETURN newface;
@@ -7888,6 +8028,7 @@ BEGIN
|| ')'
LOOP
IF rec.containing_face IS NOT NULL THEN
+
IF newedge.left_face IS NULL THEN
newedge.left_face := rec.containing_face;
newedge.right_face := rec.containing_face;
@@ -7995,6 +8136,7 @@ BEGIN
-- Find links on start node -- {
+
sql :=
'SELECT edge_id, -1 AS end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8040,6 +8182,7 @@ BEGIN
END IF;
+
az = az - span.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8079,6 +8222,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN span.was_isolated = true; END IF;
ELSE
@@ -8095,12 +8239,16 @@ BEGIN
END IF;
+
+
+
-- } start_node analysis
-- Find links on end_node {
+
sql :=
'SELECT edge_id, -1 as end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8142,6 +8290,7 @@ BEGIN
END IF;
+
az := az - epan.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8181,6 +8330,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN epan.was_isolated = true; END IF;
ELSE
@@ -8199,6 +8349,9 @@ BEGIN
-- } end_node analysis
+
+
+
----------------------------------------------------------------------
--
-- If we don't have faces setup by now we must have encountered
@@ -8294,15 +8447,18 @@ BEGIN
--------------------------------------------
+
SELECT topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, false)
INTO newface;
IF newface = 0 THEN
+
RETURN newedge.edge_id;
END IF;
newfaces[1] := newface;
+
SELECT topology._ST_AddFaceSplit(atopology, newedge.edge_id, newedge.left_face, false)
INTO newface;
@@ -8325,6 +8481,7 @@ BEGIN
FOR rec IN EXECUTE sql
LOOP
+
-- Add reference to the other face
sql := 'INSERT INTO ' || quote_ident(atopology)
|| '.relation VALUES( ' || rec.topogeo_id
@@ -8462,6 +8619,7 @@ BEGIN
|| ')'
LOOP
IF rec.containing_face IS NOT NULL THEN
+
IF newedge.left_face IS NULL THEN
newedge.left_face := rec.containing_face;
newedge.right_face := rec.containing_face;
@@ -8567,6 +8725,7 @@ BEGIN
-- Find links on start node -- {
+
sql :=
'SELECT edge_id, -1 AS end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8612,6 +8771,7 @@ BEGIN
END IF;
+
az = az - span.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8651,6 +8811,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN span.was_isolated = true; END IF;
ELSE
@@ -8667,12 +8828,16 @@ BEGIN
END IF;
+
+
+
-- } start_node analysis
-- Find links on end_node {
+
sql :=
'SELECT edge_id, -1 as end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8714,6 +8879,7 @@ BEGIN
END IF;
+
az := az - epan.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8753,6 +8919,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN epan.was_isolated = true; END IF;
ELSE
@@ -8771,6 +8938,9 @@ BEGIN
-- } end_node analysis
+
+
+
----------------------------------------------------------------------
--
-- If we don't have faces setup by now we must have encountered
@@ -8865,20 +9035,25 @@ BEGIN
-- Check face splitting
--------------------------------------------
+
SELECT topology._ST_AddFaceSplit(atopology, newedge.edge_id, newedge.left_face, false)
INTO newface;
IF newface = 0 THEN
+
RETURN newedge.edge_id;
END IF;
IF newface IS NULL THEN -- must be forming a maximal ring in universal face
+
SELECT topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, false)
INTO newface;
ELSE
+
PERFORM topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, true);
END IF;
IF newface IS NULL THEN
+
RETURN newedge.edge_id;
END IF;
@@ -8902,6 +9077,7 @@ BEGIN
FOR rec IN EXECUTE sql
LOOP
+
-- Add reference to the other face
sql := 'INSERT INTO ' || quote_ident(atopology)
|| '.relation VALUES( ' || rec.topogeo_id
@@ -9032,6 +9208,7 @@ BEGIN
END; -- }
+
--
-- Node input linework with itself
--
@@ -9045,6 +9222,7 @@ BEGIN
) as linework INTO STRICT nodededges;
+
--
-- Linemerge the resulting edges, to reduce the working set
-- NOTE: this is more of a workaround for GEOS splitting overlapping
@@ -9054,6 +9232,7 @@ BEGIN
+
--
-- Collect input points and input lines endpoints
--
@@ -9067,6 +9246,7 @@ BEGIN
) as nodes INTO STRICT points;
+
--
-- Further split edges by points
-- TODO: optimize this adding ST_Split support for multiline/multipoint
@@ -9081,6 +9261,7 @@ BEGIN
SELECT ST_UnaryUnion(nodededges) INTO STRICT nodededges;
+
--
-- Collect all nodes (from points and noded linework endpoints)
--
@@ -9099,6 +9280,7 @@ BEGIN
) as endpoints INTO points;
+
--
-- Add all nodes as isolated so that
-- later calls to AddEdgeModFace will tweak their being
@@ -9129,11 +9311,12 @@ LANGUAGE 'plpgsql' VOLATILE;
--=} SQL/MM block
+
-- The following files needs getfaceedges_returntype, defined in sqlmm.sql
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 2012 Sandro Santilli <strk@keybit.net>
--
@@ -9143,7 +9326,7 @@ LANGUAGE 'plpgsql' VOLATILE;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -9210,10 +9393,11 @@ END
$$
LANGUAGE 'plpgsql' STABLE;
--} GetRingEdges
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2012 Sandro Santilli <strk@keybit.net>
--
@@ -9254,9 +9438,11 @@ BEGIN
|| ' UNION ALL SELECT -edge_id, ST_Azimuth(ST_EndPoint(geom), ST_PointN(geom, ST_NumPoints(geom)-1)) FROM incident_edges WHERE end_node = ' || anode
|| ' ORDER BY az';
+
FOR rec IN EXECUTE sql
LOOP -- incident edges {
+
n := n + 1;
retrec.sequence := n;
retrec.edge := rec.edge_id;
@@ -9268,11 +9454,12 @@ $$
LANGUAGE 'plpgsql' STABLE;
--} GetRingEdges
+
--general management --
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://www.postgis.org
+-- http:
--
-- Copyright (C) 2011 Regina Obe <lr@pcorp.us>
--
@@ -9311,6 +9498,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
--} AddToSearchPath
+
CREATE OR REPLACE FUNCTION postgis_topology_scripts_installed() RETURNS text
AS $$ SELECT '2.0.2'::text || ' r' || 10789::text AS version $$
LANGUAGE 'sql' IMMUTABLE;
diff --git a/gcc/postgis_share/legacy.sql b/gpp/postgis_share/legacy.sql
index 234e916..529ea00 100644
--- a/gcc/postgis_share/legacy.sql
+++ b/gpp/postgis_share/legacy.sql
@@ -1,5 +1,3 @@
-
-
-- $Id: legacy.sql.in.c 9735 2012-05-16 08:29:14Z robe $
-- Legacy functions without chip functions --
-- This is the full list including the legacy_minimal.sql (minimal)
@@ -33,6 +31,10 @@
+
+
+
+
-- Deprecation in 1.2.3
CREATE OR REPLACE FUNCTION AsBinary(geometry)
RETURNS bytea
@@ -105,6 +107,7 @@ CREATE OR REPLACE FUNCTION ST_AsText(bytea)
AS
$$ SELECT ST_AsText($1::geometry);$$
LANGUAGE 'sql' IMMUTABLE STRICT;
+
--- start functions that in theory should never have been used or internal like stuff deprecated
-- these were superceded by PostGIS_AddBBOX , PostGIS_DropBBOX, PostGIS_HasBBOX in 1.5 --
@@ -375,9 +378,6 @@ DECLARE
BEGIN
-
-
-
RETURN 'This function is obsolete now that geometry_columns is a view';
END
diff --git a/gcc/postgis_share/legacy_minimal.sql b/gpp/postgis_share/legacy_minimal.sql
index 436ef53..4014863 100644
--- a/gcc/postgis_share/legacy_minimal.sql
+++ b/gpp/postgis_share/legacy_minimal.sql
@@ -1,5 +1,3 @@
-
-
-- $Id: legacy_minimal.sql.in.c 10736 2012-11-25 22:17:48Z robe $
-- Bare minimum Legacy functions --
-- This file that contains what we have determined are
diff --git a/gcc/postgis_share/postgis.sql b/gpp/postgis_share/postgis.sql
index 8c8aa23..0b9a9fb 100644
--- a/gcc/postgis_share/postgis.sql
+++ b/gpp/postgis_share/postgis.sql
@@ -1,11 +1,9 @@
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: postgis.sql.in.c 9900 2012-06-12 13:04:49Z strk $
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
-- Copyright 2001-2003 Refractions Research Inc.
--
-- This is free software; you can redistribute and/or modify it under
@@ -34,6 +32,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
SET client_min_messages TO warning;
-- INSTALL VERSION: 2.0.2
@@ -442,6 +455,7 @@ CREATE OR REPLACE FUNCTION geometry_distance_box(geom1 geometry, geom2 geometry)
AS '$libdir/postgis-2.0' ,'gserialized_distance_box_2d'
LANGUAGE 'c' IMMUTABLE STRICT;
+
CREATE OPERATOR <-> (
LEFTARG = geometry, RIGHTARG = geometry, PROCEDURE = geometry_distance_centroid,
COMMUTATOR = '<->'
@@ -452,6 +466,7 @@ CREATE OPERATOR <#> (
COMMUTATOR = '<#>'
);
+
-- Availability: 2.0.0
CREATE OR REPLACE FUNCTION geometry_contains(geom1 geometry, geom2 geometry)
RETURNS bool
@@ -588,9 +603,11 @@ CREATE OPERATOR CLASS gist_geometry_ops_2d
OPERATOR 10 <<| ,
OPERATOR 11 |>> ,
OPERATOR 12 |&> ,
+
OPERATOR 13 <-> FOR ORDER BY pg_catalog.float_ops,
OPERATOR 14 <#> FOR ORDER BY pg_catalog.float_ops,
FUNCTION 8 geometry_gist_distance_2d (internal, geometry, int4),
+
FUNCTION 1 geometry_gist_consistent_2d (internal, geometry, int4),
FUNCTION 2 geometry_gist_union_2d (bytea, internal),
FUNCTION 3 geometry_gist_compress_2d (internal),
@@ -2349,7 +2366,7 @@ CREATE OR REPLACE FUNCTION postgis_libxml_version() RETURNS text
LANGUAGE 'c' IMMUTABLE;
CREATE OR REPLACE FUNCTION postgis_scripts_build_date() RETURNS text
- AS 'SELECT ''2012-12-05 22:40:44''::text AS version'
+ AS 'SELECT ''2012-12-05 23:21:55''::text AS version'
LANGUAGE 'sql' IMMUTABLE;
CREATE OR REPLACE FUNCTION postgis_lib_build_date() RETURNS text
@@ -4263,7 +4280,7 @@ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
-- $Id: long_xact.sql.in.c 9735 2012-05-16 08:29:14Z robe $
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
-- Copyright 2001-2003 Refractions Research Inc.
--
-- This is free software; you can redistribute and/or modify it under
@@ -4274,6 +4291,10 @@ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
+
+
+
+
-----------------------------------------------------------------------
-- LONG TERM LOCKING
-----------------------------------------------------------------------
@@ -4584,6 +4605,7 @@ LANGUAGE 'plpgsql';
-- END
---------------------------------------------------------------
+
---------------------------------------------------------------------------
-- $Id: geography.sql.in.c 9900 2012-06-12 13:04:49Z strk $
--
@@ -5303,6 +5325,7 @@ CREATE OR REPLACE FUNCTION ST_Summary(geography)
+
-- Availability: 1.2.2
CREATE OR REPLACE FUNCTION ST_distance_sphere(geom1 geometry, geom2 geometry)
RETURNS FLOAT8
diff --git a/gcc/postgis_share/postgis_upgrade_20_minor.sql b/gpp/postgis_share/postgis_upgrade_20_minor.sql
index 3f363e2..6e1ec1d 100644
--- a/gcc/postgis_share/postgis_upgrade_20_minor.sql
+++ b/gpp/postgis_share/postgis_upgrade_20_minor.sql
@@ -1469,7 +1469,7 @@ CREATE OR REPLACE FUNCTION postgis_libxml_version() RETURNS text
AS '$libdir/postgis-2.0'
LANGUAGE 'c' IMMUTABLE;
CREATE OR REPLACE FUNCTION postgis_scripts_build_date() RETURNS text
- AS 'SELECT ''2012-12-05 22:40:44''::text AS version'
+ AS 'SELECT ''2012-12-05 23:21:55''::text AS version'
LANGUAGE 'sql' IMMUTABLE;
CREATE OR REPLACE FUNCTION postgis_lib_build_date() RETURNS text
AS '$libdir/postgis-2.0'
diff --git a/gcc/postgis_share/rtpostgis.sql b/gpp/postgis_share/rtpostgis.sql
index 84e8241..78dcf6e 100644
--- a/gcc/postgis_share/rtpostgis.sql
+++ b/gpp/postgis_share/rtpostgis.sql
@@ -1,10 +1,8 @@
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
--
-- PostGIS Raster - Raster Type for PostGIS
--- http://trac.osgeo.org/postgis/wiki/WKTRaster
+-- http:
--
-- Copyright (c) 2009-2012 Sandro Santilli <strk@keybit.net>
-- Copyright (c) 2009-2010 Pierre Racine <pierre.racine@sbf.ulaval.ca>
@@ -34,6 +32,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
SET client_min_messages TO warning;
BEGIN;
@@ -4754,7 +4769,7 @@ CREATE OR REPLACE FUNCTION DropRasterConstraints (
-- raster_columns
--
-- The metadata is documented in the PostGIS Raster specification:
--- http://trac.osgeo.org/postgis/wiki/WKTRaster/SpecificationFinal01
+-- http:
------------------------------------------------------------------------------
CREATE OR REPLACE VIEW raster_columns AS
diff --git a/gcc/postgis_share/rtpostgis_legacy.sql b/gpp/postgis_share/rtpostgis_legacy.sql
index 842357d..5c4ced9 100644
--- a/gcc/postgis_share/rtpostgis_legacy.sql
+++ b/gpp/postgis_share/rtpostgis_legacy.sql
@@ -1,11 +1,9 @@
-
-
-------------------------------------------------------------------------------
--
-- $Id: rtpostgis_legacy.sql.in.c 9324 2012-02-27 22:08:12Z pramsey $
--
-- PostGIS Raster - Raster Type for PostGIS
--- http://trac.osgeo.org/postgis/wiki/WKTRaster
+-- http:
--
-- Copyright (C) 2012 Regents of the University of California
-- <bkpark@ucdavis.edu>
diff --git a/gcc/postgis_share/rtpostgis_upgrade_20_minor.sql b/gpp/postgis_share/rtpostgis_upgrade_20_minor.sql
index 14e0db9..754f1a8 100644
--- a/gcc/postgis_share/rtpostgis_upgrade_20_minor.sql
+++ b/gpp/postgis_share/rtpostgis_upgrade_20_minor.sql
@@ -1,11 +1,9 @@
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: rtpostgis_drop.sql.in.c 7884 2011-09-22 15:07:25Z robe $
--
-- PostGIS Raster - Raster Type for PostGIS
--- http://trac.osgeo.org/postgis/wiki/WKTRaster
+-- http:
--
-- Copyright (C) 2011 Regina Obe <lr@pcorp.us>
-- Copyright (C) 2011 Regents of the University of California
@@ -327,14 +325,12 @@ DROP FUNCTION IF EXISTS st_intersection(raster, integer, raster, integer, text,
DROP FUNCTION IF EXISTS st_intersection(raster, integer, raster, integer, regprocedure);
DROP FUNCTION IF EXISTS st_intersection(raster, raster, text, regprocedure);
DROP FUNCTION IF EXISTS st_intersection(raster, raster, regprocedure);
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: rtpostgis_upgrade.sql.in.c 8448 2011-12-16 22:07:26Z dustymugs $
--
-- PostGIS Raster - Raster Type for PostGIS
--- http://trac.osgeo.org/postgis/wiki/WKTRaster
+-- http:
--
-- Copyright (c) 2011 Regina Obe <lr@pcorp.us>
-- Copyright (C) 2011 Regents of the University of California
@@ -368,6 +364,23 @@ DROP FUNCTION IF EXISTS st_intersection(raster, raster, regprocedure);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-- drop st_bytea
DROP CAST IF EXISTS (raster AS bytea);
DROP FUNCTION IF EXISTS st_bytea(raster);
@@ -384,6 +397,7 @@ DROP CAST IF EXISTS (raster AS box2d);
DROP FUNCTION IF EXISTS box2d(raster);
-- create box3d cast if it does not exist
+
-- If we are running 9.0+ we can use DO plpgsql to check
-- and only create if not exists so no need to force a drop
-- that way if people are using it, we will not mess them up
@@ -403,17 +417,17 @@ BEGIN
END IF;
END$$;
+
+
-- make geometry cast ASSIGNMENT
DROP CAST IF EXISTS (raster AS geometry);
CREATE CAST (raster AS geometry)
WITH FUNCTION st_convexhull(raster) AS ASSIGNMENT;
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
--
-- PostGIS Raster - Raster Type for PostGIS
--- http://trac.osgeo.org/postgis/wiki/WKTRaster
+-- http:
--
-- Copyright (c) 2009-2012 Sandro Santilli <strk@keybit.net>
-- Copyright (c) 2009-2010 Pierre Racine <pierre.racine@sbf.ulaval.ca>
@@ -443,6 +457,23 @@ CREATE CAST (raster AS geometry)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
SET client_min_messages TO warning;
BEGIN;
@@ -5063,7 +5094,7 @@ CREATE OR REPLACE FUNCTION DropRasterConstraints (
-- raster_columns
--
-- The metadata is documented in the PostGIS Raster specification:
--- http://trac.osgeo.org/postgis/wiki/WKTRaster/SpecificationFinal01
+-- http:
------------------------------------------------------------------------------
CREATE OR REPLACE VIEW raster_columns AS
diff --git a/gcc/postgis_share/topology.sql b/gpp/postgis_share/topology.sql
index 6112c12..67c59bf 100644
--- a/gcc/postgis_share/topology.sql
+++ b/gpp/postgis_share/topology.sql
@@ -1,11 +1,9 @@
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: topology.sql.in.c 10643 2012-11-05 10:25:41Z strk $
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -203,6 +201,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
CREATE SCHEMA topology;
-- Doing everything outside of a transaction helps
@@ -380,7 +395,9 @@ ALTER DOMAIN topology.TopoElement ADD
array_lower(VALUE, 1) = 1
);
ALTER DOMAIN topology.TopoElement DROP CONSTRAINT
+
IF EXISTS
+
type_range;
ALTER DOMAIN topology.TopoElement ADD
CONSTRAINT type_range CHECK (
@@ -676,6 +693,7 @@ BEGIN
-- corrupting the topology anyway ...
--
+
RETURN newlayer_id;
END;
$$
@@ -1019,6 +1037,7 @@ BEGIN
|| ') as obj ORDER BY obj';
+
-- TODO: why not using array_agg here ?
i = 1;
@@ -1416,7 +1435,7 @@ BEGIN
--
-- Closed lines have no boundary, so endpoint
-- intersection would be considered interior
- -- See http://trac.osgeo.org/postgis/ticket/770
+ -- See http:
-- See also full explanation in topology.AddEdge
--
@@ -1580,6 +1599,7 @@ BEGIN
END LOOP;
+
DROP TABLE face_check;
RETURN;
@@ -1809,7 +1829,7 @@ BEGIN
------- Indexes on left_face and right_face of edge_data
------- NOTE: these indexes speed up GetFaceGeometry (and thus
------- TopoGeometry::Geometry) by a factor of 10 !
- ------- See http://trac.osgeo.org/postgis/ticket/806
+ ------- See http:
EXECUTE 'CREATE INDEX edge_left_face_idx ON '
|| quote_ident(atopology)
|| '.edge_data (left_face);';
@@ -1820,7 +1840,7 @@ BEGIN
------- Indexes on start_node and end_node of edge_data
------- NOTE: this indexes speed up node deletion
------- by a factor of 1000 !
- ------- See http://trac.osgeo.org/postgis/ticket/2082
+ ------- See http:
EXECUTE 'CREATE INDEX edge_start_node_idx ON '
|| quote_ident(atopology)
|| '.edge_data (start_node);';
@@ -1928,7 +1948,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -2079,10 +2099,11 @@ $$
LANGUAGE 'plpgsql' STABLE STRICT;
--} TopologySummary
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -2179,11 +2200,12 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
--} TopologySummary
+
-- Spatial predicates
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011-2012 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -2697,11 +2719,12 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--} equals(TopoGeometry, TopoGeometry)
+
-- Querying
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -2787,10 +2810,11 @@ $$
LANGUAGE 'plpgsql' STABLE STRICT;
--} GetNodeByPoint
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -2878,10 +2902,11 @@ END
$$
LANGUAGE 'plpgsql' STABLE STRICT;
--} GetEdgeByPoint
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -3037,11 +3062,12 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--} GetFaceByPoint
+
-- Populating
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010-2012 Sandro Santilli <strk@keybit.net>
--
@@ -3062,7 +3088,7 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--
--
-- A pragmatic test conducted using algoritm shown here:
--- http://stackoverflow.com/questions/7408407/generate-next-largest-or-smallest-representable-floating-point-number-without-bi
+-- http:
-- showed the "tolerance" growing by an order of magnitude proportionally
-- with the order of magnitude of the input, starting with something like
-- 3.5527136788005009294e-15 for the starting value of 9.0
@@ -3118,7 +3144,7 @@ $$ LANGUAGE 'plpgsql' STABLE STRICT;
-- The newly added nodes have no containing face.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3186,6 +3212,7 @@ BEGIN
IF setContainingFace THEN
containing_face := topology.GetFaceByPoint(atopology, apoint, 0);
+
ELSE
containing_face := NULL;
END IF;
@@ -3245,7 +3272,7 @@ LANGUAGE 'sql' VOLATILE;
-- Calling code is expected to do further linking.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3334,6 +3361,7 @@ BEGIN
-- Reuse an EQUAL edge (be it closed or not)
IF ST_RelateMatch(rec.im, '1FFF*FFF2') THEN
+
RETURN rec.edge_id;
END IF;
@@ -3438,7 +3466,7 @@ LANGUAGE 'plpgsql' VOLATILE;
-- o The polygon overlaps an existing face.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3560,6 +3588,7 @@ BEGIN
ST_Line_Locate_Point(bounds, p2);
+
IF right_side THEN
right_edges := array_append(right_edges, rec.edge_id);
old_faceid = rec.right_face;
@@ -3586,6 +3615,8 @@ BEGIN
END IF;
+
+
--
-- Check that all edges found, taken togheter,
-- fully match the ring boundary and nothing more
@@ -3605,8 +3636,10 @@ BEGIN
IF faceid IS NOT NULL AND faceid != 0 THEN
IF NOT force_new THEN
+
RETURN faceid;
ELSE
+
END IF;
END IF;
@@ -3733,12 +3766,14 @@ BEGIN
|| tol || ') ORDER BY ST_Distance('
|| quote_literal(apoint::text)
|| '::geometry, a.geom) LIMIT 1;';
+
EXECUTE sql INTO id;
IF id IS NOT NULL THEN
RETURN id;
END IF;
+
-- 2. Check if any existing edge falls within tolerance
-- and if so split it by a point projected on it
sql := 'SELECT a.edge_id, a.geom FROM '
@@ -3748,35 +3783,42 @@ BEGIN
|| tol || ') ORDER BY ST_Distance('
|| quote_literal(apoint::text)
|| '::geometry, a.geom) LIMIT 1;';
+
EXECUTE sql INTO rec;
IF rec IS NOT NULL THEN
-- project point to line, split edge by point
prj := ST_ClosestPoint(rec.geom, apoint);
-- This is a workaround for ClosestPoint lack of Z support:
- -- http://trac.osgeo.org/postgis/ticket/2033
+ -- http:
z := ST_Z(apoint);
IF z IS NOT NULL THEN
prj := ST_Translate(ST_Force_3DZ(prj), 0, 0, z); -- no ST_SetZ ...
END IF;
+
IF NOT ST_Contains(rec.geom, prj) THEN
+
-- The tolerance must be big enough for snapping to happen
-- and small enough to snap only to the projected point.
-- Unfortunately ST_Distance returns 0 because it also uses
-- a projected point internally, so we need another way.
snaptol := topology._st_mintolerance(prj);
+
snapedge := ST_Snap(rec.geom, prj, snaptol);
-- Snapping currently snaps the first point below tolerance
-- so may possibly move first point. See ticket #1631
IF NOT ST_Equals(ST_StartPoint(rec.geom), ST_StartPoint(snapedge))
THEN
+
snapedge := ST_MakeLine(ST_StartPoint(rec.geom), snapedge);
END IF;
+
PERFORM ST_ChangeEdgeGeom(atopology, rec.edge_id, snapedge);
END IF;
id := topology.ST_ModEdgeSplit(atopology, rec.edge_id, prj);
ELSE
+
id := topology.ST_AddIsoNode(atopology, NULL, apoint);
END IF;
@@ -3822,6 +3864,7 @@ BEGIN
-- 1. Self-node
noded := ST_UnaryUnion(aline);
+
-- 2. Node to edges falling within tol distance
sql := 'WITH nearby AS ( SELECT e.geom FROM '
|| quote_ident(atopology)
@@ -3829,20 +3872,27 @@ BEGIN
|| quote_literal(noded::text)
|| '::geometry, '
|| tol || ') ) SELECT st_collect(geom) FROM nearby;';
+
EXECUTE sql INTO iedges;
IF iedges IS NOT NULL THEN
+
snapped := ST_Snap(noded, iedges, tol);
+
noded := ST_Difference(snapped, iedges);
+
set1 := ST_Intersection(snapped, iedges);
+
set2 := ST_LineMerge(set1);
+
noded := ST_Union(noded, set2);
+
END IF;
-- 2.1. Node with existing nodes within tol
@@ -3853,26 +3903,32 @@ BEGIN
|| quote_literal(noded::text)
|| '::geometry, '
|| tol || ') ) SELECT st_collect(geom) FROM nearby;';
+
EXECUTE sql INTO inodes;
IF inodes IS NOT NULL THEN -- {
+
-- TODO: consider snapping once against all elements
--- (rather than once with edges and once with nodes)
noded := ST_Snap(noded, inodes, tol);
+
FOR rec IN SELECT (ST_Dump(inodes)).*
LOOP
-- Use the node to split edges
SELECT ST_Collect(geom)
FROM ST_Dump(ST_Split(noded, rec.geom))
INTO STRICT noded;
+
END LOOP;
+
-- re-node to account for ST_Snap introduced self-intersections
- -- See http://trac.osgeo.org/postgis/ticket/1714
+ -- See http:
-- TODO: consider running UnaryUnion once after all noding
noded := ST_UnaryUnion(noded);
+
END IF; -- }
-- 3. For each (now-noded) segment, insert an edge
@@ -3881,14 +3937,17 @@ BEGIN
-- TODO: skip point elements ?
+
start_node := topology.TopoGeo_AddPoint(atopology,
ST_StartPoint(rec.geom),
tol);
+
end_node := topology.TopoGeo_AddPoint(atopology,
ST_EndPoint(rec.geom),
tol);
+
-- Added endpoints may have drifted due to tolerance, so
-- we need to re-snap the edge to the new nodes before adding it
sql := 'SELECT n1.geom as sn, n2.geom as en FROM ' || quote_ident(atopology)
@@ -3896,6 +3955,7 @@ BEGIN
|| '.node n2 WHERE n1.node_id = '
|| start_node || ' AND n2.node_id = ' || end_node;
+
EXECUTE sql INTO STRICT rec2;
snapped := ST_SetPoint(
@@ -3906,8 +3966,10 @@ BEGIN
snapped := ST_CollectionExtract(ST_MakeValid(snapped), 2);
+
-- Check if the so-snapped edge collapsed (see #1650)
IF ST_IsEmpty(snapped) THEN
+
CONTINUE;
END IF;
@@ -3915,11 +3977,14 @@ BEGIN
sql := 'SELECT edge_id FROM ' || quote_ident(atopology)
|| '.edge_data WHERE ST_Equals(geom, ' || quote_literal(snapped::text)
|| '::geometry)';
+
EXECUTE sql INTO id;
IF id IS NULL THEN
id := topology.ST_AddEdgeModFace(atopology, start_node, end_node,
snapped);
+
ELSE
+
END IF;
RETURN NEXT id;
@@ -3961,9 +4026,11 @@ BEGIN
-- 1. Extract boundary
boundary := ST_Boundary(apoly);
+
-- 2. Add boundaries as edges
FOR rec IN SELECT (ST_Dump(boundary)).geom LOOP
edges := array_cat(edges, array_agg(x)) FROM ( select topology.TopoGeo_addLinestring(atopology, rec.geom, tol) as x ) as foo;
+
END LOOP;
-- 3. Find faces covered by input polygon
@@ -3972,10 +4039,12 @@ BEGIN
|| '.face f WHERE f.mbr && '
|| quote_literal(apoly::text)
|| '::geometry';
+
FOR rec IN EXECUTE sql LOOP
-- check for actual containment
fgeom := ST_PointOnSurface(ST_GetFaceGeometry(atopology, rec.face_id));
IF NOT ST_Covers(apoly, fgeom) THEN
+
CONTINUE;
END IF;
RETURN NEXT rec.face_id;
@@ -4001,10 +4070,11 @@ END
$$
LANGUAGE 'plpgsql';
--} TopoGeo_AddGeometry
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4053,11 +4123,12 @@ $$
LANGUAGE 'plpgsql';
--} Polygonize(toponame)
+
-- TopoElement
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4071,7 +4142,7 @@ LANGUAGE 'plpgsql';
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -4113,11 +4184,12 @@ CREATE AGGREGATE topology.TopoElementArray_agg(
);
--} TopoElementArray_agg
+
-- TopoGeometry
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4173,10 +4245,11 @@ $$
$$
LANGUAGE 'sql' STABLE STRICT;
-- }
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011-2012 Sandro Santilli <strk@keybit.net>
--
@@ -4188,7 +4261,7 @@ LANGUAGE 'sql' STABLE STRICT;
-- {
-- Convert a simple geometry to a topologically-defined one
--
--- See http://trac.osgeo.org/postgis/ticket/1017
+-- See http:
--
-- }{
CREATE OR REPLACE FUNCTION topology.toTopoGeom(ageom Geometry, atopology varchar, alayer int, atolerance float8 DEFAULT 0)
@@ -4313,6 +4386,7 @@ BEGIN
|| '.relation(topogeo_id, layer_id, element_type, element_id) VALUES ('
|| rec.id || ',' || rec.lyr || ',' || rec.type
|| ',' || rec.primitive || ')';
+
EXECUTE sql;
END LOOP;
@@ -4323,11 +4397,12 @@ $$
LANGUAGE 'plpgsql' VOLATILE STRICT;
-- }
+
-- GML
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4341,7 +4416,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -4888,13 +4963,14 @@ $$ LANGUAGE 'sql' STABLE; -- does NOT write into visited table
-- } AsGML(TopoGeometry)
+
--=} POSTGIS-SPECIFIC block
-- SQL/MM block
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011, 2012 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -5000,6 +5076,7 @@ BEGIN
LOOP
+
retrec.sequence = n;
retrec.edge = rec.edge_id;
@@ -5298,6 +5375,7 @@ BEGIN
|| ' AND l.layer_id = r.layer_id AND abs(r.element_id) = '
|| e1id
;
+
EXECUTE sql;
@@ -5646,6 +5724,7 @@ BEGIN
|| 'WHERE l.level = 0 AND l.feature_type = 2 '
|| ' AND l.topology_id = ' || topoid
|| ' AND abs(r.element_id) = ' || e1id ;
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented dropping edge %',
rec.topogeo_id, rec.layer_id,
@@ -5670,6 +5749,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge < 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -5687,6 +5767,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge > 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -5702,6 +5783,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge < 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -5719,6 +5801,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge > 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -5764,6 +5847,7 @@ BEGIN
END IF; -- }
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented healing faces % and %',
rec.topogeo_id, rec.layer_id,
@@ -5806,6 +5890,7 @@ BEGIN
|| '.face WHERE face_id IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
END IF; -- }
@@ -5816,6 +5901,7 @@ BEGIN
|| ' WHERE left_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update right_face for all edges still referencing old faces
@@ -5824,6 +5910,7 @@ BEGIN
|| ' WHERE right_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update containing_face for all nodes still referencing old faces
@@ -5832,6 +5919,7 @@ BEGIN
|| ' WHERE containing_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- NOT IN THE SPECS:
@@ -5844,6 +5932,7 @@ BEGIN
|| ' AND l.topology_id = ' || topoid
|| ' AND l.layer_id = r.layer_id AND abs(r.element_id) = '
|| e1rec.left_face;
+
EXECUTE sql;
sql := 'UPDATE ' || quote_ident(toponame)
|| '.relation r '
@@ -5852,6 +5941,7 @@ BEGIN
|| ' AND l.topology_id = ' || topoid
|| ' AND l.layer_id = r.layer_id AND r.element_id = '
|| e1rec.right_face;
+
EXECUTE sql;
END IF; -- } two faces healed...
@@ -5859,6 +5949,7 @@ BEGIN
-- Delete the edge
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.edge_data WHERE edge_id = ' || e1id;
+
EXECUTE sql;
-- Check if any of the edge nodes remains isolated,
@@ -5870,6 +5961,7 @@ BEGIN
|| e1rec.end_node || ') AND NOT EXISTS (SELECT edge_id FROM '
|| quote_ident(toponame)
|| '.edge_data WHERE start_node = n.node_id OR end_node = n.node_id)';
+
EXECUTE sql;
IF e1rec.right_face != e1rec.left_face THEN -- {
@@ -5878,6 +5970,7 @@ BEGIN
IF e1rec.left_face != 0 THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.left_face;
+
EXECUTE sql;
END IF;
@@ -5886,6 +5979,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.right_face;
+
EXECUTE sql;
END IF;
@@ -5970,6 +6064,7 @@ BEGIN
|| 'WHERE l.level = 0 AND l.feature_type = 2 '
|| ' AND l.topology_id = ' || topoid
|| ' AND abs(r.element_id) = ' || e1id ;
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented dropping edge %',
rec.topogeo_id, rec.layer_id,
@@ -5994,6 +6089,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge < 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -6011,6 +6107,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge > 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -6026,6 +6123,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge < 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -6043,6 +6141,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge > 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -6086,6 +6185,7 @@ BEGIN
END IF; -- }
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented healing faces % and %',
rec.topogeo_id, rec.layer_id,
@@ -6118,6 +6218,7 @@ BEGIN
|| '.face WHERE face_id IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ') ) WHERE face_id = ' || floodfaceid ;
+
EXECUTE sql;
END IF; -- }
@@ -6128,6 +6229,7 @@ BEGIN
|| ' WHERE left_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update right_face for all edges still referencing old faces
@@ -6136,6 +6238,7 @@ BEGIN
|| ' WHERE right_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update containing_face for all nodes still referencing old faces
@@ -6144,6 +6247,7 @@ BEGIN
|| ' WHERE containing_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- NOT IN THE SPECS:
@@ -6158,6 +6262,7 @@ BEGIN
|| e1rec.left_face || ',' || e1rec.right_face
|| ') AND abs(r.element_id) != '
|| floodfaceid; -- could be optimized..
+
EXECUTE sql;
END IF; -- } two faces healed...
@@ -6165,6 +6270,7 @@ BEGIN
-- Delete the edge
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.edge_data WHERE edge_id = ' || e1id;
+
EXECUTE sql;
-- Check if any of the edge nodes remains isolated,
@@ -6176,6 +6282,7 @@ BEGIN
|| e1rec.end_node || ') AND NOT EXISTS (SELECT edge_id FROM '
|| quote_ident(toponame)
|| '.edge_data WHERE start_node = n.node_id OR end_node = n.node_id)';
+
EXECUTE sql;
IF e1rec.right_face != e1rec.left_face THEN -- {
@@ -6185,6 +6292,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.left_face;
+
EXECUTE sql;
END IF;
@@ -6193,6 +6301,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.right_face;
+
EXECUTE sql;
END IF;
@@ -6350,6 +6459,7 @@ BEGIN
sql := sql || ' AND f.face_id = ' || aface;
END IF;
+
EXECUTE sql INTO containingface;
-- If aface was specified, check that it was correct
@@ -6383,6 +6493,7 @@ BEGIN
|| '::geometry,' || containingface
|| ' RETURNING node_id';
+
EXECUTE sql INTO nodeid;
RETURN nodeid;
@@ -6523,7 +6634,7 @@ LANGUAGE 'plpgsql' VOLATILE;
--} ST_RemoveIsoNode
--{
--- According to http://trac.osgeo.org/postgis/ticket/798
+-- According to http:
-- ST_RemoveIsoNode was renamed to ST_RemIsoNode in the final ISO
-- document
--
@@ -6725,6 +6836,7 @@ BEGIN
END LOOP;
+
--RAISE NOTICE 'EdgeId1 % EdgeId2 %', edgeid1, edgeid2;
--RAISE DEBUG 'oldedge.next_left_edge: %', oldedge.next_left_edge;
@@ -7010,6 +7122,7 @@ BEGIN
END LOOP;
+
--
-- Insert the new edge
--
@@ -7517,25 +7630,32 @@ BEGIN
tmp1 := ST_MakeLine(ST_EndPoint(oldedge.geom), ST_StartPoint(oldedge.geom));
+
tmp2 := ST_MakeLine(oldedge.geom, tmp1);
IF ST_NumPoints(tmp2) < 4 THEN
tmp2 := ST_AddPoint(tmp2, ST_StartPoint(oldedge.geom));
END IF;
+
tmp2 := ST_CollectionExtract(ST_MakeValid(ST_MakePolygon(tmp2)), 3);
+
range := ST_MakeLine(acurve, tmp1);
IF ST_NumPoints(range) < 4 THEN
range := ST_AddPoint(range, ST_StartPoint(oldedge.geom));
END IF;
+
range := ST_CollectionExtract(ST_MakeValid(ST_MakePolygon(range)), 3);
+
range := ST_SymDifference(range, tmp2);
+
sql := 'SELECT node_id, geom FROM '
|| quote_ident(atopology)
|| '.node WHERE ST_Contains('
|| quote_literal(range::text)
|| '::geometry, geom) LIMIT 1';
+
FOR rec IN EXECUTE sql LOOP -- {
RAISE EXCEPTION 'Edge motion collision at %', ST_AsText(rec.geom);
END LOOP; -- }
@@ -7551,11 +7671,13 @@ BEGIN
) as pre, NULL::integer[] as post
INTO STRICT snode_info;
+
SELECT topology._ST_AdjacentEdges(
atopology, oldedge.end_node, -anedge
) as pre, NULL::integer[] as post
INTO STRICT enode_info;
+
--}
--
@@ -7573,10 +7695,12 @@ BEGIN
atopology, oldedge.start_node, anedge
);
+
enode_info.post := topology._ST_AdjacentEdges(
atopology, oldedge.end_node, -anedge
);
+
IF snode_info.pre != snode_info.post THEN
RAISE EXCEPTION 'Edge changed disposition around start node %',
oldedge.start_node;
@@ -7653,6 +7777,7 @@ DECLARE
BEGIN
IF oface = 0 AND mbr_only THEN
+
RETURN NULL;
END IF;
@@ -7665,24 +7790,31 @@ BEGIN
INTO STRICT fan.newring_edges;
+
-- You can't get to the other side of an edge forming a ring
IF fan.newring_edges @> ARRAY[-anedge] THEN
+
RETURN 0;
END IF;
+
sql := 'WITH ids as ( select row_number() over () as seq, edge from unnest('
|| quote_literal(fan.newring_edges::text)
|| '::int[] ) u(edge) ), edges AS ( select CASE WHEN i.edge < 0 THEN ST_Reverse(e.geom) ELSE e.geom END as g FROM ids i left join '
|| quote_ident(atopology) || '.edge_data e ON(e.edge_id = abs(i.edge)) ORDER BY seq) SELECT ST_MakePolygon(ST_MakeLine(g.g)) FROM edges g;';
+
EXECUTE sql INTO fan.shell;
+
isccw := NOT ST_OrderingEquals(fan.shell, ST_ForceRHR(fan.shell));
+
IF oface = 0 THEN
IF NOT isccw THEN
+
RETURN NULL;
END IF;
END IF;
@@ -7694,6 +7826,7 @@ BEGIN
|| quote_ident(atopology) || '.face SET mbr = '
|| quote_literal(ST_Envelope(fan.shell)::text)
|| '::geometry WHERE face_id = ' || oface;
+
EXECUTE sql;
END IF; -- }
RETURN NULL;
@@ -7714,6 +7847,7 @@ BEGIN
END IF; -- }
-- Insert new face
+
EXECUTE sql INTO STRICT newface;
-- Update forward edges
@@ -7722,6 +7856,7 @@ BEGIN
|| ' WHERE left_face = ' || oface || ' AND edge_id = ANY ('
|| quote_literal(array( select +(x) from unnest(fan.newring_edges) u(x) )::text)
|| ')';
+
EXECUTE sql;
-- Update backward edges
@@ -7730,12 +7865,15 @@ BEGIN
|| ' WHERE right_face = ' || oface || ' AND edge_id = ANY ('
|| quote_literal(array( select -(x) from unnest(fan.newring_edges) u(x) )::text)
|| ')';
+
EXECUTE sql;
IF oface != 0 AND NOT isccw THEN -- {
-- face shrinked, must update all non-contained edges and nodes
+
ishole := true;
ELSE
+
ishole := false;
END IF; -- }
@@ -7757,6 +7895,7 @@ BEGIN
sql := sql || 'ST_Contains(' || quote_literal(fan.shell::text)
-- We only need to check a single point, but must not be an endpoint
|| '::geometry, ST_Line_Interpolate_Point(geom, 0.2))';
+
EXECUTE sql;
-- Update isolated nodes in new new face
@@ -7766,6 +7905,7 @@ BEGIN
|| ' AND ';
IF ishole THEN sql := sql || 'NOT '; END IF;
sql := sql || 'ST_Contains(' || quote_literal(fan.shell::text) || '::geometry, geom)';
+
EXECUTE sql;
RETURN newface;
@@ -7889,6 +8029,7 @@ BEGIN
|| ')'
LOOP
IF rec.containing_face IS NOT NULL THEN
+
IF newedge.left_face IS NULL THEN
newedge.left_face := rec.containing_face;
newedge.right_face := rec.containing_face;
@@ -7996,6 +8137,7 @@ BEGIN
-- Find links on start node -- {
+
sql :=
'SELECT edge_id, -1 AS end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8041,6 +8183,7 @@ BEGIN
END IF;
+
az = az - span.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8080,6 +8223,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN span.was_isolated = true; END IF;
ELSE
@@ -8096,12 +8240,16 @@ BEGIN
END IF;
+
+
+
-- } start_node analysis
-- Find links on end_node {
+
sql :=
'SELECT edge_id, -1 as end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8143,6 +8291,7 @@ BEGIN
END IF;
+
az := az - epan.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8182,6 +8331,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN epan.was_isolated = true; END IF;
ELSE
@@ -8200,6 +8350,9 @@ BEGIN
-- } end_node analysis
+
+
+
----------------------------------------------------------------------
--
-- If we don't have faces setup by now we must have encountered
@@ -8295,15 +8448,18 @@ BEGIN
--------------------------------------------
+
SELECT topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, false)
INTO newface;
IF newface = 0 THEN
+
RETURN newedge.edge_id;
END IF;
newfaces[1] := newface;
+
SELECT topology._ST_AddFaceSplit(atopology, newedge.edge_id, newedge.left_face, false)
INTO newface;
@@ -8326,6 +8482,7 @@ BEGIN
FOR rec IN EXECUTE sql
LOOP
+
-- Add reference to the other face
sql := 'INSERT INTO ' || quote_ident(atopology)
|| '.relation VALUES( ' || rec.topogeo_id
@@ -8463,6 +8620,7 @@ BEGIN
|| ')'
LOOP
IF rec.containing_face IS NOT NULL THEN
+
IF newedge.left_face IS NULL THEN
newedge.left_face := rec.containing_face;
newedge.right_face := rec.containing_face;
@@ -8568,6 +8726,7 @@ BEGIN
-- Find links on start node -- {
+
sql :=
'SELECT edge_id, -1 AS end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8613,6 +8772,7 @@ BEGIN
END IF;
+
az = az - span.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8652,6 +8812,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN span.was_isolated = true; END IF;
ELSE
@@ -8668,12 +8829,16 @@ BEGIN
END IF;
+
+
+
-- } start_node analysis
-- Find links on end_node {
+
sql :=
'SELECT edge_id, -1 as end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8715,6 +8880,7 @@ BEGIN
END IF;
+
az := az - epan.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8754,6 +8920,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN epan.was_isolated = true; END IF;
ELSE
@@ -8772,6 +8939,9 @@ BEGIN
-- } end_node analysis
+
+
+
----------------------------------------------------------------------
--
-- If we don't have faces setup by now we must have encountered
@@ -8866,20 +9036,25 @@ BEGIN
-- Check face splitting
--------------------------------------------
+
SELECT topology._ST_AddFaceSplit(atopology, newedge.edge_id, newedge.left_face, false)
INTO newface;
IF newface = 0 THEN
+
RETURN newedge.edge_id;
END IF;
IF newface IS NULL THEN -- must be forming a maximal ring in universal face
+
SELECT topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, false)
INTO newface;
ELSE
+
PERFORM topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, true);
END IF;
IF newface IS NULL THEN
+
RETURN newedge.edge_id;
END IF;
@@ -8903,6 +9078,7 @@ BEGIN
FOR rec IN EXECUTE sql
LOOP
+
-- Add reference to the other face
sql := 'INSERT INTO ' || quote_ident(atopology)
|| '.relation VALUES( ' || rec.topogeo_id
@@ -9033,6 +9209,7 @@ BEGIN
END; -- }
+
--
-- Node input linework with itself
--
@@ -9046,6 +9223,7 @@ BEGIN
) as linework INTO STRICT nodededges;
+
--
-- Linemerge the resulting edges, to reduce the working set
-- NOTE: this is more of a workaround for GEOS splitting overlapping
@@ -9055,6 +9233,7 @@ BEGIN
+
--
-- Collect input points and input lines endpoints
--
@@ -9068,6 +9247,7 @@ BEGIN
) as nodes INTO STRICT points;
+
--
-- Further split edges by points
-- TODO: optimize this adding ST_Split support for multiline/multipoint
@@ -9082,6 +9262,7 @@ BEGIN
SELECT ST_UnaryUnion(nodededges) INTO STRICT nodededges;
+
--
-- Collect all nodes (from points and noded linework endpoints)
--
@@ -9100,6 +9281,7 @@ BEGIN
) as endpoints INTO points;
+
--
-- Add all nodes as isolated so that
-- later calls to AddEdgeModFace will tweak their being
@@ -9130,11 +9312,12 @@ LANGUAGE 'plpgsql' VOLATILE;
--=} SQL/MM block
+
-- The following files needs getfaceedges_returntype, defined in sqlmm.sql
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 2012 Sandro Santilli <strk@keybit.net>
--
@@ -9144,7 +9327,7 @@ LANGUAGE 'plpgsql' VOLATILE;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -9211,10 +9394,11 @@ END
$$
LANGUAGE 'plpgsql' STABLE;
--} GetRingEdges
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2012 Sandro Santilli <strk@keybit.net>
--
@@ -9255,9 +9439,11 @@ BEGIN
|| ' UNION ALL SELECT -edge_id, ST_Azimuth(ST_EndPoint(geom), ST_PointN(geom, ST_NumPoints(geom)-1)) FROM incident_edges WHERE end_node = ' || anode
|| ' ORDER BY az';
+
FOR rec IN EXECUTE sql
LOOP -- incident edges {
+
n := n + 1;
retrec.sequence := n;
retrec.edge := rec.edge_id;
@@ -9269,11 +9455,12 @@ $$
LANGUAGE 'plpgsql' STABLE;
--} GetRingEdges
+
--general management --
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://www.postgis.org
+-- http:
--
-- Copyright (C) 2011 Regina Obe <lr@pcorp.us>
--
@@ -9312,6 +9499,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
--} AddToSearchPath
+
CREATE OR REPLACE FUNCTION postgis_topology_scripts_installed() RETURNS text
AS $$ SELECT '2.0.2'::text || ' r' || 10789::text AS version $$
LANGUAGE 'sql' IMMUTABLE;
diff --git a/gcc/postgis_share/topology_upgrade_20_minor.sql b/gpp/postgis_share/topology_upgrade_20_minor.sql
index 31b5a1e..5c6d043 100644
--- a/gcc/postgis_share/topology_upgrade_20_minor.sql
+++ b/gpp/postgis_share/topology_upgrade_20_minor.sql
@@ -1,8 +1,6 @@
-
-
-- $Id: topology_drop_before.sql.in.c 9324 2012-02-27 22:08:12Z pramsey $
-- PostGIS - Spatial Types for PostgreSQL
--- http://www.postgis.org
+-- http:
--
-- Copyright (C) 2012 Regina Obe <lr@pcorp.us>
-- This is free software; you can redistribute and/or modify it under
@@ -17,14 +15,12 @@
-- I don't think too many people installed the bad name
DROP FUNCTION IF EXISTS topology.toTopoGeom(Geometry, varchar, int, float8);
-
-
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- $Id: topology.sql.in.c 10643 2012-11-05 10:25:41Z strk $
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -224,6 +220,23 @@ DROP FUNCTION IF EXISTS topology.toTopoGeom(Geometry, varchar, int, float8);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-- Doing everything outside of a transaction helps
-- upgrading in the best case.
BEGIN;
@@ -649,6 +662,7 @@ BEGIN
-- corrupting the topology anyway ...
--
+
RETURN newlayer_id;
END;
$$
@@ -992,6 +1006,7 @@ BEGIN
|| ') as obj ORDER BY obj';
+
-- TODO: why not using array_agg here ?
i = 1;
@@ -1389,7 +1404,7 @@ BEGIN
--
-- Closed lines have no boundary, so endpoint
-- intersection would be considered interior
- -- See http://trac.osgeo.org/postgis/ticket/770
+ -- See http:
-- See also full explanation in topology.AddEdge
--
@@ -1553,6 +1568,7 @@ BEGIN
END LOOP;
+
DROP TABLE face_check;
RETURN;
@@ -1782,7 +1798,7 @@ BEGIN
------- Indexes on left_face and right_face of edge_data
------- NOTE: these indexes speed up GetFaceGeometry (and thus
------- TopoGeometry::Geometry) by a factor of 10 !
- ------- See http://trac.osgeo.org/postgis/ticket/806
+ ------- See http:
EXECUTE 'CREATE INDEX edge_left_face_idx ON '
|| quote_ident(atopology)
|| '.edge_data (left_face);';
@@ -1793,7 +1809,7 @@ BEGIN
------- Indexes on start_node and end_node of edge_data
------- NOTE: this indexes speed up node deletion
------- by a factor of 1000 !
- ------- See http://trac.osgeo.org/postgis/ticket/2082
+ ------- See http:
EXECUTE 'CREATE INDEX edge_start_node_idx ON '
|| quote_ident(atopology)
|| '.edge_data (start_node);';
@@ -1901,7 +1917,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -2052,10 +2068,11 @@ $$
LANGUAGE 'plpgsql' STABLE STRICT;
--} TopologySummary
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -2152,11 +2169,12 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
--} TopologySummary
+
-- Spatial predicates
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011-2012 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -2670,11 +2688,12 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--} equals(TopoGeometry, TopoGeometry)
+
-- Querying
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -2760,10 +2779,11 @@ $$
LANGUAGE 'plpgsql' STABLE STRICT;
--} GetNodeByPoint
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -2851,10 +2871,11 @@ END
$$
LANGUAGE 'plpgsql' STABLE STRICT;
--} GetEdgeByPoint
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Andrea Peri <aperi2007@gmail.com>
--
@@ -3010,11 +3031,12 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--} GetFaceByPoint
+
-- Populating
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010-2012 Sandro Santilli <strk@keybit.net>
--
@@ -3035,7 +3057,7 @@ LANGUAGE 'plpgsql' STABLE STRICT;
--
--
-- A pragmatic test conducted using algoritm shown here:
--- http://stackoverflow.com/questions/7408407/generate-next-largest-or-smallest-representable-floating-point-number-without-bi
+-- http:
-- showed the "tolerance" growing by an order of magnitude proportionally
-- with the order of magnitude of the input, starting with something like
-- 3.5527136788005009294e-15 for the starting value of 9.0
@@ -3091,7 +3113,7 @@ $$ LANGUAGE 'plpgsql' STABLE STRICT;
-- The newly added nodes have no containing face.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3159,6 +3181,7 @@ BEGIN
IF setContainingFace THEN
containing_face := topology.GetFaceByPoint(atopology, apoint, 0);
+
ELSE
containing_face := NULL;
END IF;
@@ -3218,7 +3241,7 @@ LANGUAGE 'sql' VOLATILE;
-- Calling code is expected to do further linking.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3307,6 +3330,7 @@ BEGIN
-- Reuse an EQUAL edge (be it closed or not)
IF ST_RelateMatch(rec.im, '1FFF*FFF2') THEN
+
RETURN rec.edge_id;
END IF;
@@ -3411,7 +3435,7 @@ LANGUAGE 'plpgsql' VOLATILE;
-- o The polygon overlaps an existing face.
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -3533,6 +3557,7 @@ BEGIN
ST_Line_Locate_Point(bounds, p2);
+
IF right_side THEN
right_edges := array_append(right_edges, rec.edge_id);
old_faceid = rec.right_face;
@@ -3559,6 +3584,8 @@ BEGIN
END IF;
+
+
--
-- Check that all edges found, taken togheter,
-- fully match the ring boundary and nothing more
@@ -3578,8 +3605,10 @@ BEGIN
IF faceid IS NOT NULL AND faceid != 0 THEN
IF NOT force_new THEN
+
RETURN faceid;
ELSE
+
END IF;
END IF;
@@ -3706,12 +3735,14 @@ BEGIN
|| tol || ') ORDER BY ST_Distance('
|| quote_literal(apoint::text)
|| '::geometry, a.geom) LIMIT 1;';
+
EXECUTE sql INTO id;
IF id IS NOT NULL THEN
RETURN id;
END IF;
+
-- 2. Check if any existing edge falls within tolerance
-- and if so split it by a point projected on it
sql := 'SELECT a.edge_id, a.geom FROM '
@@ -3721,35 +3752,42 @@ BEGIN
|| tol || ') ORDER BY ST_Distance('
|| quote_literal(apoint::text)
|| '::geometry, a.geom) LIMIT 1;';
+
EXECUTE sql INTO rec;
IF rec IS NOT NULL THEN
-- project point to line, split edge by point
prj := ST_ClosestPoint(rec.geom, apoint);
-- This is a workaround for ClosestPoint lack of Z support:
- -- http://trac.osgeo.org/postgis/ticket/2033
+ -- http:
z := ST_Z(apoint);
IF z IS NOT NULL THEN
prj := ST_Translate(ST_Force_3DZ(prj), 0, 0, z); -- no ST_SetZ ...
END IF;
+
IF NOT ST_Contains(rec.geom, prj) THEN
+
-- The tolerance must be big enough for snapping to happen
-- and small enough to snap only to the projected point.
-- Unfortunately ST_Distance returns 0 because it also uses
-- a projected point internally, so we need another way.
snaptol := topology._st_mintolerance(prj);
+
snapedge := ST_Snap(rec.geom, prj, snaptol);
-- Snapping currently snaps the first point below tolerance
-- so may possibly move first point. See ticket #1631
IF NOT ST_Equals(ST_StartPoint(rec.geom), ST_StartPoint(snapedge))
THEN
+
snapedge := ST_MakeLine(ST_StartPoint(rec.geom), snapedge);
END IF;
+
PERFORM ST_ChangeEdgeGeom(atopology, rec.edge_id, snapedge);
END IF;
id := topology.ST_ModEdgeSplit(atopology, rec.edge_id, prj);
ELSE
+
id := topology.ST_AddIsoNode(atopology, NULL, apoint);
END IF;
@@ -3795,6 +3833,7 @@ BEGIN
-- 1. Self-node
noded := ST_UnaryUnion(aline);
+
-- 2. Node to edges falling within tol distance
sql := 'WITH nearby AS ( SELECT e.geom FROM '
|| quote_ident(atopology)
@@ -3802,20 +3841,27 @@ BEGIN
|| quote_literal(noded::text)
|| '::geometry, '
|| tol || ') ) SELECT st_collect(geom) FROM nearby;';
+
EXECUTE sql INTO iedges;
IF iedges IS NOT NULL THEN
+
snapped := ST_Snap(noded, iedges, tol);
+
noded := ST_Difference(snapped, iedges);
+
set1 := ST_Intersection(snapped, iedges);
+
set2 := ST_LineMerge(set1);
+
noded := ST_Union(noded, set2);
+
END IF;
-- 2.1. Node with existing nodes within tol
@@ -3826,26 +3872,32 @@ BEGIN
|| quote_literal(noded::text)
|| '::geometry, '
|| tol || ') ) SELECT st_collect(geom) FROM nearby;';
+
EXECUTE sql INTO inodes;
IF inodes IS NOT NULL THEN -- {
+
-- TODO: consider snapping once against all elements
--- (rather than once with edges and once with nodes)
noded := ST_Snap(noded, inodes, tol);
+
FOR rec IN SELECT (ST_Dump(inodes)).*
LOOP
-- Use the node to split edges
SELECT ST_Collect(geom)
FROM ST_Dump(ST_Split(noded, rec.geom))
INTO STRICT noded;
+
END LOOP;
+
-- re-node to account for ST_Snap introduced self-intersections
- -- See http://trac.osgeo.org/postgis/ticket/1714
+ -- See http:
-- TODO: consider running UnaryUnion once after all noding
noded := ST_UnaryUnion(noded);
+
END IF; -- }
-- 3. For each (now-noded) segment, insert an edge
@@ -3854,14 +3906,17 @@ BEGIN
-- TODO: skip point elements ?
+
start_node := topology.TopoGeo_AddPoint(atopology,
ST_StartPoint(rec.geom),
tol);
+
end_node := topology.TopoGeo_AddPoint(atopology,
ST_EndPoint(rec.geom),
tol);
+
-- Added endpoints may have drifted due to tolerance, so
-- we need to re-snap the edge to the new nodes before adding it
sql := 'SELECT n1.geom as sn, n2.geom as en FROM ' || quote_ident(atopology)
@@ -3869,6 +3924,7 @@ BEGIN
|| '.node n2 WHERE n1.node_id = '
|| start_node || ' AND n2.node_id = ' || end_node;
+
EXECUTE sql INTO STRICT rec2;
snapped := ST_SetPoint(
@@ -3879,8 +3935,10 @@ BEGIN
snapped := ST_CollectionExtract(ST_MakeValid(snapped), 2);
+
-- Check if the so-snapped edge collapsed (see #1650)
IF ST_IsEmpty(snapped) THEN
+
CONTINUE;
END IF;
@@ -3888,11 +3946,14 @@ BEGIN
sql := 'SELECT edge_id FROM ' || quote_ident(atopology)
|| '.edge_data WHERE ST_Equals(geom, ' || quote_literal(snapped::text)
|| '::geometry)';
+
EXECUTE sql INTO id;
IF id IS NULL THEN
id := topology.ST_AddEdgeModFace(atopology, start_node, end_node,
snapped);
+
ELSE
+
END IF;
RETURN NEXT id;
@@ -3934,9 +3995,11 @@ BEGIN
-- 1. Extract boundary
boundary := ST_Boundary(apoly);
+
-- 2. Add boundaries as edges
FOR rec IN SELECT (ST_Dump(boundary)).geom LOOP
edges := array_cat(edges, array_agg(x)) FROM ( select topology.TopoGeo_addLinestring(atopology, rec.geom, tol) as x ) as foo;
+
END LOOP;
-- 3. Find faces covered by input polygon
@@ -3945,10 +4008,12 @@ BEGIN
|| '.face f WHERE f.mbr && '
|| quote_literal(apoly::text)
|| '::geometry';
+
FOR rec IN EXECUTE sql LOOP
-- check for actual containment
fgeom := ST_PointOnSurface(ST_GetFaceGeometry(atopology, rec.face_id));
IF NOT ST_Covers(apoly, fgeom) THEN
+
CONTINUE;
END IF;
RETURN NEXT rec.face_id;
@@ -3974,10 +4039,11 @@ END
$$
LANGUAGE 'plpgsql';
--} TopoGeo_AddGeometry
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4026,11 +4092,12 @@ $$
LANGUAGE 'plpgsql';
--} Polygonize(toponame)
+
-- TopoElement
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4044,7 +4111,7 @@ LANGUAGE 'plpgsql';
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -4086,11 +4153,12 @@ CREATE AGGREGATE topology.TopoElementArray_agg(
);
--} TopoElementArray_agg
+
-- TopoGeometry
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4146,10 +4214,11 @@ $$
$$
LANGUAGE 'sql' STABLE STRICT;
-- }
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011-2012 Sandro Santilli <strk@keybit.net>
--
@@ -4161,7 +4230,7 @@ LANGUAGE 'sql' STABLE STRICT;
-- {
-- Convert a simple geometry to a topologically-defined one
--
--- See http://trac.osgeo.org/postgis/ticket/1017
+-- See http:
--
-- }{
CREATE OR REPLACE FUNCTION topology.toTopoGeom(ageom Geometry, atopology varchar, alayer int, atolerance float8 DEFAULT 0)
@@ -4286,6 +4355,7 @@ BEGIN
|| '.relation(topogeo_id, layer_id, element_type, element_id) VALUES ('
|| rec.id || ',' || rec.lyr || ',' || rec.type
|| ',' || rec.primitive || ')';
+
EXECUTE sql;
END LOOP;
@@ -4296,11 +4366,12 @@ $$
LANGUAGE 'plpgsql' VOLATILE STRICT;
-- }
+
-- GML
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011 Sandro Santilli <strk@keybit.net>
--
@@ -4314,7 +4385,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -4861,13 +4932,14 @@ $$ LANGUAGE 'sql' STABLE; -- does NOT write into visited table
-- } AsGML(TopoGeometry)
+
--=} POSTGIS-SPECIFIC block
-- SQL/MM block
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2010, 2011, 2012 Sandro Santilli <strk@keybit.net>
-- Copyright (C) 2005 Refractions Research Inc.
@@ -4970,6 +5042,7 @@ BEGIN
LOOP
+
retrec.sequence = n;
retrec.edge = rec.edge_id;
@@ -5268,6 +5341,7 @@ BEGIN
|| ' AND l.layer_id = r.layer_id AND abs(r.element_id) = '
|| e1id
;
+
EXECUTE sql;
@@ -5616,6 +5690,7 @@ BEGIN
|| 'WHERE l.level = 0 AND l.feature_type = 2 '
|| ' AND l.topology_id = ' || topoid
|| ' AND abs(r.element_id) = ' || e1id ;
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented dropping edge %',
rec.topogeo_id, rec.layer_id,
@@ -5640,6 +5715,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge < 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -5657,6 +5733,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge > 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -5672,6 +5749,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge < 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -5689,6 +5767,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge > 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -5734,6 +5813,7 @@ BEGIN
END IF; -- }
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented healing faces % and %',
rec.topogeo_id, rec.layer_id,
@@ -5776,6 +5856,7 @@ BEGIN
|| '.face WHERE face_id IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
END IF; -- }
@@ -5786,6 +5867,7 @@ BEGIN
|| ' WHERE left_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update right_face for all edges still referencing old faces
@@ -5794,6 +5876,7 @@ BEGIN
|| ' WHERE right_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update containing_face for all nodes still referencing old faces
@@ -5802,6 +5885,7 @@ BEGIN
|| ' WHERE containing_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- NOT IN THE SPECS:
@@ -5814,6 +5898,7 @@ BEGIN
|| ' AND l.topology_id = ' || topoid
|| ' AND l.layer_id = r.layer_id AND abs(r.element_id) = '
|| e1rec.left_face;
+
EXECUTE sql;
sql := 'UPDATE ' || quote_ident(toponame)
|| '.relation r '
@@ -5822,6 +5907,7 @@ BEGIN
|| ' AND l.topology_id = ' || topoid
|| ' AND l.layer_id = r.layer_id AND r.element_id = '
|| e1rec.right_face;
+
EXECUTE sql;
END IF; -- } two faces healed...
@@ -5829,6 +5915,7 @@ BEGIN
-- Delete the edge
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.edge_data WHERE edge_id = ' || e1id;
+
EXECUTE sql;
-- Check if any of the edge nodes remains isolated,
@@ -5840,6 +5927,7 @@ BEGIN
|| e1rec.end_node || ') AND NOT EXISTS (SELECT edge_id FROM '
|| quote_ident(toponame)
|| '.edge_data WHERE start_node = n.node_id OR end_node = n.node_id)';
+
EXECUTE sql;
IF e1rec.right_face != e1rec.left_face THEN -- {
@@ -5848,6 +5936,7 @@ BEGIN
IF e1rec.left_face != 0 THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.left_face;
+
EXECUTE sql;
END IF;
@@ -5856,6 +5945,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.right_face;
+
EXECUTE sql;
END IF;
@@ -5940,6 +6030,7 @@ BEGIN
|| 'WHERE l.level = 0 AND l.feature_type = 2 '
|| ' AND l.topology_id = ' || topoid
|| ' AND abs(r.element_id) = ' || e1id ;
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented dropping edge %',
rec.topogeo_id, rec.layer_id,
@@ -5964,6 +6055,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge < 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -5981,6 +6073,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_left_edge > 0 AND abs(next_left_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -5996,6 +6089,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge < 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- If the edge being removed links to self,
@@ -6013,6 +6107,7 @@ BEGIN
|| abs(elink)
|| ' WHERE next_right_edge > 0 AND abs(next_right_edge) = '
|| e1id;
+
EXECUTE sql;
-- }
@@ -6056,6 +6151,7 @@ BEGIN
END IF; -- }
+
FOR rec IN EXECUTE sql LOOP
RAISE EXCEPTION 'TopoGeom % in layer % (%.%.%) cannot be represented healing faces % and %',
rec.topogeo_id, rec.layer_id,
@@ -6088,6 +6184,7 @@ BEGIN
|| '.face WHERE face_id IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ') ) WHERE face_id = ' || floodfaceid ;
+
EXECUTE sql;
END IF; -- }
@@ -6098,6 +6195,7 @@ BEGIN
|| ' WHERE left_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update right_face for all edges still referencing old faces
@@ -6106,6 +6204,7 @@ BEGIN
|| ' WHERE right_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- Update containing_face for all nodes still referencing old faces
@@ -6114,6 +6213,7 @@ BEGIN
|| ' WHERE containing_face IN ('
|| e1rec.left_face || ',' || e1rec.right_face
|| ')';
+
EXECUTE sql;
-- NOT IN THE SPECS:
@@ -6128,6 +6228,7 @@ BEGIN
|| e1rec.left_face || ',' || e1rec.right_face
|| ') AND abs(r.element_id) != '
|| floodfaceid; -- could be optimized..
+
EXECUTE sql;
END IF; -- } two faces healed...
@@ -6135,6 +6236,7 @@ BEGIN
-- Delete the edge
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.edge_data WHERE edge_id = ' || e1id;
+
EXECUTE sql;
-- Check if any of the edge nodes remains isolated,
@@ -6146,6 +6248,7 @@ BEGIN
|| e1rec.end_node || ') AND NOT EXISTS (SELECT edge_id FROM '
|| quote_ident(toponame)
|| '.edge_data WHERE start_node = n.node_id OR end_node = n.node_id)';
+
EXECUTE sql;
IF e1rec.right_face != e1rec.left_face THEN -- {
@@ -6155,6 +6258,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.left_face;
+
EXECUTE sql;
END IF;
@@ -6163,6 +6267,7 @@ BEGIN
THEN
sql := 'DELETE FROM ' || quote_ident(toponame)
|| '.face WHERE face_id = ' || e1rec.right_face;
+
EXECUTE sql;
END IF;
@@ -6320,6 +6425,7 @@ BEGIN
sql := sql || ' AND f.face_id = ' || aface;
END IF;
+
EXECUTE sql INTO containingface;
-- If aface was specified, check that it was correct
@@ -6353,6 +6459,7 @@ BEGIN
|| '::geometry,' || containingface
|| ' RETURNING node_id';
+
EXECUTE sql INTO nodeid;
RETURN nodeid;
@@ -6493,7 +6600,7 @@ LANGUAGE 'plpgsql' VOLATILE;
--} ST_RemoveIsoNode
--{
--- According to http://trac.osgeo.org/postgis/ticket/798
+-- According to http:
-- ST_RemoveIsoNode was renamed to ST_RemIsoNode in the final ISO
-- document
--
@@ -6695,6 +6802,7 @@ BEGIN
END LOOP;
+
--RAISE NOTICE 'EdgeId1 % EdgeId2 %', edgeid1, edgeid2;
--RAISE DEBUG 'oldedge.next_left_edge: %', oldedge.next_left_edge;
@@ -6980,6 +7088,7 @@ BEGIN
END LOOP;
+
--
-- Insert the new edge
--
@@ -7487,25 +7596,32 @@ BEGIN
tmp1 := ST_MakeLine(ST_EndPoint(oldedge.geom), ST_StartPoint(oldedge.geom));
+
tmp2 := ST_MakeLine(oldedge.geom, tmp1);
IF ST_NumPoints(tmp2) < 4 THEN
tmp2 := ST_AddPoint(tmp2, ST_StartPoint(oldedge.geom));
END IF;
+
tmp2 := ST_CollectionExtract(ST_MakeValid(ST_MakePolygon(tmp2)), 3);
+
range := ST_MakeLine(acurve, tmp1);
IF ST_NumPoints(range) < 4 THEN
range := ST_AddPoint(range, ST_StartPoint(oldedge.geom));
END IF;
+
range := ST_CollectionExtract(ST_MakeValid(ST_MakePolygon(range)), 3);
+
range := ST_SymDifference(range, tmp2);
+
sql := 'SELECT node_id, geom FROM '
|| quote_ident(atopology)
|| '.node WHERE ST_Contains('
|| quote_literal(range::text)
|| '::geometry, geom) LIMIT 1';
+
FOR rec IN EXECUTE sql LOOP -- {
RAISE EXCEPTION 'Edge motion collision at %', ST_AsText(rec.geom);
END LOOP; -- }
@@ -7521,11 +7637,13 @@ BEGIN
) as pre, NULL::integer[] as post
INTO STRICT snode_info;
+
SELECT topology._ST_AdjacentEdges(
atopology, oldedge.end_node, -anedge
) as pre, NULL::integer[] as post
INTO STRICT enode_info;
+
--}
--
@@ -7543,10 +7661,12 @@ BEGIN
atopology, oldedge.start_node, anedge
);
+
enode_info.post := topology._ST_AdjacentEdges(
atopology, oldedge.end_node, -anedge
);
+
IF snode_info.pre != snode_info.post THEN
RAISE EXCEPTION 'Edge changed disposition around start node %',
oldedge.start_node;
@@ -7623,6 +7743,7 @@ DECLARE
BEGIN
IF oface = 0 AND mbr_only THEN
+
RETURN NULL;
END IF;
@@ -7635,24 +7756,31 @@ BEGIN
INTO STRICT fan.newring_edges;
+
-- You can't get to the other side of an edge forming a ring
IF fan.newring_edges @> ARRAY[-anedge] THEN
+
RETURN 0;
END IF;
+
sql := 'WITH ids as ( select row_number() over () as seq, edge from unnest('
|| quote_literal(fan.newring_edges::text)
|| '::int[] ) u(edge) ), edges AS ( select CASE WHEN i.edge < 0 THEN ST_Reverse(e.geom) ELSE e.geom END as g FROM ids i left join '
|| quote_ident(atopology) || '.edge_data e ON(e.edge_id = abs(i.edge)) ORDER BY seq) SELECT ST_MakePolygon(ST_MakeLine(g.g)) FROM edges g;';
+
EXECUTE sql INTO fan.shell;
+
isccw := NOT ST_OrderingEquals(fan.shell, ST_ForceRHR(fan.shell));
+
IF oface = 0 THEN
IF NOT isccw THEN
+
RETURN NULL;
END IF;
END IF;
@@ -7664,6 +7792,7 @@ BEGIN
|| quote_ident(atopology) || '.face SET mbr = '
|| quote_literal(ST_Envelope(fan.shell)::text)
|| '::geometry WHERE face_id = ' || oface;
+
EXECUTE sql;
END IF; -- }
RETURN NULL;
@@ -7684,6 +7813,7 @@ BEGIN
END IF; -- }
-- Insert new face
+
EXECUTE sql INTO STRICT newface;
-- Update forward edges
@@ -7692,6 +7822,7 @@ BEGIN
|| ' WHERE left_face = ' || oface || ' AND edge_id = ANY ('
|| quote_literal(array( select +(x) from unnest(fan.newring_edges) u(x) )::text)
|| ')';
+
EXECUTE sql;
-- Update backward edges
@@ -7700,12 +7831,15 @@ BEGIN
|| ' WHERE right_face = ' || oface || ' AND edge_id = ANY ('
|| quote_literal(array( select -(x) from unnest(fan.newring_edges) u(x) )::text)
|| ')';
+
EXECUTE sql;
IF oface != 0 AND NOT isccw THEN -- {
-- face shrinked, must update all non-contained edges and nodes
+
ishole := true;
ELSE
+
ishole := false;
END IF; -- }
@@ -7727,6 +7861,7 @@ BEGIN
sql := sql || 'ST_Contains(' || quote_literal(fan.shell::text)
-- We only need to check a single point, but must not be an endpoint
|| '::geometry, ST_Line_Interpolate_Point(geom, 0.2))';
+
EXECUTE sql;
-- Update isolated nodes in new new face
@@ -7736,6 +7871,7 @@ BEGIN
|| ' AND ';
IF ishole THEN sql := sql || 'NOT '; END IF;
sql := sql || 'ST_Contains(' || quote_literal(fan.shell::text) || '::geometry, geom)';
+
EXECUTE sql;
RETURN newface;
@@ -7859,6 +7995,7 @@ BEGIN
|| ')'
LOOP
IF rec.containing_face IS NOT NULL THEN
+
IF newedge.left_face IS NULL THEN
newedge.left_face := rec.containing_face;
newedge.right_face := rec.containing_face;
@@ -7966,6 +8103,7 @@ BEGIN
-- Find links on start node -- {
+
sql :=
'SELECT edge_id, -1 AS end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8011,6 +8149,7 @@ BEGIN
END IF;
+
az = az - span.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8050,6 +8189,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN span.was_isolated = true; END IF;
ELSE
@@ -8066,12 +8206,16 @@ BEGIN
END IF;
+
+
+
-- } start_node analysis
-- Find links on end_node {
+
sql :=
'SELECT edge_id, -1 as end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8113,6 +8257,7 @@ BEGIN
END IF;
+
az := az - epan.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8152,6 +8297,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN epan.was_isolated = true; END IF;
ELSE
@@ -8170,6 +8316,9 @@ BEGIN
-- } end_node analysis
+
+
+
----------------------------------------------------------------------
--
-- If we don't have faces setup by now we must have encountered
@@ -8265,15 +8414,18 @@ BEGIN
--------------------------------------------
+
SELECT topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, false)
INTO newface;
IF newface = 0 THEN
+
RETURN newedge.edge_id;
END IF;
newfaces[1] := newface;
+
SELECT topology._ST_AddFaceSplit(atopology, newedge.edge_id, newedge.left_face, false)
INTO newface;
@@ -8296,6 +8448,7 @@ BEGIN
FOR rec IN EXECUTE sql
LOOP
+
-- Add reference to the other face
sql := 'INSERT INTO ' || quote_ident(atopology)
|| '.relation VALUES( ' || rec.topogeo_id
@@ -8433,6 +8586,7 @@ BEGIN
|| ')'
LOOP
IF rec.containing_face IS NOT NULL THEN
+
IF newedge.left_face IS NULL THEN
newedge.left_face := rec.containing_face;
newedge.right_face := rec.containing_face;
@@ -8538,6 +8692,7 @@ BEGIN
-- Find links on start node -- {
+
sql :=
'SELECT edge_id, -1 AS end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8583,6 +8738,7 @@ BEGIN
END IF;
+
az = az - span.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8622,6 +8778,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN span.was_isolated = true; END IF;
ELSE
@@ -8638,12 +8795,16 @@ BEGIN
END IF;
+
+
+
-- } start_node analysis
-- Find links on end_node {
+
sql :=
'SELECT edge_id, -1 as end_node, start_node, left_face, right_face, '
|| 'ST_RemoveRepeatedPoints(geom) as geom FROM '
@@ -8685,6 +8846,7 @@ BEGIN
END IF;
+
az := az - epan.myaz;
IF az < 0 THEN
az := az + 2*PI();
@@ -8724,6 +8886,7 @@ BEGIN
END LOOP; -- incident edges }
+
IF newedge.isclosed THEN
IF i < 2 THEN epan.was_isolated = true; END IF;
ELSE
@@ -8742,6 +8905,9 @@ BEGIN
-- } end_node analysis
+
+
+
----------------------------------------------------------------------
--
-- If we don't have faces setup by now we must have encountered
@@ -8836,20 +9002,25 @@ BEGIN
-- Check face splitting
--------------------------------------------
+
SELECT topology._ST_AddFaceSplit(atopology, newedge.edge_id, newedge.left_face, false)
INTO newface;
IF newface = 0 THEN
+
RETURN newedge.edge_id;
END IF;
IF newface IS NULL THEN -- must be forming a maximal ring in universal face
+
SELECT topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, false)
INTO newface;
ELSE
+
PERFORM topology._ST_AddFaceSplit(atopology, -newedge.edge_id, newedge.left_face, true);
END IF;
IF newface IS NULL THEN
+
RETURN newedge.edge_id;
END IF;
@@ -8873,6 +9044,7 @@ BEGIN
FOR rec IN EXECUTE sql
LOOP
+
-- Add reference to the other face
sql := 'INSERT INTO ' || quote_ident(atopology)
|| '.relation VALUES( ' || rec.topogeo_id
@@ -9003,6 +9175,7 @@ BEGIN
END; -- }
+
--
-- Node input linework with itself
--
@@ -9016,6 +9189,7 @@ BEGIN
) as linework INTO STRICT nodededges;
+
--
-- Linemerge the resulting edges, to reduce the working set
-- NOTE: this is more of a workaround for GEOS splitting overlapping
@@ -9025,6 +9199,7 @@ BEGIN
+
--
-- Collect input points and input lines endpoints
--
@@ -9038,6 +9213,7 @@ BEGIN
) as nodes INTO STRICT points;
+
--
-- Further split edges by points
-- TODO: optimize this adding ST_Split support for multiline/multipoint
@@ -9052,6 +9228,7 @@ BEGIN
SELECT ST_UnaryUnion(nodededges) INTO STRICT nodededges;
+
--
-- Collect all nodes (from points and noded linework endpoints)
--
@@ -9070,6 +9247,7 @@ BEGIN
) as endpoints INTO points;
+
--
-- Add all nodes as isolated so that
-- later calls to AddEdgeModFace will tweak their being
@@ -9100,11 +9278,12 @@ LANGUAGE 'plpgsql' VOLATILE;
--=} SQL/MM block
+
-- The following files needs getfaceedges_returntype, defined in sqlmm.sql
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2011 2012 Sandro Santilli <strk@keybit.net>
--
@@ -9114,7 +9293,7 @@ LANGUAGE 'plpgsql' VOLATILE;
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@keybit.net>
--- for Faunalia (http://www.faunalia.it) with funding from
+-- for Faunalia (http:
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
@@ -9181,10 +9360,11 @@ END
$$
LANGUAGE 'plpgsql' STABLE;
--} GetRingEdges
+
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://postgis.refractions.net
+-- http:
--
-- Copyright (C) 2012 Sandro Santilli <strk@keybit.net>
--
@@ -9225,9 +9405,11 @@ BEGIN
|| ' UNION ALL SELECT -edge_id, ST_Azimuth(ST_EndPoint(geom), ST_PointN(geom, ST_NumPoints(geom)-1)) FROM incident_edges WHERE end_node = ' || anode
|| ' ORDER BY az';
+
FOR rec IN EXECUTE sql
LOOP -- incident edges {
+
n := n + 1;
retrec.sequence := n;
retrec.edge := rec.edge_id;
@@ -9239,11 +9421,12 @@ $$
LANGUAGE 'plpgsql' STABLE;
--} GetRingEdges
+
--general management --
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
--- http://www.postgis.org
+-- http:
--
-- Copyright (C) 2011 Regina Obe <lr@pcorp.us>
--
@@ -9282,6 +9465,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
--} AddToSearchPath
+
CREATE OR REPLACE FUNCTION postgis_topology_scripts_installed() RETURNS text
AS $$ SELECT '2.0.2'::text || ' r' || 10789::text AS version $$
LANGUAGE 'sql' IMMUTABLE;
@@ -9290,11 +9474,9 @@ CREATE OR REPLACE FUNCTION postgis_topology_scripts_installed() RETURNS text
SELECT topology.AddToSearchPath('topology');
COMMIT;
-
-
-- $Id: topology_drop_after.sql.in.c 9324 2012-02-27 22:08:12Z pramsey $
-- PostGIS - Spatial Types for PostgreSQL
--- http://www.postgis.org
+-- http:
--
-- Copyright (C) 2012 Regina Obe <lr@pcorp.us>
-- This is free software; you can redistribute and/or modify it under
diff --git a/gcc/postgis_share/uninstall_legacy.sql b/gpp/postgis_share/uninstall_legacy.sql
index 3b86915..0d8c46f 100644
--- a/gcc/postgis_share/uninstall_legacy.sql
+++ b/gpp/postgis_share/uninstall_legacy.sql
@@ -8,7 +8,7 @@
--
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
--
--- Generated on: Wed Dec 5 14:41:00 2012
+-- Generated on: Wed Dec 5 15:22:13 2012
-- by: ../utils/create_undef.pl
-- from: legacy.sql
--
diff --git a/gcc/postgis_share/uninstall_postgis.sql b/gpp/postgis_share/uninstall_postgis.sql
index 7b8e85e..98b668f 100644
--- a/gcc/postgis_share/uninstall_postgis.sql
+++ b/gpp/postgis_share/uninstall_postgis.sql
@@ -8,7 +8,7 @@
--
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
--
--- Generated on: Wed Dec 5 14:41:00 2012
+-- Generated on: Wed Dec 5 15:22:13 2012
-- by: ../utils/create_undef.pl
-- from: postgis.sql
--
diff --git a/gcc/postgis_share/uninstall_rtpostgis.sql b/gpp/postgis_share/uninstall_rtpostgis.sql
index 24c8abe..0eed275 100644
--- a/gcc/postgis_share/uninstall_rtpostgis.sql
+++ b/gpp/postgis_share/uninstall_rtpostgis.sql
@@ -8,7 +8,7 @@
--
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
--
--- Generated on: Wed Dec 5 14:41:04 2012
+-- Generated on: Wed Dec 5 15:22:20 2012
-- by: ../../utils/create_undef.pl
-- from: rtpostgis.sql
--
diff --git a/gcc/postgis_share/uninstall_topology.sql b/gpp/postgis_share/uninstall_topology.sql
index 7633152..4fff688 100644
--- a/gcc/postgis_share/uninstall_topology.sql
+++ b/gpp/postgis_share/uninstall_topology.sql
@@ -8,7 +8,7 @@
--
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
--
--- Generated on: Wed Dec 5 14:41:05 2012
+-- Generated on: Wed Dec 5 15:22:22 2012
-- by: ../utils/create_undef.pl
-- from: topology.sql
--
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment