[postgis-users] Editing Topology with QGIs, nno more precision issues

Rémi Cura remi.cura at gmail.com
Tue Aug 5 11:04:55 PDT 2014


Hey,
I noticed that QGIs is introducing slight errors when editing topology
edge_data layer (with the regular edition, no pluggin ).

This is dangerous because function such a s ST_getFaceGeometry won't work
afterward (in some case).

SO here is a trigger designed to snap the modified edge_data onto the
correct node (begin/end) (if within the "precision" set at the topology
creation).

Here is the code (one function, then the trigger using it).

Cheers,
Rémi-C
PS : I'm going to put it online, but I can't now.
--------------------

DROP FUNCTION IF EXISTS rc_CleanEdge_geom(toponame character varying, IN
iedge_id integer, INOUT igeom GEOMETRY, IN tolerance FLOAT  );

CREATE OR REPLACE FUNCTION public.rc_CleanEdge_geom(toponame character
varying, IN  iedge_id integer, INOUT igeom GEOMETRY, IN tolerance FLOAT
DEFAULT 0.01 )   AS
$BODY$
    -- at brief given a precision , for an edge in edge_data (we use the geom
that is provided), snap the start/end point to node if it is within the
correct distance
DECLARE
r record;
q text;
BEGIN

    --getting the end point
    q:= '  SELECT ed.edge_id, ed.start_node, ed.end_node, ed.geom ,
            n1.geom AS start_node_geom, n2.geom AS end_node_geom
            , ST_StartPoint($2) AS start_point, ST_EndPoint($2) AS end_point
            ,ST_NPoints($2)-1 AS npoints
        FROM  ' || quote_ident(toponame)||'.edge_data AS ed
            INNER JOIN  ' || quote_ident(toponame)||'.node AS n1 ON
(ed.start_node = n1.node_id)
            INNER JOIN  ' || quote_ident(toponame)||'.node AS n2 ON
(ed.end_node = n2.node_id)
        WHERE ed.edge_id = $1 ;';

    EXECUTE q INTO r USING iedge_id, igeom;

    IF ST_DWithin(r.start_point ,r.start_node_geom , tolerance) THEN
igeom:= ST_SetPoint(igeom, 0, r.start_node_geom);
    END IF;
    IF ST_DWithin( r.end_point ,r.end_node_geom , tolerance) THEN igeom:=
ST_SetPoint(igeom, r.npoints, r.end_node_geom);
    END IF;

    RETURN ;
END
$BODY$
  LANGUAGE plpgsql VOLATILE ;
---------------





        --correct topoloogy precision on edge_data trigger
        CREATE OR REPLACE FUNCTION
rc_enforce_edge_precison_on_edge_data_geom_change(  )
          RETURNS  trigger  AS
        $BODY$
            --this trigger is designed to update the result of street amp
processing when edge_data is modified.
            --The directly impacted tables are result_arc, result_axis and
result_intersection
                --the inderectly impacted tables are visualisation tables.

            --if the event is a deleting. Delete stuff accordingly and
relaunch on previous geometry
            --if the eventis update or insert, juste update on modified
geometry
                DECLARE
                BEGIN
                     SELECT  rc_CleanEdge_geom(
                                    TG_TABLE_SCHEMA::text
                                    , NEW.edge_id
                                    ,NEW.geom
                                    ,(SELECT precision FROM
topology.topology WHERE name = TG_TABLE_SCHEMA::text)
                                ) INTO NEW.geom
                     FROM bdtopo_topological.edge_data
                     WHERE edge_id = NEW.edge_id ;


                returN NEW;
                END ;
                $BODY$
          LANGUAGE plpgsql VOLATILE;

        DROP TRIGGER IF EXISTS
rc_enforce_edge_precison_on_edge_data_geom_change ON edge_data;
        CREATE  TRIGGER rc_enforce_edge_precison_on_edge_data_geom_change
BEFORE  UPDATE
            ON edge_data
         FOR EACH ROW
         WHEN (ST_Equals(NEW.geom , OLD.geom)=FALSE) --only triggering that
when change in geom
            EXECUTE PROCEDURE
rc_enforce_edge_precison_on_edge_data_geom_change();
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/postgis-users/attachments/20140805/55253f07/attachment.html>


More information about the postgis-users mailing list