576 lines
15 KiB
MySQL
576 lines
15 KiB
MySQL
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
--
|
|
-- PostGIS - Spatial Types for PostgreSQL
|
|
-- http://postgis.net
|
|
--
|
|
-- Copyright (C) 2010-2015 Sandro Santilli <strk@kbt.io>
|
|
-- Copyright (C) 2005 Refractions Research Inc.
|
|
--
|
|
-- This is free software; you can redistribute and/or modify it under
|
|
-- the terms of the GNU General Public Licence. See the COPYING file.
|
|
--
|
|
-- Author: Sandro Santilli <strk@kbt.io>
|
|
--
|
|
--
|
|
|
|
/*#define POSTGIS_TOPOLOGY_DEBUG 1*/
|
|
|
|
--={ ----------------------------------------------------------------
|
|
-- SQL/MM block
|
|
--
|
|
-- This part contains function in the SQL/MM specification
|
|
--
|
|
---------------------------------------------------------------------
|
|
|
|
--
|
|
-- Type returned by ST_GetFaceEdges
|
|
--
|
|
-- Availability: 1.1.0
|
|
--
|
|
CREATE TYPE topology.GetFaceEdges_ReturnType AS (
|
|
sequence integer,
|
|
edge integer
|
|
);
|
|
|
|
--{
|
|
-- Topo-Geo and Topo-Net 3: Routine Details
|
|
-- X.3.5
|
|
--
|
|
-- ST_GetFaceEdges(atopology, aface)
|
|
--
|
|
-- Availability: 1.1.0
|
|
--
|
|
CREATE OR REPLACE FUNCTION topology.ST_GetFaceEdges(toponame varchar, face_id integer)
|
|
RETURNS SETOF topology.GetFaceEdges_ReturnType AS
|
|
'MODULE_PATHNAME', 'ST_GetFaceEdges'
|
|
LANGUAGE 'c' STABLE;
|
|
--} ST_GetFaceEdges
|
|
|
|
--{
|
|
-- Topo-Geo and Topo-Net 3: Routine Details
|
|
-- X.3.10
|
|
--
|
|
-- ST_NewEdgeHeal(atopology, anedge, anotheredge)
|
|
--
|
|
-- Not in the specs:
|
|
-- * Refuses to heal two edges if any of the two is closed
|
|
-- * Raise an exception when trying to heal an edge with itself
|
|
-- * Raise an exception if any TopoGeometry is defined by only one
|
|
-- of the two edges
|
|
-- * Update references in the Relation table.
|
|
--
|
|
CREATE OR REPLACE FUNCTION topology.ST_NewEdgeHeal(toponame varchar, e1id integer, e2id integer)
|
|
RETURNS int AS
|
|
'MODULE_PATHNAME','ST_NewEdgeHeal'
|
|
LANGUAGE 'c' VOLATILE;
|
|
--} ST_NewEdgeHeal
|
|
|
|
--{
|
|
-- Topo-Geo and Topo-Net 3: Routine Details
|
|
-- X.3.11
|
|
--
|
|
-- ST_ModEdgeHeal(atopology, anedge, anotheredge)
|
|
--
|
|
-- Not in the specs:
|
|
-- * Returns the id of the node being removed
|
|
-- * Refuses to heal two edges if any of the two is closed
|
|
-- * Raise an exception when trying to heal an edge with itself
|
|
-- * Raise an exception if any TopoGeometry is defined by only one
|
|
-- of the two edges
|
|
-- * Update references in the Relation table.
|
|
-- {
|
|
CREATE OR REPLACE FUNCTION topology.ST_ModEdgeHeal(toponame varchar, e1id integer, e2id integer)
|
|
RETURNS int AS
|
|
'MODULE_PATHNAME','ST_ModEdgeHeal'
|
|
LANGUAGE 'c' VOLATILE;
|
|
--} ST_ModEdgeHeal
|
|
|
|
--{
|
|
-- Topo-Geo and Topo-Net 3: Routine Details
|
|
-- X.3.14
|
|
--
|
|
-- ST_RemEdgeNewFace(atopology, anedge)
|
|
--
|
|
-- Not in the specs:
|
|
-- * Raise an exception if any TopoGeometry is defined by only one
|
|
-- of the two faces that will dissolve.
|
|
-- * Raise an exception if any TopoGeometry is defined by
|
|
-- the edge being removed.
|
|
-- * Properly set containg_face on nodes that remains isolated by the drop
|
|
-- * Update containg_face for isolated nodes in the dissolved faces
|
|
-- * Update references in the Relation table
|
|
--
|
|
-- }{
|
|
CREATE OR REPLACE FUNCTION topology.ST_RemEdgeNewFace(toponame varchar, e1id integer)
|
|
RETURNS int AS
|
|
'MODULE_PATHNAME','ST_RemEdgeNewFace'
|
|
LANGUAGE 'c' VOLATILE;
|
|
--} ST_RemEdgeNewFace
|
|
|
|
--{
|
|
-- Topo-Geo and Topo-Net 3: Routine Details
|
|
-- X.3.15
|
|
--
|
|
-- ST_RemEdgeModFace(atopology, anedge)
|
|
--
|
|
-- Not in the specs:
|
|
-- * Raise an exception if any TopoGeometry is defined by only one
|
|
-- of the two faces that will dissolve.
|
|
-- * Raise an exception if any TopoGeometry is defined by
|
|
-- the edge being removed.
|
|
-- * Properly set containg_face on nodes that remains isolated by the drop
|
|
-- * Update containg_face for isolated nodes in the dissolved faces
|
|
-- * Update references in the Relation table
|
|
-- * Return id of the face taking up the removed edge space
|
|
--
|
|
-- }{
|
|
CREATE OR REPLACE FUNCTION topology.ST_RemEdgeModFace(toponame varchar, e1id integer)
|
|
RETURNS int AS
|
|
'MODULE_PATHNAME','ST_RemEdgeModFace'
|
|
LANGUAGE 'c' VOLATILE;
|
|
--} ST_RemEdgeModFace
|
|
|
|
--{
|
|
-- Topo-Geo and Topo-Net 3: Routine Details
|
|
-- X.3.16
|
|
--
|
|
-- ST_GetFaceGeometry(atopology, aface)
|
|
--
|
|
CREATE OR REPLACE FUNCTION topology.ST_GetFaceGeometry(toponame varchar, aface integer)
|
|
RETURNS GEOMETRY AS
|
|
'MODULE_PATHNAME', 'ST_GetFaceGeometry'
|
|
LANGUAGE 'c' STABLE;
|
|
--} ST_GetFaceGeometry
|
|
|
|
--{
|
|
-- Topo-Geo and Topo-Net 3: Routine Details
|
|
-- X.3.1
|
|
--
|
|
-- ST_AddIsoNode(atopology, aface, apoint)
|
|
--
|
|
-- Availability: 1.1.0
|
|
--
|
|
CREATE OR REPLACE FUNCTION topology.ST_AddIsoNode(atopology varchar, aface integer, apoint geometry)
|
|
RETURNS INTEGER AS
|
|
'MODULE_PATHNAME','ST_AddIsoNode'
|
|
LANGUAGE 'c' VOLATILE;
|
|
--} ST_AddIsoNode
|
|
|
|
--{
|
|
-- Topo-Geo and Topo-Net 3: Routine Details
|
|
-- X.3.2
|
|
--
|
|
-- ST_MoveIsoNode(atopology, anode, apoint)
|
|
--
|
|
CREATE OR REPLACE FUNCTION topology.ST_MoveIsoNode(atopology character varying, anode integer, apoint geometry)
|
|
RETURNS text AS
|
|
'MODULE_PATHNAME','ST_MoveIsoNode'
|
|
LANGUAGE 'c' VOLATILE;
|
|
--} ST_MoveIsoNode
|
|
|
|
--{
|
|
-- Topo-Geo and Topo-Net 3: Routine Details
|
|
-- X.3.3
|
|
--
|
|
-- ST_RemoveIsoNode(atopology, anode)
|
|
--
|
|
-- Availability: 1.1.0
|
|
--
|
|
CREATE OR REPLACE FUNCTION topology.ST_RemoveIsoNode(atopology varchar, anode integer)
|
|
RETURNS TEXT AS
|
|
'MODULE_PATHNAME','ST_RemoveIsoNode'
|
|
LANGUAGE 'c' VOLATILE;
|
|
--} ST_RemoveIsoNode
|
|
|
|
--{
|
|
-- According to http://trac.osgeo.org/postgis/ticket/798
|
|
-- ST_RemoveIsoNode was renamed to ST_RemIsoNode in the final ISO
|
|
-- document
|
|
--
|
|
CREATE OR REPLACE FUNCTION topology.ST_RemIsoNode(varchar, integer)
|
|
RETURNS TEXT AS
|
|
'MODULE_PATHNAME','ST_RemoveIsoNode'
|
|
LANGUAGE 'c' VOLATILE;
|
|
--} ST_RemIsoNode
|
|
|
|
--{
|
|
-- Topo-Geo and Topo-Net 3: Routine Details
|
|
-- X.3.7
|
|
--
|
|
-- ST_RemoveIsoEdge(atopology, anedge)
|
|
--
|
|
-- Availability: 1.1.0
|
|
--
|
|
CREATE OR REPLACE FUNCTION topology.ST_RemoveIsoEdge(atopology varchar, anedge integer)
|
|
RETURNS TEXT AS
|
|
'MODULE_PATHNAME','ST_RemIsoEdge'
|
|
LANGUAGE 'c' VOLATILE;
|
|
--} ST_RemoveIsoEdge
|
|
|
|
--{
|
|
-- Topo-Geo and Topo-Net 3: Routine Details
|
|
-- X.3.8
|
|
--
|
|
-- ST_NewEdgesSplit(atopology, anedge, apoint)
|
|
--
|
|
-- Not in the specs:
|
|
-- * Update references in the Relation table.
|
|
--
|
|
-- Availability: 1.1.0
|
|
--
|
|
CREATE OR REPLACE FUNCTION topology.ST_NewEdgesSplit(atopology varchar, anedge integer, apoint geometry)
|
|
RETURNS INTEGER AS
|
|
'MODULE_PATHNAME','ST_NewEdgesSplit'
|
|
LANGUAGE 'c' VOLATILE;
|
|
--} ST_NewEdgesSplit
|
|
|
|
--{
|
|
-- Topo-Geo and Topo-Net 3: Routine Details
|
|
-- X.3.9
|
|
--
|
|
-- ST_ModEdgeSplit(atopology, anedge, apoint)
|
|
--
|
|
-- Not in the specs:
|
|
-- * Update references in the Relation table.
|
|
--
|
|
-- Availability: 2.0.0
|
|
-- Replaces ST_ModEdgesSplit(varchar, integer, geometry) deprecated in 2.0.0
|
|
--
|
|
CREATE OR REPLACE FUNCTION topology.ST_ModEdgeSplit(atopology varchar, anedge integer, apoint geometry)
|
|
RETURNS INTEGER AS
|
|
'MODULE_PATHNAME','ST_ModEdgeSplit'
|
|
LANGUAGE 'c' VOLATILE;
|
|
--} ST_ModEdgesSplit
|
|
|
|
--{
|
|
-- Topo-Geo and Topo-Net 3: Routine Details
|
|
-- X.3.4
|
|
--
|
|
-- ST_AddIsoEdge(atopology, anode, anothernode, acurve)
|
|
--
|
|
-- Not in the specs:
|
|
-- * Reset containing_face for starting and ending point,
|
|
-- as they stop being isolated nodes
|
|
-- * Refuse to add a closed edge, as it would not be isolated
|
|
-- (ie: would create a ring)
|
|
--
|
|
-- Availability: 1.1.0
|
|
--
|
|
-- }{
|
|
--
|
|
CREATE OR REPLACE FUNCTION topology.ST_AddIsoEdge(atopology varchar, anode integer, anothernode integer, acurve geometry)
|
|
RETURNS INTEGER AS
|
|
'MODULE_PATHNAME','ST_AddIsoEdge'
|
|
LANGUAGE 'c' VOLATILE;
|
|
--} ST_AddIsoEdge
|
|
|
|
-- Internal function used by ST_ChangeEdgeGeom to compare
|
|
-- adjacent edges of an edge endpoint
|
|
--
|
|
-- @param anode the node to use edge end star of
|
|
-- @param anedge the directed edge to get adjacents from
|
|
-- if positive `anode' is assumed to be its start node
|
|
-- if negative `anode' is assumed to be its end node
|
|
--
|
|
-- @todo DROP, NOT NEEDED ANYMORE (might need to go in some _drop, I guess)
|
|
-- {
|
|
CREATE OR REPLACE FUNCTION topology._ST_AdjacentEdges(atopology varchar, anode integer, anedge integer)
|
|
RETURNS integer[] AS
|
|
$$
|
|
DECLARE
|
|
ret integer[];
|
|
BEGIN
|
|
WITH edgestar AS (
|
|
SELECT *, count(*) over () AS cnt
|
|
FROM topology.GetNodeEdges(atopology, anode)
|
|
)
|
|
SELECT ARRAY[ (
|
|
SELECT p.edge AS prev FROM edgestar p
|
|
WHERE p.sequence = CASE WHEN m.sequence-1 < 1 THEN cnt
|
|
ELSE m.sequence-1 END
|
|
), (
|
|
SELECT p.edge AS prev FROM edgestar p WHERE p.sequence = ((m.sequence)%cnt)+1
|
|
) ]
|
|
FROM edgestar m
|
|
WHERE edge = anedge
|
|
INTO ret;
|
|
|
|
RETURN ret;
|
|
END
|
|
$$
|
|
LANGUAGE 'plpgsql' STABLE;
|
|
--}
|
|
|
|
--{
|
|
-- Topo-Geo and Topo-Net 3: Routine Details
|
|
-- X.3.6
|
|
--
|
|
-- ST_ChangeEdgeGeom(atopology, anedge, acurve)
|
|
--
|
|
-- Not in the specs:
|
|
-- * Raise an exception if given a non-existent edge
|
|
-- * Raise an exception if movement is not topologically isomorphic
|
|
--
|
|
-- }{
|
|
CREATE OR REPLACE FUNCTION topology.ST_ChangeEdgeGeom(atopology varchar, anedge integer, acurve geometry)
|
|
RETURNS TEXT AS
|
|
'MODULE_PATHNAME','ST_ChangeEdgeGeom'
|
|
LANGUAGE 'c' VOLATILE;
|
|
--} ST_ChangeEdgeGeom
|
|
|
|
--{
|
|
-- Topo-Geo and Topo-Net 3: Routine Details
|
|
-- X.3.12
|
|
--
|
|
-- ST_AddEdgeNewFaces(atopology, anode, anothernode, acurve)
|
|
--
|
|
-- Not in the specs:
|
|
-- * Reset containing_face for starting and ending point,
|
|
-- as they stop being isolated nodes
|
|
-- * Update references in the Relation table.
|
|
--
|
|
CREATE OR REPLACE FUNCTION topology.ST_AddEdgeNewFaces(atopology varchar, anode integer, anothernode integer, acurve geometry)
|
|
RETURNS INTEGER AS
|
|
'MODULE_PATHNAME','ST_AddEdgeNewFaces'
|
|
LANGUAGE 'c' VOLATILE;
|
|
--} ST_AddEdgeNewFaces
|
|
|
|
--{
|
|
-- Topo-Geo and Topo-Net 3: Routine Details
|
|
-- X.3.13
|
|
--
|
|
-- ST_AddEdgeModFace(atopology, anode, anothernode, acurve)
|
|
--
|
|
-- Not in the specs:
|
|
-- * Reset containing_face for starting and ending point,
|
|
-- as they stop being isolated nodes
|
|
-- * Update references in the Relation table.
|
|
--
|
|
CREATE OR REPLACE FUNCTION topology.ST_AddEdgeModFace(atopology varchar, anode integer, anothernode integer, acurve geometry)
|
|
RETURNS INTEGER AS
|
|
'MODULE_PATHNAME','ST_AddEdgeModFace'
|
|
LANGUAGE 'c' VOLATILE;
|
|
--} ST_AddEdgeModFace
|
|
|
|
--{
|
|
-- Topo-Geo and Topo-Net 3: Routine Details
|
|
-- X.3.17
|
|
--
|
|
-- ST_InitTopoGeo(atopology)
|
|
--
|
|
-- Availability: 1.1.0
|
|
--
|
|
CREATE OR REPLACE FUNCTION topology.ST_InitTopoGeo(atopology varchar)
|
|
RETURNS text
|
|
AS
|
|
$$
|
|
DECLARE
|
|
rec RECORD;
|
|
topology_id numeric;
|
|
BEGIN
|
|
IF atopology IS NULL THEN
|
|
RAISE EXCEPTION 'SQL/MM Spatial exception - null argument';
|
|
END IF;
|
|
|
|
FOR rec IN SELECT * FROM pg_namespace WHERE text(nspname) = atopology
|
|
LOOP
|
|
RAISE EXCEPTION 'SQL/MM Spatial exception - schema already exists';
|
|
END LOOP;
|
|
|
|
FOR rec IN EXECUTE 'SELECT topology.CreateTopology('
|
|
||quote_literal(atopology)|| ') as id'
|
|
LOOP
|
|
topology_id := rec.id;
|
|
END LOOP;
|
|
|
|
RETURN 'Topology-Geometry ' || quote_literal(atopology)
|
|
|| ' (id:' || topology_id || ') created.';
|
|
END
|
|
$$
|
|
LANGUAGE 'plpgsql' VOLATILE;
|
|
--} ST_InitTopoGeo
|
|
|
|
--{
|
|
-- Topo-Geo and Topo-Net 3: Routine Details
|
|
-- X.3.18
|
|
--
|
|
-- ST_CreateTopoGeo(atopology, acollection)
|
|
--}{
|
|
CREATE OR REPLACE FUNCTION topology.ST_CreateTopoGeo(atopology varchar, acollection geometry)
|
|
RETURNS text
|
|
AS
|
|
$$
|
|
DECLARE
|
|
typ char(4);
|
|
rec RECORD;
|
|
ret int;
|
|
nodededges GEOMETRY;
|
|
points GEOMETRY;
|
|
snode_id int;
|
|
enode_id int;
|
|
tolerance FLOAT8;
|
|
topoinfo RECORD;
|
|
BEGIN
|
|
|
|
IF atopology IS NULL OR acollection IS NULL THEN
|
|
RAISE EXCEPTION 'SQL/MM Spatial exception - null argument';
|
|
END IF;
|
|
|
|
-- Get topology information
|
|
BEGIN
|
|
SELECT * FROM topology.topology
|
|
INTO STRICT topoinfo WHERE name = atopology;
|
|
EXCEPTION
|
|
WHEN NO_DATA_FOUND THEN
|
|
RAISE EXCEPTION 'SQL/MM Spatial exception - invalid topology name';
|
|
END;
|
|
|
|
-- Check SRID compatibility
|
|
IF ST_SRID(acollection) != topoinfo.SRID THEN
|
|
RAISE EXCEPTION 'Geometry SRID (%) does not match topology SRID (%)',
|
|
ST_SRID(acollection), topoinfo.SRID;
|
|
END IF;
|
|
|
|
-- Verify pre-conditions (valid, empty topology schema exists)
|
|
BEGIN -- {
|
|
|
|
-- Verify the topology views in the topology schema to be empty
|
|
FOR rec in EXECUTE
|
|
'SELECT count(*) FROM '
|
|
|| quote_ident(atopology) || '.edge_data '
|
|
|| ' UNION ' ||
|
|
'SELECT count(*) FROM '
|
|
|| quote_ident(atopology) || '.node '
|
|
LOOP
|
|
IF rec.count > 0 THEN
|
|
RAISE EXCEPTION 'SQL/MM Spatial exception - non-empty view';
|
|
END IF;
|
|
END LOOP;
|
|
|
|
-- face check is separated as it will contain a single (world)
|
|
-- face record
|
|
FOR rec in EXECUTE
|
|
'SELECT count(*) FROM '
|
|
|| quote_ident(atopology) || '.face '
|
|
LOOP
|
|
IF rec.count != 1 THEN
|
|
RAISE EXCEPTION 'SQL/MM Spatial exception - non-empty face view';
|
|
END IF;
|
|
END LOOP;
|
|
|
|
EXCEPTION
|
|
WHEN INVALID_SCHEMA_NAME THEN
|
|
RAISE EXCEPTION 'SQL/MM Spatial exception - invalid topology name';
|
|
WHEN UNDEFINED_TABLE THEN
|
|
RAISE EXCEPTION 'SQL/MM Spatial exception - non-existent view';
|
|
|
|
END; -- }
|
|
|
|
#ifdef POSTGIS_TOPOLOGY_DEBUG
|
|
RAISE DEBUG 'Noding input linework';
|
|
#endif
|
|
|
|
--
|
|
-- Node input linework with itself
|
|
--
|
|
WITH components AS ( SELECT geom FROM ST_Dump(acollection) )
|
|
SELECT ST_UnaryUnion(ST_Collect(geom)) FROM (
|
|
SELECT geom FROM components
|
|
WHERE ST_Dimension(geom) = 1
|
|
UNION ALL
|
|
SELECT ST_Boundary(geom) FROM components
|
|
WHERE ST_Dimension(geom) = 2
|
|
) as linework INTO STRICT nodededges;
|
|
|
|
#ifdef POSTGIS_TOPOLOGY_DEBUG
|
|
RAISE DEBUG 'Computed % noded edges', ST_NumGeometries(nodededges);
|
|
#endif
|
|
|
|
--
|
|
-- Linemerge the resulting edges, to reduce the working set
|
|
-- NOTE: this is more of a workaround for GEOS splitting overlapping
|
|
-- lines to each of the segments.
|
|
--
|
|
SELECT ST_LineMerge(nodededges) INTO STRICT nodededges;
|
|
|
|
#ifdef POSTGIS_TOPOLOGY_DEBUG
|
|
RAISE DEBUG 'Merged edges: %', ST_NumGeometries(nodededges);
|
|
#endif
|
|
|
|
--
|
|
-- Collect input points and input lines endpoints
|
|
--
|
|
WITH components AS ( SELECT geom FROM ST_Dump(acollection) )
|
|
SELECT ST_Union(geom) FROM (
|
|
SELECT geom FROM components
|
|
WHERE ST_Dimension(geom) = 0
|
|
UNION ALL
|
|
SELECT ST_Boundary(geom) FROM components
|
|
WHERE ST_Dimension(geom) = 1
|
|
) as nodes INTO STRICT points;
|
|
|
|
#ifdef POSTGIS_TOPOLOGY_DEBUG
|
|
RAISE DEBUG 'Collected % input points', ST_NumGeometries(points);
|
|
#endif
|
|
|
|
--
|
|
-- Further split edges by points, if needed
|
|
--
|
|
IF points IS NOT NULL THEN
|
|
nodededges := ST_Split(nodededges, points);
|
|
#ifdef POSTGIS_TOPOLOGY_DEBUG
|
|
RAISE DEBUG 'Noded edges became % after point-split',
|
|
ST_NumGeometries(nodededges);
|
|
#endif
|
|
END IF; -- points is not null
|
|
|
|
--
|
|
-- Collect all nodes (from points and noded linework endpoints)
|
|
--
|
|
|
|
WITH edges AS ( SELECT geom FROM ST_Dump(nodededges) )
|
|
SELECT ST_Union( -- TODO: ST_UnaryUnion ?
|
|
COALESCE(ST_UnaryUnion(ST_Collect(geom)),
|
|
ST_SetSRID('POINT EMPTY'::geometry, topoinfo.SRID)),
|
|
COALESCE(points,
|
|
ST_SetSRID('POINT EMPTY'::geometry, topoinfo.SRID))
|
|
)
|
|
FROM (
|
|
SELECT ST_StartPoint(geom) as geom FROM edges
|
|
UNION ALL
|
|
SELECT ST_EndPoint(geom) FROM edges
|
|
) as endpoints INTO points;
|
|
|
|
#ifdef POSTGIS_TOPOLOGY_DEBUG
|
|
RAISE DEBUG 'Total nodes count: %', ST_NumGeometries(points);
|
|
#endif
|
|
|
|
--
|
|
-- Add all nodes as isolated so that
|
|
-- later calls to AddEdgeModFace will tweak their being
|
|
-- isolated or not...
|
|
--
|
|
FOR rec IN SELECT geom FROM ST_Dump(points)
|
|
LOOP
|
|
PERFORM topology.ST_AddIsoNode(atopology, 0, rec.geom);
|
|
END LOOP;
|
|
|
|
FOR rec IN SELECT geom FROM ST_Dump(nodededges)
|
|
LOOP
|
|
SELECT topology.GetNodeByPoint(atopology, st_startpoint(rec.geom), 0)
|
|
INTO STRICT snode_id;
|
|
SELECT topology.GetNodeByPoint(atopology, st_endpoint(rec.geom), 0)
|
|
INTO STRICT enode_id;
|
|
PERFORM topology.ST_AddEdgeModFace(atopology, snode_id, enode_id, rec.geom);
|
|
END LOOP;
|
|
|
|
RETURN 'Topology ' || atopology || ' populated';
|
|
|
|
END
|
|
$$
|
|
LANGUAGE 'plpgsql' VOLATILE;
|
|
--} ST_CreateTopoGeo
|
|
|
|
--=} SQL/MM block
|
|
|