dijkstra (#16) - Solution for getting "parts" of lines (#281) - Message List
Dear users,
the pgrouting algorith as knows has the problem that after clicking in a map in the most cases not the "whole" route is visualised (or a bit too much), see it here:
http://www.kneipenculture.de/routing_works.png
With the following function a point on a multiline is caught:
geometry)
RETURNS geometry AS
$BODY$ DECLARE
mindistance float8; nearestlinestring geometry; nearestpoint geometry; i integer;
BEGIN
mindistance := (distance(apoint,amultils)+100); FOR i IN 1 .. NumGeometries?(amultils) LOOP
if distance(apoint,GeometryN(amultils,i)) < mindistance THEN
mindistance:=distance(apoint,GeometryN(amultils,i)); nearestlinestring:=GeometryN(amultils,i);
END IF;
END LOOP;
nearestpoint:=line_interpolate_point(nearestlinestring,line_locate_point(nearestlinestring,apoint));
RETURN nearestpoint;
END; $BODY$
LANGUAGE 'plpgsql' IMMUTABLE STRICT;
....and with the following function the part between the point and the (before that) missing routing-part is drwan:
CREATE OR REPLACE FUNCTION schnittpunkt(gid_a integer,gid_b integer,start geometry)
RETURNS geometry AS
$BODY$ DECLARE intercept_point geometry; number_of_points integer; first_point_of_geometry geometry; j integer; point_geom geometry; line text; mywkt text; p text; new_factor integer; endgeometry geometry[] := '{}';
BEGIN
RAISE NOTICE 'Here we go........';
--Give me the intercept point of two geometries we use...... intercept_point:= ST_astext(intersection(a.the_geom, b.the_geom)) from (select the_geom from ways where gid=$1)a, (select the_geom from ways where gid = $2) b;
RAISE NOTICE 'intercept_point %',astext(intercept_point);
-- Give me the number of points of the geometry we touch with the start-point number_of_points:=ST_NumPoints(the_geom) from ways where gid=$1;
mywkt:=; line:=;
RAISE NOTICE 'Numer of points in that geometry is %',number_of_points;
first_point_of_geometry:=PointN(c.the_geom,1) from (select (the_geom) from ways where gid=$1)c,ways where gid=$1;
-- If intercept_point and first point of geometry (with start point) is equal IF astext(intercept_point)=astext(first_point_of_geometry) THEN
RAISE NOTICE 'Equal!!';
FOR j IN 1 .. number_of_points LOOP
point_geom:=PointN(c.the_geom,j) from (select (the_geom) from ways where gid=$1)c,ways where gid=$1;
RAISE NOTICE 'Call: %',j; endgeometry[j]:=point_geom;
RAISE NOTICE 'The point is %',astext(point_geom);
line:=;
line:= line
-- A line is build
line:='LINESTRING'
SELECT INTO p ST_intersects(line,buffer($3,1));
IF j=1 THEN
mywkt:= mywkt
IF p!= 't' THEN RAISE NOTICE 'The start point does not touch a part of a multiline';
mywkt:= mywkt
END IF;
IF p = 't' THEN RAISE NOTICE 'Interesting: Start point touches part of multiline, we replace it!!';
mywkt:= mywkt
mywkt:='MULTILINESTRING'
END LOOP;
ELSE
-- Ok, intercept_point and first point of geometry (with start point)are not equal -- We have to go "thr other way round"
FOR j IN 1 .. number_of_points LOOP
new_factor:=number_of_points+1-j;
point_geom:=PointN(c.the_geom,new_factor) from (select (the_geom) from ways where gid=$1)c,ways where gid=$1;
RAISE NOTICE 'Call number: %',j; endgeometry[j]:=point_geom;
RAISE NOTICE 'The point is at %',astext(point_geom);
line:=;
line:= line
line:='LINESTRING'
SELECT INTO p ST_intersects(line,buffer($3,1));
IF j=1 THEN
mywkt:= mywkt
IF p!= 't' THEN RAISE NOTICE 'The start point does not touch a part of a multiline';
mywkt:= mywkt
END IF;
IF p = 't' THEN RAISE NOTICE 'The start point touches a part of a multiline';
mywkt:= mywkt
mywkt:='MULTILINESTRING'
END LOOP;
END IF;
RETURN mywkt;
END; $BODY$
LANGUAGE 'plpgsql' IMMUTABLE STRICT;
I will integrate it in here http://pgrouting.postlbs.org/wiki/WorkshopOL2.7andOSM
within the next days to make this clearer.
Best regards, Kai
-
Message #980
Ups, the first part of the first function was cut,
It needs to be like this:
CREATE OR REPLACE FUNCTION multiline_locate_point(amultils geometry,apoint geometry)
RETURNS geometry AS
$BODY$ DECLARE
mindistance float8; nearestlinestring geometry; nearestpoint geometry; i integer;
BEGIN
mindistance := (distance(apoint,amultils)+100); FOR i IN 1 .. NumGeometries?(amultils) LOOP
if distance(apoint,GeometryN(amultils,i)) < mindistance THEN
mindistance:=distance(apoint,GeometryN(amultils,i)); nearestlinestring:=GeometryN(amultils,i);
END IF;
END LOOP;
nearestpoint:=line_interpolate_point(nearestlinestring,line_locate_point(nearestlinestring,apoint));
RETURN nearestpoint;
END; $BODY$
LANGUAGE 'plpgsql' IMMUTABLE STRICT;
Kai-Behncke07/12/09 21:37:30 (17 months ago)-
Message #1030
The tutorial has been updated now, you find it at:
http://pgrouting.postlbs.org/wiki/WorkshopOL2.7andOSM
Now the "gaps" are filled:
http://www.kneipenculture.de/filling_the_gaps.PNG
It works also with OL 2.8
Best regards, Kai
Kai-Behncke08/20/09 05:15:14 (15 months ago)
-
Powered by Trac 0.11.5rc1
By Edgewall Software.
pgRouting is a project of PostLBS
http://www.postlbs.org/