Batch driving distance - a pgRouting function

A function to batch process driving distance results for a set of input points, in this case, schools.

The function creates a table to hold the results (dropping it if it exists) and then selects each school from the your_schools table and calculates the driving distance numbers. For each school it writes the results to a temp table (temp_dd, dropping it first if it exists) and writes those results to the output table (school_driving_distance). In the end you have a table with a lot of rows (more or less depending on your cost) with which you can do neat things with QGIS Time Manager.

The schools data needs to be pre-processed to give each school an id field, school_nn, which contains the node id of the nearest network node.

Note: You'll need to VACUUM ANALYZE your output table to update the statistics.

-- Function: public.school_driving_distance()
-- DROP FUNCTION public.school_driving_distance();

CREATE OR REPLACE FUNCTION public.school_driving_distance()
  RETURNS character varying AS
$BODY$
DECLARE

  cur_school refcursor;
  v_snn integer;  --variable for the school nearest node
  v_node integer;
  v_seq integer;  --variable for the sequence id
  v_cost double precision;  --variable for the cost results
  v_geom geometry;  --variable for the output geometry
  v_sql varchar(1000);  --variable to hold some SQL

BEGIN
-- Drop the results table first
    RAISE NOTICE 'Dropping table...';
    v_sql:='DROP TABLE IF EXISTS public.school_driving_distance;';
    EXECUTE v_sql;

-- Create a new results table next
    RAISE NOTICE 'Creating table...';
    v_sql:='CREATE TABLE IF NOT EXISTS public.school_driving_distance 
    (
      gid serial NOT NULL,
      seq integer,
      node integer,
      school_nn integer,
      agg_cost double precision, 
      geometry geometry(Point,27700), 
      CONSTRAINT school_dd_ipk PRIMARY KEY (gid)
    );

    CREATE INDEX school_driving_distance_geometry_ixs
    ON public.school_driving_distance
    USING gist(geometry);';

    EXECUTE v_sql;

-- Process the schools    
    RAISE NOTICE 'Processing school...';
    OPEN cur_school FOR EXECUTE format('SELECT school_nn FROM your_schools WHERE school_nn IS NOT NULL');
    LOOP

-- Drop the temp table
    v_sql:='DROP TABLE IF EXISTS temp_dd;';
    EXECUTE v_sql;

-- Create a temp table to hold results for each school
    v_sql:='CREATE TEMPORARY TABLE temp_dd(
      seq integer,
      node integer,
      school_nn integer,
      agg_cost double precision, 
      geometry geometry(Point,27700)
      );';
    EXECUTE v_sql;

    FETCH cur_school INTO v_snn;
    EXIT WHEN NOT FOUND;

-- Do 30 minute driving distance calculation for each school
    INSERT INTO temp_dd(seq, node, school_nn, agg_cost, geometry)
    SELECT foo.seq AS v_seq, foo.node AS v_node, v_snn AS school_nn, foo.agg_cost AS v_cost, n.the_geom AS v_geom FROM pgr_drivingDistance(
      'SELECT ogc_fid AS id, source, target, cost, reverse_cost 
      FROM your_network',
      v_snn,          -- school name
      1800) AS foo    -- change this cost to change the output
      LEFT JOIN your_network_vertices_pgr n ON n.id = foo.node;

-- Insert results into driving distance table
    EXECUTE format('INSERT INTO public.school_driving_distance(seq,node,school_nn,agg_cost,geometry) SELECT * FROM temp_dd;');
    END LOOP;
    RETURN 'Completed the driving distance calculations';
    CLOSE cur_school;

END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
COMMENT ON FUNCTION public.school_driving_distance() IS '30 minute driving distance function for each school';

Once all the results are written to the output table you can then query the table to get the overall minimum distance to each school:

SELECT DISTINCT ON (node) *
FROM school_driving_distance
ORDER BY node, agg_cost ASC;

Here's a result from the function above processed with QGIS Time Manager and stitched together with Avidemux and VLC.

And another one.

See this stackexchange post for another way of doing it.