pgRouting includes a function called pgr_drivingDistance , that, together with three others functions , pgr_withPointsDD , pgr_alphaShape and pgr_pointsAsPolygon , can be used to establish which paths have a certain cost versus a starting or arrival point .
The area surrounding these paths is designated as a catchment area . pgr_drivingDistance , in conjunction with pgr_pointsAsPolygon is often used to determine coverage requirements for a service or to determine optimal locations for new facilities.
For example , if you have
a
fire
station, you must determine
all
parts of the city that can be reached
within five minutes. A reverse
problem would be to find all parts of the city
where
the residents could drive
to
a hospital within five minutes.
The
function that calculates the paths for both problems
is
called
pgr_drivingDistance
because it is often used
when
the cost is measured as driving
time . However, the costs are not necessarily
limited to a time or a
distance.
For
this type of application , knowing all routes towards
or
from a given point is not very useful. It
is here where the functions pgr _alphaShape and
pgr_pointsAsPolygon come into play. The
pgr_alphaShape use as input a set of x, y
coordinates and returns a set of x, y which correspond to the vertices of a
polygon that includes all the input points.
pgr_pointsAsPolygon
is
similar
to pgr_alphaShape , it uses as input a set of coordinates x, y, but instead of
returning another
series
of points, returns a polygon that surrounds all input
points . Internally, it uses the pgr_alphaShape function .
Using pgr_drivingDistance
Let’s take the case of a fire station and search the area covered in 5 minutes. The order sql corresponding to these criteria can be translated by the following:
SELECT * FROM pgr_drivingDistance (‘SELECT gid as id, source, target, cost_s as cost, reverse_cost_s as reverse_cost FROM public.ways ‘, 25736, 300, true) In the SELECT clause we use the cost of a section in seconds (cost_s), and indicate the reverse_cost_s because even fire trucks cannot drive against traffic. 25736 is the node corresponding to the fire station, 300 is the forecasted cost (5 minutes x 60 seconds ), and the true value indicates that the graph is directional (takes into account the forbidden driving sense ).

The result of the query returns 6948 nodes that are in within 5 minutes from the fire station. By cons the result of the query having no geometry , we can not visualize them in QGis.
You have to modify the query as follows:
SELECT * FROM pgr_drivingDistance (‘SELECT gid as id, source, target, cost_s as cost, reverse_cost_s as reverse_cost FROM public.ways ‘, 25736, 300, true) as JOIN ways_vertices_pgr on di.node = ways_vertices_pgr.id We perform a join with the node table ( ways_vertices_pgr ) and the result of the query includes the geometries :

We can see the result in QGis:

How to create
the
catchment
area
with
pgr_pointsAsPolygon
To create the catchment area, we use
the former query as sql
of the function pgr_pointsAsPolygon , by
creating
a polygon in output that we can load in QGis:
SELECT 1 As id,ST_SetSRID(pgr_pointsAsPolygon(
$$ SELECTdi.seqAS id, ST_X
(v.the_geom) AS x, ST_Y (v.the_geom) As y
FROMpgr_drivingDistance(SELECTgidAs id, source, target,
cost_sAS cost,reverse_cost_sASreverse_cost
FROMpublic.ways», 25736, 300, true
) AS di INNER JOINpublic.ways_vertices_pgrAS v ONdi.node= v.id $$
), 4326) Asgeom;

pgr_pointAsPolygon uses the id, x, and y points generated by pgr_drivingDistance . For x and y we use the functions St_x and St_y on the points geometry. Once loaded in QGis, the result is as follows :

How to create the isochrones
The isochrones correspond to the reachable areas in a series of time steps. We could , in this example , want to know which are the areas we can reach in 1, 2, 3, 4 and 5 minutes.
Therefore we will proceed in two steps .
The first one, is to create a table with our nodes resulting from pgr_drivingDistance for the fastest time step (5 minutes). Logically , in this table it will, also, be found the nodes reachable in the shortest periods of time.
We create this table ( dd_caserne ) with the following sql command :
CREATE TABLE dd_caserne AS
SELECT di.seq As id,
di.node , di.edge ,
di.agg_cost As time_access
, v.the_geom As geom
FROM pgr_drivingDistance (SELECT
gid As id, source, target,
cost_s AS cost, reverse_cost_s
AS reverse_cost
FROM public.ways’, 25736, 300, true
) AS di INNER JOIN public.ways_vertices_pgr
AS v ON di.node = v.id;
The resulting table is the following :

Based on this table we will build
a
series
of polygons with pgr_pointsAsPolygon for points at 60, 120 180 240 and 300
seconds of access time by using generate_series
SELECTiAstime_access,
ST_SetSRID(pgr_pointsAsPolygon(
‘SELECT id, ST_X (geom) AS
x, ST_Y (geom) As y
FROMdd_caserne
WHEREaccess_time<= ‘||i :: text), 4326) Asgeom
FROMgenerate_series(60,300,60)
Asi
ORDER BYiDESC

The result includes the 5 isochrones polygons , which we can, now, display in QGis:
