From 8aaa246193f9ac06c4770db3f75ec810441a2fd3 Mon Sep 17 00:00:00 2001 From: Sandro Santilli Date: Tue, 24 May 2011 13:15:01 +0000 Subject: [PATCH] ST_AddEdgeNewFaces: don't get fooled by empty segments when computing azimuts [RT-SIGTA] git-svn-id: http://svn.osgeo.org/postgis/trunk@7232 b70326c6-7e19-0410-871a-916f4a2858ee --- topology/sql/sqlmm.sql | 42 ++++++++++++------- topology/test/regress/st_addedgenewfaces.sql | 26 ++++++++++++ .../test/regress/st_addedgenewfaces_expected | 10 +++++ 3 files changed, 64 insertions(+), 14 deletions(-) diff --git a/topology/sql/sqlmm.sql b/topology/sql/sqlmm.sql index bd022c9c8..1c444ce10 100644 --- a/topology/sql/sqlmm.sql +++ b/topology/sql/sqlmm.sql @@ -1877,6 +1877,7 @@ DECLARE sql TEXT; newfaces INTEGER[]; newface INTEGER; + cleangeom GEOMETRY; BEGIN -- @@ -2045,25 +2046,29 @@ BEGIN quote_ident(atopology) || '.edge_data_edge_id_seq') || ')' INTO STRICT newedge.edge_id; + cleangeom := ST_RemoveRepeatedPoints(acurve); + -- Compute azimut of first edge end on start node SELECT null::int AS nextCW, null::int AS nextCCW, null::float8 AS minaz, null::float8 AS maxaz, false AS was_isolated, - ST_Azimuth(ST_StartPoint(acurve), - ST_PointN(acurve, 2)) AS myaz - -- TODO: second point might be equals to first point... - -- ... we should check that and find a better candidate + ST_Azimuth(ST_StartPoint(cleangeom), + ST_PointN(cleangeom, 2)) AS myaz INTO span; + IF span.myaz IS NULL THEN + RAISE EXCEPTION 'Invalid edge (no two distinct nodes exist)'; + END IF; -- Compute azimuth of last edge end on end node SELECT null::int AS nextCW, null::int AS nextCCW, null::float8 AS minaz, null::float8 AS maxaz, false AS was_isolated, - ST_Azimuth(ST_EndPoint(acurve), - ST_PointN(acurve, ST_NumPoints(acurve)-1)) AS myaz - -- TODO: one-to-last point might be equals to last point... - -- ... we should check that and find a better candidate + ST_Azimuth(ST_EndPoint(cleangeom), + ST_PointN(cleangeom, ST_NumPoints(cleangeom)-1)) AS myaz INTO epan; + IF epan.myaz IS NULL THEN + RAISE EXCEPTION 'Invalid edge (no two distinct nodes exist)'; + END IF; -- Find links on start node -- { @@ -2090,24 +2095,31 @@ BEGIN i := i + 1; + cleangeom := ST_RemoveRepeatedPoints(rec.geom); + IF rec.start_node = anode THEN -- -- Edge starts at our node, we compute -- azimuth from node to its second point -- - az := ST_Azimuth(ST_StartPoint(acurve), ST_PointN(rec.geom, 2)); + az := ST_Azimuth(ST_StartPoint(cleangeom), ST_PointN(cleangeom, 2)); ELSE -- -- Edge ends at our node, we compute -- azimuth from node to its second-last point -- - az := ST_Azimuth(ST_StartPoint(acurve), - ST_PointN(rec.geom, ST_NumPoints(rec.geom)-1)); + az := ST_Azimuth(ST_EndPoint(cleangeom), + ST_PointN(cleangeom, ST_NumPoints(cleangeom)-1)); rec.edge_id := -rec.edge_id; END IF; + IF az IS NULL THEN + RAISE EXCEPTION 'Invalid edge % found (no two distinct nodes exist)', + rec.edge_id; + END IF; + RAISE DEBUG 'Edge % - az % (%) - fl:% fr:%', rec.edge_id, az, az - span.myaz, rec.left_face, rec.right_face; @@ -2200,20 +2212,22 @@ BEGIN i := i + 1; + cleangeom := ST_RemoveRepeatedPoints(rec.geom); + IF rec.start_node = anothernode THEN -- -- Edge starts at our node, we compute -- azimuth from node to its second point -- - az := ST_Azimuth(ST_EndPoint(acurve), ST_PointN(rec.geom, 2)); + az := ST_Azimuth(ST_StartPoint(cleangeom), ST_PointN(cleangeom, 2)); ELSE -- -- Edge ends at our node, we compute -- azimuth from node to its second-last point -- - az := ST_Azimuth(ST_EndPoint(acurve), - ST_PointN(rec.geom, ST_NumPoints(rec.geom)-1)); + az := ST_Azimuth(ST_EndPoint(cleangeom), + ST_PointN(cleangeom, ST_NumPoints(cleangeom)-1)); rec.edge_id := -rec.edge_id; END IF; diff --git a/topology/test/regress/st_addedgenewfaces.sql b/topology/test/regress/st_addedgenewfaces.sql index a1672acb7..0cc0d4908 100644 --- a/topology/test/regress/st_addedgenewfaces.sql +++ b/topology/test/regress/st_addedgenewfaces.sql @@ -307,6 +307,32 @@ SELECT 'T19', 'E'||edge_id, next_left_edge, next_right_edge, ( SELECT edge_id FROM newedge WHERE id = 19 ) ) ORDER BY edge_id; +-- +-- New face in universal face, with both endpoints on same existing edge +-- and endpoints duplicated +-- +INSERT INTO newedge SELECT 20, topology.st_addedgenewfaces('city_data', + 10, 11, 'LINESTRING(35 6, 35 6, 44 0, 47 6, 47 6)'); +SELECT 'T20', 'E'||edge_id, next_left_edge, next_right_edge, + left_face, right_face FROM + city_data.edge WHERE edge_id IN ( 36, 14, 16, + ( SELECT edge_id FROM newedge WHERE id = 20 ) ) + ORDER BY edge_id; + +-- +-- Another face in universal face, with both endpoints on same existing edge +-- and both edges' endpoints duplicated +-- +INSERT INTO newedge SELECT 21, topology.st_addedgenewfaces('city_data', + 10, 11, 'LINESTRING(35 6, 35 6, 44 -4, 47 6, 47 6)'); +SELECT 'T21', 'E'||edge_id, next_left_edge, next_right_edge, + left_face, right_face FROM + city_data.edge WHERE edge_id IN ( + SELECT edge_id FROM newedge WHERE id IN (20, 21) + UNION VALUES (36),(16) ) + ORDER BY edge_id; + + --------------------------------------------------------------------- -- Check new relations and faces status --------------------------------------------------------------------- diff --git a/topology/test/regress/st_addedgenewfaces_expected b/topology/test/regress/st_addedgenewfaces_expected index fb955b882..d91a5a70d 100644 --- a/topology/test/regress/st_addedgenewfaces_expected +++ b/topology/test/regress/st_addedgenewfaces_expected @@ -87,6 +87,14 @@ T19|E12|-31|-45|20|34 T19|E22|37|32|0|21 T19|E35|35|45|26|0 T19|E45|22|-12|0|34 +T20|E14|16|46|14|35 +T20|E16|29|-46|14|0 +T20|E36|-13|-36|0|27 +T20|E46|-14|36|35|0 +T21|E16|29|-47|14|0 +T21|E36|-13|-36|0|27 +T21|E46|-14|47|35|36 +T21|E47|-46|36|36|0 F3,F4|{3:10,3:11,3:23,3:24,3:25} F5,N4|{1:4,3:12,3:13} F0| @@ -115,4 +123,6 @@ F31|POLYGON((17 30,17 40,31 40,31 30,17 30)) F32|POLYGON((20 34,20 37,23 37,23 34,20 34)) F33|POLYGON((35 25,35 45,63 45,63 25,35 25)) F34|POLYGON((9 0,9 6,21 6,21 0,9 0)) +F35|POLYGON((35 0,35 6,47 6,47 0,35 0)) +F36|POLYGON((35 -4,35 6,47 6,47 -4,35 -4)) Topology 'city_data' dropped -- 2.50.1