Spaces:
Sleeping
Sleeping
File size: 6,860 Bytes
bcd426b b4a6f1f bcd426b 9bf403c 18840e8 b4a6f1f 4862d3a 4c45263 bcd426b 4862d3a bcd426b 4c45263 b4a6f1f bcd426b b4a6f1f 4c45263 bcd426b b4a6f1f 1511ce3 b4a6f1f 4c45263 bcd426b b4a6f1f 4862d3a bcd426b b4a6f1f bcd426b 8a43c34 b4a6f1f bcd426b b4a6f1f 8a43c34 b4a6f1f 4862d3a b4a6f1f bcd426b b4a6f1f 4862d3a b4a6f1f 4862d3a 4c45263 b4a6f1f 4c45263 4862d3a b4a6f1f b526476 b4a6f1f b526476 b4a6f1f b526476 b4a6f1f 9aad01f b4a6f1f 9aad01f b4a6f1f 4862d3a b4a6f1f 4862d3a 46c4e1f b4a6f1f 46c4e1f b4a6f1f 4c45263 4862d3a b4a6f1f 4862d3a b4a6f1f 4862d3a b4a6f1f bcd426b b4a6f1f bcd426b b4a6f1f bcd426b b4a6f1f bcd426b b4a6f1f |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
import geopandas as gpd
import pandas as pd
from shapely.geometry import shape, Polygon, LineString, Point
from shapely.ops import unary_union
import xml.etree.ElementTree as ET
import zipfile
import os
import matplotlib.pyplot as plt
import streamlit as st
from transformers import pipeline
# For KML access, extracting 3D coordinates (Polygon Z)
def p(kml_file):
cont = kml_file.decode('utf-8') # Decode bytes to string
k = ET.ElementTree(ET.fromstring(cont))
root = k.getroot()
ns = {'kml': 'http://www.opengis.net/kml/2.2'}
shapes = []
for mark in root.findall('.//kml:Placemark', ns):
polygon = mark.find('.//kml:Polygon/kml:coordinates', ns)
if polygon is not None:
coordinates = polygon.text.strip().split()
coords = [(float(lon), float(lat), float(z) if z else 0) for lon, lat, z in [coord.split(',') for coord in coordinates]]
shapes.append(Polygon([coords])) # Make it a Polygon with Z
line = mark.find('.//kml:LineString/kml:coordinates', ns)
if line is not None:
coordinates = line.text.strip().split()
coords = [(float(lon), float(lat), float(z) if z else 0) for lon, lat, z in [coord.split(',') for coord in coordinates]]
shapes.append(LineString(coords))
point = mark.find('.//kml:Point/kml:coordinates', ns)
if point is not None:
lon, lat, z = point.text.strip().split(',')
shapes.append(Point(float(lon), float(lat), float(z) if z else 0))
return shapes if shapes else None
# For file extraction if it is in KMZ form
def ext(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]
with open(os.path.join('temp_kml', kml_file), 'rb') as f:
return p(f.read())
# See if it is a kml or kmz file
def choose(upf):
file_bytes = upf.read()
if upf.name.endswith('.kmz'):
return ext(file_bytes)
else:
return p(file_bytes)
# For file uploading
st.title("Flood Zone Analysis")
upf = st.file_uploader("Upload KML/KMZ file", type=['kml', 'kmz'])
# Convert 2D to 3D if needed (add default Z = 0)
def convert_to_3d(geom):
"""Convert 2D geometries to 3D by adding a Z value (default = 0)"""
if geom.geom_type == 'Polygon':
coords = [(x, y, 0) for x, y in geom.exterior.coords]
return Polygon(coords)
elif geom.geom_type == 'LineString':
coords = [(x, y, 0) for x, y in geom.coords]
return LineString(coords)
elif geom.geom_type == 'Point':
return Point(geom.x, geom.y, 0)
return geom # Return unchanged if not 2D
# For comparing the boundary between KML and shapefile
def bound(f, gdf):
if f.empty: # Handle invalid KML shapes
return "Invalid KML shape or no valid polygon found.", None
overlaps = [] # Save matching boundaries
for kml_shape in f:
intersection = gdf[gdf.intersects(kml_shape)]
if not intersection.empty:
overlaps.append(intersection)
if not overlaps:
return "Boundary doesn't match", None
every_int = unary_union([geom for intersect in overlaps for geom in intersect.geometry])
return overlaps, every_int
# Find common bound's Acreage and Usable Land
def land(overlaps, every_int):
all = pd.concat(overlaps)
all['area'] = all.geometry.area
all['area_acres'] = all['area'] / 4046.86 # Convert to acres
fza = {zone: all[all['FLD_ZONE'] == zone]['area_acres'].sum() for zone in all['FLD_ZONE'].unique()}
areas = ['A', 'AE', 'AH', 'AO', 'VE']
non = all[~all['FLD_ZONE'].isin(areas)]['area_acres'].sum()
merged_area = every_int.area / 4046.86
return fza, non, merged_area
# Initial summary was with GPT-2
def summ(fza, non, total_acreage):
summarizer = pipeline("summarization", model="gpt2")
areas = ['A', 'AE', 'AH', 'AO', 'VE']
flood_zone_summary = "\n".join([f" Zone {zone}: {fza.get(zone, 0):.2f} acres" for zone in areas])
prompt = f"""
**Total Land Area**: {total_acreage:.2f} acres
**Usable Area**: {non:.2f} acres
**Flood-prone Zones**:
{flood_zone_summary}
Summarize the above given data in 2-3 sentences.
"""
response = summarizer(prompt, max_length=200, min_length=30, do_sample=False)
return response[0]['summary_text']
if upf is not None:
# Read shapefiles and convert them to 3D if needed
kent = gpd.read_file("K_FLD_HAZ_AR.shp")
nc = gpd.read_file("N_FLD_HAZ_AR.shp")
sussex = gpd.read_file("S_FLD_HAZ_AR.shp")
# Combine them
dela = gpd.GeoDataFrame(pd.concat([kent, nc, sussex], ignore_index=True))
# Add Coordinate Reference System
dela = dela.set_crs(kent.crs, allow_override=True)
# Convert to 3D (add Z = 0 if missing)
dela['geometry'] = dela['geometry'].apply(convert_to_3d)
dela = dela.to_crs(epsg=3857)
# Fix invalid geometries
dela['geometry'] = dela['geometry'].apply(lambda x: x.buffer(0) if not x.is_valid else x)
# Upload KML/KMZ file
f = choose(upf)
if f:
# Check if KML has valid geometries
kml_gdf = gpd.GeoDataFrame(geometry=f, crs="EPSG:4326")
kml_gdf = kml_gdf.to_crs(epsg=3857)
# Convert KML to 3D (add Z = 0 if missing)
kml_gdf['geometry'] = kml_gdf['geometry'].apply(convert_to_3d)
# Compare KML and Shapefile
intersection, every_int = bound(kml_gdf.geometry, dela)
if isinstance(intersection, str):
st.write(intersection)
else:
flood_zone_areas, non, merged_area = land(intersection, every_int)
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:.2f} acres")
st.write(f"\nMerged Area of Intersected Boundary: {merged_area:.2f} acres")
summary = summ(flood_zone_areas, non, merged_area)
st.write(f"GPT-2 Summary: {summary}")
# Show map
fig, ax = plt.subplots(figsize=(10, 10))
# shapefile
dela.plot(ax=ax, color='blue', alpha=0.5)
# Show overlap with KML
if intersection:
intersection_geom = unary_union([geom for intersect in intersection for geom in intersect.geometry])
gpd.GeoDataFrame(geometry=[intersection_geom], crs=dela.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.")
|