Using the routing module

Please note that the routing module is currently in beta and it can be subject to changes.

In this guide you will learn how to use the routing module of our Analytics Toolbox for BigQuery to generate routes and calculate isolines, with all needed data and computation happening natively in BigQuery.

The routing module consists of two main functionalities:

  • Computation of origin-destination matrices based on time or distance for one or several origins and destinations.

  • Computation of isolines based on time or distance for one or several locations in parallel.

These functionalities run natively on BigQuery and rely on OSM network that is publicly available through CARTO’s Data Observatory for which a subscription is required.

In order to run the functions of the routing module you need to subscribe first to CARTO's road network (that has been derived from OSM) which is available as a public subscription via the Data Observatory. To learn how to subscribe to data from Data Observatory please read this guide.

In this guide, we show you how to use both functionalities with an example using San Francisco bike share data, which is publicly available at `bigquery-public-data.san_francisco_bikeshare.bikeshare_station_info`.

Let’s start by visualizing our area of interest. We are interested in computing distances between bike stations as well as reachable areas from specific stations. Therefore, we set as our area of interest a bounding box around San Francisco city.

Origin-destination matrices

We would like to calculate the distance matrix between bike stations in San Francisco's financial district and all stations that are at most one block away from Golden Gate Park so that bike users can consult alternative stations if the nearest one is full. See these stations in the map above.

In this example, we focus on distance, but we could also use the network max speed by transport mode to compute expected travel times.

We use the ROUTING_MATRIX procedure. For one or several origins (start_point_array) and one or several destinations (end_point_array), this function computes the network distance between all origin-destination pairs. Make sure to pass:

  • An area of interest. This can be a bounding box around San Francisco, an entire state/country, or even an area covering several countries. Note that the more restricted this area is, the more efficient the routing engine will be.

  • Transportation mode:

    • car: this option will include all roads accessible to cars.

    • car_motorway_only: this option will only include motorways. This option is recommended when secondary roads are not relevant and may make the routing engine less performant.

    • car_major_road_only: this option will only include major roads. This option is also recommended for long-distance routing where secondary roads are not relevant and may make the routing engine less performant.

    • bike: this option will include all roads and paths accessible to bikes.

    • foot: this option will include all walkable paths.

  • DO subscription dataset and name of the network table of your subscription.

  • Name of the output table that will be generated with the origin-destination matrix.

  • Options to customize routing computation. Please check the SQL reference for details.

Below is the query to compute the origin-destination distance matrix between bike stations in San Francisco's financial district and all stations that are at most one block away from Golden Gate Park.

DECLARE origins ARRAY<GEOGRAPHY>;
DECLARE destinations ARRAY<GEOGRAPHY>;

-- Start locations: Bike stations in San Francisco's financial district
SET origins = (
    SELECT ARRAY_AGG(station_geom) AS origins
    FROM `bigquery-public-data.san_francisco_bikeshare.bikeshare_station_info`
    WHERE capacity > 0 AND
          ST_INTERSECTSBOX(station_geom, -122.403294,37.787666,-122.392620,37.796759)
);

-- End locations: Bike stations at most one block far from Golden Gate Park
SET destinations = (
    SELECT ARRAY_AGG(station_geom) AS destinations
    FROM `bigquery-public-data.san_francisco_bikeshare.bikeshare_station_info`
    WHERE capacity > 0 AND
          ST_INTERSECTS(station_geom, ST_GEOGFROMTEXT('POLYGON ((-122.450746 37.764183, -122.452806 37.776802, -122.511685 37.773342, -122.510741 37.761672, -122.450746 37.764183))'))
);


CALL `carto-un`.carto.ROUTING_MATRIX(
 -- Start locations: Bike stations in San Francisco's financial district
 origins,
 -- End locations: Bike stations at most one block far from Golden Gate Park
 destinations,
 -- Area of interest,
 ST_GEOGFROMTEXT('POLYGON ((-122.342519 37.691224, -122.342519 37.824769, -122.563619 37.824769, -122.563619 37.691224, -122.342519 37.691224))'),
 -- Transportation mode
 'bicycle',
-- do_network_table
  "your_network",
  --do_source
  '<my-dataobs-project>.<my-dataobs-dataset>',
  --output_table
  '<my-project>.<my-dataset>.<output_filename>',
 -- Options
 """
 {
    "TYPE":"distance",
    "MAX_COST":"100000",
    "WITH_PATH":"True"
 }
 """
);

The first two rows of the resulting table are shown below. Every row corresponds to one origin-destination pair and contains the following information:

  • start_geo: Origin location.

  • dest_geo: Destination location.

  • start_geo_snapped: Closest point of the network to the origin. Note that the routing engine relies on a network to compute distances. Distances are calculated between the nodes of the network and, therefore, both the origin and destination are assigned (snapped) to the nearest node in the network.

  • dest_geo_snapped: Closest point of the network to the destination (see description of start_geo_snapped).

  • start_order: Position of the origin in the list of origins passed to the ROUTING_MATRIX procedure.

  • dest_order: Position of the destination in the list of destinations passed to the ROUTING_MATRIX procedure.

  • start_s2: Unique identifier of the origin node snapped from the origin location.

  • dest_s2: Unique identifier of the destination node snapped from the destination location.

  • cost: Total cost of the path/route (travel time or distance).

  • distance: Total distance of the path/route.

  • travel_time: Total travel time of the path/route in seconds.

  • path: Linestring of the complete route (shortest/fastest path) from origin to destination.

  • detailed_linestring: Array of all links that make up the path/route.

