celikn commited on
Commit
7353ed1
·
verified ·
1 Parent(s): acd267e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +121 -13
app.py CHANGED
@@ -606,15 +606,15 @@ def create_comparison_map(gdf1, gdf2):
606
 
607
 
608
 
609
-
610
  def run_overpass_to_map(query: str):
611
  """
612
- Overpass QL sorgusunu çalıştırır ve sonucu Folium haritası olarak HTML döndürür.
613
- Shapely / GeoPandas KULLANMIYOR.
614
  """
615
- query = normalize_overpass_query(query)
 
616
  if not query or not query.strip():
617
- return "<b>Overpass sorgusu boş.</b>"
618
 
619
  url = "https://overpass-api.de/api/interpreter"
620
 
@@ -623,17 +623,16 @@ def run_overpass_to_map(query: str):
623
  resp.raise_for_status()
624
  data = resp.json()
625
  except Exception as e:
626
- # Overpass'ın text çıktısını da logla (çoğu zaman içinde 'line X: parse error' yazar)
627
  try:
628
  print("Overpass response text:", resp.text[:500])
629
  except Exception:
630
  pass
631
- print("Overpass isteği hatası:", e)
632
- return f"<b>Overpass isteği hatası:</b> {e}"
633
 
634
  elements = data.get("elements", [])
635
  if not elements:
636
- return "<b>Overpass sonucu: veri bulunamadı.</b>"
637
 
638
  # Merkez için ilk noktanın koordinatlarını bulalım
639
  center_lat, center_lon = None, None
@@ -642,7 +641,7 @@ def run_overpass_to_map(query: str):
642
  center_lat, center_lon = el["lat"], el["lon"]
643
  break
644
  if center_lat is None:
645
- return "<b>Overpass sonucu: nokta verisi yok.</b>"
646
 
647
  m = folium.Map(location=[center_lat, center_lon], zoom_start=14)
648
 
@@ -690,8 +689,11 @@ def run_overpass_to_map(query: str):
690
  ).add_to(fg_ways)
691
 
692
  folium.LayerControl().add_to(m)
693
- return m._repr_html_()
694
 
 
 
 
 
695
 
696
 
697
 
@@ -716,6 +718,98 @@ def llm_overpass_to_map(natural_prompt: str, model_name: str):
716
  map_html = run_overpass_to_map(query)
717
  return query, map_html
718
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
719
 
720
 
721
 
@@ -732,6 +826,7 @@ def respond(
732
  temperature,
733
  top_p,
734
  compare_context, # mahalle karşılaştırma bağlamı
 
735
  ):
736
 
737
 
@@ -791,6 +886,14 @@ def respond(
791
  "Kullanıcı bu mahalleler hakkında soru sorarsa bu bağlama göre cevap ver:\n"
792
  f"{compare_context}"
793
  )
 
 
 
 
 
 
 
 
794
 
795
  messages = [{"role": "system", "content": full_system}]
796
  messages.extend(history)
@@ -820,6 +923,8 @@ with gr.Blocks() as demo:
820
  gr.Markdown("## Mahalle Karşılaştırmalı Chat Botu")
821
 
822
  compare_state = gr.State("")
 
 
823
 
824
  with gr.Row():
825
  # SOL SÜTUN: CHAT
@@ -837,7 +942,7 @@ with gr.Blocks() as demo:
837
  "Qwen/Qwen2.5-72B-Instruct", # 72B
838
 
839
  # Çok büyük model
840
- "openai/gpt-oss-120b", # 120B
841
  ],
842
  label="Model Seç (Bu listedeki modeller Hugging Face Inference API chat_completion ile uyumludur)",
843
  value="abacusai/Dracarys-72B-Instruct"
@@ -885,6 +990,8 @@ with gr.Blocks() as demo:
885
  temperature_slider,
886
  top_p_slider,
887
  compare_state, # >>> mahalle karşılaştırma bağlamı
 
 
888
  ],
889
  )
890
 
@@ -972,10 +1079,11 @@ with gr.Blocks() as demo:
972
  run_overpass_btn.click(
973
  fn=run_overpass_to_map,
974
  inputs=[overpass_box],
975
- outputs=[map_html],
976
  )
977
 
