import re
import json
import streamlit as st
import pandas as pd
import geopandas as gpd
import leafmap.foliumap as leafmap
from optree import tree_map
from shapely.ops import transform
import kml2geojson
from io import BytesIO, StringIO
import requests
def shape_3d_to_2d(shape):
if shape.has_z:
return transform(lambda x, y, z: (x, y), shape)
else:
return shape
def preprocess_gdf(gdf):
gdf = gdf.to_crs(epsg=7761) # epsg for Gujarat
gdf["geometry"] = gdf["geometry"].apply(shape_3d_to_2d)
gdf["geometry"] = gdf.buffer(0) # Fixes some invalid geometries
return gdf
def is_valid_polygon(geometry_gdf):
geometry = geometry_gdf.geometry.item()
return (geometry.type == "Polygon") and (not geometry.is_empty)
# wide streamlit display
st.set_page_config(layout="wide")
# Function
# Logo
cols = st.columns([1, 11, 1])
with cols[0]:
st.image("Final_IITGN-Logo-symmetric-Color.png")
with cols[-1]:
st.image("IFS.jpg")
# Title
# make title in center
with cols[1]:
st.markdown(
f"""
KML Viewer
""",
unsafe_allow_html=True,
)
file_url = st.query_params.get("file_url", None)
if not file_url:
st.warning(
"Please provide a KML or GeoJSON URL as a query parameter, e.g., `?file_url=` or upload a file."
)
file_url = st.file_uploader("Upload KML/GeoJSON file", type=["geojson", "kml", "shp"])
if not file_url:
st.stop()
if ("file_url" in st.session_state) and ("input_gdf" in st.session_state) and (st.session_state.file_url == file_url):
# st.toast("Using cached data")
input_gdf = st.session_state.input_gdf
else:
st.session_state.file_url = file_url
print(file_url, type(file_url))
if isinstance(file_url, str):
if file_url.startswith("https://drive.google.com/file/d/"):
ID = file_url.replace("https://drive.google.com/file/d/", "").split("/")[0]
file_url = f"https://drive.google.com/uc?id={ID}"
elif file_url.startswith("https://drive.google.com/open?id="):
ID = file_url.replace("https://drive.google.com/open?id=", "")
file_url = f"https://drive.google.com/uc?id={ID}"
response = requests.get(file_url)
bytes_data = BytesIO(response.content)
string_data = response.text
else:
bytes_data = BytesIO(file_url.getvalue())
string_data = file_url.getvalue().decode("utf-8")
if string_data.startswith(" 1:
st.warning(f"Only the first polygon in the KML will be processed; all other geometries will be ignored.")
for i in range(len(input_gdf)):
geometry_gdf = input_gdf[input_gdf.index == i]
if is_valid_polygon(geometry_gdf):
break
else:
st.error(f"No polygon found inside KML. Please check the KML file.")
st.stop()
st.session_state.input_gdf = input_gdf
# st.toast("Data loaded and cached")
def format_fn(x):
return input_gdf.drop(columns=["geometry"]).loc[x].to_dict()
with st.expander("Advanced Controls", expanded=False):
# input_geometry_idx = st.selectbox("Select the geometry", input_gdf.index, format_func=format_fn)
map_type = st.radio(
"",
["Esri Satellite Map", "Google Hybrid Map (displays place names)", "Google Satellite Map"],
horizontal=True,
)
height = st.number_input("Map height (px)", 1, 10000, 600, 1)
geometry_gdf = input_gdf[input_gdf.index == 0]
def check_valid_geometry(geometry_gdf):
geometry = geometry_gdf.geometry.item()
if geometry.type != "Polygon":
st.error(f"Selected geometry is of type '{geometry.type}'. Please provide a 'Polygon' geometry.")
st.stop()
check_valid_geometry(geometry_gdf)
m = leafmap.Map()
st.markdown(
"""
""",
unsafe_allow_html=True,
)
if map_type == "Google Hybrid Map (displays place names)":
st.write(
"