|
|
| import os
|
| import re
|
| import tempfile
|
|
|
| import requests
|
|
|
| from models.city import DB, _norm
|
|
|
| OSM_URL = "https://nominatim.openstreetmap.org/search"
|
| STOPWORDS = {
|
| "depart", "départ", "arrival", "arrivee", "arrivée", "vol", "flight", "plane", "train",
|
| "bus", "boat", "cruise", "kayak", "velo", "vélo", "jeep", "en", "vers", "pour", "de", "da", "di",
|
| }
|
|
|
|
|
| def suggest_unknown_from_text(raw_text: str) -> str:
|
| known = set(DB.match_in_text(raw_text or ""))
|
| cand = re.findall(r"[A-ZÀ-ỴÂÊÔƠƯĐ][\wÀ-ỹ'-\-]+(?:\s+[A-ZÀ-ỴÂÊÔƠƯĐ][\wÀ-ỹ'-\-]+)*", raw_text or "")
|
| out, seen = [], set()
|
| for c in cand:
|
| n = _norm(c)
|
| if n in DB.alias2name:
|
| continue
|
| if any(_norm(k) == n for k in known):
|
| continue
|
| tokens = [t for t in _norm(c).split(" ") if t]
|
| if any(t in STOPWORDS for t in tokens):
|
| continue
|
| if c not in seen:
|
| out.append(c)
|
| seen.add(c)
|
| return "\n".join(out)
|
|
|
|
|
| def nominatim_geocode(q: str, lang="vi", countrycodes="vn,la,kh,th", limit=1):
|
| try:
|
| r = requests.get(OSM_URL, params={
|
| "q": q, "format": "jsonv2", "limit": limit, "accept-language": lang,
|
| "countrycodes": countrycodes
|
| }, headers={"User-Agent": "Tonkin-Map-App/1.0"})
|
| r.raise_for_status()
|
| js = r.json()
|
| if not js:
|
| return None
|
| item = js[0]
|
| lat = float(item.get("lat"))
|
| lon = float(item.get("lon"))
|
| cc = (item.get("address", {}).get("country_code", "") or "").upper()
|
| return {"name": q.strip(), "lat": lat, "lon": lon, "country": cc or "", "aliases": ""}
|
| except Exception:
|
| return None
|
|
|
|
|
| def geocode_unknown_list(text_list: str):
|
| names = [ln.strip() for ln in (text_list or "").splitlines() if ln.strip()]
|
| rows = []
|
| for nm in names:
|
| g = nominatim_geocode(nm)
|
| if g:
|
| rows.append(g)
|
| fns = ["name", "lat", "lon", "country", "aliases", "label_ang", "label_dist"]
|
| lines = [",".join(fns)]
|
| for r in rows:
|
| lines.append(f"{r['name']},{r['lat']},{r['lon']},{r['country']},{r['aliases']},,")
|
| csv_text = "\n".join(lines)
|
| out_path = os.path.join(tempfile.gettempdir(), "cities_geocoded.csv")
|
| with open(out_path, "w", encoding="utf-8-sig") as f:
|
| f.write(csv_text)
|
| return csv_text, out_path, csv_text
|
|
|