mattritchey commited on
Commit
2d5ba4a
·
1 Parent(s): 3bc497e

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +207 -0
app.py ADDED
@@ -0,0 +1,207 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Created on Fri Oct 14 10:35:25 2022
4
+ @author: mritchey
5
+ """
6
+
7
+ import datetime
8
+ import glob
9
+ import os
10
+ import urllib.request
11
+ import branca.colormap as cm
12
+ import folium
13
+ import numpy as np
14
+ import pandas as pd
15
+ import plotly.express as px
16
+ import rasterio
17
+ import rioxarray
18
+ import streamlit as st
19
+ from geopy.extra.rate_limiter import RateLimiter
20
+ from geopy.geocoders import Nominatim
21
+ from joblib import Parallel, delayed
22
+ from matplotlib import colors as colors
23
+ from streamlit_folium import st_folium
24
+ from threading import Thread
25
+
26
+ def download_file_get_data(url,rows, columns):
27
+ file = urllib.request.urlretrieve(url, url[-23:])[0]
28
+ rds = rioxarray.open_rasterio(file)
29
+ wind_mph = rds.rio.reproject("EPSG:4326")[0, rows, columns].values*2.23694
30
+ time = url[-15:-11]
31
+ return [wind_mph, time]
32
+
33
+ def threading(df_input,func_input):
34
+ starttime=time.time()
35
+ tasks_thread=df_input
36
+ results_thread=[]
37
+ def thread_func(value_input):
38
+ response=func_input(value_input)
39
+ results_thread.append(response)
40
+ return True
41
+
42
+ threads = []
43
+ for i in range(len(tasks_thread)):
44
+ process = Thread(target=thread_func, args=[tasks_thread[i]])
45
+ process.start()
46
+ threads.append(process)
47
+
48
+ for process in threads:
49
+ process.join()
50
+ print(f'Time: {str(round((time.time()-starttime)/60,5))} Minutes')
51
+ return results_thread
52
+
53
+ def mapvalue2color(value, cmap):
54
+ if np.isnan(value):
55
+ return (1, 0, 0, 0)
56
+ else:
57
+ return colors.to_rgba(cmap(value), 0.7)
58
+
59
+
60
+
61
+ def geocode(address):
62
+ try:
63
+ address2 = address.replace(' ', '+').replace(',', '%2C')
64
+ df = pd.read_json(
65
+ f'https://geocoding.geo.census.gov/geocoder/locations/onelineaddress?address={address2}&benchmark=2020&format=json')
66
+ results = df.iloc[:1, 0][0][0]['coordinates']
67
+ lat, lon = results['y'], results['x']
68
+ except:
69
+ geolocator = Nominatim(user_agent="GTA Lookup")
70
+ geocode = RateLimiter(geolocator.geocode, min_delay_seconds=1)
71
+ location = geolocator.geocode(address)
72
+ lat, lon = location.latitude, location.longitude
73
+ return lat, lon
74
+
75
+ @st.cache
76
+ def get_grib_data(url, d, t):
77
+ file = urllib.request.urlretrieve(url, f'{d}{t}{type_wind}.grib2')[0]
78
+ return file
79
+
80
+ @st.cache
81
+ def graph_entire_day(d,rows, columns):
82
+ year, month, day = d[:4], d[4:6], d[6:8]
83
+ times = [f'0{str(i)}'[-2:] for i in range(0, 24)]
84
+ urls = [
85
+ f'https://mtarchive.geol.iastate.edu/{year}/{month}/{day}/grib2/ncep/RTMA/{d}{t}00_{type_wind.upper()}.grib2' for t in times]
86
+
87
+ results = Parallel(n_jobs=4)(
88
+ delayed(download_file_get_data)(i,rows, columns) for i in urls)
89
+
90
+ df_all = pd.DataFrame(results, columns=['MPH', 'Time'])
91
+ df_all['MPH'] = df_all['MPH'].round(2)
92
+ df_all['Time'] = pd.to_datetime(d+df_all['Time'], format='%Y%m%d%H%M')
93
+ return df_all
94
+
95
+
96
+ @st.cache
97
+ def convert_df(df):
98
+ return df.to_csv(index=0).encode('utf-8')
99
+
100
+
101
+ try:
102
+ for i in glob.glob('*.grib2'):
103
+ os.remove(i)
104
+ except:
105
+ pass
106
+
107
+ st.set_page_config(layout="wide")
108
+ col1, col2 = st.columns((2))
109
+
110
+ address = st.sidebar.text_input(
111
+ "Address", "123 Main Street, Columbus, OH 43215")
112
+ d = st.sidebar.date_input(
113
+ "Date", pd.Timestamp(2022, 9, 28)).strftime('%Y%m%d')
114
+
115
+ time = st.sidebar.selectbox('Time:', ('12 AM', '6 AM', '12 PM', '6 PM',))
116
+ type_wind = st.sidebar.selectbox('Type:', ('Gust', 'Wind'))
117
+ entire_day = st.sidebar.radio(
118
+ 'Graph Entire Day (Takes a Bit):', ('No', 'Yes'))
119
+
120
+ if time[-2:] == 'PM' and int(time[:2].strip()) < 12:
121
+ t = datetime.time(int(time[:2].strip())+12, 00).strftime('%H')+'00'
122
+ elif time[-2:] == 'AM' and int(time[:2].strip()) == 12:
123
+ t = '0000'
124
+ else:
125
+ t = datetime.time(int(time[:2].strip()), 00).strftime('%H')+'00'
126
+
127
+ year, month, day = d[:4], d[4:6], d[6:8]
128
+
129
+ url = f'https://mtarchive.geol.iastate.edu/{year}/{month}/{day}/grib2/ncep/RTMA/{d}{t}_{type_wind.upper()}.grib2'
130
+ file = get_grib_data(url, d, t)
131
+
132
+ lat, lon = geocode(address)
133
+
134
+ rds = rioxarray.open_rasterio(file)
135
+ projected = rds.rio.reproject("EPSG:4326")
136
+ wind_mph = projected.sel(x=lon, y=lat, method="nearest").values*2.23694
137
+
138
+ affine = projected.rio.transform()
139
+
140
+ rows, columns = rasterio.transform.rowcol(affine, lon, lat)
141
+
142
+ size = 40
143
+
144
+ projected2 = projected[0, rows-size:rows+size, columns-size:columns+size]
145
+
146
+ img = projected2.values*2.23694
147
+ boundary = projected2.rio.bounds()
148
+ left, bottom, right, top = boundary
149
+
150
+ img[img < 0.0] = np.nan
151
+
152
+ clat = (bottom + top)/2
153
+ clon = (left + right)/2
154
+
155
+ vmin = np.floor(np.nanmin(img))
156
+ vmax = np.ceil(np.nanmax(img))
157
+
158
+ colormap = cm.LinearColormap(
159
+ colors=['blue', 'lightblue', 'red'], vmin=vmin, vmax=vmax)
160
+
161
+ m = folium.Map(location=[lat, lon], zoom_start=9, height=500)
162
+
163
+ folium.Marker(
164
+ location=[lat, lon],
165
+ popup=f"{wind_mph[0].round(2)} MPH").add_to(m)
166
+
167
+ folium.raster_layers.ImageOverlay(
168
+ image=img,
169
+ name='Wind Speed Map',
170
+ opacity=.8,
171
+ bounds=[[bottom, left], [top, right]],
172
+ colormap=lambda value: mapvalue2color(value, colormap)
173
+ ).add_to(m)
174
+
175
+
176
+ folium.LayerControl().add_to(m)
177
+ colormap.caption = 'Wind Speed: MPH'
178
+ m.add_child(colormap)
179
+
180
+ with col1:
181
+ st.title('RTMA Model')
182
+ st.write(
183
+ f"{type_wind.title()} Speed: {wind_mph[0].round(2)} MPH at {time} UTC")
184
+ st_folium(m, height=500)
185
+
186
+
187
+ if entire_day == 'Yes':
188
+ df_all = graph_entire_day(d,rows, columns)
189
+ fig = px.line(df_all, x="Time", y="MPH")
190
+ with col2:
191
+ st.title('Analysis')
192
+ st.plotly_chart(fig)
193
+
194
+ csv = convert_df(df_all)
195
+
196
+ st.download_button(
197
+ label="Download data as CSV",
198
+ data=csv,
199
+ file_name=f'{d}.csv',
200
+ mime='text/csv')
201
+ else:
202
+ pass
203
+
204
+ st.markdown(""" <style>
205
+ #MainMenu {visibility: hidden;}
206
+ footer {visibility: hidden;}
207
+ </style> """, unsafe_allow_html=True)