From 3e08ad3a3a43389516e5684afbc390863b82029c Mon Sep 17 00:00:00 2001 From: Sandro Santilli Date: Sat, 28 Jan 2012 17:05:34 +0000 Subject: [PATCH] Simplify code in _ST_AddFaceSplit, reduce edges table scans. Also set debugging off by default git-svn-id: http://svn.osgeo.org/postgis/trunk@8959 b70326c6-7e19-0410-871a-916f4a2858ee --- topology/sql/sqlmm.sql.in.c | 106 ++++++++++++------------------------ 1 file changed, 35 insertions(+), 71 deletions(-) diff --git a/topology/sql/sqlmm.sql.in.c b/topology/sql/sqlmm.sql.in.c index 4d34def10..a6ceec1ee 100644 --- a/topology/sql/sqlmm.sql.in.c +++ b/topology/sql/sqlmm.sql.in.c @@ -13,7 +13,7 @@ -- -- -#define POSTGIS_TOPOLOGY_DEBUG 1 +/*#define POSTGIS_TOPOLOGY_DEBUG 1*/ --={ ---------------------------------------------------------------- -- SQL/MM block @@ -2692,6 +2692,7 @@ DECLARE newface INTEGER; sql TEXT; isccw BOOLEAN; + ishole BOOLEAN; BEGIN @@ -2796,7 +2797,7 @@ BEGIN || quote_literal(array( select +(x) from unnest(fan.newring_edges) u(x) )::text) || ')'; #ifdef POSTGIS_TOPOLOGY_DEBUG - RAISE DEBUG 'Updating forward edges'; + RAISE DEBUG 'Updating forward edges in new ring'; #endif EXECUTE sql; @@ -2807,7 +2808,7 @@ BEGIN || quote_literal(array( select -(x) from unnest(fan.newring_edges) u(x) )::text) || ')'; #ifdef POSTGIS_TOPOLOGY_DEBUG - RAISE DEBUG 'Updating backward edges'; + RAISE DEBUG 'Updating backward edges in new ring'; #endif EXECUTE sql; @@ -2816,82 +2817,46 @@ BEGIN #ifdef POSTGIS_TOPOLOGY_DEBUG RAISE DEBUG 'Updating rings in former shell'; #endif - -- TODO: use a single query - - -- Update edges having new face on the left - sql := 'UPDATE ' - || quote_ident(atopology) || '.edge_data SET left_face = ' || newface - || ' WHERE left_face = ' || oface || ' AND NOT edge_id = ANY (' - || quote_literal(array( select abs(x) from unnest(fan.newring_edges) u(x) )::text) - || ') AND NOT ST_Contains(' || quote_literal(fan.shell::text) || '::geometry, geom)'; -#ifdef POSTGIS_TOPOLOGY_DEBUG - RAISE DEBUG 'Updating non-contained edges having new face on the left'; -#endif - EXECUTE sql; - - -- Update edges having new face on the right - sql := 'UPDATE ' - || quote_ident(atopology) || '.edge_data SET right_face = ' || newface - || ' WHERE right_face = ' || oface || ' AND NOT edge_id = ANY (' - || quote_literal(array( select abs(x) from unnest(fan.newring_edges) u(x) )::text) - || ') AND NOT ST_Contains(' || quote_literal(fan.shell::text) || '::geometry, geom)'; -#ifdef POSTGIS_TOPOLOGY_DEBUG - RAISE DEBUG 'Updating non-contained edges having new face on the right'; -#endif - EXECUTE sql; - - -- Update isolated nodes in new new face - sql := 'UPDATE ' - || quote_ident(atopology) || '.node SET containing_face = ' || newface - || ' WHERE containing_face = ' || oface - || ' AND NOT ST_Contains(' || quote_literal(fan.shell::text) || '::geometry, geom)'; -#ifdef POSTGIS_TOPOLOGY_DEBUG - RAISE DEBUG 'Updating non-contained isolated nodes'; -#endif - EXECUTE sql; - - END IF; -- } - - IF oface = 0 OR isccw THEN -- { - + ishole := true; + ELSE #ifdef POSTGIS_TOPOLOGY_DEBUG RAISE DEBUG 'Updating contained edges'; #endif - -- TODO: use a single query - - -- Update edges having new face on the left - sql := 'UPDATE ' - || quote_ident(atopology) || '.edge_data SET left_face = ' || newface - || ' WHERE left_face = ' || oface || ' AND NOT edge_id = ANY (' - || quote_literal(array( select abs(x) from unnest(fan.newring_edges) u(x) )::text) - || ') AND ST_Contains(' || quote_literal(fan.shell::text) || '::geometry, geom)'; -#ifdef POSTGIS_TOPOLOGY_DEBUG - RAISE DEBUG 'Updating contained edges having old face on the left'; -#endif - EXECUTE sql; + ishole := false; + END IF; - -- Update edges having new face on the right - sql := 'UPDATE ' - || quote_ident(atopology) || '.edge_data SET right_face = ' || newface - || ' WHERE right_face = ' || oface || ' AND NOT edge_id = ANY (' - || quote_literal(array( select abs(x) from unnest(fan.newring_edges) u(x) )::text) - || ') AND ST_Contains(' || quote_literal(fan.shell::text) || '::geometry, geom)'; + -- Update edges having new face on the left + sql := 'UPDATE ' + || quote_ident(atopology) + || '.edge_data SET left_face = CASE WHEN left_face = ' + || oface || ' THEN ' || newface + || ' ELSE left_face END, right_face = CASE WHEN right_face = ' + || oface || ' THEN ' || newface + || ' ELSE right_face END WHERE ( left_face = ' || oface + || ' OR right_face = ' || oface + || ') AND NOT edge_id = ANY (' + || quote_literal( array( + select abs(x) from unnest(fan.newring_edges) u(x) + )::text ) + || ') AND '; + IF ishole THEN sql := sql || 'NOT '; END IF; + sql := sql || 'ST_Contains(' || quote_literal(fan.shell::text) || '::geometry, geom)'; #ifdef POSTGIS_TOPOLOGY_DEBUG - RAISE DEBUG 'Updating contained edges having old face on the right'; + RAISE DEBUG 'Updating edges binding old face'; #endif - EXECUTE sql; + EXECUTE sql; - -- Update isolated nodes in new new face - sql := 'UPDATE ' - || quote_ident(atopology) || '.node SET containing_face = ' || newface - || ' WHERE containing_face = ' || oface - || ' AND ST_Contains(' || quote_literal(fan.shell::text) || '::geometry, geom)'; + -- Update isolated nodes in new new face + sql := 'UPDATE ' + || quote_ident(atopology) || '.node SET containing_face = ' || newface + || ' WHERE containing_face = ' || oface + || ' AND '; + IF ishole THEN sql := sql || 'NOT '; END IF; + sql := sql || 'ST_Contains(' || quote_literal(fan.shell::text) || '::geometry, geom)'; #ifdef POSTGIS_TOPOLOGY_DEBUG - RAISE DEBUG 'Updating contained isolated nodes'; + RAISE DEBUG 'Updating isolated nodes in old face'; #endif - EXECUTE sql; - - END IF; -- } + EXECUTE sql; RETURN newface; @@ -4404,4 +4369,3 @@ LANGUAGE 'plpgsql' VOLATILE; --=} SQL/MM block -#undef POSTGIS_TOPOLOGY_DEBUG -- 2.40.0