# Create isochrone from multiple start points

I want to create an isochrone. For this I could use the pgr_drivingDistance function with pgRouting (http://docs.pgrouting.org/dev/src/driving_distance/doc/index.html) but it only takes one start node.

How could I compute isochrones efficiently from multiple start nodes?

• Can you show an example of what you want to achieve? Can't you just run the function many times and merge the results? Sep 26, 2013 at 12:02
• Isochrones (as i understand them) are "lines of equal travel time from a defined starting point". So having two starting points would not make sense. Or you'd have to elaborate more why you need multiple starting points. Sep 26, 2013 at 12:38
• The thing is that I want the max distance from all start nodes but looping on each start node with pgr_drivingDistance doesn't seem efficient to me. Sep 27, 2013 at 8:31

To make catchment areas (for example shortest cycling time to affected high schools, or shortest time to nearest hospitals) :

If there is not too many start_points, you can first manually union the result of each drivingdistance in a table and then filter with minimum cost for each node :

Step 1 : create table xxx as (select seq as id, id1 as node, id2 as edge, cost, the_geom from pgr_drivingDistance ([...],node1,[...]) union select [...] from pgr_drivingDistance ([...],node2,[...]) union ...

Step 2 : select id, node, edge, min(cost) as cost, the_geom from xxx group by id, node,edge, the_geom ;

If there's too many points to do it manually, create a function that will loop on the start_node_id and that return a table for step #1. I made this one (for pgrouting 1.5), for cycling isochrones around targets (global table cibles) with limits for each target (global table sectorisation) :

``````create or replace function isochrones_velo_depuis () returns table (cible_node int, gid int, geom geometry, vertex_id int, edge_id int , cost float8) as
\$BODY\$
declare
node record;
secteur geometry ;
begin
raise info 'Début du calcul...';
for node in select * from cibles order by nearest_node loop
raise info 'Traitement du noeud %', node.nearest_node ;
execute 'select geom from sectorisations as foo where ST_Contains (foo.geom,\$1)' into secteur using node.geom ;
return query execute 'SELECT ' || node.nearest_node || ' as cible_node, noeuds.noeud_id, noeuds.geom, route.vertex_id, route.edge_id, route.cost FROM noeuds
join
(select * from driving_distance (''
select gid as id,
depuis::int4 as source,
vers::int4 as target,
longueur_voirie*60/vitesse1/1000::float8 as cost,
longueur_voirie*60/vitesse2/1000::float8 as reverse_cost from bdtopo'','
|| node.nearest_node || ',
45,
true,
true)) as route
on
noeuds.noeud_id = route.vertex_id
join (select \$1 as geom) as s on ST_Contains (s.geom,noeuds.geom)' using secteur ;
end loop;
return ;
end
\$BODY\$
Language 'plpgsql' ;
``````

and then filter as in step #2 directly on the isochrones_velo_depuis ().

• It's a solution but it doesn't seem very efficient because pgr_drivingDistance will compute again each nodes for each new start node. What I'd like is that as in the dijkstra algorithm if a shortest path is found for a node, pgr_drivingDistance stop computing paths after this node for next start nodes. Sep 27, 2013 at 8:46
• @yowza Summing up the cost of the path is relatively insignificant compared to the cost of finding the shortest path in complicated networks so there's not much place for improvment. Sep 27, 2013 at 12:28
• Driving distance starts the computation from the start point and enlarges the resulting network until max cost is reached. In that way, it doesn't have to compute every node as your comment suggests. Sep 27, 2013 at 14:05