Last active
July 8, 2016 14:23
-
-
Save worthlutz/72fce4ba32093754c1d4f819707e595a to your computer and use it in GitHub Desktop.
pgrw_xyroute is an example of a wrapper around the pgr_trsp function to require only x/y inputs for source and target points. Routing is then done by pgr_trsp using the nearest location on the closest edges to the source and target points.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
pgrw_xyroute is an example of a wrapper around the pgr_trsp function to require only x/y inputs | |
for source and target points. Routing is then done by pgr_trsp using the nearest location on | |
the closest edges to the source and target points. To achieve this result, the details of the | |
specific routing network are hard-coded as constants in the wrapper. Modification to your | |
specific situation should be simple. | |
*/ | |
CREATE OR REPLACE FUNCTION pgrw_xyroute(source_x double precision, source_y double precision, | |
target_x double precision, target_y double precision) | |
RETURNS SETOF pgr_costresult | |
AS | |
$BODY$ | |
DECLARE | |
edge_tbl_name CONSTANT TEXT = '_rt_geom_streets_base'; -- edge table name | |
srid CONSTANT INTEGER = 2264; -- edge table and x,y srid | |
cost_column CONSTANT TEXT = 'cost_len'; -- cost_len | cost_time | |
rcost_column CONSTANT TEXT = 'rcost_len'; -- rcost_len | rcost_time | |
local_radius CONSTANT DOUBLE PRECISION = 5280.0; -- radius in ft. for selecting all edges around point | |
-- sql to locate the closest edge to the source and target points is built from sql1, sql2, sql3 & sql4 | |
-- SELECT | |
-- id, | |
-- ST_LineLocatePoint(the_geom, ST_SetSRID(ST_Point( source_x, source_x), srid)) AS fraction | |
-- FROM edge_tbl_name | |
-- WHERE ST_DWithin(the_geom, ST_SetSRID(ST_Point(source_x, source_x), srid), local_radius) | |
-- ORDER BY ST_Distance(the_geom, ST_SetSRID(ST_Point(source_x, source_y), srid)) ASC | |
-- LIMIT 1 | |
-- returns a record (id, fraction) | |
sql1 CONSTANT TEXT = 'SELECT id, ST_LineLocatePoint(the_geom, '; | |
-- point definition sql goes here | |
sql2 CONSTANT TEXT = ') AS fraction FROM ' || edge_tbl_name || ' WHERE ST_DWithin(the_geom, '; | |
-- point definition sql goes here | |
sql3 CONSTANT TEXT = ', ' || local_radius || ') ORDER BY ST_Distance(the_geom, '; | |
-- point definition sql goes here | |
sql4 CONSTANT TEXT = ') ASC LIMIT 1'; | |
-- this defines the select for ALL edges in the edge table | |
edge_select CONSTANT TEXT = 'SELECT | |
id, source, target, ' || cost_column || ' AS cost, ' || cost_column || ' AS reverse_cost | |
FROM ' || edge_tbl_name; | |
-- WHERE clause to limit edges to major roads | |
major_roads_where CONSTANT TEXT = $$ WHERE sd_flag = 'ROADS' $$; | |
source_point TEXT; -- point definition sql for source point | |
target_point TEXT; -- point definition sql for target point | |
source_edge RECORD; -- nearest edge to source point | |
target_edge RECORD; -- nearest edge to target point | |
edge_sql TEXT; -- sql to select edges to use for routing | |
BEGIN | |
-- point definition sql for source point | |
source_point = 'ST_SetSRID(ST_Point(' || source_x || ',' || source_y || '), ' || srid || ')'; | |
EXECUTE sql1 || source_point || sql2 || source_point || sql3 || source_point || sql4 | |
INTO source_edge; | |
IF source_edge.id IS NULL THEN | |
RAISE NOTICE '** source_edge.id IS NULL **'; | |
END IF; | |
-- point definition sql for target point | |
target_point = 'ST_SetSRID(ST_Point(' || target_x || ',' || target_y || '), ' || srid || ')'; | |
EXECUTE sql1 || target_point || sql2 || target_point || sql3 || target_point || sql4 | |
INTO target_edge; | |
IF target_edge.id IS NULL THEN | |
RAISE NOTICE '** target_edge.id IS NULL **'; | |
END IF; | |
-- there are three edge selects unioned here: | |
-- all edges within 'local_radius' of the source point | |
-- all 'Major' roads in the table (marked with sd_flag='ROADS') | |
-- all edges within 'street_radius' of the target point | |
edge_sql := edge_select || ' WHERE ST_DWithin(the_geom, ' || source_point || ', ' || local_radius || ') | |
UNION '|| edge_select || major_roads_where || ' | |
UNION '|| edge_select || ' WHERE ST_DWithin(the_geom, ' || target_point || ', ' || local_radius || ') | |
'; | |
RETURN QUERY SELECT * | |
FROM pgr_trsp(edge_sql, source_edge.id, source_edge.fraction, target_edge.id, target_edge.fraction, TRUE, TRUE); | |
END; | |
$BODY$ | |
LANGUAGE plpgsql IMMUTABLE | |
COST 100 | |
ROWS 1000; | |
/* | |
-- test function only | |
SELECT (pgrw_xyroute(2088111,731419,2088111,700700)).*; | |
-- get all edge data for route | |
WITH route AS ( | |
SELECT (pgrw_xyroute(2088111,731419,2088111,700700)).* | |
) | |
SELECT * | |
FROM _rt_geom_streets_base edges | |
JOIN route | |
ON edges.id = route.id2 | |
*/ | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment