# -------------------------------------------------------------------------- # GraphHopper v11 — إعدادات محرك التوجيه # # ملاحظة جوهرية عن الاتجاهات (oneway): # الاتجاه المسموح لكل حافة (edge) يُحسب مرة واحدة أثناء الاستيراد من وسوم OSM # (oneway / oneway:motorcar / junction=roundabout ...). لا يمكن لأي custom_model # هنا أن يفتح اتجاهاً مغلقاً في البيانات. لذلك أي طريق رئيسي ثنائي الاتجاه يظهر # كأحادي الاتجاه = مشكلة بيانات، وتُعالج قبل البناء عبر: # infrastructure/scripts/normalize-oneway.sh # أما الالتفافات الطويلة "للعودة من نفس الطريق" فهي مشكلة إعدادات، وتُعالج هنا # بواسطة turn_costs.u_turn_costs (كانت لانهائية = ممنوع الالتفاف نهائياً). # -------------------------------------------------------------------------- graphhopper: datareader.file: /data/master_map.osm.pbf graph.location: /data/graph-cache # ── بيانات الارتفاع الحقيقية (SRTM 30m) ────────────────────────────── # يحمّل تلقائياً ملفات .hgt من NASA SRTM لتغطية الأردن. # يربط كل حافة (Edge) في الغراف بارتفاعها الفعلي بالأمتار. # يُفعّل حقول ascend/descend في الـ Response + إحداثيات 3D. graph.elevation.provider: srtm graph.elevation.cache_dir: /data/srtm-cache/ graph.elevation.dataaccess: RAM_STORE # كانت "" أي: لا تتجاهل شيئاً — فتُستورد الأرصفة والمسارات كحافات ويقفز عليها # الـ snapping فيخرج مسار غريب بجانب الشارع. نعيد القيمة الافتراضية الآمنة. import.osm.ignored_highways: "footway,cycleway,path,pedestrian,steps" # قائمة واحدة بلا مسافات — GraphHopper يفصل على الفاصلة فقط # car_access إلزامية لأن custom_model يستخدمها لفرض اتجاه السير (انظر priority أدناه) graph.encoded_values: road_class,road_environment,max_speed,road_access,surface,roundabout,lanes,car_access profiles: - name: car # قيود الدوران الحقيقية من OSM (no_left_turn ...) مع تكلفة محدودة # للالتفاف 180°. بدون u_turn_costs تكون التكلفة لانهائية، فيرفض المحرك # أي عودة على نفس الطريق ويولّد التفافات ضخمة. turn_costs: vehicle_types: [motorcar, motor_vehicle] u_turn_costs: 60 # ثانية — يسمح بالالتفاف عند فتحات الجزيرة الوسطية دون تفضيله custom_model: # 70 ث/كم كانت تدفع المحرك لاختيار الأقصر جغرافياً (حواري وطرق خدمة) # على حساب الشارع الرئيسي. 20 توازن بين الزمن والمسافة. distance_influence: 20 speed: # القاعدة العامة أولاً ثم التخصيص؛ limit_to يأخذ الأدنى دائماً. # (قاعدة MOTORWAY/TRUNK القديمة بـ 60 كانت بلا أثر لأن العام 60 أصلاً) - if: "true" limit_to: 60 - if: "road_class == PRIMARY" limit_to: 45 - if: "road_class == SECONDARY" limit_to: 28 - if: "road_class == TERTIARY" limit_to: 20 - if: "road_class == RESIDENTIAL || road_class == UNCLASSIFIED" limit_to: 14 - if: "road_class == LIVING_STREET || road_class == SERVICE" limit_to: 14 priority: # فرض اتجاه السير: بدون هذه القاعدة تبقى car_access مخزّنة في الغراف # لكن غير مُطبَّقة في حساب الوزن، فيُخترق كل oneway. القاعدة تأتي # افتراضياً من car.json، ولا تُدمج حين يُكتب custom_model سطرياً. - if: "!car_access" multiply_by: 0 # تفضيل الشرايين الرئيسية بدل قصّ الطريق عبر الأحياء - if: "road_class == LIVING_STREET" multiply_by: 0.5 - if: "road_class == SERVICE" multiply_by: 0.6 - if: "road_class == TRACK" multiply_by: 0.3 # CH مُعطّل: مع turn_costs يصبح البناء edge-based ويستهلك ذاكرة كبيرة على # ملف مدمج (الأردن+سوريا+مصر)، كما أن الـ API يرسل ch.disable في كل طلب # يحتوي custom_model أو alternative_route أصلاً. LM يعطي السرعة المطلوبة. profiles_ch: [] profiles_lm: - profile: car routing.non_ch.max_visited_nodes: 2000000 server: application_connectors: - type: http # 8080 داخل الحاوية: docker-compose يعرّض 8989:8080، والـ healthcheck # و GRAPH_HOPPER_URL في الـ API يستهدفان 8080. القيمة القديمة (8989) # كانت تخالف الثلاثة. port: 8080 bind_host: 0.0.0.0