Spaces:
Sleeping
Sleeping
# import streamlit as st | |
# import geopandas as gpd | |
# from shapely.geometry import Point | |
# import folium | |
# from streamlit_folium import st_folium | |
# from geopy.geocoders import Nominatim | |
# import tempfile | |
# import os | |
# import zipfile | |
# # Configure page | |
# st.set_page_config(page_title="City Shapefile Generator", layout="wide") | |
# st.title("π City Location Exporter") | |
# # Initialize geocoder | |
# geolocator = Nominatim(user_agent="city_shape_app") | |
# def get_city_location(city_name): | |
# """Get coordinates for a city name""" | |
# location = geolocator.geocode(city_name) | |
# if location: | |
# return location.latitude, location.longitude | |
# return None | |
# def create_geodataframe(lat, lon, city_name): | |
# """Create a GeoDataFrame from coordinates""" | |
# geometry = Point(lon, lat) | |
# return gpd.GeoDataFrame( | |
# [[city_name, lat, lon, geometry]], | |
# columns=["city", "latitude", "longitude", "geometry"], | |
# crs="EPSG:4326" | |
# ) | |
# def create_map(lat, lon, city_name): | |
# """Create Folium map with marker""" | |
# m = folium.Map(location=[lat, lon], zoom_start=12) | |
# folium.Marker( | |
# [lat, lon], | |
# popup=city_name, | |
# tooltip=city_name, | |
# icon=folium.Icon(color="red", icon="info-sign") | |
# ).add_to(m) | |
# folium.CircleMarker( | |
# [lat, lon], | |
# radius=100, | |
# color='blue', | |
# fill=True, | |
# fill_color='blue' | |
# ).add_to(m) | |
# return m | |
# def save_to_format(gdf, format_type, temp_dir, city_name): | |
# """Save to specific format and return file path""" | |
# base_path = os.path.join(temp_dir, f"{city_name}_location") | |
# if format_type == "SHP": | |
# full_path = f"{base_path}.shp" | |
# gdf.to_file(full_path) | |
# return [f"{base_path}.{ext}" for ext in ["shp", "shx", "dbf", "prj", "cpg"]] | |
# elif format_type == "GeoJSON": | |
# full_path = f"{base_path}.geojson" | |
# gdf.to_file(full_path, driver='GeoJSON') | |
# return [full_path] | |
# elif format_type == "KML": | |
# full_path = f"{base_path}.kml" | |
# gdf.to_file(full_path, driver='KML') | |
# return [full_path] | |
# def create_download_button(file_paths, format_type, city_name): | |
# """Create a download button for the files""" | |
# if format_type == "SHP": | |
# zip_path = f"{city_name}_shapefile.zip" | |
# with zipfile.ZipFile(zip_path, 'w') as zipf: | |
# for file in file_paths: | |
# if os.path.exists(file): | |
# zipf.write(file, os.path.basename(file)) | |
# with open(zip_path, 'rb') as f: | |
# return st.download_button( | |
# label=f"Download {format_type}", | |
# data=f, | |
# file_name=zip_path, | |
# mime="application/zip", | |
# key=f"{city_name}_shp" # Unique key for each button | |
# ) | |
# else: | |
# with open(file_paths[0], 'rb') as f: | |
# return st.download_button( | |
# label=f"Download {format_type}", | |
# data=f, | |
# file_name=os.path.basename(file_paths[0]), | |
# mime="application/octet-stream", | |
# key=f"{city_name}_{format_type.lower()}" | |
# ) | |
# # Main app | |
# city_name = st.text_input("Enter city name:", "Paris") | |
# if 'coords' not in st.session_state: | |
# st.session_state.coords = None | |
# if 'city_found' not in st.session_state: | |
# st.session_state.city_found = None | |
# if st.button("Locate City"): | |
# with st.spinner("Searching location..."): | |
# coords = get_city_location(city_name) | |
# st.session_state.coords = coords | |
# st.session_state.city_found = city_name | |
# if st.session_state.coords: | |
# lat, lon = st.session_state.coords | |
# st.success(f"Found {st.session_state.city_found} at coordinates: {lat:.4f}, {lon:.4f}") | |
# # Display persistent map | |
# m = create_map(lat, lon, st.session_state.city_found) | |
# st_folium(m, width=800, height=500) | |
# # Create GeoDataFrame | |
# gdf = create_geodataframe(lat, lon, st.session_state.city_found) | |
# # Persistent download buttons | |
# st.header("Download Options") | |
# col1, col2, col3 = st.columns(3) | |
# with tempfile.TemporaryDirectory() as temp_dir: | |
# # Shapefile | |
# with col1: | |
# shp_files = save_to_format(gdf, "SHP", temp_dir, st.session_state.city_found) | |
# create_download_button(shp_files, "SHP", st.session_state.city_found) | |
# # GeoJSON | |
# with col2: | |
# geojson_file = save_to_format(gdf, "GeoJSON", temp_dir, st.session_state.city_found) | |
# create_download_button(geojson_file, "GeoJSON", st.session_state.city_found) | |
# # KML | |
# with col3: | |
# kml_file = save_to_format(gdf, "KML", temp_dir, st.session_state.city_found) | |
# create_download_button(kml_file, "KML", st.session_state.city_found) | |
# elif st.session_state.city_found and not st.session_state.coords: | |
# st.error("City not found. Please try a different name.") | |
import streamlit as st | |
import geopandas as gpd | |
import folium | |
from streamlit_folium import st_folium | |
import tempfile | |
import os | |
import zipfile | |
import osmnx as ox | |
from shapely.geometry import Polygon | |
# Configure page | |
st.set_page_config(page_title="City Boundary Exporter", layout="wide") | |
st.title("π City Boundary Exporter") | |
def get_city_boundary(city_name): | |
"""Get city boundary polygon from OpenStreetMap""" | |
try: | |
# Get the boundary geometry | |
gdf = ox.geocode_to_gdf(city_name) | |
# Simplify geometry if too complex | |
if gdf.shape[0] > 0: | |
gdf['geometry'] = gdf['geometry'].simplify(0.001) | |
return gdf | |
return None | |
except Exception as e: | |
st.error(f"Error fetching boundary: {str(e)}") | |
return None | |
def create_map(gdf): | |
"""Create Folium map with the boundary""" | |
centroid = gdf.geometry.centroid.iloc[0] | |
m = folium.Map(location=[centroid.y, centroid.x], zoom_start=11) | |
folium.GeoJson( | |
gdf.__geo_interface__, | |
style_function=lambda x: { | |
'fillColor': '#1f77b4', | |
'color': '#1f77b4', | |
'weight': 2, | |
'fillOpacity': 0.4 | |
} | |
).add_to(m) | |
# Add centroid marker | |
folium.Marker( | |
[centroid.y, centroid.x], | |
popup="Centroid", | |
icon=folium.Icon(color="red") | |
).add_to(m) | |
return m | |
def save_to_format(gdf, format_type, temp_dir, city_name): | |
"""Save to specific format and return file path""" | |
base_path = os.path.join(temp_dir, f"{city_name}_boundary") | |
if format_type == "SHP": | |
full_path = f"{base_path}.shp" | |
gdf.to_file(full_path) | |
return [f"{base_path}.{ext}" for ext in ["shp", "shx", "dbf", "prj", "cpg"]] | |
elif format_type == "GeoJSON": | |
full_path = f"{base_path}.geojson" | |
gdf.to_file(full_path, driver='GeoJSON') | |
return [full_path] | |
elif format_type == "KML": | |
full_path = f"{base_path}.kml" | |
gdf.to_file(full_path, driver='KML') | |
return [full_path] | |
def create_download_button(file_paths, format_type, city_name): | |
"""Create a download button for the files""" | |
if format_type == "SHP": | |
zip_path = f"{city_name}_boundary.zip" | |
with zipfile.ZipFile(zip_path, 'w') as zipf: | |
for file in file_paths: | |
if os.path.exists(file): | |
zipf.write(file, os.path.basename(file)) | |
with open(zip_path, 'rb') as f: | |
st.download_button( | |
label=f"Download {format_type}", | |
data=f, | |
file_name=zip_path, | |
mime="application/zip", | |
key=f"{city_name}_shp" | |
) | |
else: | |
with open(file_paths[0], 'rb') as f: | |
st.download_button( | |
label=f"Download {format_type}", | |
data=f, | |
file_name=os.path.basename(file_paths[0]), | |
mime="application/octet-stream", | |
key=f"{city_name}_{format_type.lower()}" | |
) | |
# Main app | |
city_name = st.text_input("Enter city name (include country if needed):", "Berlin, Germany") | |
if st.button("Get City Boundary"): | |
with st.spinner("Fetching boundary from OpenStreetMap..."): | |
boundary_gdf = get_city_boundary(city_name) | |
if boundary_gdf is not None: | |
st.session_state.boundary_gdf = boundary_gdf | |
st.session_state.city_found = city_name | |
if 'boundary_gdf' in st.session_state: | |
st.success(f"Found boundary for {st.session_state.city_found}") | |
# Display map | |
m = create_map(st.session_state.boundary_gdf) | |
st_folium(m, width=800, height=500) | |
# Download options | |
st.header("Download Options") | |
col1, col2, col3 = st.columns(3) | |
with tempfile.TemporaryDirectory() as temp_dir: | |
# Shapefile | |
with col1: | |
shp_files = save_to_format(st.session_state.boundary_gdf, "SHP", temp_dir, st.session_state.city_found) | |
create_download_button(shp_files, "SHP", st.session_state.city_found) | |
# GeoJSON | |
with col2: | |
geojson_file = save_to_format(st.session_state.boundary_gdf, "GeoJSON", temp_dir, st.session_state.city_found) | |
create_download_button(geojson_file, "GeoJSON", st.session_state.city_found) | |
# KML | |
with col3: | |
kml_file = save_to_format(st.session_state.boundary_gdf, "KML", temp_dir, st.session_state.city_found) | |
create_download_button(kml_file, "KML", st.session_state.city_found) |