pggeodb.nancy.inra.fr/db_cefs - db_cefs on pggeodb.nancy.inra.fr
Previous topic Chapter index Next topic

Function: _st_addfacesplit

 

 

Schema

topology

 

Owner

postgres

 

Descriptions

There is no description for function _st_addfacesplit

 

Options

Option

Value

Returns

integer

Language

plpgsql

Parameters

atopology varchar

anedge integer

oface integer

mbr_only boolean

 

Definition

CREATE OR REPLACE FUNCTION topology._st_addfacesplit (
 atopology varchar,
 anedge integer,
 oface integer,
 mbr_only boolean
)
RETURNS integer AS
$span$
DECLARE

 fan RECORD;
 newface INTEGER;
 sql TEXT;
 isccw BOOLEAN;
 ishole BOOLEAN;

BEGIN

 IF
oface = 0 AND mbr_only THEN
   RETURN NULL
;
 END IF;

 SELECT null::int[] as newring_edges,
        null::geometry as shell
 INTO fan;

 SELECT array_agg(edge)
 FROM topology.getringedges(atopology, anedge)
 INTO STRICT fan.newring_edges;


 -- You can't get to the other side of an edge forming a ring
 IF fan.newring_edges @> ARRAY[-anedge] THEN
   RETURN
0;
 END IF;


 sql := 'WITH ids as ( select row_number() over () as seq, edge '
   || 'from unnest($1) u(edge) ), edges AS ( select CASE WHEN i.edge < 0 '
   || 'THEN ST_Reverse(e.geom) ELSE e.geom END as g FROM ids i left join '
   || quote_ident(atopology) || '.edge_data e ON(e.edge_id = abs(i.edge)) '
   || 'ORDER BY seq) SELECT ST_MakePolygon(ST_MakeLine(g.g)) FROM edges g';
 EXECUTE sql INTO fan.shell USING
   fan.newring_edges
 ;


 isccw := NOT ST_OrderingEquals(fan.shell, ST_ForceRHR(fan.shell));


 IF oface = 0 THEN
   IF NOT
isccw THEN
     RETURN NULL
;
   END IF;
 END IF;

 IF mbr_only AND oface != 0 THEN
   -- Update old face mbr (nothing to do if we're opening an hole)
   IF isccw THEN -- {
     sql := 'UPDATE '
       || quote_ident(atopology)
       || '.face SET mbr = $1 WHERE face_id = $2';
    EXECUTE sql USING
       ST_Envelope(fan.shell),
       oface
     ;
   END IF; -- }
   RETURN NULL;
 END IF;

 IF oface != 0 AND NOT isccw THEN -- {
   -- Face created an hole in an outer face

   sql := 'INSERT INTO '
     || quote_ident(atopology) || '.face(mbr) SELECT mbr FROM '
     || quote_ident(atopology)
     || '.face WHERE face_id = ' || oface
     || ' RETURNING face_id';
 ELSE
   sql := 'INSERT INTO '
     || quote_ident(atopology) || '.face(mbr) VALUES ($1) RETURNING face_id';
 END IF; -- }

 -- Insert new face

 EXECUTE sql INTO STRICT newface USING ST_Envelope(fan.shell);

 -- Update forward edges
 sql := 'UPDATE ' || quote_ident(atopology) ||
   '.edge_data SET left_face = $1 WHERE edge_id = ANY($3)'
 ;
 EXECUTE sql USING newface, oface,
   array(select +x from unnest(fan.newring_edges) u(x) where x > 0)
 ;

 -- Update backward edges
 sql := 'UPDATE ' || quote_ident(atopology) ||
   '.edge_data SET right_face = $1 WHERE edge_id = ANY($3)'
 ;
 EXECUTE sql USING newface, oface,
   array(select -x from unnest(fan.newring_edges) u(x) where x < 0)
 ;

 IF oface != 0 AND NOT isccw THEN -- {
   -- face shrinked, must update all non-contained edges and nodes

   ishole := true;
 ELSE
   ishole := false;
 END IF; -- }

 -- Update edges bounding the old face

 sql := 'UPDATE '
   || quote_ident(atopology)
   || '.edge_data SET left_face = CASE WHEN left_face = $2 THEN $3'
   || ' ELSE left_face END, right_face = CASE WHEN right_face = $2 '
   || ' THEN $3 ELSE right_face END WHERE ( left_face = $2 '
   || ' OR right_face = $2 ) AND NOT edge_id = ANY ($4) AND ';
 IF ishole THEN sql := sql || 'NOT '; END IF;
 sql := sql || '($1 && geom AND _ST_Contains($1'
   -- We only need to check a single point, but must not be an endpoint
   || ', ST_LineInterpolatePoint(geom, 0.2)) )';
 EXECUTE sql USING fan.shell, oface, newface,
   array(select abs(x) from unnest(fan.newring_edges) u(x));

 -- Update isolated nodes in new new face
 sql := 'UPDATE '
   || quote_ident(atopology) || '.node SET containing_face = $2 '
   || ' WHERE containing_face = $3 AND ';
 IF ishole THEN sql := sql || 'NOT '; END IF;
 sql := sql || 'ST_Contains($1, geom)';
 EXECUTE sql USING fan.shell, newface, oface;

 RETURN newface;

END
$span$
LANGUAGE
'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST
100;

This file was generated with SQL Manager for PostgreSQL (www.pgsqlmanager.com) at 13/03/2014 13:23
Previous topic Chapter index Next topic