5.3 KiB
اتجاهات السير في محرك التوجيه — قاعدة لا تُكسر
سجلّ عطل حقيقي كلّف يومين (26–28 يوليو 2026). اقرأ هذا قبل أي تعديل على
infrastructure/docker/graphhopper/config.yml.
القاعدة
custom_model المكتوب سطرياً داخل profiles لا يرث القواعد الافتراضية
لملف car.json. أهم قاعدة ساقطة هي التي تفرض اتجاه السير:
- if: "!car_access"
multiply_by: 0
بدونها تبقى car_access مخزّنة في الغراف (تراها في اللوغ) لكنها لا تدخل في
حساب الوزن إطلاقاً. النتيجة: المحرك يتجاهل كل oneway وكل junction=roundabout
ويمشي في الاتجاهين على كل شارع — يبدو للمستخدم «كأنه يمشي كالمشاة».
القاعدة تتطلّب وجود car_access ضمن graph.encoded_values، وإلا يرفض المحرك
الإقلاع بـ Encoded values missing: car_access.
السطران الإلزاميان في config.yml:
graph.encoded_values: ...,car_access # car_access إلزامية
custom_model:
priority:
- if: "!car_access" # أول قاعدة في priority
multiply_by: 0
كيف يبدو العطل
| العرض | الملاحظة |
|---|---|
A→B و B→A بنفس المسافة تماماً على شارع أحادي |
البصمة القاطعة |
المسار يقطع دواراً مستقيماً بلا تعليمة sign: 6 |
حلقات الدوار أحادية ضمناً، فتُفتح بالاتجاهين |
details=car_access يُظهر False على مقطع ضمن مسار مقبول |
المحرك مرّ عبر حافة ممنوعة |
تشخيص سريع
bash infrastructure/scripts/verify-oneway.sh
الفحص اليدوي لمسار بعينه:
curl -s "http://localhost:8989/route?point=LAT1,LON1&point=LAT2,LON2&profile=car&details=car_access&details=roundabout" | python3 -m json.tool
⚠️ تحذير: check-bidirectional.sh منطقه معكوس
check-bidirectional.sh يعتبر اختلاف الذهاب عن العودة فشلاً، وينصح بتشغيل
normalize-oneway.sh. هذا خطأ: الاختلاف على شارع أحادي هو السلوك الصحيح.
لا تتبع نصيحته، ولا تشغّل normalize-oneway.sh apply إلا بعد التحقق ميدانياً
من أن الشارع ثنائي الاتجاه فعلاً على الأرض.
normalize_oneway.py يكتب oneway=no على البيانات نفسها. تعديل البيانات لإخفاء
عرَض ناتج عن خطأ إعداد يُنتج مسارات غير قانونية للسائقين.
متى يكون السبب البيانات لا الإعداد
إن كان verify-oneway.sh ناجحاً وما زال مسار بعينه خاطئاً، فالنقص في OSM:
osmium extract -b LON1,LAT1,LON2,LAT2 infrastructure/osm-data/master_map.osm.pbf -o /tmp/a.pbf --overwrite
osmium cat -f opl /tmp/a.pbf | grep '^w' | grep -c 'junction=roundabout'
صفر = الدوار غير مرسوم. الحل: ارسمه على openstreetmap.org — يصل تلقائياً في
دورة التحديث القادمة ويفيد الجميع. البديل الموضعي هو approved_roads عبر
apply-delta.sh، لكنه يحتاج صيانة يدوية لكل حالة.
الصورة
نستخدم GraphHopper 11.0 الرسمي مبنياً محلياً من
infrastructure/docker/graphhopper/Dockerfile.
الصورة السابقة israelhikingmap/graphhopper كانت تتجاهل graph.location
(تبني في /data/default-gh) وتتجاهل JAVA_OPTS. لا تعُد إليها.
ENTRYPOINT يستخدم sh -c عمداً — الصيغة exec المباشرة لا توسّع $JAVA_OPTS
فيبقى الـ heap على الافتراضي.
الطرق المرسومة (approved_roads)
update-data.sh يستدعي apply-delta.sh بعد كل دمج، فيصدّر approved_roads
كـ OSM XML ويدمجها في master_map.osm.pbf. الطرق المرسومة تنجو من كل تحديث.
الاتصال بالشبكة يعتمد على start_node / end_node (معرّفات OSM حقيقية تُحلّ
وقت الموافقة). بدونهما تُنشأ عقد جديدة بمعرّفات سالبة ويصبح الطريق معزولاً —
موجود في الخريطة لكن لا يمر به التوجيه.
oneway يُصدَّر أيضاً: 1 → yes، -1 → -1. أي أن الاتجاه المرسوم محترم،
شرط أن تكون قاعدة !car_access أعلاه موجودة.
بعد أي تعديل على config.yml
docker compose stop routing
rm -rf infrastructure/osm-data/graph-cache infrastructure/osm-data/default-gh
docker compose up -d routing && docker compose logs -f routing # انتظر "Started Server"
bash infrastructure/scripts/verify-oneway.sh
البناء ~4 دقائق. إن ظهر exited with code 137 فهو OOM — أوقف
api web dashboard martin redis أثناء البناء، أو أنزل -Xmx في docker-compose.