Skip to content

Commit ce1d9c2

Browse files
committed
(sql/separateTouching) Adding new function separateTouching
1 parent ea0605f commit ce1d9c2

File tree

3 files changed

+117
-0
lines changed

3 files changed

+117
-0
lines changed

sql/sigs/pgrouting--3.8.sig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,7 @@ pgr_pushrelabel(text,bigint,bigint)
266266
pgr_pushrelabel(text,text)
267267
_pgr_quote_ident(text)
268268
pgr_separatecrossing(text,double precision,boolean)
269+
pgr_separatetouching(text,double precision,boolean)
269270
_pgr_sequentialvertexcoloring(text)
270271
pgr_sequentialvertexcoloring(text)
271272
_pgr_startpoint(geometry)

sql/utilities/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
SET(LOCAL_FILES
33
findCloseEdges.sql
44
separateCrossing.sql
5+
separateTouching.sql
56
)
67

78
foreach (f ${LOCAL_FILES})

sql/utilities/separateTouching.sql

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/*PGR-GNU*****************************************************************
2+
File: separateTouching.sql
3+
4+
Copyright (c) 2025 pgRouting developers
5+
6+
7+
Copyright (c) 2025 Celia Virginia Vergara Castillo
8+
Mail: vicky at erosion.dev
9+
10+
------
11+
12+
This program is free software; you can redistribute it and/or modify
13+
it under the terms of the GNU General Public License as published by
14+
the Free Software Foundation; either version 2 of the License, or
15+
(at your option) any later version.
16+
17+
This program is distributed in the hope that it will be useful,
18+
but WITHOUT ANY WARRANTY; without even the implied warranty of
19+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20+
GNU General Public License for more details.
21+
22+
You should have received a copy of the GNU General Public License
23+
along with this program; if not, write to the Free Software
24+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25+
26+
********************************************************************PGR-GNU*/
27+
28+
--v3.8
29+
CREATE FUNCTION pgr_separateTouching(
30+
TEXT, -- edges SQL
31+
tolerance FLOAT DEFAULT 0.01, -- tolerance
32+
dryrun BOOLEAN DEFAULT false,
33+
34+
OUT seq INTEGER,
35+
OUT id BIGINT,
36+
OUT sub_id INTEGER,
37+
OUT geom geometry)
38+
RETURNS SETOF RECORD AS
39+
$BODY$
40+
DECLARE
41+
edges_sql TEXT := $1;
42+
43+
the_query TEXT;
44+
sqlhint TEXT;
45+
has_geom BOOLEAN;
46+
has_id BOOLEAN;
47+
BEGIN
48+
49+
BEGIN
50+
edges_sql := _pgr_checkQuery($1);
51+
EXCEPTION WHEN OTHERS THEN
52+
GET STACKED DIAGNOSTICS sqlhint = PG_EXCEPTION_HINT;
53+
RAISE EXCEPTION '%', SQLERRM USING HINT = sqlhint, ERRCODE = SQLSTATE;
54+
END;
55+
56+
has_id := _pgr_checkColumn(edges_sql, 'id', 'ANY-INTEGER', true, dryrun => $3);
57+
has_geom := _pgr_checkColumn(edges_sql, 'geom', 'geometry', true, dryrun => $3);
58+
59+
the_query := format($$
60+
WITH
61+
edges_table AS (
62+
%s
63+
),
64+
65+
get_touching AS (
66+
SELECT e1.id id1, e2.id id2, ST_Snap(e1.geom, e2.geom, %2$s) AS geom, e1.geom AS g1, e2.geom AS g2
67+
FROM edges_table e1, edges_table e2
68+
WHERE e1.id != e2.id AND ST_DWithin(e1.geom, e2.geom, %2$s) AND NOT(
69+
ST_StartPoint(e1.geom) = ST_StartPoint(e2.geom) OR ST_StartPoint(e1.geom) = ST_EndPoint(e2.geom)
70+
OR ST_EndPoint(e1.geom) = ST_StartPoint(e2.geom) OR ST_EndPoint(e1.geom) = ST_EndPoint(e2.geom))
71+
),
72+
73+
touchings AS (
74+
SELECT id1, g1, g2, st_intersection(geom, g2) AS point
75+
FROM get_touching
76+
WHERE NOT (geom = g1)
77+
),
78+
79+
blades AS (
80+
SELECT id1, g1, ST_UnaryUnion(ST_Collect(point)) AS blade
81+
FROM touchings
82+
GROUP BY id1, g1
83+
),
84+
85+
collection AS (
86+
SELECT id1, (st_dump(st_split(st_snap(g1, blade, %2$s), blade))).*
87+
FROM blades
88+
)
89+
90+
SELECT row_number() over()::INTEGER AS seq, id1::BIGINT, path[1], geom
91+
FROM collection;
92+
$$,
93+
94+
edges_sql, tolerance);
95+
96+
IF dryrun THEN
97+
RAISE NOTICE '%', the_query || ';';
98+
ELSE
99+
RETURN QUERY EXECUTE the_query;
100+
END IF;
101+
102+
END;
103+
$BODY$ LANGUAGE 'plpgsql' VOLATILE STRICT;
104+
105+
-- COMMENTS
106+
COMMENT ON FUNCTION pgr_separateTouching(TEXT, FLOAT, BOOLEAN)
107+
IS 'pgr_separateTouching
108+
- Parameters
109+
- Edges SQL with columns: id, geom
110+
- Optional parameters
111+
- tolerance => 0.01
112+
- dryrun => true
113+
- DOCUMENTATION:
114+
- ${PROJECT_DOC_LINK}/pgr_separateTouching.html
115+
';

0 commit comments

Comments
 (0)