978
 
 
979
  compare_btn.click(
980
  fn=prepare_comparison,
981
  inputs=[city_in, district1_in, neigh1_in, district2_in, neigh2_in],
 
606
 
607
 
608
 
 
609
  def run_overpass_to_map(query: str):
610
  """
611
+ Overpass QL sorgusunu çalıştırır, Folium haritası ve LLM bağlamı için
612
+ metinsel bir özet döndürür.
613
  """
614
+ query = normalize_overpass_query(query) if 'normalize_overpass_query' in globals() else query
615
+
616
  if not query or not query.strip():
617
+ return "<b>Overpass sorgusu boş.</b>", "Geçerli bir Overpass sorgusu sağlanmadı."
618
 
619
  url = "https://overpass-api.de/api/interpreter"
620
 
 
623
  resp.raise_for_status()
624
  data = resp.json()
625
  except Exception as e:
626
+ print("Overpass isteği hatası:", e)
627
  try:
628
  print("Overpass response text:", resp.text[:500])
629
  except Exception:
630
  pass
631
+ return f"<b>Overpass isteği hatası:</b> {e}", "Overpass isteğinde hata oluştu, veri yok."
 
632
 
633
  elements = data.get("elements", [])
634
  if not elements:
635
+ return "<b>Overpass sonucu: veri bulunamadı.</b>", "Overpass sonucu: hiç element bulunamadı."
636
 
637
  # Merkez için ilk noktanın koordinatlarını bulalım
638
  center_lat, center_lon = None, None
 
641
  center_lat, center_lon = el["lat"], el["lon"]
642
  break
643
  if center_lat is None:
644
+ return "<b>Overpass sonucu: nokta verisi yok.</b>", "Overpass sonucu: nokta verisi bulunamadı."
645
 
646
  m = folium.Map(location=[center_lat, center_lon], zoom_start=14)
647
 
 
689
  ).add_to(fg_ways)
690
 
691
  folium.LayerControl().add_to(m)
 
692
 
693
+ map_html = m._repr_html_()
694
+ summary_text = summarize_overpass_data(data)
695
+
696
+ return map_html, summary_text
697
 
698
 
699
 
 
718
  map_html = run_overpass_to_map(query)
719
  return query, map_html
720
 
721
+ def summarize_overpass_data(data: dict, max_examples: int = 30) -> str:
722
+ """
723
+ Overpass JSON sonucundan LLM'e verilecek metinsel bir özet üretir.
724
+ Çok büyük verilerde token patlamaması için sınırlı örnek verir.
725
+ """
726
+ if not data:
727
+ return "Overpass sonucu boş veya geçersiz.\n"
728
+
729
+ elements = data.get("elements", [])
730
+ if not elements:
731
+ return "Overpass sonucu: hiç element bulunamadı.\n"
732
+
733
+ total_nodes = sum(1 for e in elements if e.get("type") == "node")
734
+ total_ways = sum(1 for e in elements if e.get("type") == "way")
735
+ total_rel = sum(1 for e in elements if e.get("type") == "relation")
736
+
737
+ # Basit tag istatistikleri
738
+ amenity_counts = {}
739
+ leisure_counts = {}
740
+ shop_counts = {}
741
+ highway_counts = {}
742
+ railway_counts = {}
743
+ pt_counts = {}
744
+
745
+ examples = []
746
+
747
+ for e in elements[:max_examples]:
748
+ etype = e.get("type")
749
+ tags = e.get("tags", {})
750
+ name = tags.get("name", "(isimsiz)")
751
+
752
+ amenity = tags.get("amenity")
753
+ leisure = tags.get("leisure")
754
+ shop = tags.get("shop")
755
+ highway = tags.get("highway")
756
+ railway = tags.get("railway")
757
+ pt = tags.get("public_transport")
758
+ opening_hours = tags.get("opening_hours")
759
+ wheelchair = tags.get("wheelchair")
760
+
761
+ if amenity:
762
+ amenity_counts[amenity] = amenity_counts.get(amenity, 0) + 1
763
+ if leisure:
764
+ leisure_counts[leisure] = leisure_counts.get(leisure, 0) + 1
765
+ if shop:
766
+ shop_counts[shop] = shop_counts.get(shop, 0) + 1
767
+ if highway:
768
+ highway_counts[highway] = highway_counts.get(highway, 0) + 1
769
+ if railway:
770
+ railway_counts[railway] = railway_counts.get(railway, 0) + 1
771
+ if pt:
772
+ pt_counts[pt] = pt_counts.get(pt, 0) + 1
773
+
774
+ # Örnek satır
775
+ tag_parts = []
776
+ for k in ["amenity", "leisure", "shop", "highway", "railway", "public_transport",
777
+ "opening_hours", "wheelchair"]:
778
+ v = tags.get(k)
779
+ if v:
780
+ tag_parts.append(f"{k}={v}")
781
+
782
+ tag_text = ", ".join(tag_parts) if tag_parts else "etiket yok"
783
+ examples.append(f"- {etype} | {name} | {tag_text}")
784
+
785
+ def dict_to_lines(title, d):
786
+ if not d:
787
+ return []
788
+ items = sorted(d.items(), key=lambda x: -x[1])
789
+ lines = [title]
790
+ for k, v in items:
791
+ lines.append(f" - {k}: {v}")
792
+ return lines
793
+
794
+ lines = [
795
+ f"Toplam node sayısı: {total_nodes}",
796
+ f"Toplam way sayısı: {total_ways}",
797
+ f"Toplam relation sayısı: {total_rel}",
798
+ "",
799
+ ]
800
+ lines += dict_to_lines("Amenity türleri:", amenity_counts)
801
+ lines += dict_to_lines("Leisure türleri:", leisure_counts)
802
+ lines += dict_to_lines("Shop türleri:", shop_counts)
803
+ lines += dict_to_lines("Highway türleri:", highway_counts)
804
+ lines += dict_to_lines("Railway türleri:", railway_counts)
805
+ lines += dict_to_lines("Public transport türleri:", pt_counts)
806
+
807
+ if examples:
808
+ lines.append("")
809
+ lines.append(f"İlk {len(examples)} elementten bazı örnekler:")
810
+ lines.extend(examples)
811
+
812
+ return "\n".join(lines)
813
 
