mattritchey/QuickAddresses
1
1# -*- coding: utf-8 -*-2"""3Created on Fri Nov 11 07:26:42 20224 5@author: mritchey6"""7# streamlit run "C:\Users\mritchey\.spyder-py3\Python Scripts\streamlit projects\quick address\quick_address.py"8import streamlit as st9from streamlit_folium import st_folium10import pandas as pd11import numpy as np12import folium13from joblib import Parallel, delayed14 15 16@st.cache17def convert_df(df):18 return df.to_csv(index=0).encode('utf-8')19 20 21def map_results(results):22 for index, row in results.iterrows():23 address, sq_ft = results.loc[index,24 'Address'], results.loc[index, 'Total Area']25 html = f"""<p style="arial"><p style="font-size:14px"> 26 {address} 27 <br> Square Footage: {sq_ft}"""28 29 iframe = folium.IFrame(html)30 popup = folium.Popup(iframe,31 min_width=140,32 max_width=140)33 34 folium.Marker(location=[results.loc[index, 'Lat'],35 results.loc[index, 'Lon']],36 fill_color='#43d9de',37 popup=popup,38 radius=8).add_to(m)39 return folium40 41 42# @st.cache43def get_housing_data(address_input):44 address = address_input.replace(45 ' ', '+').replace(',', '').replace('#+', '').upper()46 try:47 census = pd.read_json(48 f"https://geocoding.geo.census.gov/geocoder/geographies/onelineaddress?address={address}&benchmark=2020&vintage=2020&format=json")49 results = census.iloc[:1, 0][0]50 matchedAddress_first = results[0]['matchedAddress']51 matchedAddress_last = results[-1]['matchedAddress']52 lat, lon = results[0]['coordinates']['y'], results[0]['coordinates']['x']53 # lat2, lon2 = results[-1]['coordinates']['y'], results[-1]['coordinates']['x']54 censusb = pd.DataFrame({'Description': ['Address Input', 'Census Matched Address: First',55 'Census Matched Address: Last', 'Lat', 'Lon'],56 'Values': [address_input, matchedAddress_first, matchedAddress_last, lat, lon]})57 58 #Property Records59 url = f'https://www.countyoffice.org/property-records-search/?q={address}'60 county_office_list = pd.read_html(url)61 62 if county_office_list[1].shape[1] == 2:63 df2 = pd.concat([county_office_list[0], county_office_list[1]])64 else:65 df2 = county_office_list[0]66 df2.columns = ['Description', 'Values']67 68 final = censusb.append(df2)69 70 #Transpose71 final2 = final.T72 final2.columns = final2.loc['Description']73 final2 = final2.loc[['Values']].set_index('Address Input')74 # final2['County Office Url']=url75 except:76 final2 = address_input77 return final278 79 80# @st.cache(allow_output_mutation=True)81def address_quick(df, n_jobs=24):82 if isinstance(df, pd.DataFrame):83 df = df.drop_duplicates()84 df['address_input'] = df.iloc[:, 0]+', '+df.iloc[:, 1] + \85 ', '+df.iloc[:, 2]+' '+df.iloc[:, 3].astype(str).str[:5]86 df['address'] = df['address_input'].replace(87 {' ': '+', ',': ''}, regex=True).str.upper()88 df['address'] = df['address'].replace({'#+': ''}, regex=True)89 # addresses=df['address'].values90 addresses_input = df['address_input'].values91 else:92 addresses_input = [df]93 results = Parallel(n_jobs=n_jobs, prefer="threads")(94 delayed(get_housing_data)(i) for i in addresses_input)95 results_df = [i for i in results if isinstance(i, pd.DataFrame)]96 results_errors = [i for i in results if not isinstance(i, pd.DataFrame)]97 errors = pd.DataFrame({'Error Addresses': results_errors})98 final_results = pd.concat(results_df)99 final_results = final_results[final_results.columns[2:]].copy()100 101 return final_results, errors102 103 104st.set_page_config(layout="wide")105col1, col2 = st.columns((2))106 107address = st.sidebar.text_input(108 "Address", "1500 MOHICAN DR, FORESTDALE, AL, 35214")109uploaded_file = st.sidebar.file_uploader("Choose a file")110uploaded_file = 'C:/Users/mritchey/addresses_sample.csv'111address_file = st.sidebar.radio('Choose',112 ('Single Address', 'Addresses (Geocode: Will take a bit)'))113 114 115if address_file == 'Addresses (Geocode: Will take a bit)':116 try:117 df = pd.read_csv(uploaded_file)118 cols = df.columns.to_list()[:4]119 with st.spinner("Getting Data: Hang On..."):120 results, errors = address_quick(df[cols])121 122 except:123 st.header('Make Sure File is Loaded First and then hit "Addresses"')124 125else:126 results, errors = address_quick(address)127 128m = folium.Map(location=[39.50, -98.35], zoom_start=3)129 130 131with col1:132 st.title('Addresses')133 map_results(results)134 st_folium(m, height=500, width=500)135 136with col2:137 st.title('Results')138 results.index = np.arange(1, len(results) + 1)139 st.dataframe(results)140 csv = convert_df(results)141 st.download_button(142 label="Download data as CSV",143 data=csv,144 file_name='Results.csv',145 mime='text/csv')146 try:147 if errors.shape[0] > 0:148 149 st.header('Errors')150 errors.index = np.arange(1, len(errors) + 1)151 st.dataframe(errors)152 # st.table(errors.assign(hack='').set_index('hack'))153 csv2 = convert_df(errors)154 st.download_button(155 label="Download Errors as CSV",156 data=csv2,157 file_name='Errors.csv',158 mime='text/csv')159 except:160 pass161 162st.markdown(""" <style>163#MainMenu {visibility: hidden;}164footer {visibility: hidden;}165</style> """, unsafe_allow_html=True)166 