ST_DriveTime#

Table of Contents#

  1. What is ST_DriveTime

  2. ST_DriveTime Input Data

  3. Using ST_DriveTime

  4. Visualizing Results

[ ]:
import bdt
bdt.auth("bdt.lic")
from bdt.functions import *
from bdt.processors import *
from pyspark.sql.functions import *
import geopandas
import folium
import mapclassify
import matplotlib
BDT has been successfully authorized!

            Welcome to
             ___    _                ___         __             ______             __   __     _   __
            / _ )  (_)  ___ _       / _ \ ___ _ / /_ ___ _     /_  __/ ___  ___   / /  / /__  (_) / /_
           / _  | / /  / _ `/      / // // _ `// __// _ `/      / /   / _ \/ _ \ / /  /  '_/ / / / __/
          /____/ /_/   \_, /      /____/ \_,_/ \__/ \_,_/      /_/    \___/\___//_/  /_/\_\ /_/  \__/
                      /___/

BDT python version: v3.3.0-v3.3.0
BDT jar version: v3.3.0-v3.3.0

Part 1: What is ST_DriveTime#

  • ST_DriveTime takes in a point shape struct and outputs the drive time (hexagon based service area) polygons up to the cost in minutes from the input point. The point shape struct must be in spatial reference 3857 Web Mercator.

  • The output is an array of drive_time_cost and polygon which can be unpacked with the inline() function.

  • Functions that function similarly to st_drive_time:

  1. st_drive_time_xy - performs the same action as st_drive_time but allows for the input of x and y coordinates instead of a point shape struct.

  2. st_drive_time_h3 - takes in a point shape struct and outputs drive time service area polygons using Uber H3 hexagons.

  3. st_drive_time_h3_xy - performs the same action as st_drive_time_h3 but allows for the input of x and y coordinates instead of a point shape struct.

  4. st_drive_time_points - takes in a point in web mercator (3857) and outputs points placed on a regular interval that are reachable within a given drive time from the source point.

  • This example will be using st_drive_time

Part 2: ST_DriveTime Input Data#

  • Use Spark to read in sample parquet dataframe with points around San Diego.

