mattritchey commited on
Commit
fb64c7d
·
0 Parent(s):

Duplicate from mattritchey/wildfires

Browse files
Files changed (5) hide show
  1. .gitattributes +34 -0
  2. README.md +13 -0
  3. app.py +191 -0
  4. requirements.txt +9 -0
  5. wildfire_perimeters.parquet +3 -0
.gitattributes ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ *.7z filter=lfs diff=lfs merge=lfs -text
2
+ *.arrow filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
5
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
6
+ *.ftz filter=lfs diff=lfs merge=lfs -text
7
+ *.gz filter=lfs diff=lfs merge=lfs -text
8
+ *.h5 filter=lfs diff=lfs merge=lfs -text
9
+ *.joblib filter=lfs diff=lfs merge=lfs -text
10
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
+ *.model filter=lfs diff=lfs merge=lfs -text
13
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
14
+ *.npy filter=lfs diff=lfs merge=lfs -text
15
+ *.npz filter=lfs diff=lfs merge=lfs -text
16
+ *.onnx filter=lfs diff=lfs merge=lfs -text
17
+ *.ot filter=lfs diff=lfs merge=lfs -text
18
+ *.parquet filter=lfs diff=lfs merge=lfs -text
19
+ *.pb filter=lfs diff=lfs merge=lfs -text
20
+ *.pickle filter=lfs diff=lfs merge=lfs -text
21
+ *.pkl filter=lfs diff=lfs merge=lfs -text
22
+ *.pt filter=lfs diff=lfs merge=lfs -text
23
+ *.pth filter=lfs diff=lfs merge=lfs -text
24
+ *.rar filter=lfs diff=lfs merge=lfs -text
25
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
26
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
28
+ *.tflite filter=lfs diff=lfs merge=lfs -text
29
+ *.tgz filter=lfs diff=lfs merge=lfs -text
30
+ *.wasm filter=lfs diff=lfs merge=lfs -text
31
+ *.xz filter=lfs diff=lfs merge=lfs -text
32
+ *.zip filter=lfs diff=lfs merge=lfs -text
33
+ *.zst filter=lfs diff=lfs merge=lfs -text
34
+ *tfevents* filter=lfs diff=lfs merge=lfs -text
README.md ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Wildfires
3
+ emoji: 🏢
4
+ colorFrom: blue
5
+ colorTo: yellow
6
+ sdk: streamlit
7
+ sdk_version: 1.21.0
8
+ app_file: app.py
9
+ pinned: false
10
+ duplicated_from: mattritchey/wildfires
11
+ ---
12
+
13
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
app.py ADDED
@@ -0,0 +1,191 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Created on Thu Jun 8 03:39:02 2023
4
+
5
+ @author: mritchey
6
+ """
7
+ import pandas as pd
8
+ import numpy as np
9
+ import streamlit as st
10
+ from geopy.extra.rate_limiter import RateLimiter
11
+ from geopy.geocoders import Nominatim
12
+ import folium
13
+ from streamlit_folium import st_folium
14
+ import geopandas as gpd
15
+ from vincenty import vincenty
16
+
17
+ st.set_page_config(layout="wide")
18
+
19
+ @st.cache_resource
20
+ def get_perimeters(refresh=False):
21
+ if refresh:
22
+ gdf_perimeters = gpd.read_file(
23
+ 'https://opendata.arcgis.com/api/v3/datasets/5e72b1699bf74eefb3f3aff6f4ba5511_0/downloads/data?format=shp&spatialRefId=4326&where=1%3D1') # .to_crs(epsg=epsg_input)
24
+ gdf_perimeters = gdf_perimeters[['OBJECTID', 'poly_Incid', 'attr_Fir_7', 'poly_Creat',
25
+ 'poly_DateC', 'poly_Polyg', 'poly_Acres', 'attr_Estim', 'geometry']].copy()
26
+ gdf_perimeters.columns = ['OBJECTID', 'Incident', 'DiscoveryDate', 'poly_Creat',
27
+ 'LastUpdate', 'poly_Polyg', 'Size_acres', 'CurrentEstCost', 'geometry']
28
+ gdf_perimeters['Lat_centroid'] = gdf_perimeters.centroid.y
29
+ gdf_perimeters['Lon_centroid'] = gdf_perimeters.centroid.x
30
+ gdf_perimeters['DiscoveryDate'] = pd.to_datetime(
31
+ gdf_perimeters['DiscoveryDate'])
32
+
33
+ else:
34
+ gdf_perimeters = gpd.read_parquet(
35
+ "wildfire_perimeters.parquet").query("geometry==geometry")
36
+ return gdf_perimeters
37
+
38
+
39
+ def map_perimeters(_gdf_data, address):
40
+ geojson_data = _gdf_data[['OBJECTID', 'Incident', 'DiscoveryDate',
41
+ 'Miles to Fire Centroid', 'geometry']].to_json()
42
+
43
+ m = folium.Map(location=[lat, lon],
44
+
45
+ zoom_start=6,
46
+ height=500)
47
+ folium.Marker(
48
+ location=[lat, lon],
49
+ tooltip=f'Address: {address}',
50
+ ).add_to(m)
51
+
52
+ folium.GeoJson(geojson_data,
53
+ tooltip=folium.GeoJsonTooltip(fields=["Incident",
54
+ "DiscoveryDate",
55
+ 'Miles to Fire Centroid']),
56
+ ).add_to(m)
57
+ return m
58
+
59
+ def distance(x):
60
+ left_coords = (x[0], x[1])
61
+ right_coords = (x[2], x[3])
62
+ return vincenty(left_coords, right_coords, miles=True)
63
+
64
+ def geocode(address):
65
+ try:
66
+ address2 = address.replace(' ', '+').replace(',', '%2C')
67
+ df = pd.read_json(
68
+ f'https://geocoding.geo.census.gov/geocoder/locations/onelineaddress?address={address2}&benchmark=2020&format=json')
69
+ results = df.iloc[:1, 0][0][0]['coordinates']
70
+ lat, lon = results['y'], results['x']
71
+ except:
72
+ geolocator = Nominatim(user_agent="GTA Lookup")
73
+ geocode = RateLimiter(geolocator.geocode, min_delay_seconds=1)
74
+ location = geolocator.geocode(address)
75
+ lat, lon = location.latitude, location.longitude
76
+ return lat, lon
77
+
78
+ def extract_vertices(gdf):
79
+ g = [i for i in gdf.geometry]
80
+ all_data = []
81
+ for i in range(len(g)):
82
+ try:
83
+ try:
84
+ x, y = g[i].exterior.coords.xy
85
+ except:
86
+ x, y = g[i].coords.xy
87
+ df = pd.DataFrame({'Lat': y, 'Lon': x})
88
+ except:
89
+ all_data2 = []
90
+ try:
91
+ for j in range(len(g[i])):
92
+ try:
93
+ x, y = g[i][j].exterior.coords.xy
94
+ except:
95
+ x, y = g[i][j].coords.xy
96
+ all_data2.append(pd.DataFrame({'Lat': y, 'Lon': x}))
97
+ df = pd.concat(all_data2)
98
+ except:
99
+ for i in g.geometry:
100
+ x=np.concatenate([poly.exterior.coords.xy[0] for poly in i.geoms])
101
+ y=np.concatenate([poly.exterior.coords.xy[1] for poly in i.geoms])
102
+ df = pd.DataFrame({'Lat': y,
103
+ 'Lon': x, })
104
+ df['index_gdf'] = i
105
+ all_data.append(df)
106
+ return pd.concat(all_data).query('Lat==Lat').reset_index(drop=1).drop(columns='index_gdf')
107
+
108
+
109
+ #Side Bar
110
+ address = st.sidebar.text_input(
111
+ "Address", "Sacramento, CA")
112
+ date = st.sidebar.date_input("Date", pd.Timestamp(2021, 7, 14), key='date')
113
+ number_days_range = st.sidebar.selectbox(
114
+ 'Within Day Range:', (5, 10, 30, 90, 180))
115
+
116
+ refresh = st.sidebar.radio(
117
+ 'Refresh Data (as of 6/7/23): Will Take Time ', (False, True))
118
+ miles_range = st.sidebar.selectbox(
119
+ 'Find Fires within Range (Miles):', (None, 50, 100, 250, 500))
120
+
121
+ size = st.sidebar.radio(
122
+ 'Greater than 100 Acres', ("Yes", "No"))
123
+
124
+ #Get Data
125
+ gdf = get_perimeters(refresh)
126
+
127
+ # Geocode Addreses
128
+ lat, lon = geocode(address)
129
+
130
+ #Filter Data
131
+ start_date, end_date = date - \
132
+ pd.Timedelta(days=number_days_range), date + \
133
+ pd.Timedelta(days=number_days_range+1)
134
+ start_date_str, end_date_str = start_date.strftime(
135
+ '%Y-%m-%d'), end_date.strftime('%Y-%m-%d')
136
+ gdf_cut = gdf.query(f"'{start_date_str}'<=DiscoveryDate<='{end_date_str}'")
137
+ gdf_cut['DiscoveryDate'] = gdf_cut['DiscoveryDate'].dt.strftime('%Y-%m-%d')
138
+
139
+
140
+ #Distance to Fire
141
+ gdf_cut["Lat_address"] = lat
142
+ gdf_cut["Lon_address"] = lon
143
+ gdf_cut['Miles to Fire Centroid'] = [
144
+ distance(i) for i in gdf_cut[gdf_cut.columns[-4:]].values]
145
+ gdf_cut['Miles to Fire Centroid'] = gdf_cut['Miles to Fire Centroid'].round(2)
146
+ if miles_range is not None:
147
+ gdf_cut = gdf_cut.query(f"`Miles to Fire Centroid`<={miles_range}")
148
+
149
+ if size == 'Yes':
150
+ gdf_cut = gdf_cut.query("Size_acres>100")
151
+
152
+ gdf_cut = gdf_cut.sort_values('Miles to Fire Centroid').reset_index(drop=1)
153
+ gdf_cut.index = gdf_cut.index+1
154
+
155
+ #Map Data
156
+ m = map_perimeters(gdf_cut, address)
157
+
158
+ #Incident Edge
159
+ indicents = list(gdf_cut['Incident'].values)
160
+ incident_edge = st.sidebar.selectbox(
161
+ 'Find Distance to Closest Edge:', indicents)
162
+ vertices = extract_vertices(gdf_cut[gdf_cut['Incident']==incident_edge])
163
+ vertices["Lat_address"] = lat
164
+ vertices["Lon_address"] = lon
165
+ vertices['Distance'] = [
166
+ distance(i) for i in vertices.values]
167
+ closest_edge = vertices[vertices['Distance']
168
+ == vertices['Distance'].min()]
169
+
170
+ try:
171
+ lon_point, lat_point = closest_edge[['Lon', 'Lat']].values[0]
172
+ distance_edge = closest_edge['Distance'].round(2).values[0]
173
+ folium.PolyLine([[lat, lon],
174
+ [lat_point, lon_point]],
175
+ color='black',
176
+ tooltip=f'Distance: {distance_edge} Miles'
177
+ ).add_to(m)
178
+ except:
179
+ pass
180
+
181
+ #Display
182
+ col1, col2 = st.columns((2, 3))
183
+ with col1:
184
+ st.header('Fire Perimeters')
185
+ st_folium(m, height=600)
186
+ with col2:
187
+ st.header('Fires')
188
+ gdf_cut[['Incident', 'DiscoveryDate', 'Size_acres','Miles to Fire Centroid']]
189
+
190
+
191
+
requirements.txt ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ folium
2
+ geopandas
3
+ geopy
4
+ numpy
5
+ pandas
6
+ streamlit
7
+ streamlit_folium
8
+ vincenty
9
+ Shapely==1.8.1.post1
wildfire_perimeters.parquet ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:6e1b2b8347d7116e8a10a31db26905f48a67e3100eda50ebf7c371bce952eb7d
3
+ size 145374232