# -*- coding: utf-8 -*- """ Created on Fri Oct 14 10:35:25 2022 @author: mritchey """ import gzip import pickle import h5py import rasterio 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") @st.cache_data 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]], interactive=True ).add_to(m) return m # @st.cache_data 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 # @st.cache_data def get_data(row, col, radius): files = [ "2023_hail.h5", "2022_hail.h5"] all_data = [] all_dates = [] for f in files: with h5py.File(f, 'r') as f: data = f['hail'][:, row-radius:row + radius+1, col-radius:col+radius+1] dates = f['dates'][:] all_data.append(data) all_dates.append(dates) data_mat = np.concatenate(all_data) data_mat = np.where(data_mat < 0, 0, data_mat)*0.0393701 dates_mat = np.concatenate(all_dates) data_actual = [i[radius, radius] for i in data_mat] data_max = np.max(data_mat, axis=(1, 2)) data_max_2 = np.max(data_mat, axis=0) df = pd.DataFrame({'Date': dates_mat, 'Actual': data_actual, 'Max': data_max}) df['Date'] = pd.to_datetime(df['Date'], format='%Y%m%d') return df, data_max_2 #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") start_date = st.sidebar.date_input("Start Date", pd.Timestamp(2022, 1, 1)) end_date = st.sidebar.date_input("End Date", pd.Timestamp(2023, 12, 31)) circle_radius = st.sidebar.selectbox('Box Radius (Miles)', (5, 10, 25)) zoom_dic = {5: 12, 10: 11, 25: 10} zoom = zoom_dic[circle_radius] #Geocode and get Data result = geocode(address) lat, lon = result.values[0] #Raster Data extracted_file = 'hail_stage.grib2' ds_stage = xr.open_dataarray(extracted_file,engine='rasterio') transform = ds_stage.rio.transform() row, col = rasterio.transform.rowcol(transform, lon, lat) radius = int(np.ceil(circle_radius*1.6)) crop_coords = col-radius, row-radius, col+radius+1, row+radius+1 # Get Data df_data, max_values = get_data(row, col, radius) df_data=df_data.query(f"'{start_date}'<=Date<='{end_date}'") # 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)) fig = px.bar(df_data, x="Date", y="Actual", color="Actual", # barmode="stack", # color='red', # color_discrete_map=color_discrete_map, ) # 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(df_data) 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(""" """, unsafe_allow_html=True)