Spaces:
Sleeping
Sleeping
Update app.py
Browse filesTransportation bilgisi eklendi
app.py
CHANGED
|
@@ -48,9 +48,14 @@ DEFAULT_TAGS = {
|
|
| 48 |
"amenity": ["school", "pharmacy", "hospital", "restaurant", "cafe", "bank"],
|
| 49 |
"leisure": ["park", "playground"],
|
| 50 |
"shop": True,
|
|
|
|
|
|
|
|
|
|
|
|
|
| 51 |
}
|
| 52 |
|
| 53 |
|
|
|
|
| 54 |
# ==========================================
|
| 55 |
# OSM / CBS FONKSİYONLARI
|
| 56 |
# ==========================================
|
|
@@ -147,21 +152,8 @@ def get_pois_within(gdf, tags=None):
|
|
| 147 |
|
| 148 |
|
| 149 |
def summarize_pois(gdf, pois):
|
| 150 |
-
"""
|
| 151 |
-
Mahalle alanı ve POI'lerden basit istatistikler üretir.
|
| 152 |
-
"""
|
| 153 |
summary = {}
|
| 154 |
-
|
| 155 |
-
# Alan (m^2 ve km^2)
|
| 156 |
-
try:
|
| 157 |
-
area_m2 = gdf.to_crs(epsg=3857).geometry.iloc[0].area
|
| 158 |
-
summary["alan_m2"] = float(area_m2)
|
| 159 |
-
summary["alan_km2"] = float(area_m2 / 1_000_000)
|
| 160 |
-
except Exception as e:
|
| 161 |
-
print("Alan hesaplama hatası:", e)
|
| 162 |
-
summary["alan_m2"] = None
|
| 163 |
-
summary["alan_km2"] = None
|
| 164 |
-
|
| 165 |
if pois is None or len(pois) == 0:
|
| 166 |
summary["toplam_poi"] = 0
|
| 167 |
return summary
|
|
@@ -183,8 +175,25 @@ def summarize_pois(gdf, pois):
|
|
| 183 |
for k, v in shop_counts.items():
|
| 184 |
summary[f"shop_{k}"] = int(v)
|
| 185 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 186 |
return summary
|
| 187 |
|
|
|
|
| 188 |
def build_poi_names_text(pois, max_per_category=15) -> str:
|
| 189 |
"""
|
| 190 |
POI GeoDataFrame'inden okul, eczane, kafe, restoran, market vb.
|
|
@@ -238,9 +247,6 @@ def build_poi_names_text(pois, max_per_category=15) -> str:
|
|
| 238 |
|
| 239 |
|
| 240 |
def build_stats_text(summary: dict) -> str:
|
| 241 |
-
"""
|
| 242 |
-
Sayısal özetleri insan okunur kısa bir metne çevirir (LLM prompt'u için).
|
| 243 |
-
"""
|
| 244 |
if not summary:
|
| 245 |
return "Veri bulunamadı."
|
| 246 |
|
|
@@ -252,6 +258,12 @@ def build_stats_text(summary: dict) -> str:
|
|
| 252 |
cafe = summary.get("amenity_cafe", 0)
|
| 253 |
restoran = summary.get("amenity_restaurant", 0)
|
| 254 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 255 |
lines = [
|
| 256 |
f"- Tahmini alan: {alan:.2f} km²",
|
| 257 |
f"- Toplam POI (ilgi noktası): {toplam_poi}",
|
|
@@ -260,11 +272,17 @@ def build_stats_text(summary: dict) -> str:
|
|
| 260 |
f"- Eczane sayısı: {eczane}",
|
| 261 |
f"- Kafe sayısı: {cafe}",
|
| 262 |
f"- Restoran sayısı: {restoran}",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 263 |
]
|
| 264 |
|
| 265 |
return "\n".join(lines)
|
| 266 |
|
| 267 |
|
|
|
|
| 268 |
# ==========================================
|
| 269 |
# MAHALLE KARŞILAŞTIRMA BAĞLAMI
|
| 270 |
# ==========================================
|
|
@@ -344,56 +362,36 @@ def prepare_comparison(city, district1, neigh1, district2, neigh2):
|
|
| 344 |
|
| 345 |
|
| 346 |
|
| 347 |
-
def add_poi_markers_to_map(pois, m, layer_prefix="POI"):
|
| 348 |
-
"""
|
| 349 |
-
POI GeoDataFrame'ini alır, amenity/leisure/shop sütunlarına göre
|
| 350 |
-
kategorik katmanlar oluşturup haritaya ekler.
|
| 351 |
-
"""
|
| 352 |
-
if pois is None or len(pois) == 0:
|
| 353 |
-
return
|
| 354 |
-
|
| 355 |
-
# Gerekirse WGS84'e (lat/lon) çevir
|
| 356 |
-
try:
|
| 357 |
-
if pois.crs is not None and pois.crs.to_epsg() != 4326:
|
| 358 |
-
pois = pois.to_crs(epsg=4326)
|
| 359 |
-
except Exception:
|
| 360 |
-
# CRS yoksa veya hata olursa direkt devam
|
| 361 |
-
pass
|
| 362 |
-
|
| 363 |
-
layer_groups = {} # {kategori_ismi: folium.FeatureGroup}
|
| 364 |
|
|
|
|
|
|
|
| 365 |
for _, row in pois.iterrows():
|
| 366 |
-
|
| 367 |
-
if geom is None or geom.is_empty:
|
| 368 |
-
continue
|
| 369 |
-
|
| 370 |
-
# Nokta değilse centroid al
|
| 371 |
-
try:
|
| 372 |
-
if geom.geom_type == "Point":
|
| 373 |
-
lat, lon = geom.y, geom.x
|
| 374 |
-
else:
|
| 375 |
-
c = geom.centroid
|
| 376 |
-
lat, lon = c.y, c.x
|
| 377 |
-
except Exception:
|
| 378 |
-
continue
|
| 379 |
-
|
| 380 |
-
# Kategori belirle (öncelik: amenity > leisure > shop)
|
| 381 |
amenity = row.get("amenity")
|
| 382 |
leisure = row.get("leisure")
|
| 383 |
shop = row.get("shop")
|
|
|
|
|
|
|
|
|
|
| 384 |
|
|
|
|
| 385 |
if isinstance(amenity, str):
|
| 386 |
cat = f"Amenity: {amenity}"
|
| 387 |
elif isinstance(leisure, str):
|
| 388 |
cat = f"Leisure: {leisure}"
|
| 389 |
elif isinstance(shop, str):
|
| 390 |
cat = f"Shop: {shop}"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 391 |
else:
|
| 392 |
cat = "Diğer"
|
| 393 |
|
| 394 |
layer_name = f"{layer_prefix} - {cat}"
|
| 395 |
|
| 396 |
-
# İlgili katman yoksa yaratıp haritaya ekle
|
| 397 |
if layer_name not in layer_groups:
|
| 398 |
fg = folium.FeatureGroup(name=layer_name, show=True)
|
| 399 |
fg.add_to(m)
|
|
@@ -412,10 +410,16 @@ def add_poi_markers_to_map(pois, m, layer_prefix="POI"):
|
|
| 412 |
popup_items.append(f"leisure={leisure}")
|
| 413 |
if isinstance(shop, str):
|
| 414 |
popup_items.append(f"shop={shop}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 415 |
|
| 416 |
popup_text = ", ".join(popup_items) if popup_items else "POI"
|
| 417 |
|
| 418 |
-
|
| 419 |
location=[lat, lon],
|
| 420 |
radius=4,
|
| 421 |
popup=popup_text,
|
|
|
|
| 48 |
"amenity": ["school", "pharmacy", "hospital", "restaurant", "cafe", "bank"],
|
| 49 |
"leisure": ["park", "playground"],
|
| 50 |
"shop": True,
|
| 51 |
+
# >>> ULAŞIM ETİKETLERİ
|
| 52 |
+
"highway": ["bus_stop"], # otobüs durakları
|
| 53 |
+
"railway": ["station", "halt", "tram_stop"], # tren / metro / tramvay istasyonları
|
| 54 |
+
"public_transport": ["stop_position", "platform"], # toplu taşıma durak/istasyonları
|
| 55 |
}
|
| 56 |
|
| 57 |
|
| 58 |
+
|
| 59 |
# ==========================================
|
| 60 |
# OSM / CBS FONKSİYONLARI
|
| 61 |
# ==========================================
|
|
|
|
| 152 |
|
| 153 |
|
| 154 |
def summarize_pois(gdf, pois):
|
|
|
|
|
|
|
|
|
|
| 155 |
summary = {}
|
| 156 |
+
...
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 157 |
if pois is None or len(pois) == 0:
|
| 158 |
summary["toplam_poi"] = 0
|
| 159 |
return summary
|
|
|
|
| 175 |
for k, v in shop_counts.items():
|
| 176 |
summary[f"shop_{k}"] = int(v)
|
| 177 |
|
| 178 |
+
# >>> ULAŞIM: highway / railway / public_transport
|
| 179 |
+
if "highway" in pois.columns:
|
| 180 |
+
hw_counts = pois["highway"].value_counts().to_dict()
|
| 181 |
+
for k, v in hw_counts.items():
|
| 182 |
+
summary[f"highway_{k}"] = int(v)
|
| 183 |
+
|
| 184 |
+
if "railway" in pois.columns:
|
| 185 |
+
rw_counts = pois["railway"].value_counts().to_dict()
|
| 186 |
+
for k, v in rw_counts.items():
|
| 187 |
+
summary[f"railway_{k}"] = int(v)
|
| 188 |
+
|
| 189 |
+
if "public_transport" in pois.columns:
|
| 190 |
+
pt_counts = pois["public_transport"].value_counts().to_dict()
|
| 191 |
+
for k, v in pt_counts.items():
|
| 192 |
+
summary[f"public_transport_{k}"] = int(v)
|
| 193 |
+
|
| 194 |
return summary
|
| 195 |
|
| 196 |
+
|
| 197 |
def build_poi_names_text(pois, max_per_category=15) -> str:
|
| 198 |
"""
|
| 199 |
POI GeoDataFrame'inden okul, eczane, kafe, restoran, market vb.
|
|
|
|
| 247 |
|
| 248 |
|
| 249 |
def build_stats_text(summary: dict) -> str:
|
|
|
|
|
|
|
|
|
|
| 250 |
if not summary:
|
| 251 |
return "Veri bulunamadı."
|
| 252 |
|
|
|
|
| 258 |
cafe = summary.get("amenity_cafe", 0)
|
| 259 |
restoran = summary.get("amenity_restaurant", 0)
|
| 260 |
|
| 261 |
+
# >>> ULAŞIM SAYILARI
|
| 262 |
+
otobus_duragi = summary.get("highway_bus_stop", 0)
|
| 263 |
+
tren_istasyonu = summary.get("railway_station", 0) + summary.get("railway_halt", 0)
|
| 264 |
+
tramvay_duragi = summary.get("railway_tram_stop", 0)
|
| 265 |
+
pt_platform = summary.get("public_transport_platform", 0)
|
| 266 |
+
|
| 267 |
lines = [
|
| 268 |
f"- Tahmini alan: {alan:.2f} km²",
|
| 269 |
f"- Toplam POI (ilgi noktası): {toplam_poi}",
|
|
|
|
| 272 |
f"- Eczane sayısı: {eczane}",
|
| 273 |
f"- Kafe sayısı: {cafe}",
|
| 274 |
f"- Restoran sayısı: {restoran}",
|
| 275 |
+
# >>> ULAŞIM SATIRLARI
|
| 276 |
+
f"- Otobüs durağı sayısı: {otobus_duragi}",
|
| 277 |
+
f"- Tren/metro istasyonu sayısı: {tren_istasyonu}",
|
| 278 |
+
f"- Tramvay durağı sayısı: {tramvay_duragi}",
|
| 279 |
+
f"- Toplu taşıma platform/istasyon öğesi: {pt_platform}",
|
| 280 |
]
|
| 281 |
|
| 282 |
return "\n".join(lines)
|
| 283 |
|
| 284 |
|
| 285 |
+
|
| 286 |
# ==========================================
|
| 287 |
# MAHALLE KARŞILAŞTIRMA BAĞLAMI
|
| 288 |
# ==========================================
|
|
|
|
| 362 |
|
| 363 |
|
| 364 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 365 |
|
| 366 |
+
def add_poi_markers_to_map(pois, m, layer_prefix="POI"):
|
| 367 |
+
...
|
| 368 |
for _, row in pois.iterrows():
|
| 369 |
+
...
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 370 |
amenity = row.get("amenity")
|
| 371 |
leisure = row.get("leisure")
|
| 372 |
shop = row.get("shop")
|
| 373 |
+
highway = row.get("highway")
|
| 374 |
+
railway = row.get("railway")
|
| 375 |
+
public_transport = row.get("public_transport")
|
| 376 |
|
| 377 |
+
# Kategori belirle (öncelik: amenity > leisure > shop > railway > highway > public_transport)
|
| 378 |
if isinstance(amenity, str):
|
| 379 |
cat = f"Amenity: {amenity}"
|
| 380 |
elif isinstance(leisure, str):
|
| 381 |
cat = f"Leisure: {leisure}"
|
| 382 |
elif isinstance(shop, str):
|
| 383 |
cat = f"Shop: {shop}"
|
| 384 |
+
elif isinstance(railway, str):
|
| 385 |
+
cat = f"Railway: {railway}"
|
| 386 |
+
elif isinstance(highway, str):
|
| 387 |
+
cat = f"Highway: {highway}"
|
| 388 |
+
elif isinstance(public_transport, str):
|
| 389 |
+
cat = f"PT: {public_transport}"
|
| 390 |
else:
|
| 391 |
cat = "Diğer"
|
| 392 |
|
| 393 |
layer_name = f"{layer_prefix} - {cat}"
|
| 394 |
|
|
|
|
| 395 |
if layer_name not in layer_groups:
|
| 396 |
fg = folium.FeatureGroup(name=layer_name, show=True)
|
| 397 |
fg.add_to(m)
|
|
|
|
| 410 |
popup_items.append(f"leisure={leisure}")
|
| 411 |
if isinstance(shop, str):
|
| 412 |
popup_items.append(f"shop={shop}")
|
| 413 |
+
if isinstance(railway, str):
|
| 414 |
+
popup_items.append(f"railway={railway}")
|
| 415 |
+
if isinstance(highway, str):
|
| 416 |
+
popup_items.append(f"highway={highway}")
|
| 417 |
+
if isinstance(public_transport, str):
|
| 418 |
+
popup_items.append(f"public_transport={public_transport}")
|
| 419 |
|
| 420 |
popup_text = ", ".join(popup_items) if popup_items else "POI"
|
| 421 |
|
| 422 |
+
folium.CircleMarker(
|
| 423 |
location=[lat, lon],
|
| 424 |
radius=4,
|
| 425 |
popup=popup_text,
|