YashMK89 commited on
Commit
840b26e
·
verified ·
1 Parent(s): 324a2f6

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +209 -72
app.py CHANGED
@@ -1,57 +1,204 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import streamlit as st
2
  import geopandas as gpd
3
- from shapely.geometry import Point
4
  import folium
5
  from streamlit_folium import st_folium
6
- from geopy.geocoders import Nominatim
7
  import tempfile
8
  import os
9
  import zipfile
 
 
10
 
11
  # Configure page
12
- st.set_page_config(page_title="City Shapefile Generator", layout="wide")
13
- st.title("🌍 City Location Exporter")
14
-
15
- # Initialize geocoder
16
- geolocator = Nominatim(user_agent="city_shape_app")
17
-
18
- def get_city_location(city_name):
19
- """Get coordinates for a city name"""
20
- location = geolocator.geocode(city_name)
21
- if location:
22
- return location.latitude, location.longitude
23
- return None
24
-
25
- def create_geodataframe(lat, lon, city_name):
26
- """Create a GeoDataFrame from coordinates"""
27
- geometry = Point(lon, lat)
28
- return gpd.GeoDataFrame(
29
- [[city_name, lat, lon, geometry]],
30
- columns=["city", "latitude", "longitude", "geometry"],
31
- crs="EPSG:4326"
32
- )
33
-
34
- def create_map(lat, lon, city_name):
35
- """Create Folium map with marker"""
36
- m = folium.Map(location=[lat, lon], zoom_start=12)
37
- folium.Marker(
38
- [lat, lon],
39
- popup=city_name,
40
- tooltip=city_name,
41
- icon=folium.Icon(color="red", icon="info-sign")
 
42
  ).add_to(m)
43
- folium.CircleMarker(
44
- [lat, lon],
45
- radius=100,
46
- color='blue',
47
- fill=True,
48
- fill_color='blue'
49
  ).add_to(m)
 
50
  return m
51
 
52
  def save_to_format(gdf, format_type, temp_dir, city_name):
53
  """Save to specific format and return file path"""
54
- base_path = os.path.join(temp_dir, f"{city_name}_location")
55
 
56
  if format_type == "SHP":
57
  full_path = f"{base_path}.shp"
@@ -69,23 +216,23 @@ def save_to_format(gdf, format_type, temp_dir, city_name):
69
  def create_download_button(file_paths, format_type, city_name):
70
  """Create a download button for the files"""
71
  if format_type == "SHP":
72
- zip_path = f"{city_name}_shapefile.zip"
73
  with zipfile.ZipFile(zip_path, 'w') as zipf:
74
  for file in file_paths:
75
  if os.path.exists(file):
76
  zipf.write(file, os.path.basename(file))
77
 
78
  with open(zip_path, 'rb') as f:
79
- return st.download_button(
80
  label=f"Download {format_type}",
81
  data=f,
82
  file_name=zip_path,
83
  mime="application/zip",
84
- key=f"{city_name}_shp" # Unique key for each button
85
  )
86
  else:
87
  with open(file_paths[0], 'rb') as f:
88
- return st.download_button(
89
  label=f"Download {format_type}",
90
  data=f,
91
  file_name=os.path.basename(file_paths[0]),
@@ -94,49 +241,39 @@ def create_download_button(file_paths, format_type, city_name):
94
  )
95
 
96
  # Main app
97
- city_name = st.text_input("Enter city name:", "Paris")
98
-
99
- if 'coords' not in st.session_state:
100
- st.session_state.coords = None
101
- if 'city_found' not in st.session_state:
102
- st.session_state.city_found = None
103
-
104
- if st.button("Locate City"):
105
- with st.spinner("Searching location..."):
106
- coords = get_city_location(city_name)
107
- st.session_state.coords = coords
108
- st.session_state.city_found = city_name
109
-
110
- if st.session_state.coords:
111
- lat, lon = st.session_state.coords
112
- st.success(f"Found {st.session_state.city_found} at coordinates: {lat:.4f}, {lon:.4f}")
113
 
