Backup before syncing server scripts
This commit is contained in:
Executable
+82
@@ -0,0 +1,82 @@
|
||||
#!/bin/bash
|
||||
# --------------------------------------------------------------------------
|
||||
# verify-oneway.sh — يتحقق أن محرك التوجيه يحترم اتجاهات السير
|
||||
#
|
||||
# يختار طرقاً موسومة oneway=yes من البيانات نفسها، ويطلب مساراً على كل منها
|
||||
# في الاتجاهين. على طريق أحادي سليم يجب أن تختلف المسافتان (العودة تحتاج
|
||||
# التفافاً). التطابق التام = المحرك يتجاهل oneway.
|
||||
#
|
||||
# السبب المعتاد للفشل: سقوط قاعدة "!car_access → 0" من custom_model.
|
||||
# التفاصيل الكاملة: docs/ROUTING_ONEWAY_AR.md
|
||||
#
|
||||
# bash infrastructure/scripts/verify-oneway.sh
|
||||
#
|
||||
# متغيّرات: GH_URL (افتراضي http://localhost:8989)، BBOX، SAMPLES
|
||||
# --------------------------------------------------------------------------
|
||||
set -uo pipefail
|
||||
|
||||
APP_DIR="${APP_DIR:-/home/hamzadoctor/app}"
|
||||
GH_URL="${GH_URL:-http://localhost:8989}"
|
||||
PBF="${PBF:-${APP_DIR}/infrastructure/osm-data/master_map.osm.pbf}"
|
||||
BBOX="${BBOX:-36.055,32.100,36.072,32.116}" # lon1,lat1,lon2,lat2
|
||||
SAMPLES="${SAMPLES:-8}"
|
||||
|
||||
command -v osmium >/dev/null || { echo "❌ osmium غير مثبّت: apt-get install -y osmium-tool"; exit 2; }
|
||||
[ -f "$PBF" ] || { echo "❌ الملف غير موجود: $PBF"; exit 2; }
|
||||
curl -fsS "$GH_URL/health" >/dev/null || { echo "❌ المحرك لا يستجيب على $GH_URL"; exit 2; }
|
||||
|
||||
TMP=$(mktemp -d); trap 'rm -rf "$TMP"' EXIT
|
||||
|
||||
osmium extract -b "$BBOX" "$PBF" -o "$TMP/area.pbf" --overwrite >/dev/null 2>&1
|
||||
osmium tags-filter "$TMP/area.pbf" w/oneway=yes -o "$TMP/ow.pbf" --overwrite >/dev/null 2>&1
|
||||
osmium export -f geojson "$TMP/ow.pbf" -o "$TMP/ow.geojson" --overwrite >/dev/null 2>&1
|
||||
|
||||
GH_URL="$GH_URL" SAMPLES="$SAMPLES" python3 - "$TMP/ow.geojson" <<'PY'
|
||||
import json, os, sys, urllib.request
|
||||
|
||||
gh = os.environ["GH_URL"]
|
||||
want = int(os.environ["SAMPLES"])
|
||||
|
||||
def route(a, b):
|
||||
u = f"{gh}/route?point={a}&point={b}&profile=car"
|
||||
try:
|
||||
return round(json.load(urllib.request.urlopen(u, timeout=20))["paths"][0]["distance"])
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
feats = json.load(open(sys.argv[1]))["features"]
|
||||
print("═" * 60)
|
||||
print(" فحص احترام اتجاهات السير — " + gh)
|
||||
print("═" * 60)
|
||||
|
||||
tested = identical = 0
|
||||
for f in feats:
|
||||
if tested >= want:
|
||||
break
|
||||
g = f["geometry"]
|
||||
if g["type"] != "LineString" or len(g["coordinates"]) < 2:
|
||||
continue
|
||||
c = g["coordinates"]
|
||||
a = f"{c[0][1]:.7f},{c[0][0]:.7f}"
|
||||
b = f"{c[-1][1]:.7f},{c[-1][0]:.7f}"
|
||||
fwd, rev = route(a, b), route(b, a)
|
||||
if fwd is None or rev is None or fwd == 0:
|
||||
continue
|
||||
tested += 1
|
||||
name = (f["properties"].get("name") or "بلا اسم")[:24]
|
||||
# المعيار هو الاختلاف لا نسبته: الالتفاف قد يكون صغيراً نسبياً على مقطع طويل
|
||||
ok = fwd != rev
|
||||
identical += (not ok)
|
||||
print(f" {name:24} ذهاب:{fwd:6d}م عودة:{rev:6d}م {'✅' if ok else '❌ متطابق'}")
|
||||
|
||||
print()
|
||||
if tested == 0:
|
||||
print("⚠️ لم يُعثر على طرق أحادية صالحة للاختبار — راجع BBOX أو البيانات.")
|
||||
sys.exit(2)
|
||||
if identical:
|
||||
print(f"❌ فشل: {identical} من {tested} طريقاً أحادياً يُخترق — المحرك يتجاهل oneway.")
|
||||
print(" الأرجح: سقوط قاعدة '!car_access → 0' من custom_model في config.yml")
|
||||
print(" اقرأ: docs/ROUTING_ONEWAY_AR.md")
|
||||
sys.exit(1)
|
||||
print(f"✅ نجح: {tested} طريقاً أحادياً، كلها محترمة الاتجاه.")
|
||||
PY
|
||||
Reference in New Issue
Block a user