-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathst_event_travel.py
71 lines (53 loc) · 2.63 KB
/
st_event_travel.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import streamlit as st
import pandas as pd
import geopandas as gpd
import requests
st.title('Event travel time coverage')
@st.cache_data
def load_postcodes():
return pd.read_parquet('./onspd_may24.parquet')
if 'disabled' not in st.session_state:
st.session_state.disabled = True
with st.spinner("Loading postcode data"):
postcodes = load_postcodes()
postcodes_gdf = gpd.GeoDataFrame(postcodes, geometry= gpd.points_from_xy(postcodes.long, postcodes.lat))
st.write("This tool allows you to generate a list of postcodes reachable within a set driving time from a start point.")
if postcodes is not None:
# Get venue postcode input
venue_postcode = st.text_input(label="Venue postcode (required)", value= None)
# Get travel time input
travel_time = st.number_input(label="Travel time in mins (required)", value=60, step=10)
# Get Mapbox API key input
token = st.text_input(label="Mapbox token (required)", type="password")
# help info - where to get a token
st.info("How to get a Mapbox token: https://docs.mapbox.com/help/getting-started/access-tokens/")
valid_postcode = False
# validate postcode
if type(venue_postcode) == None or venue_postcode == "":
valid_postcode = False
elif type(venue_postcode) != None and ~postcodes.pcds.isin([venue_postcode]).any():
valid_postcode = False
elif postcodes.pcds.isin([venue_postcode]).any():
valid_postcode=True
# Lookup venue lat/long
pcds = postcodes.set_index('pcds')
if valid_postcode == True:
longitude, latitude = pcds.at[venue_postcode, 'long'], pcds.at[venue_postcode, 'lat']
# Set API request parameters
url = f'https://api.mapbox.com/isochrone/v1/mapbox/driving/{longitude}%2C{latitude}?contours_minutes={travel_time}&polygons=true&access_token={token}'
if token and venue_postcode:
st.session_state.disabled = False
if st.button(label="Search", type="primary", disabled=st.session_state.disabled):
# Send API request
r = requests.get(url)
# Create GeoDataFrame from API response
gdf = gpd.GeoDataFrame.from_features(r.json()['features'])
# Spatial join the reachable area to the postcode point locations
reachable_postcodes = postcodes_gdf.sjoin(gdf)
# Display map of results
st.map(reachable_postcodes, latitude='lat', longitude='long')
# Button to generate CSV of reachable postcodes
st.download_button(label="Download postcodes as CSV", data=reachable_postcodes.to_csv(columns=["pcds"], index=False),
file_name=venue_postcode+"_reachable_postcodes.csv",
mime="text/csv", type="secondary")
st.write("Share suggestions or feedback by opening an issue on the [GitHub repo](https://github.com/britishredcrosssociety/event-venue-catchment-area/issues)")