KML_new / app.py
khushidhar1210's picture
Update app.py
239cd60 verified
raw
history blame
5.16 kB
import geopandas as gpd
import pandas as pd
from shapely.geometry import shape
from shapely.ops import unary_union
import xml.etree.ElementTree as ET
import zipfile
import os
from transformers import AutoTokenizer, AutoModelForCausalLM
import torch
import matplotlib.pyplot as plt
import streamlit as st
# Function to parse KML
def parse_kml(kml_file):
with open(kml_file, 'rt') as f:
doc = f.read()
k = ET.ElementTree(ET.fromstring(doc))
root = k.getroot()
ns = {'kml': 'http://www.opengis.net/kml/2.2'}
shapes = []
for placemark in root.findall('.//kml:Placemark', ns):
polygon = placemark.find('.//kml:Polygon/kml:coordinates', ns)
if polygon is not None:
coordinates = polygon.text.strip().split()
coords = [(float(lon), float(lat)) for lon, lat, _ in [coord.split(',') for coord in coordinates]]
shapes.append(shape({'type': 'Polygon', 'coordinates': [coords]}))
line = placemark.find('.//kml:LineString/kml:coordinates', ns)
if line is not None:
coordinates = line.text.strip().split()
coords = [(float(lon), float(lat)) for lon, lat in [coord.split(',') for coord in coordinates]]
shapes.append(shape({'type': 'LineString', 'coordinates': coords}))
point = placemark.find('.//kml:Point/kml:coordinates', ns)
if point is not None:
lon, lat, _ = point.text.strip().split(',')
shapes.append(shape({'type': 'Point', 'coordinates': (float(lon), float(lat))}))
return shapes if shapes else None
def extract_kmz(kmz_file):
with zipfile.ZipFile(kmz_file, 'r') as zip_ref:
zip_ref.extractall('temp_kml')
kml_file = [f for f in os.listdir('temp_kml') if f.endswith('.kml')][0]
return parse_kml(os.path.join('temp_kml', kml_file))
# Function to handle KML/KMZ file input
def handle_kml_upload(uploaded_file):
if uploaded_file.name.endswith('.kmz'):
kml_shapes = extract_kmz(uploaded_file)
else:
kml_shapes = parse_kml(uploaded_file)
return kml_shapes
# Streamlit file uploader widget
st.title("Flood Zone Analysis")
uploaded_file = st.file_uploader("Upload KML/KMZ file", type=['kml', 'kmz'])
if uploaded_file is not None:
# Step 1: Read in the shapefiles
shapefile_1 = gpd.read_file("K_FLD_HAZ_AR.shp")
shapefile_2 = gpd.read_file("N_FLD_HAZ_AR.shp")
shapefile_3 = gpd.read_file("S_FLD_HAZ_AR.shp")
# Step 2: Concatenate them into a single GeoDataFrame
merged_gdf = gpd.GeoDataFrame(pd.concat([shapefile_1, shapefile_2, shapefile_3], ignore_index=True))
# Step 3: Ensure CRS consistency
merged_gdf = merged_gdf.set_crs(shapefile_1.crs, allow_override=True)
# Step 4: Reproject GeoDataFrame to a common projected CRS (EPSG:3857)
merged_gdf = merged_gdf.to_crs(epsg=3857)
# Step 5: Validate and fix invalid geometries
merged_gdf['geometry'] = merged_gdf['geometry'].apply(lambda x: x.buffer(0) if not x.is_valid else x)
# Step 6: Process uploaded KML/KMZ file
kml_shapes = handle_kml_upload(uploaded_file)
if kml_shapes:
# Ensure that the KML shapes are valid geometries
kml_gdf = gpd.GeoDataFrame(geometry=kml_shapes, crs="EPSG:4326")
# Convert to projected CRS (EPSG:3857) for consistency with shapefile
kml_gdf = kml_gdf.to_crs(epsg=3857)
# Compare KML and Shapefile
intersection, merged_geometry = compare_kml_with_shapefile(kml_gdf.geometry, merged_gdf)
if isinstance(intersection, str):
st.write(intersection)
else:
flood_zone_areas, non_flooded_area, merged_area = calculate_acreage_and_usable_land(intersection, merged_geometry)
st.write(f"Flood Zone Areas:")
for zone, area in flood_zone_areas.items():
st.write(f" Zone {zone}: {area:.2f} acres")
st.write(f"\nNon-Flooded Land Area: {non_flooded_area:.2f} acres")
st.write(f"\nMerged Area of Intersected Boundary: {merged_area:.2f} acres")
summary = summarize_flood_data_llama(flood_zone_areas, non_flooded_area, merged_area)
st.write(f"LLM Summary: {summary}")
# Step 10: Visualize the intersection of KML shapes and merged shapefile
fig, ax = plt.subplots(figsize=(10, 10))
# Plot the merged shapefile (blue color)
merged_gdf.plot(ax=ax, color='blue', alpha=0.5)
# Highlight the intersection area (overlap with KML)
if intersection:
# Combine the intersection geometries into a single geometry for display
intersection_geom = unary_union([geom for intersect in intersection for geom in intersect.geometry])
gpd.GeoDataFrame(geometry=[intersection_geom], crs=merged_gdf.crs).plot(ax=ax, color='red', alpha=0.7)
# Plot the KML boundary (green color)
kml_gdf.plot(ax=ax, color='green', alpha=0.3)
# Display the plot
st.pyplot(fig)
else:
st.write("No valid geometries found in the uploaded KML file.")
else:
st.write("Please upload a KML/KMZ file to continue.")