Skip to content

Commit

Permalink
Merge pull request #1179 from cal-itp/speedmap-colors-readme
Browse files Browse the repository at this point in the history
Speedmap colors readme
  • Loading branch information
edasmalchi authored Jul 17, 2024
2 parents a6617b0 + d21000d commit 87371de
Show file tree
Hide file tree
Showing 152 changed files with 417 additions and 338 deletions.
4 changes: 4 additions & 0 deletions _shared_utils/shared_utils/rt_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,16 @@
SPA_MAP_SITE = "https://embeddable-maps.calitp.org/"
SPA_MAP_BUCKET = "calitp-map-tiles/"
SPEEDMAP_LEGEND_URL = "https://storage.googleapis.com/calitp-map-tiles/speeds_legend.svg"
VARIANCE_LEGEND_URL = "https://storage.googleapis.com/calitp-map-tiles/variance_legend.svg"
ACCESS_SPEEDMAP_LEGEND_URL = "https://storage.googleapis.com/calitp-map-tiles/speeds_legend_color_access.svg"

MPH_PER_MPS = 2.237 # use to convert meters/second to miles/hour
METERS_PER_MILE = 1609.34
# Colorscale
ZERO_THIRTY_COLORSCALE = branca.colormap.step.RdYlGn_10.scale(vmin=0, vmax=30)
ZERO_THIRTY_COLORSCALE.caption = "Speed (miles per hour)"
ACCESS_ZERO_THIRTY_COLORSCALE = branca.colormap.step.RdBu_10.scale(vmin=0, vmax=30)
ACCESS_ZERO_THIRTY_COLORSCALE.caption = "Speed (miles per hour)"
VARIANCE_COLORS = branca.colormap.step.Blues_06.colors[1:] # actual breaks will vary
VARIANCE_RANGE = np.arange(1, 2.8, 0.3)
VARIANCE_FIXED_COLORSCALE = branca.colormap.StepColormap(
Expand Down
52 changes: 36 additions & 16 deletions ca_transit_speed_maps/README.md
Original file line number Diff line number Diff line change
@@ -1,41 +1,61 @@
# Introduction
# California Transit Speed Maps

Supporting transit is integral to Caltrans' vision of delivering a connected, equitable, and more sustainable state transportation network as well as the Department’s work to combat the climate crisis.

To help realize that vision, the California Integrated Travel Program (Cal-ITP) is developing analyses alongside our partners such as the Caltrans Division of Research, Innovation and System Information (DRISI) in order to provide Caltrans staff and external stakeholders with actionable data to prioritize transit projects.

Transit in California is overwhelmingly provided by buses. However, speeds have been declining for years, and now average below 10mph across much of California – and often much lower during peak times in urban areas. These slow speeds translate to countless hours wasted for transit riders and jeopardize the ability of California’s transit agencies to provide frequent, reliable service.

We also measure speed variation. Low speeds delay transit, but variation is equally problematic since it leads to an inconsistent experience for transit riders and complicates scheduling of transit services.

Our maps already include routes and operators accounting for about 80% of bus riders in the state, including operators in every Caltrans district. Cal-ITP continues to work daily to onboard and support new agencies in providing quality data that improves the transit rider experience and powers useful and timely analysis.

# About This Speedmap Site
This site is updated at least quarterly.

These maps, tables, and charts provide an overview of typical weekday transit vehicle speeds in California. They are based on actual, archived positions data from each vehicle. They are generally accurate for their intended purpose of identifying slower parts of bus routes that would be candidates for projects to speed up buses, but some erroneous data may be present. Feel free to contact Cal-ITP with any data questions.
Select source code can be found at:

Maps are organized by Caltrans district, with a separate page for each transit operator within the district. It's easiest to navigate the site using the menu on the left side of the page. Click the dropdown icon for each district to show links to each operator within the district. Alternatively, you can navigate through all pages in order using the "Next" and "Previous" links at the bottom of each page.
[https://github.com/cal-itp/data-analyses/tree/main/ca_transit_speed_maps](https://github.com/cal-itp/data-analyses/tree/main/ca_transit_speed_maps)

## New: Speed Variation Maps and Download Links!
[https://github.com/cal-itp/data-analyses/tree/main/rt_delay/rt_analysis](https://github.com/cal-itp/data-analyses/tree/main/rt_delay/rt_analysis)

![speedmap header with download link in top right circled in red](https://github.com/cal-itp/data-analyses/blob/065adb2838482619c039791f6f3090b7efaa9e82/ca_transit_speed_maps/img/download.png?raw=true)
[https://github.com/cal-itp/data-analyses/blob/main/_shared_utils/shared_utils/rt_utils.py](https://github.com/cal-itp/data-analyses/blob/main/_shared_utils/shared_utils/rt_utils.py)

We've updated our map rendering technology for better performance and flexibility.

Speed variation maps are now displayed for each time of day, just like speed maps. Segments with high variation in speeds make it difficult for transit operators to set accurate schedules, and can cause inconsistent service for riders. Identifying where speeds are inconsistent provides another useful data point to target transit priority measures in addition to actual speeds.
## Definitions

Each map now comes with a link to download its geospatial data in a gzip-compressed GeoJSON format (.geojson.gz). Most file compression software, including 7zip on Windows, will decompress these files. Once decompressed, most GIS software including ESRI ArcGIS Pro and QGIS can import the GeoJSON.
* AM Peak: 0600-0900
* Midday: 1000-1400
* PM Peak: 1500-1900

## Data Sources
## Methodology

* General Transit Feed Specification (GTFS)
* GTFS Schedule (static for each operator, includes timetable and route geometry information)
* Archived GTFS-Realtime (GTFS-RT) vehicle positions data (vehicle locations updated about every 20 seconds)
Segment speed is estimated using the time and distance between vehicle positions reports, with distance being measured linearly along the corresponding transit route. These maps show speeds along segments, which are calculated by interpolating the two nearest position reports for each trip in order to estimate speed along each segment, then taking the 20th percentile of speeds for that segment in each period (morning peak, afternoon peak, and midday). This site shows data for a specific day, usually a Wednesday (and not a holiday or other date we believe could be atypical).

## Methodology
Generally, segments are constructed from one stop to the next, however, if the distance between stops is large we add interpolated segments every kilometer to provide additional resolution for rural and express services.

Segment speed is estimated using the time and distance between vehicle positions reports, with distance being measured linearly along the corresponding transit route. These maps show speeds along segments, which are calculated by interpolating the two nearest position reports for each trip in order to estimate speed along each segment, then taking the 20th percentile of speeds for that segment in each period (morning peak, afternoon peak, and midday). Generally, segments are constructed from one stop to the next, however, if the distance between stops is large we add interpolated segments every kilometer to provide additional resolution for rural and express services.
We use the ratio between 80th and 20th percentile speeds in a segment to measure speed variation.

## Frequently Asked Questions

Are colorblind safe speed maps available?

_Yes, by following the "Open Colorblind Safe Map in New Tab" links displayed before each speed map. Variation maps already use a colorblind safe scheme._

## Data Sources
Archived GTFS-Realtime Vehicle Positions data, plus corresponding GTFS Schedule data.

Each map includes a link to download its geospatial data in a gzip-compressed GeoJSON format (.geojson.gz). Most file compression software, including 7zip on Windows, will decompress these files. Once decompressed, most GIS software including ESRI ArcGIS Pro and QGIS can import the GeoJSON.

## Ongoing Work

The Cal-ITP team is working to share broader speed and delay data using the California Open Data Portal.

### Questions or Feedback? Please email hello@calitp.org
Questions or feedback? Please email hello@calitp.org

## Who We Are

This website was created by the [California Department of Transportation](https://dot.ca.gov/)'s Division of Data and Digital Services. We are a group of data analysts and scientists who analyze transportation data, such as General Transit Feed Specification (GTFS) data, or data from funding programs such as the Active Transportation Program. Our goal is to transform messy and indecipherable original datasets into usable, customer-friendly products to better the transportation landscape. For more of our work, visit our [portfolio](https://analysis.calitp.org/).

<img src="https://raw.githubusercontent.com/cal-itp/data-analyses/main/portfolio/Calitp_logo_MAIN.png" alt="Alt text" width="200" height="100"> <img src="https://raw.githubusercontent.com/cal-itp/data-analyses/main/portfolio/CT_logo_Wht_outline.gif" alt="Alt text" width="129" height="100">

<br>Caltrans®, the California Department of Transportation® and the Caltrans logo are registered service marks of the California Department of Transportation and may not be copied, distributed, displayed, reproduced or transmitted in any form without prior written permission from the California Department of Transportation.
36 changes: 17 additions & 19 deletions ca_transit_speed_maps/export_legends.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import os
os.environ['USE_PYGEOS'] = '0'

from shared_utils.rt_utils import *
from calitp_data_analysis import get_fs

# utility script for saving branca colormaps as static svg files for the map app to pick up and display
# could be moved to shared_utils or as part of future map app refactor efforts?

def add_lines_header(svg):

# add newlines
Expand Down Expand Up @@ -34,21 +34,19 @@ def add_inner_labels_caption(svg, labels, spacing, caption):

return export_svg

# export speed legend
speeds_legend = add_lines_header(ZERO_THIRTY_COLORSCALE._repr_html_())
speeds_legend = add_inner_labels_caption(speeds_legend, [6, 12, 18, 24], 100, ZERO_THIRTY_COLORSCALE.caption)

fs = get_fs()
path = f'calitp-map-tiles/speeds_legend.svg'
with fs.open(path, 'w') as writer: # write out to public-facing GCS?
writer.write(speeds_legend)
print(f'speed legend written to {path}')
def export_legend(cmap:branca.colormap.StepColormap, filename):

legend = add_lines_header(cmap._repr_html_())
legend = add_inner_labels_caption(legend, [6, 12, 18, 24], 100, cmap.caption)

# export variance legend
variance_legend = add_lines_header(VARIANCE_FIXED_COLORSCALE._repr_html_())
variance_legend = add_inner_labels_caption(variance_legend, VARIANCE_RANGE[1:-1], 100, VARIANCE_FIXED_COLORSCALE.caption)
path = f'calitp-map-tiles/{filename}'
with fs.open(path, 'w') as writer: # write out to public-facing GCS?
writer.write(legend)
print(f'legend written to {path}')

path = f'calitp-map-tiles/variance_legend.svg'
with fs.open(path, 'w') as writer: # write out to public-facing GCS?
writer.write(variance_legend)
print(f'variance legend written to {path}')
if __name__ == "__main__":

fs = get_fs()
export_legend(ZERO_THIRTY_COLORSCALE, 'speeds_legend.svg')
export_legend(VARIANCE_FIXED_COLORSCALE, 'variance_legend.svg')
export_legend(ACCESS_ZERO_THIRTY_COLORSCALE, 'speeds_legend_color_access.svg')
129 changes: 80 additions & 49 deletions ca_transit_speed_maps/speedmaps.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"cells": [
{
"cell_type": "code",
"execution_count": 24,
"execution_count": null,
"id": "46898b5c-b5cc-4096-ab68-8c3e42fab870",
"metadata": {},
"outputs": [],
Expand All @@ -21,29 +21,7 @@
},
{
"cell_type": "code",
"execution_count": 25,
"id": "2e268961-6125-4fe6-a654-0592a6e949c0",
"metadata": {},
"outputs": [],
"source": [
"from IPython.core.magic import register_cell_magic"
]
},
{
"cell_type": "code",
"execution_count": 26,
"id": "39a54a6e-1bd9-4b8f-85fe-b1e558aba6b7",
"metadata": {},
"outputs": [],
"source": [
"@register_cell_magic\n",
"def full_width(line, cell):\n",
" return"
]
},
{
"cell_type": "code",
"execution_count": 27,
"execution_count": null,
"id": "9f15ed6a-5ab7-4f57-9695-3f762781b74c",
"metadata": {
"tags": [
Expand All @@ -53,12 +31,12 @@
"outputs": [],
"source": [
"## parameters cell\n",
"itp_id = 293"
"itp_id = 300"
]
},
{
"cell_type": "code",
"execution_count": 28,
"execution_count": null,
"id": "a639fd84-29ca-4678-b568-2b1022701e14",
"metadata": {},
"outputs": [],
Expand All @@ -71,18 +49,10 @@
},
{
"cell_type": "code",
"execution_count": 29,
"execution_count": null,
"id": "47c79d99-c82f-4e1e-b11e-2b1e83c13a1b",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{\"human_date\": \"September 13 2023 (Wednesday)\"}\n"
]
}
],
"outputs": [],
"source": [
"%%capture_parameters\n",
"human_date = analysis_date.strftime('%B %d %Y (%A)')\n",
Expand All @@ -91,7 +61,7 @@
},
{
"cell_type": "code",
"execution_count": 30,
"execution_count": null,
"id": "e4cbefc6-9bbb-4989-85b7-1f31da17fcb8",
"metadata": {},
"outputs": [],
Expand All @@ -102,18 +72,10 @@
},
{
"cell_type": "code",
"execution_count": 31,
"execution_count": null,
"id": "6c335d40-7a7b-4641-8a3d-c970b2823cdf",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{\"organization_name\": \"Santa Barbara Metropolitan Transit District\"}\n"
]
}
],
"outputs": [],
"source": [
"%%capture_parameters\n",
"organization_name = rt_day.organization_name\n",
Expand Down Expand Up @@ -192,7 +154,30 @@
{
"cell_type": "code",
"execution_count": null,
"id": "1b8ea029-c5e3-4b97-8bef-30df3934d877",
"id": "3f25f8b6-e5e5-423e-a7ef-50fd06a82aaf",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"%%capture\n",
"rt_day.map_gz_export(access_cmap=True)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ae4a2e32-9258-4881-869c-b4a5995d6e9e",
"metadata": {},
"outputs": [],
"source": [
"rt_day.render_spa_link(text='Colorblind Safe Map')"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1fb98926-11f6-47f5-b54c-dcc305668caf",
"metadata": {
"tags": []
},
Expand All @@ -205,7 +190,7 @@
{
"cell_type": "code",
"execution_count": null,
"id": "faa5e04f-d1f7-47c5-b2d3-60590eb73bdc",
"id": "478be483-6dd3-4b0f-adca-dfedf2540088",
"metadata": {},
"outputs": [],
"source": [
Expand Down Expand Up @@ -320,6 +305,29 @@
" )"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a8ecf442-e6bb-4e30-b2bf-539ecbbc926f",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"%%capture\n",
"rt_day.map_gz_export(access_cmap=True)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "2c58c59b-3669-4aaa-8773-c7e75b8b5be2",
"metadata": {},
"outputs": [],
"source": [
"rt_day.render_spa_link(text='Colorblind Safe Map')"
]
},
{
"cell_type": "code",
"execution_count": null,
Expand Down Expand Up @@ -451,6 +459,29 @@
" )"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "7f8aaf05-a63a-4e4d-9a7e-1efb63039046",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"%%capture\n",
"rt_day.map_gz_export(access_cmap=True)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "da6d778e-53c5-4759-bcba-100298afdd7f",
"metadata": {},
"outputs": [],
"source": [
"rt_day.render_spa_link(text='Colorblind Safe Map')"
]
},
{
"cell_type": "code",
"execution_count": null,
Expand Down
Loading

0 comments on commit 87371de

Please sign in to comment.