MiMTSS_ISDMaps / app.py
ProfessorLeVesseur's picture
Update app.py
00bbf14 verified
import streamlit as st
import pandas as pd
import geopandas
import folium
from streamlit_folium import st_folium
from pathlib import Path
import tempfile
# Streamlit page setup
st.set_page_config(page_title="ISD Mapping", layout="centered", initial_sidebar_state="collapsed")
st.image('MTSS.ai_Logo.png', width=300)
st.header('MittenTopography™ | ISDs')
st.subheader('Map Maker')
# CSV file upload
# uploaded_file = st.file_uploader("Upload your ISD data CSV", type=["csv"])
# if uploaded_file is not None:
# df = pd.read_csv(uploaded_file)
# Excel file upload
uploaded_file = st.file_uploader("Upload your ISD data XLSX", type=["xlsx"])
if uploaded_file is not None:
# Specify dtype as str for 'ISD Code' to ensure it reads in as string
df = pd.read_excel(uploaded_file, dtype={"ISD Code": str})
# Add column "Count" and add 1 to all rows
df['Count'] = 1
# If the 'ISD Code' column contains integers without leading zeros, add them
df['ISD Code'] = df['ISD Code'].apply(lambda x: str(x).zfill(5))
# Load GeoJSON file from the root directory
geojson_filename = "Intermediate_School_Districts.geojson" # Name of your GeoJSON file
geojson_path = Path(__file__).parent / geojson_filename # Construct the path to the GeoJSON file
if geojson_path.exists():
Mi_ISD_geojson = geopandas.read_file(str(geojson_path))
Mi_ISD_geojson.rename(columns={'ISD': 'ISD Code', 'NAME': 'ISD'}, inplace=True)
# Drop unwanted columns
columns_to_drop = ['OBJECTID', 'LABEL', 'TYPE', 'SQKM', 'SQMILES', 'ACRES', 'VER','LAYOUT', 'PENINSULA', 'ISDCode', 'ISD1', 'ShapeSTArea', 'ShapeSTLength']
Mi_ISD_geojson.drop(columns=columns_to_drop, axis=1, inplace=True)
# Ensure 'ISD Code' is treated as a string to preserve leading zeros
Mi_ISD_geojson['ISD Code'] = Mi_ISD_geojson['ISD Code'].astype(str)
# If the 'ISD Code' column contains integers without leading zeros, add them
Mi_ISD_geojson['ISD Code'] = Mi_ISD_geojson['ISD Code'].apply(lambda x: str(x).zfill(5))
# Merge GeoJSON file and DataFrame
ISD_Combined = pd.merge(Mi_ISD_geojson, df, on='ISD Code', how='left', suffixes=('', '_drop')).fillna(0)
# Identify any columns that end with '_drop' and drop them
ISD_Combined = ISD_Combined.loc[:, ~ISD_Combined.columns.str.endswith('_drop')]
# Generating the Folium map
def style_function(feature):
count = feature['properties'].get('Count', 0)
return {
'fillColor': '#375173' if count > 0 else 'white',
'color': 'black',
'weight': 0.15,
'fillOpacity': 0.7 if count > 0 else 0.25,
'lineOpacity': 0.4,
}
m = folium.Map(location=[44.3148, -85.6024], zoom_start=7)
folium.GeoJson(
ISD_Combined.to_json(),
style_function=style_function,
tooltip=folium.GeoJsonTooltip(fields=['ISD'], aliases=['ISD:'])
).add_to(m)
st.divider()
# Displaying ISDs with a count of 1
ISDs_with_one = ISD_Combined[ISD_Combined['Count'] == 1]
if not ISDs_with_one.empty:
st.write("ISDs:")
st.dataframe(ISDs_with_one[['ISD', 'ISD Code']].reset_index(drop=True))
# Informing the user about the total number of ISD with a count of 1
total_ISDs_with_one = len(ISDs_with_one)
st.write(f"Total number of ISD: {total_ISDs_with_one}")
# Convert DataFrame to CSV for the download button
csv = ISDs_with_one[['ISD', 'ISD Code']].to_csv(index=False).encode('utf-8')
st.download_button(
label="Download Included ISD List to Verify",
data=csv,
file_name="ISD_List_to_Verify.csv",
mime="text/csv",
key='download-csv'
)
else:
st.write("No ISDs")
st.divider()
# call to render Folium map in Streamlit
st_data = st_folium(m, width=725)
# Save the map to a temporary HTML file and offer it for download
with tempfile.NamedTemporaryFile(delete=False, suffix=".html") as tmpfile:
m.save(tmpfile.name)
tmpfile.seek(0)
with open(tmpfile.name, "rb") as file:
btn = st.download_button(
label="Download Map as HTML",
data=file,
file_name="ISD_Map.html",
mime="text/html",
type="primary"
)