814
 
815
 
 
826
  temperature,
827
  top_p,
828
  compare_context, # mahalle karşılaştırma bağlamı
829
+ spatial_context, # 👈 yeni: son Overpass sonuç özeti
830
  ):
831
 
832
 
 
886
  "Kullanıcı bu mahalleler hakkında soru sorarsa bu bağlama göre cevap ver:\n"
887
  f"{compare_context}"
888
  )
889
+
890
+ if spatial_context:
891
+ full_system += (
892
+ "\n\nAyrıca kullanıcı tarafından en son çalıştırılan bir Overpass (spatial) sorgusunun"
893
+ " özet sonuçları var. Kullanıcı bu sorgudan gelen veriler hakkında soru sorarsa,"
894
+ " bu özet bağlamına dayanarak cevap ver:\n"
895
+ f"{spatial_context}"
896
+ )
897
 
898
  messages = [{"role": "system", "content": full_system}]
899
  messages.extend(history)
 
923
  gr.Markdown("## Mahalle Karşılaştırmalı Chat Botu")
924
 
925
  compare_state = gr.State("")
926
+ spatial_state = gr.State("") # 👈 yeni: son Overpass sonuç özeti
927
+
928
 
929
  with gr.Row():
930
  # SOL SÜTUN: CHAT
 
942
  "Qwen/Qwen2.5-72B-Instruct", # 72B
943
 
944
  # Çok büyük model
945
+ "openai/gpt-oss-120b", # 120Bdı
946
  ],
947
  label="Model Seç (Bu listedeki modeller Hugging Face Inference API chat_completion ile uyumludur)",
948
  value="abacusai/Dracarys-72B-Instruct"
 
990
  temperature_slider,
991
  top_p_slider,
992
  compare_state, # >>> mahalle karşılaştırma bağlamı
993
+ spatial_state, # >>> son Overpass sonucu özeti
994
+
995
  ],
996
  )
997
 
 
1079
  run_overpass_btn.click(
1080
  fn=run_overpass_to_map,
1081
  inputs=[overpass_box],
1082
+ outputs=[map_html, spatial_state], # 👈 harita + LLM için özet
1083
  )
1084
 
1085
 
1086
+
1087
  compare_btn.click(
1088
  fn=prepare_comparison,
1089
  inputs=[city_in, district1_in, neigh1_in, district2_in, neigh2_in],