The first row corresponds to the path between the first bike station in the origins array (start_order = 0) and the first bike station in the destinations array (dest_order = 0). We can observe that the distance between these two locations is 9.08 km.

Let’s now visualize the resulting routes in Builder. The map below shows the shortest paths between all origin-destination pairs. You can filter one specific origin and/or destination for a detailed analysis of the route. Below, we have filtered the first origin (start_0) and two destinations (dest_7 and dest_12). We can observe that the distance between start_0 and dest_7 is 11.17 km and between start_0 and dest_12 8.32 km.

Isolines

Now we would like to identify all bike stations that are at most at a 10 and 30-minute walking distance from:

  • Battery St at California St station in San Francisco’s financial distinct, and

  • McAllister St at Arguello Blvd station next to Golden Gate Park.

In this example, we focus on walking time, but we could also use distances.

We use the ROUTING_ISOLINES function. For one or several origins (start_point_array), this function computes the isoline (isochrone or isodistance) from those origins using the reference network. Make sure to pass:

  • The maximum distance/time of the isoline (aka maximum cost or cost limit).

  • An area of interest. This can be a bounding box around San Francisco, an entire state/country, or even an area covering several countries. Note that the more restricted this area is, the more efficient the routing engine will be.

  • Transportation mode:

    • car: this option will include all roads accessible to cars

    • car_motorway_only: this option will only include motorways. This option is recommended when secondary roads are not relevant and may make the routing engine less performant.

    • car_major_road_only: this option will only include major roads. This option is recommended for long-distance routing where secondary roads are not relevant and may make the routing engine less performant.

    • bike: this option will include all roads accessible to bikes.

    • foot: this option will include all walkable paths.

  • DO subscription dataset and name of the network table of your subscription.

  • Name of the output table that will be generated with the origin-destination matrix.

  • Options to customize routing computation. Please check the documentation for details.

Below is the query to compute the 10 and 30-minute isochrones.

DECLARE origins ARRAY<GEOGRAPHY>;

-- Start locations
SET origins = (
    SELECT ARRAY_AGG(station_geom) AS origins
    FROM `bigquery-public-data.san_francisco_bikeshare.bikeshare_station_info`
    WHERE name IN ("Battery St at California St", "McAllister St at Arguello Blvd")
);


CALL `carto-un`.carto.ISOLINES(
-- Start locations
origins,
-- Max time (cost limit) (in seconds)
 [600., 1800.],
-- Area of interest
ST_GEOGFROMTEXT('POLYGON ((-122.342519 37.691224, -122.342519 37.824769, -122.563619 37.824769, -122.563619 37.691224, -122.342519 37.691224))'),
-- Transportation mode
'foot',
-- do_network_table
 "your_network",
 --do_source
 '<my-dataobs-project>.<my-dataobs-dataset>',
 --output_table
 '<my-project>.<my-dataset>.<output_filename>',
-- Options
"""
{
   "TYPE":"time",
   "MAX_COST":"100000",
   "WITH_PATH":"True"
}
"""
);

The first three of rows of the resulting table are shown below. Every row corresponds to a network segment of one specific isoline, i.e., in order to get the complete isoline for one origin, the user must aggregate all the network segments with the same origin location. Every row contains the following information:

  • cost_limit: The size of the isoline, i.e. the maximum distance/time. Note that all network segments corresponding to one isoline will have the same value which refers to the total size of the isoline.

  • cost_limit_idx: Position of the cost limit (max distance/time) in the input array of cost limits passed to the ROUTING_ISOLINES function.

  • start_order: Position of the origin in the list of origins passed to the ROUTING_ISOLINES function.

  • start_geo: Origin location.

  • start_geo_snapped: Closest point of the network to the origin. Note that the routing engine relies on a network to compute distances. Distances are calculated between the nodes of the network and, therefore, both the origin and destination are assigned (snapped) to the nearest node in the network.

  • start_s2: Unique identifier of the origin node snapped from the origin location.

  • start_cost: Cost (distance/time) from snapped origin to the start node of the network link of the corresponding row.

  • dest_s2: Unique identifier of the end node of the link.

  • dest_cost: Cost (distance/time) from snapped origin to the end node of the network link of the corresponding row.

  • detailed_geography: Array of points that makes up the link.

  • detailed_geography_chunked_agg: Link geography chunked to cost limit. This geography contains only the proportion of the link that is reachable within cost (distance/time) limits.

The first row corresponds to the segment of the isochrone of the first bike station passed (start_order=0) that would finish in the destination node with identifier dest_s2, which will take 1068.65 seconds to be reached on foot.

Let’s now visualize the resulting isochrones in Builder. The map below shows both isochrones where every link is styled based on the distance to its start node. You can use the widgets on the right to filter by bike station and by isochrone size.

Last updated