<div dir="ltr"><div><div><div><div><div>Hey,<br></div>I noticed that QGIs is introducing slight errors when editing topology edge_data layer (with the regular edition, no pluggin ).<br><br></div>This is dangerous because function such a s ST_getFaceGeometry won't work afterward (in some case).<br>
<br></div>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).<br><br></div>Here is the code (one function, then the trigger using it).<br>
<br></div>Cheers,<br>Rémi-C<br><div>PS : I'm going to put it online, but I can't now.<br></div><div>--------------------<br><br>DROP FUNCTION IF EXISTS rc_CleanEdge_geom(toponame character varying, IN iedge_id integer, INOUT igeom GEOMETRY, IN tolerance FLOAT );<br>
<br>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<br>$BODY$<br> --@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<br>
DECLARE <br>r record; <br>q text;<br>BEGIN<br><br> --getting the end point<br> q:= ' SELECT ed.edge_id, ed.start_node, ed.end_node, ed.geom ,<br> n1.geom AS start_node_geom, n2.geom AS end_node_geom<br>
, ST_StartPoint($2) AS start_point, ST_EndPoint($2) AS end_point<br> ,ST_NPoints($2)-1 AS npoints<br> FROM ' || quote_ident(toponame)||'.edge_data AS ed<br> INNER JOIN ' || quote_ident(toponame)||'.node AS n1 ON (ed.start_node = n1.node_id)<br>
INNER JOIN ' || quote_ident(toponame)||'.node AS n2 ON (ed.end_node = n2.node_id)<br> WHERE ed.edge_id = $1 ;';<br><br> EXECUTE q INTO r USING iedge_id, igeom; <br> <br> IF ST_DWithin(r.start_point ,r.start_node_geom , tolerance) THEN igeom:= ST_SetPoint(igeom, 0, r.start_node_geom);<br>
END IF;<br> IF ST_DWithin( r.end_point ,r.end_node_geom , tolerance) THEN igeom:= ST_SetPoint(igeom, r.npoints, r.end_node_geom);<br> END IF; <br> <br> RETURN ; <br>END<br>$BODY$<br> LANGUAGE plpgsql VOLATILE ;<br>
---------------<br><br><br><br><br><br> --correct topoloogy precision on edge_data trigger<br> CREATE OR REPLACE FUNCTION rc_enforce_edge_precison_on_edge_data_geom_change( )<br> RETURNS trigger AS<br>
$BODY$ <br> --this trigger is designed to update the result of street amp processing when edge_data is modified. <br> --The directly impacted tables are result_arc, result_axis and result_intersection<br>
--the inderectly impacted tables are visualisation tables. <br><br> --if the event is a deleting. Delete stuff accordingly and relaunch on previous geometry<br> --if the eventis update or insert, juste update on modified geometry<br>
DECLARE <br> BEGIN <br> SELECT rc_CleanEdge_geom(<br> TG_TABLE_SCHEMA::text<br> , NEW.edge_id<br> ,NEW.geom<br>
,(SELECT precision FROM topology.topology WHERE name = TG_TABLE_SCHEMA::text) <br> ) INTO NEW.geom <br> FROM bdtopo_topological.edge_data <br>
WHERE edge_id = NEW.edge_id ;<br><br> <br> returN NEW;<br> END ;<br> $BODY$<br> LANGUAGE plpgsql VOLATILE;<br><br> DROP TRIGGER IF EXISTS rc_enforce_edge_precison_on_edge_data_geom_change ON edge_data; <br>
CREATE TRIGGER rc_enforce_edge_precison_on_edge_data_geom_change BEFORE UPDATE <br> ON edge_data<br> FOR EACH ROW <br> WHEN (ST_Equals(NEW.geom , OLD.geom)=FALSE) --only triggering that when change in geom<br>
EXECUTE PROCEDURE rc_enforce_edge_precison_on_edge_data_geom_change(); <br><br><br><br></div></div>