gis-ai-model / app.py
engratif78's picture
Update app.py
8444ac4 verified
import streamlit as st
import geopandas as gpd
import folium
import zipfile
import tempfile
import os
from streamlit_folium import st_folium
from shapely.geometry import LineString
st.set_page_config(page_title="GIS Viewer", layout="wide")
st.title("πŸ—ΊοΈ GIS Viewer with Connected Points")
st.markdown("Upload a GeoJSON, KMZ, or zipped Shapefile. This app will connect every 2 consecutive points with a solid line.")
uploaded_file = st.file_uploader("Upload GeoJSON, KMZ or zipped Shapefile", type=["geojson", "zip", "kmz"])
def load_geodata(file):
ext = file.name.lower()
with tempfile.TemporaryDirectory() as tmpdir:
if ext.endswith(".geojson"):
gdf = gpd.read_file(file)
elif ext.endswith(".zip"):
with zipfile.ZipFile(file, "r") as z:
z.extractall(tmpdir)
shp_files = [f for f in os.listdir(tmpdir) if f.endswith(".shp")]
if not shp_files:
raise Exception("No .shp file found in ZIP.")
gdf = gpd.read_file(os.path.join(tmpdir, shp_files[0]))
elif ext.endswith(".kmz"):
with zipfile.ZipFile(file, "r") as z:
z.extractall(tmpdir)
kml_files = [f for f in os.listdir(tmpdir) if f.endswith(".kml")]
if not kml_files:
raise Exception("No .kml file found inside KMZ.")
gdf = gpd.read_file(os.path.join(tmpdir, kml_files[0]))
else:
raise Exception("Unsupported file format.")
if gdf.crs and gdf.crs.to_epsg() != 4326:
gdf = gdf.to_crs(epsg=4326)
return gdf
def create_lines_from_points(points_gdf):
lines = []
for i in range(0, len(points_gdf) - 1, 2):
p1 = points_gdf.iloc[i].geometry
p2 = points_gdf.iloc[i+1].geometry
if p1.geom_type == "Point" and p2.geom_type == "Point":
line = LineString([p1, p2])
lines.append({"geometry": line})
return gpd.GeoDataFrame(lines, geometry="geometry", crs="EPSG:4326")
if uploaded_file:
try:
with st.spinner("Processing file..."):
gdf = load_geodata(uploaded_file)
st.success("File loaded successfully!")
# Filter only points
point_gdf = gdf[gdf.geometry.type == "Point"].reset_index(drop=True)
line_gdf = create_lines_from_points(point_gdf)
# Map setup
center = gdf.geometry.unary_union.centroid
m = folium.Map(location=[center.y, center.x], zoom_start=10)
folium.GeoJson(gdf, name="Features",
tooltip=folium.GeoJsonTooltip(fields=gdf.columns[:3].tolist())).add_to(m)
# Add lines between points
folium.GeoJson(line_gdf, name="Lines Between Points",
style_function=lambda x: {"color": "red", "weight": 3}).add_to(m)
# Add point markers
for idx, row in point_gdf.iterrows():
coords = row.geometry.coords[0]
folium.Marker(
location=[coords[1], coords[0]],
popup=f"Point {idx+1} - ({coords[1]}, {coords[0]})",
icon=folium.Icon(color="blue", icon="info-sign")
).add_to(m)
folium.LayerControl().add_to(m)
st.subheader("🌍 Map Viewer")
st_folium(m, width=1100, height=600)
st.subheader("πŸ“ Points Table")
st.dataframe(point_gdf)
st.subheader("πŸ“‹ Full Attribute Table")
st.dataframe(gdf)
except Exception as e:
st.error(f"Error: {e}")
else:
st.info("Please upload a geospatial file to get started.")