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) |