Spaces:
Runtime error
Runtime error
| # -*- coding: utf-8 -*- | |
| """ | |
| Created on Thu Jun 8 03:39:02 2023 | |
| @author: mritchey | |
| """ | |
| import pandas as pd | |
| import numpy as np | |
| import streamlit as st | |
| from geopy.extra.rate_limiter import RateLimiter | |
| from geopy.geocoders import Nominatim | |
| import folium | |
| from streamlit_folium import st_folium | |
| import geopandas as gpd | |
| from vincenty import vincenty | |
| st.set_page_config(layout="wide") | |
| def get_perimeters(refresh=False): | |
| if refresh: | |
| gdf_perimeters = gpd.read_file( | |
| 'https://opendata.arcgis.com/api/v3/datasets/5e72b1699bf74eefb3f3aff6f4ba5511_0/downloads/data?format=shp&spatialRefId=4326&where=1%3D1') # .to_crs(epsg=epsg_input) | |
| gdf_perimeters = gdf_perimeters[['OBJECTID', 'poly_Incid', 'attr_Fir_7', 'poly_Creat', | |
| 'poly_DateC', 'poly_Polyg', 'poly_Acres', 'attr_Estim', 'geometry']].copy() | |
| gdf_perimeters.columns = ['OBJECTID', 'Incident', 'DiscoveryDate', 'poly_Creat', | |
| 'LastUpdate', 'poly_Polyg', 'Size_acres', 'CurrentEstCost', 'geometry'] | |
| gdf_perimeters['Lat_centroid'] = gdf_perimeters.centroid.y | |
| gdf_perimeters['Lon_centroid'] = gdf_perimeters.centroid.x | |
| gdf_perimeters['DiscoveryDate'] = pd.to_datetime( | |
| gdf_perimeters['DiscoveryDate']) | |
| else: | |
| gdf_perimeters = gpd.read_parquet( | |
| "wildfire_perimeters.parquet").query("geometry==geometry") | |
| return gdf_perimeters | |
| def map_perimeters(_gdf_data, address): | |
| geojson_data = _gdf_data[['OBJECTID', 'Incident', 'DiscoveryDate', | |
| 'Miles to Fire Centroid', 'geometry']].to_json() | |
| m = folium.Map(location=[lat, lon], | |
| zoom_start=6, | |
| height=500) | |
| folium.Marker( | |
| location=[lat, lon], | |
| tooltip=f'Address: {address}', | |
| ).add_to(m) | |
| folium.GeoJson(geojson_data, | |
| tooltip=folium.GeoJsonTooltip(fields=["Incident", | |
| "DiscoveryDate", | |
| 'Miles to Fire Centroid']), | |
| ).add_to(m) | |
| return m | |
| def distance(x): | |
| left_coords = (x[0], x[1]) | |
| right_coords = (x[2], x[3]) | |
| return vincenty(left_coords, right_coords, miles=True) | |
| def geocode(address): | |
| try: | |
| address2 = address.replace(' ', '+').replace(',', '%2C') | |
| df = pd.read_json( | |
| f'https://geocoding.geo.census.gov/geocoder/locations/onelineaddress?address={address2}&benchmark=2020&format=json') | |
| results = df.iloc[:1, 0][0][0]['coordinates'] | |
| lat, lon = results['y'], results['x'] | |
| except: | |
| geolocator = Nominatim(user_agent="GTA Lookup") | |
| geocode = RateLimiter(geolocator.geocode, min_delay_seconds=1) | |
| location = geolocator.geocode(address) | |
| lat, lon = location.latitude, location.longitude | |
| return lat, lon | |
| def extract_vertices(gdf): | |
| g = [i for i in gdf.geometry] | |
| all_data = [] | |
| for i in range(len(g)): | |
| try: | |
| try: | |
| x, y = g[i].exterior.coords.xy | |
| except: | |
| x, y = g[i].coords.xy | |
| df = pd.DataFrame({'Lat': y, 'Lon': x}) | |
| except: | |
| all_data2 = [] | |
| try: | |
| for j in range(len(g[i])): | |
| try: | |
| x, y = g[i][j].exterior.coords.xy | |
| except: | |
| x, y = g[i][j].coords.xy | |
| all_data2.append(pd.DataFrame({'Lat': y, 'Lon': x})) | |
| df = pd.concat(all_data2) | |
| except: | |
| df = pd.DataFrame({'Lat': [np.nan], | |
| 'Lon': [np.nan], }) | |
| df['index_gdf'] = i | |
| all_data.append(df) | |
| return pd.concat(all_data).query('Lat==Lat').reset_index(drop=1).drop(columns='index_gdf') | |
| #Side Bar | |
| address = st.sidebar.text_input( | |
| "Address", "San Jose, CA") | |
| date = st.sidebar.date_input("Date", pd.Timestamp(2021, 7, 14), key='date') | |
| number_days_range = st.sidebar.selectbox( | |
| 'Within Day Range:', (5, 10, 30, 90, 180)) | |
| refresh = st.sidebar.radio( | |
| 'Refresh Data (as of 6/7/23): Will Take Time ', (False, True)) | |
| miles_range = st.sidebar.selectbox( | |
| 'Find Fires within Range (Miles):', (None, 50, 100, 250, 500)) | |
| size = st.sidebar.radio( | |
| 'Greater than 100 Acres', ("Yes", "No")) | |
| #Get Data | |
| gdf = get_perimeters(refresh) | |
| # Geocode Addreses | |
| lat, lon = geocode(address) | |
| #Filter Data | |
| start_date, end_date = date - \ | |
| pd.Timedelta(days=number_days_range), date + \ | |
| pd.Timedelta(days=number_days_range+1) | |
| start_date_str, end_date_str = start_date.strftime( | |
| '%Y-%m-%d'), end_date.strftime('%Y-%m-%d') | |
| gdf_cut = gdf.query(f"'{start_date_str}'<=DiscoveryDate<='{end_date_str}'") | |
| gdf_cut['DiscoveryDate'] = gdf_cut['DiscoveryDate'].dt.strftime('%Y-%m-%d') | |
| #Distance to Fire | |
| gdf_cut["Lat_address"] = lat | |
| gdf_cut["Lon_address"] = lon | |
| gdf_cut['Miles to Fire Centroid'] = [ | |
| distance(i) for i in gdf_cut[gdf_cut.columns[-4:]].values] | |
| gdf_cut['Miles to Fire Centroid'] = gdf_cut['Miles to Fire Centroid'].round(2) | |
| if miles_range is not None: | |
| gdf_cut = gdf_cut.query(f"`Miles to Fire Centroid`<={miles_range}") | |
| if size == 'Yes': | |
| gdf_cut = gdf_cut.query("Size_acres>100") | |
| gdf_cut = gdf_cut.sort_values('Miles to Fire Centroid').reset_index(drop=1) | |
| gdf_cut.index = gdf_cut.index+1 | |
| #Map Data | |
| m = map_perimeters(gdf_cut, address) | |
| #Incident Edge | |
| indicents = list(gdf_cut['Incident'].values) | |
| incident_edge = st.sidebar.selectbox( | |
| 'Find Distance to Closest Edge:', indicents) | |
| vertices = extract_vertices(gdf_cut[gdf_cut['Incident']==incident_edge]) | |
| vertices["Lat_address"] = lat | |
| vertices["Lon_address"] = lon | |
| vertices['Distance'] = [ | |
| distance(i) for i in vertices.values] | |
| closest_edge = vertices[vertices['Distance'] | |
| == vertices['Distance'].min()] | |
| try: | |
| lon_point, lat_point = closest_edge[['Lon', 'Lat']].values[0] | |
| distance_edge = closest_edge['Distance'].round(2).values[0] | |
| folium.PolyLine([[lat, lon], | |
| [lat_point, lon_point]], | |
| color='black', | |
| tooltip=f'Distance: {distance_edge} Miles' | |
| ).add_to(m) | |
| except: | |
| pass | |
| #Display | |
| col1, col2 = st.columns((2, 3)) | |
| with col1: | |
| st.header('Fire Perimeters') | |
| st_folium(m, height=600) | |
| with col2: | |
| st.header('Fires') | |
| gdf_cut[['Incident', 'DiscoveryDate', 'Size_acres','Miles to Fire Centroid']] | |