114
- # Display persistent map
115
- m = create_map(lat, lon, st.session_state.city_found)
116
  st_folium(m, width=800, height=500)
117
 
118
- # Create GeoDataFrame
119
- gdf = create_geodataframe(lat, lon, st.session_state.city_found)
120
-
121
- # Persistent download buttons
122
  st.header("Download Options")
123
  col1, col2, col3 = st.columns(3)
124
 
125
  with tempfile.TemporaryDirectory() as temp_dir:
126
  # Shapefile
127
  with col1:
128
- shp_files = save_to_format(gdf, "SHP", temp_dir, st.session_state.city_found)
129
  create_download_button(shp_files, "SHP", st.session_state.city_found)
130
 
131
  # GeoJSON
132
  with col2:
133
- geojson_file = save_to_format(gdf, "GeoJSON", temp_dir, st.session_state.city_found)
134
  create_download_button(geojson_file, "GeoJSON", st.session_state.city_found)
135
 
136
  # KML
137
  with col3:
138
- kml_file = save_to_format(gdf, "KML", temp_dir, st.session_state.city_found)
139
- create_download_button(kml_file, "KML", st.session_state.city_found)
140
-
141
- elif st.session_state.city_found and not st.session_state.coords:
142
- st.error("City not found. Please try a different name.")
 
