From: Sandro Santilli Date: Fri, 23 Nov 2012 22:15:38 +0000 (+0000) Subject: Fix ST_{Mod,New}EdgeHeal joining edges sharing both endpoints X-Git-Tag: 2.1.0beta2~363 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ad6cbf2540f6317fb882afac002ee93a3f47da49;p=postgis Fix ST_{Mod,New}EdgeHeal joining edges sharing both endpoints Closes #1998. Include testcases. Also simplifies the code and avoids a GEOS call. [RT-SIGTA] C.I.G.: 0494241492 git-svn-id: http://svn.osgeo.org/postgis/trunk@10734 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/topology/sql/sqlmm.sql.in.c b/topology/sql/sqlmm.sql.in.c index c8dc953e1..5abb4e20c 100644 --- a/topology/sql/sqlmm.sql.in.c +++ b/topology/sql/sqlmm.sql.in.c @@ -308,44 +308,23 @@ BEGIN -- Create new edge { rec := e1rec; - rec.geom = ST_LineMerge(ST_Collect(e1rec.geom, e2rec.geom)); IF caseno = 1 THEN -- e1.end = e2.start - IF NOT ST_Equals(ST_StartPoint(rec.geom), ST_StartPoint(e1rec.geom)) THEN -#ifdef POSTGIS_TOPOLOGY_DEBUG - RAISE DEBUG 'caseno=1: LineMerge did not maintain startpoint'; -#endif - rec.geom = ST_Reverse(rec.geom); - END IF; + rec.geom = ST_MakeLine(e1rec.geom, e2rec.geom); rec.end_node = e2rec.end_node; rec.next_left_edge = e2rec.next_left_edge; e2sign = 1; ELSIF caseno = 2 THEN -- e1.end = e2.end - IF NOT ST_Equals(ST_StartPoint(rec.geom), ST_StartPoint(e1rec.geom)) THEN -#ifdef POSTGIS_TOPOLOGY_DEBUG - RAISE DEBUG 'caseno=2: LineMerge did not maintain startpoint'; -#endif - rec.geom = ST_Reverse(rec.geom); - END IF; + rec.geom = ST_MakeLine(e1rec.geom, st_reverse(e2rec.geom)); rec.end_node = e2rec.start_node; rec.next_left_edge = e2rec.next_right_edge; e2sign = -1; ELSIF caseno = 3 THEN -- e1.start = e2.start - IF NOT ST_Equals(ST_EndPoint(rec.geom), ST_EndPoint(e1rec.geom)) THEN -#ifdef POSTGIS_TOPOLOGY_DEBUG - RAISE DEBUG 'caseno=4: LineMerge did not maintain endpoint'; -#endif - rec.geom = ST_Reverse(rec.geom); - END IF; + rec.geom = ST_MakeLine(st_reverse(e2rec.geom), e1rec.geom); rec.start_node = e2rec.end_node; rec.next_right_edge = e2rec.next_left_edge; e2sign = -1; ELSIF caseno = 4 THEN -- e1.start = e2.end - IF NOT ST_Equals(ST_EndPoint(rec.geom), ST_EndPoint(e1rec.geom)) THEN -#ifdef POSTGIS_TOPOLOGY_DEBUG - RAISE DEBUG 'caseno=4: LineMerge did not maintain endpoint'; -#endif - rec.geom = ST_Reverse(rec.geom); - END IF; + rec.geom = ST_MakeLine(e2rec.geom, e1rec.geom); rec.start_node = e2rec.start_node; rec.next_right_edge = e2rec.next_right_edge; e2sign = 1; @@ -622,44 +601,23 @@ BEGIN -- Update data of the first edge { rec := e1rec; - rec.geom = ST_LineMerge(ST_Collect(e1rec.geom, e2rec.geom)); IF caseno = 1 THEN -- e1.end = e2.start - IF NOT ST_Equals(ST_StartPoint(rec.geom), ST_StartPoint(e1rec.geom)) THEN -#ifdef POSTGIS_TOPOLOGY_DEBUG - RAISE DEBUG 'caseno=1: LineMerge did not maintain startpoint'; -#endif - rec.geom = ST_Reverse(rec.geom); - END IF; + rec.geom = ST_MakeLine(e1rec.geom, e2rec.geom); rec.end_node = e2rec.end_node; rec.next_left_edge = e2rec.next_left_edge; e2sign = 1; ELSIF caseno = 2 THEN -- e1.end = e2.end - IF NOT ST_Equals(ST_StartPoint(rec.geom), ST_StartPoint(e1rec.geom)) THEN -#ifdef POSTGIS_TOPOLOGY_DEBUG - RAISE DEBUG 'caseno=2: LineMerge did not maintain startpoint'; -#endif - rec.geom = ST_Reverse(rec.geom); - END IF; + rec.geom = ST_MakeLine(e1rec.geom, st_reverse(e2rec.geom)); rec.end_node = e2rec.start_node; rec.next_left_edge = e2rec.next_right_edge; e2sign = -1; ELSIF caseno = 3 THEN -- e1.start = e2.start - IF NOT ST_Equals(ST_EndPoint(rec.geom), ST_EndPoint(e1rec.geom)) THEN -#ifdef POSTGIS_TOPOLOGY_DEBUG - RAISE DEBUG 'caseno=4: LineMerge did not maintain endpoint'; -#endif - rec.geom = ST_Reverse(rec.geom); - END IF; + rec.geom = ST_MakeLine(st_reverse(e2rec.geom), e1rec.geom); rec.start_node = e2rec.end_node; rec.next_right_edge = e2rec.next_left_edge; e2sign = -1; ELSIF caseno = 4 THEN -- e1.start = e2.end - IF NOT ST_Equals(ST_EndPoint(rec.geom), ST_EndPoint(e1rec.geom)) THEN -#ifdef POSTGIS_TOPOLOGY_DEBUG - RAISE DEBUG 'caseno=4: LineMerge did not maintain endpoint'; -#endif - rec.geom = ST_Reverse(rec.geom); - END IF; + rec.geom = ST_MakeLine(e2rec.geom, e1rec.geom); rec.start_node = e2rec.start_node; rec.next_right_edge = e2rec.next_right_edge; e2sign = 1; diff --git a/topology/test/regress/st_modedgeheal.sql b/topology/test/regress/st_modedgeheal.sql index 1e39f2351..0dd53c34b 100644 --- a/topology/test/regress/st_modedgeheal.sql +++ b/topology/test/regress/st_modedgeheal.sql @@ -160,6 +160,25 @@ SELECT '#1955', topology.DropTopology('t'); ------------------------------------------------------------------------- ------------------------------------------------------------------------- +-- Another case of merging edges sharing both endpoints +-- See http://trac.osgeo.org/postgis/ticket/1998 + +SELECT '#1998.+', CreateTopology('t1998') > 1; +SELECT '#1998.N1', ST_AddIsoNode('t1998', 0, 'POINT(1 1)'); +SELECT '#1998.N2', ST_AddIsoNode('t1998', 0, 'POINT(0 0)'); +SELECT '#1998.E1', ST_AddEdgeModFace('t1998', 1, 1, 'LINESTRING(1 1,1 2,2 2,2 1,1 1)'); +SELECT '#1998.E2', ST_AddEdgeModFace('t1998', 2, 1, 'LINESTRING(0 0,0 1,1 1)'); +SELECT '#1998.E3', ST_AddEdgeModFace('t1998', 1, 2, 'LINESTRING(1 1,1 0,0 0)'); +SELECT '#1998.X0' as lbl, count(*) FROM ValidateTopology('t1998') GROUP BY lbl; +SELECT '#1998.N-', ST_ModEdgeHeal('t1998', 2, 3); +SELECT '#1998.M2', ST_AsText(geom) FROM t1998.edge WHERE edge_id = 2; +SELECT '#1998.X1' as lbl, count(*) FROM ValidateTopology('t1998') GROUP BY lbl; +SELECT '#1998.-', topology.DropTopology('t1998'); + +------------------------------------------------------------------------- +------------------------------------------------------------------------- +------------------------------------------------------------------------- + -- TODO: test registered but unexistent topology -- TODO: test registered but corrupted topology -- (missing node, edge, relation...) diff --git a/topology/test/regress/st_modedgeheal_expected b/topology/test/regress/st_modedgeheal_expected index 94e5294e8..f9fb8c39d 100644 --- a/topology/test/regress/st_modedgeheal_expected +++ b/topology/test/regress/st_modedgeheal_expected @@ -139,3 +139,12 @@ Topology 't' dropped #1955.3|H:6,7|N7|deleted #1955.3|4|nodes left #1955|Topology 't' dropped +#1998.+|t +#1998.N1|1 +#1998.N2|2 +#1998.E1|1 +#1998.E2|2 +#1998.E3|3 +#1998.N-|2 +#1998.M2|LINESTRING(1 1,1 0,0 0,0 1,1 1) +#1998.-|Topology 't1998' dropped diff --git a/topology/test/regress/st_newedgeheal.sql b/topology/test/regress/st_newedgeheal.sql index e3192205d..9f529f235 100644 --- a/topology/test/regress/st_newedgeheal.sql +++ b/topology/test/regress/st_newedgeheal.sql @@ -157,6 +157,25 @@ SELECT '#1955', topology.DropTopology('t'); ------------------------------------------------------------------------- ------------------------------------------------------------------------- +-- Another case of merging edges sharing both endpoints +-- See http://trac.osgeo.org/postgis/ticket/1998 + +SELECT '#1998.+', CreateTopology('t1998') > 1; +SELECT '#1998.N1', ST_AddIsoNode('t1998', 0, 'POINT(1 1)'); +SELECT '#1998.N2', ST_AddIsoNode('t1998', 0, 'POINT(0 0)'); +SELECT '#1998.E1', ST_AddEdgeModFace('t1998', 1, 1, 'LINESTRING(1 1,1 2,2 2,2 1,1 1)'); +SELECT '#1998.E2', ST_AddEdgeModFace('t1998', 2, 1, 'LINESTRING(0 0,0 1,1 1)'); +SELECT '#1998.E3', ST_AddEdgeModFace('t1998', 1, 2, 'LINESTRING(1 1,1 0,0 0)'); +SELECT '#1998.X0' as lbl, count(*) FROM ValidateTopology('t1998') GROUP BY lbl; +SELECT '#1998.NE', ST_NewEdgeHeal('t1998', 2, 3); +SELECT '#1998.NE4', ST_AsText(geom) FROM t1998.edge WHERE edge_id = 4; +SELECT '#1998.X1' as lbl, count(*) FROM ValidateTopology('t1998') GROUP BY lbl; +SELECT '#1998.-', topology.DropTopology('t1998'); + +------------------------------------------------------------------------- +------------------------------------------------------------------------- +------------------------------------------------------------------------- + -- TODO: test registered but unexistent topology -- TODO: test registered but corrupted topology diff --git a/topology/test/regress/st_newedgeheal_expected b/topology/test/regress/st_newedgeheal_expected index 09be659bc..2e127b695 100644 --- a/topology/test/regress/st_newedgeheal_expected +++ b/topology/test/regress/st_newedgeheal_expected @@ -139,3 +139,12 @@ Topology 't' dropped #1955.3|H:8,9|E11|created #1955.3|4|nodes left #1955|Topology 't' dropped +#1998.+|t +#1998.N1|1 +#1998.N2|2 +#1998.E1|1 +#1998.E2|2 +#1998.E3|3 +#1998.NE|4 +#1998.NE4|LINESTRING(1 1,1 0,0 0,0 1,1 1) +#1998.-|Topology 't1998' dropped