Spaces:
Sleeping
Sleeping
# -*- coding: utf-8 -*- | |
""" | |
Created on Fri Oct 14 10:35:25 2022 | |
@author: mritchey | |
""" | |
from tqdm import tqdm | |
from joblib import Parallel, delayed | |
import rasterio | |
import glob | |
from PIL import Image | |
import streamlit as st | |
import os | |
import branca.colormap as cm | |
import folium | |
from streamlit_folium import st_folium | |
import numpy as np | |
import pandas as pd | |
import plotly.express as px | |
from geopy.extra.rate_limiter import RateLimiter | |
from geopy.geocoders import Nominatim | |
import rioxarray | |
import xarray as xr | |
import warnings | |
warnings.filterwarnings("ignore") | |
def convert_df(df): | |
return df.to_csv(index=0).encode('utf-8') | |
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 pd.DataFrame({'Lat': lat, 'Lon': lon}, index=[0]) | |
def map_folium(data, zoom=12): | |
m = folium.Map(location=[lat, lon], zoom_start=zoom, height=300) | |
folium.Marker( | |
location=[lat, lon], | |
popup=address).add_to(m) | |
# folium.GeoJson(gdf['buffer']).add_to(m) | |
folium.raster_layers.ImageOverlay( | |
data, opacity=0.8, bounds=[[bottom, left], [top, right]]).add_to(m) | |
return m | |
def crop_hail_jpg_filter(f, crop_coords, scaling_factor=255): | |
date = f[-19:-11] | |
image = Image.open(f) | |
cropped_image = image.crop(crop_coords) | |
image = (np.array(cropped_image)/scaling_factor) | |
if image.sum() > 0: | |
return date, image | |
def get_data(start_date,end_date,crop_coords): | |
files = glob.glob(f'png/**/*.png', recursive=True) | |
files_dates = np.array([int(f[-19:-11]) for f in files]) | |
mask = np.where((files_dates >= int(start_date)) & ( | |
files_dates <= int(end_date)), True, False) | |
files = np.array(files)[mask] | |
results = Parallel(n_jobs=96, prefer='threads')( | |
delayed(crop_hail_jpg_filter)(i, crop_coords) for i in tqdm(files)) | |
results = [i for i in results if i is not None] | |
return results | |
#Set up 2 Columns | |
st.set_page_config(layout="wide") | |
col1, col2 = st.columns((2)) | |
#Input Values | |
address = st.sidebar.text_input("Address", "123 Main Street, Dallas, TX 75126") | |
d = st.sidebar.date_input("Date", pd.Timestamp(2022, 7, 1)) | |
days_within = st.sidebar.selectbox('Days Within:', ('30', '90', '180', 'Day Of',)) | |
circle_radius = st.sidebar.selectbox('Box Radius (Miles)', (5, 10, 25)) | |
zoom_dic = {5: 12, 10: 11, 25: 10} | |
zoom = zoom_dic[circle_radius] | |
try: | |
days_within = int(days_within) | |
start_date, end_date = d - \ | |
pd.Timedelta(days=days_within), d+pd.Timedelta(days=days_within+1) | |
start_date, end_date = start_date.strftime( | |
'%Y%m%d'), end_date.strftime('%Y%m%d') | |
except: | |
days_within = 0 | |
start_date = end_date=d -pd.Timedelta(days=days_within) | |
start_date = end_date=start_date.strftime('%Y%m%d') | |
#Geocode and get Data | |
result = geocode(address) | |
lat, lon = result.values[0] | |
ds_stage = xr.open_rasterio('hail_stage.grib2') | |
transform = ds_stage.rio.transform() | |
row, col = rasterio.transform.rowcol(transform, lon, lat) | |
# center=row,col | |
radius = int(np.ceil(circle_radius*1.6)) | |
crop_coords = col-radius, row-radius, col+radius+1, row+radius+1 | |
# Get Data | |
results=get_data(start_date,end_date,crop_coords) | |
try: | |
max_values = np.max(np.array([i[1] for i in results]), axis=0)*0.0393701 | |
except: | |
max_values=np.zeros(shape=(2*radius+1,2*radius+1)) | |
# Bin Data | |
bin_edges = [0, 0.1, 0.2, 0.4, 0.8, 1.2, 1.6, 2, 3, 4, np.inf] | |
bin_names = ["<0.1", "0.1-0.2", "0.2-0.4", "0.4-0.8", "0.8-1.2", "1.2-1.6", "1.6-2", | |
"2-3", "3-4", ">4"] | |
colors_values = ['#ffffff', '#ffff00', '#d1ab00', '#ff9b00', '#fe0000', '#cd0000', '#ff30ce', | |
'#ff30cd', '#9a009b', '#4a4d4c'] | |
color_discrete_map = dict(zip(bin_names, colors_values)) | |
all_data = [] | |
for date, mat in results: | |
mat = mat*0.0393701 | |
hist_values, _ = np.histogram(mat, bins=bin_edges) | |
df = pd.DataFrame({'bin_edges': bin_edges[:-1], | |
'Bin': bin_names, | |
'Values': hist_values}, | |
) | |
df['Date'] = pd.to_datetime(date) | |
all_data.append(df) | |
try: | |
final = pd.concat(all_data) | |
final = final.query('bin_edges!=0') | |
fig = px.bar(final, x="Date", y="Values", color="Bin", | |
barmode="stack", | |
color_discrete_map=color_discrete_map) | |
except: | |
pass | |
# Crop the raster using the bounds | |
cropped_data = ds_stage[0][row-radius:row+radius+1, col-radius:col+radius+1] | |
cropped_data.values = max_values | |
# Max Values Bin for RGB | |
def hex_to_rgb(hex_code): | |
hex_code = hex_code.lstrip('#') # Remove the '#' character if present | |
rgb = tuple(int(hex_code[i:i+2], 16) for i in (0, 2, 4)) | |
return rgb | |
def hex_to_rgba(hex_code, alpha=.8): | |
if hex_code == '#ffffff': | |
alpha = 0.0 | |
alpha_scaled = int(alpha * 255) | |
rgb = hex_to_rgb(hex_code) | |
rgba = rgb + (alpha_scaled,) | |
return rgba | |
bin_indices = np.digitize(max_values, bin_edges)-1 | |
bin_colors = np.take(colors_values, bin_indices) | |
max_values_rgb = np.array([hex_to_rgba(i) for i in bin_colors.flatten()]).reshape( | |
max_values.shape[0], max_values.shape[0], 4) | |
#Mapping | |
img = max_values_rgb.astype('uint8') | |
boundary = cropped_data.rio.bounds() | |
left, bottom, right, top = boundary | |
# img[img < 0.0] = np.nan | |
clat = (bottom + top)/2 | |
clon = (left + right)/2 | |
vmin = np.floor(np.nanmin(img)) | |
vmax = np.ceil(np.nanmax(img)) | |
# colormap = cm.StepColormap(colors=list(color_discrete_map.values()), | |
# index=bin_edges, | |
# # vmin=vmin, vmax=vmax | |
# ) | |
m = map_folium(img, zoom) | |
with col1: | |
st.title('Hail Mesh') | |
st_folium(m, height=500) | |
with col2: | |
st.title(f'Hail') | |
try: | |
st.plotly_chart(fig) | |
csv = convert_df(final) | |
st.download_button( | |
label="Download data as CSV", | |
data=csv, | |
file_name='data.csv', | |
mime='text/csv') | |
except: | |
pass | |
# st.bokeh_chart(hv.render(nice_plot*points_lat_lon, backend='bokeh'),use_container_width=True) | |
st.markdown(""" <style> | |
#MainMenu {visibility: hidden;} | |
footer {visibility: hidden;} | |
</style> """, unsafe_allow_html=True) | |