1
+ # import streamlit as st
2
+ # import geopandas as gpd
3
+ # from shapely.geometry import Point
4
+ # import folium
5
+ # from streamlit_folium import st_folium
6
+ # from geopy.geocoders import Nominatim
7
+ # import tempfile
8
+ # import os
9
+ # import zipfile
10
+
11
+ # # Configure page
12
+ # st.set_page_config(page_title="City Shapefile Generator", layout="wide")
13
+ # st.title("🌍 City Location Exporter")
14
+
15
+ # # Initialize geocoder
16
+ # geolocator = Nominatim(user_agent="city_shape_app")
17
+
18
+ # def get_city_location(city_name):
19
+ # """Get coordinates for a city name"""
20
+ # location = geolocator.geocode(city_name)
21
+ # if location:
22
+ # return location.latitude, location.longitude
23
+ # return None
24
+
25
+ # def create_geodataframe(lat, lon, city_name):
26
+ # """Create a GeoDataFrame from coordinates"""
27
+ # geometry = Point(lon, lat)
28
+ # return gpd.GeoDataFrame(
29
+ # [[city_name, lat, lon, geometry]],
30
+ # columns=["city", "latitude", "longitude", "geometry"],
31
+ # crs="EPSG:4326"
32
+ # )
33
+
34
+ # def create_map(lat, lon, city_name):
35
+ # """Create Folium map with marker"""
36
+ # m = folium.Map(location=[lat, lon], zoom_start=12)
37
+ # folium.Marker(
38
+ # [lat, lon],
39
+ # popup=city_name,
40
+ # tooltip=city_name,
41
+ # icon=folium.Icon(color="red", icon="info-sign")
42
+ # ).add_to(m)
43
+ # folium.CircleMarker(
44
+ # [lat, lon],
45
+ # radius=100,
46
+ # color='blue',
47
+ # fill=True,
48
+ # fill_color='blue'
49
+ # ).add_to(m)
50
+ # return m
51
+
52
+ # def save_to_format(gdf, format_type, temp_dir, city_name):
53
+ # """Save to specific format and return file path"""
54
+ # base_path = os.path.join(temp_dir, f"{city_name}_location")
55
+
56
+ # if format_type == "SHP":
57
+ # full_path = f"{base_path}.shp"
58
+ # gdf.to_file(full_path)
59
+ # return [f"{base_path}.{ext}" for ext in ["shp", "shx", "dbf", "prj", "cpg"]]
60
+ # elif format_type == "GeoJSON":
61
+ # full_path = f"{base_path}.geojson"
62
+ # gdf.to_file(full_path, driver='GeoJSON')
63
+ # return [full_path]
64
+ # elif format_type == "KML":
65
+ # full_path = f"{base_path}.kml"
66
+ # gdf.to_file(full_path, driver='KML')
67
+ # return [full_path]
68
+
69
+ # def create_download_button(file_paths, format_type, city_name):
70
+ # """Create a download button for the files"""
71
+ # if format_type == "SHP":
72
+ # zip_path = f"{city_name}_shapefile.zip"
73
+ # with zipfile.ZipFile(zip_path, 'w') as zipf:
74
+ # for file in file_paths:
75
+ # if os.path.exists(file):
76
+ # zipf.write(file, os.path.basename(file))
77
+
78
+ # with open(zip_path, 'rb') as f:
79
+ # return st.download_button(
80
+ # label=f"Download {format_type}",
81
+ # data=f,
82
+ # file_name=zip_path,
83
+ # mime="application/zip",
84
+ # key=f"{city_name}_shp" # Unique key for each button
85
+ # )
86
+ # else:
87
+ # with open(file_paths[0], 'rb') as f:
88
+ # return st.download_button(
89
+ # label=f"Download {format_type}",
90
+ # data=f,
91
+ # file_name=os.path.basename(file_paths[0]),
92
+ # mime="application/octet-stream",
93
+ # key=f"{city_name}_{format_type.lower()}"
94
+ # )
95
+
96
+ # # Main app
97
+ # city_name = st.text_input("Enter city name:", "Paris")
98
+
99
+ # if 'coords' not in st.session_state:
100
+ # st.session_state.coords = None
101
+ # if 'city_found' not in st.session_state:
102
+ # st.session_state.city_found = None
103
+
104
+ # if st.button("Locate City"):
105
+ # with st.spinner("Searching location..."):
106
+ # coords = get_city_location(city_name)
107
+ # st.session_state.coords = coords
108
+ # st.session_state.city_found = city_name
109
+
110
+ # if st.session_state.coords:
111
+ # lat, lon = st.session_state.coords
112
+ # st.success(f"Found {st.session_state.city_found} at coordinates: {lat:.4f}, {lon:.4f}")
113
+
114
+ # # Display persistent map
115
+ # m = create_map(lat, lon, st.session_state.city_found)
116
+ # st_folium(m, width=800, height=500)
117
+
118
+ # # Create GeoDataFrame
119
+ # gdf = create_geodataframe(lat, lon, st.session_state.city_found)
120
+
121
+ # # Persistent download buttons
122
+ # st.header("Download Options")
123
+ # col1, col2, col3 = st.columns(3)
124
+
125
+ # with tempfile.TemporaryDirectory() as temp_dir:
126
+ # # Shapefile
127
+ # with col1:
128
+ # shp_files = save_to_format(gdf, "SHP", temp_dir, st.session_state.city_found)
129
+ # create_download_button(shp_files, "SHP", st.session_state.city_found)
130
+
131
+ # # GeoJSON
132
+ # with col2:
133
+ # geojson_file = save_to_format(gdf, "GeoJSON", temp_dir, st.session_state.city_found)
134
+ # create_download_button(geojson_file, "GeoJSON", st.session_state.city_found)
135
+
136
+ # # KML
137
+ # with col3:
138
+ # kml_file = save_to_format(gdf, "KML", temp_dir, st.session_state.city_found)
139
+ # create_download_button(kml_file, "KML", st.session_state.city_found)
140
+
141
+ # elif st.session_state.city_found and not st.session_state.coords:
142
+ # st.error("City not found. Please try a different name.")
143
+
144
+
145
+
146
  import streamlit as st
147
  import geopandas as gpd
 
148
  import folium
149
  from streamlit_folium import st_folium
 
150
  import tempfile
151
  import os
152
  import zipfile
153
+ import osmnx as ox
154
+ from shapely.geometry import Polygon
155
 
156
  # Configure page