[ ]:
points_df = spark.read.parquet("./data/stdrivetime_samplepoints.parquet")
points_df.show()
+---+--------------------+
|ID1|              SHAPE1|
+---+--------------------+
|  1|{[01 01 00 00 00 ...|
|  2|{[01 01 00 00 00 ...|
|  3|{[01 01 00 00 00 ...|
|  4|{[01 01 00 00 00 ...|
|  5|{[01 01 00 00 00 ...|
|  6|{[01 01 00 00 00 ...|
|  7|{[01 01 00 00 00 ...|
|  8|{[01 01 00 00 00 ...|
|  9|{[01 01 00 00 00 ...|
| 10|{[01 01 00 00 00 ...|
| 11|{[01 01 00 00 00 ...|
| 12|{[01 01 00 00 00 ...|
| 13|{[01 01 00 00 00 ...|
| 14|{[01 01 00 00 00 ...|
| 15|{[01 01 00 00 00 ...|
| 16|{[01 01 00 00 00 ...|
| 17|{[01 01 00 00 00 ...|
| 18|{[01 01 00 00 00 ...|
| 19|{[01 01 00 00 00 ...|
| 20|{[01 01 00 00 00 ...|
+---+--------------------+
only showing top 20 rows

Explore Points#

  • This function allows quick visualizations of Spark dataframes using geopandas and folium.

[ ]:
def explore_points(df, shape_col_name="SHAPE"):
    gdf = to_geo_pandas(df, 3857, shape_col_name)
    m = gdf.explore(name="ID1", color="red", legend=False, tiles="Esri.WorldTopoMap")
    folium.LayerControl().add_to(m)
    return m
[ ]:
explore_points(points_df, "SHAPE1")
Make this Notebook Trusted to load map: File -> Trust Notebook

Part 3: Using ST_DriveTime#

The function requires the following arguments:

  • struct – The shape struct point geometry in 3857.

  • no_of_costs – The number of minute costs.

  • hex_size – The hexSize in DoubleType.

  • fill – Optional. When true, remove holes from the returned drive time polygons. When false, leave the polygons as is.

This example uses 15 minute drive time polygons.

[ ]:
drive_time_df = points_df \
                        .select("ID1", st_drive_time("SHAPE1", 15, 125.0, False).alias("SA")) \
                        .selectExpr("inline(SA)", "ID1")
drive_time_df.show()
+---------------+--------------------+---+
|DRIVE_TIME_COST|               SHAPE|ID1|
+---------------+--------------------+---+
|            1.0|{[01 06 00 00 00 ...|  1|
|            2.0|{[01 06 00 00 00 ...|  1|
|            3.0|{[01 06 00 00 00 ...|  1|
|            4.0|{[01 06 00 00 00 ...|  1|
|            5.0|{[01 06 00 00 00 ...|  1|
|            6.0|{[01 06 00 00 00 ...|  1|
|            7.0|{[01 06 00 00 00 ...|  1|
|            8.0|{[01 06 00 00 00 ...|  1|
|            9.0|{[01 06 00 00 00 ...|  1|
|           10.0|{[01 06 00 00 00 ...|  1|
|           11.0|{[01 06 00 00 00 ...|  1|
|           12.0|{[01 06 00 00 00 ...|  1|
|           13.0|{[01 06 00 00 00 ...|  1|
|           14.0|{[01 06 00 00 00 ...|  1|
|           15.0|{[01 06 00 00 00 ...|  1|
|            1.0|{[01 06 00 00 00 ...|  2|
|            2.0|{[01 06 00 00 00 ...|  2|
|            3.0|{[01 06 00 00 00 ...|  2|
|            4.0|{[01 06 00 00 00 ...|  2|
|            5.0|{[01 06 00 00 00 ...|  2|
+---------------+--------------------+---+
only showing top 20 rows

Part 4: Visualizing Results#

  • Use spark to filter the dataframe to singular point.

[ ]:
single_point_df = drive_time_df.where(drive_time_df.ID1 == 7)
single_point_df.show()
+---------------+--------------------+---+
|DRIVE_TIME_COST|               SHAPE|ID1|
+---------------+--------------------+---+
|            1.0|{[01 06 00 00 00 ...|  7|
|            2.0|{[01 06 00 00 00 ...|  7|
|            3.0|{[01 06 00 00 00 ...|  7|
|            4.0|{[01 06 00 00 00 ...|  7|
|            5.0|{[01 06 00 00 00 ...|  7|
|            6.0|{[01 06 00 00 00 ...|  7|
|            7.0|{[01 06 00 00 00 ...|  7|
|            8.0|{[01 06 00 00 00 ...|  7|
|            9.0|{[01 06 00 00 00 ...|  7|
|           10.0|{[01 06 00 00 00 ...|  7|
|           11.0|{[01 06 00 00 00 ...|  7|
|           12.0|{[01 06 00 00 00 ...|  7|
|           13.0|{[01 06 00 00 00 ...|  7|
|           14.0|{[01 06 00 00 00 ...|  7|
|           15.0|{[01 06 00 00 00 ...|  7|
+---------------+--------------------+---+

  • This custom function allows for quick visualization of the drivetime polygons with geopandas.

  • The blue inner areas are shorter drive time distance.

  • The pink and purple outer areas are longer drive time distances.

[ ]:
def explore_drivetime_point(df, shape_col_name="SHAPE", drive_time_col_name="DRIVE_TIME_COST"):
    df = df.orderBy(col(drive_time_col_name).desc())
    gdf = to_geo_pandas(df, 3857, shape_col_name)
    m = gdf.explore("DRIVE_TIME_COST", name="DRIVE_TIME_COST", cmap="cool", legend=False, tiles="Esri.WorldTopoMap",  style_kwds=dict(color="black", weight=0.001))
    folium.LayerControl().add_to(m)
    return m
[ ]:
explore_drivetime_point(single_point_df)
Make this Notebook Trusted to load map: File -> Trust Notebook