[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