157
+ st.set_page_config(page_title="City Boundary Exporter", layout="wide")
158
+ st.title("🌆 City Boundary Exporter")
159
+
160
+ def get_city_boundary(city_name):
161
+ """Get city boundary polygon from OpenStreetMap"""
162
+ try:
163
+ # Get the boundary geometry
164
+ gdf = ox.geocode_to_gdf(city_name)
165
+
166
+ # Simplify geometry if too complex
167
+ if gdf.shape[0] > 0:
168
+ gdf['geometry'] = gdf['geometry'].simplify(0.001)
169
+ return gdf
170
+ return None
171
+ except Exception as e:
172
+ st.error(f"Error fetching boundary: {str(e)}")
173
+ return None
174
+
175
+ def create_map(gdf):
176
+ """Create Folium map with the boundary"""
177
+ centroid = gdf.geometry.centroid.iloc[0]
178
+ m = folium.Map(location=[centroid.y, centroid.x], zoom_start=11)
179
+
180
+ folium.GeoJson(
181
+ gdf.__geo_interface__,
182
+ style_function=lambda x: {
183
+ 'fillColor': '#1f77b4',
184
+ 'color': '#1f77b4',
185
+ 'weight': 2,
186
+ 'fillOpacity': 0.4
187
+ }
188
  ).add_to(m)
189
+
190
+ # Add centroid marker
191
+ folium.Marker(
192
+ [centroid.y, centroid.x],
193
+ popup="Centroid",
194
+ icon=folium.Icon(color="red")
195
  ).add_to(m)
196
+
197
  return m
198
 
199
  def save_to_format(gdf, format_type, temp_dir, city_name):
200
  """Save to specific format and return file path"""
201
+ base_path = os.path.join(temp_dir, f"{city_name}_boundary")
202
 
203
  if format_type == "SHP":
204
  full_path = f"{base_path}.shp"
 
216
  def create_download_button(file_paths, format_type, city_name):
217
  """Create a download button for the files"""
218
  if format_type == "SHP":
219
+ zip_path = f"{city_name}_boundary.zip"
220
  with zipfile.ZipFile(zip_path, 'w') as zipf:
221
  for file in file_paths:
222
  if os.path.exists(file):
223
  zipf.write(file, os.path.basename(file))
224
 
225
  with open(zip_path, 'rb') as f:
226
+ st.download_button(
227
  label=f"Download {format_type}",
228
  data=f,
229
  file_name=zip_path,
230
  mime="application/zip",
231
+ key=f"{city_name}_shp"
232
  )
233
  else:
234
  with open(file_paths[0], 'rb') as f:
235
+ st.download_button(
236
  label=f"Download {format_type}",
237
  data=f,
238
  file_name=os.path.basename(file_paths[0]),
 
241
  )
242
 
243
  # Main app
244
+ city_name = st.text_input("Enter city name (include country if needed):", "Berlin, Germany")
245
+
246
+ if st.button("Get City Boundary"):
247
+ with st.spinner("Fetching boundary from OpenStreetMap..."):
248
+ boundary_gdf = get_city_boundary(city_name)
249
+
250
+ if boundary_gdf is not None:
251
+ st.session_state.boundary_gdf = boundary_gdf
252
+ st.session_state.city_found = city_name
253
+
254
+ if 'boundary_gdf' in st.session_state:
255
+ st.success(f"Found boundary for {st.session_state.city_found}")
 
 
 
 
256
 
257
+ # Display map
258
+ m = create_map(st.session_state.boundary_gdf)
259
  st_folium(m, width=800, height=500)
260
 
261
+ # Download options
 
 
 
262
  st.header("Download Options")
263
  col1, col2, col3 = st.columns(3)
264
 
265
  with tempfile.TemporaryDirectory() as temp_dir:
266
  # Shapefile
267
  with col1:
268
+ shp_files = save_to_format(st.session_state.boundary_gdf, "SHP", temp_dir, st.session_state.city_found)
269
  create_download_button(shp_files, "SHP", st.session_state.city_found)
270
 
271
  # GeoJSON
272
  with col2:
273
+ geojson_file = save_to_format(st.session_state.boundary_gdf, "GeoJSON", temp_dir, st.session_state.city_found)
274
  create_download_button(geojson_file, "GeoJSON", st.session_state.city_found)
275
 
276
  # KML
277
  with col3:
278
+ kml_file = save_to_format(st.session_state.boundary_gdf, "KML", temp_dir, st.session_state.city_found)
279
+ create_download_button(kml_file, "KML", st.session_state.city_found)