Files
maps-saas/infrastructure/scripts/update-data.sh
T

155 lines
8.2 KiB
Bash

#!/bin/bash
# --------------------------------------------------------------------------
# Intaleq Map Platform - 10-Day Update Script
# سكربت تحديث خرائط انطلاقة - التحديث الدوري (كل 10 أيام)
# FIXES:
# v2 - Corrected output filename: region.osm.pbf → master_map.osm.pbf
# (GraphHopper reads master_map.osm.pbf per docker-compose.yml)
# v2 - Added Egypt download and import
# v2 - Applies approved-roads delta after every update so custom roads survive
# --------------------------------------------------------------------------
set -e # Exit on error
echo "🚀 Starting 10-day map update (v3 — Jordan + Syria + Egypt + Iraq + Delta)..."
APP_DIR="/home/hamzadoctor/app"
DATA_DIR="${APP_DIR}/infrastructure/osm-data"
# ✅ FIX: Correct filename that GraphHopper actually reads (was: region.osm.pbf)
MASTER_FILE="${DATA_DIR}/master_map.osm.pbf"
DELTA_FILE="${DATA_DIR}/delta.osm"
cd "${APP_DIR}"
# ── Step 1: Download all four country PBFs ─────────────────────────────────
echo "🌍 Downloading Jordan, Syria, Egypt & Iraq PBF data from Geofabrik..."
wget -q --show-progress -O "${DATA_DIR}/jordan-latest.osm.pbf.new" \
"https://download.geofabrik.de/asia/jordan-latest.osm.pbf"
# ✅ FIX: كان يحمّل مصر إلى ملف سوريا ثم يعيد تحميل سوريا فوقها — هدر 177MB كل دورة
wget -q --show-progress -O "${DATA_DIR}/syria-latest.osm.pbf.new" \
"https://download.geofabrik.de/asia/syria-latest.osm.pbf"
wget -q --show-progress -O "${DATA_DIR}/egypt-latest.osm.pbf.new" \
"https://download.geofabrik.de/africa/egypt-latest.osm.pbf"
wget -q --show-progress -O "${DATA_DIR}/iraq-latest.osm.pbf.new" \
"https://download.geofabrik.de/asia/iraq-latest.osm.pbf"
mv "${DATA_DIR}/jordan-latest.osm.pbf.new" "${DATA_DIR}/jordan-latest.osm.pbf"
mv "${DATA_DIR}/syria-latest.osm.pbf.new" "${DATA_DIR}/syria-latest.osm.pbf"
mv "${DATA_DIR}/egypt-latest.osm.pbf.new" "${DATA_DIR}/egypt-latest.osm.pbf"
mv "${DATA_DIR}/iraq-latest.osm.pbf.new" "${DATA_DIR}/iraq-latest.osm.pbf"
echo "✅ Downloads complete."
# ── Step 2: Import all four countries into PostGIS ─────────────────────────
echo "💾 Importing Jordan into PostGIS (--create resets planet_osm_* tables)..."
docker compose --profile import run --rm osm-import \
osm2pgsql --create --slim --cache 1000 \
--database mapdb --host db --user mapuser \
/data/jordan-latest.osm.pbf
echo "💾 Importing Syria into PostGIS (--append)..."
docker compose --profile import run --rm osm-import \
osm2pgsql --append --slim --cache 1000 \
--database mapdb --host db --user mapuser \
/data/syria-latest.osm.pbf
# ✅ FIX: Egypt was missing from the update cycle — added here
echo "💾 Importing Egypt into PostGIS (--append)..."
docker compose --profile import run --rm osm-import \
osm2pgsql --append --slim --cache 1000 \
--database mapdb --host db --user mapuser \
/data/egypt-latest.osm.pbf
echo "💾 Importing Iraq into PostGIS (--append)..."
docker compose --profile import run --rm osm-import \
osm2pgsql --append --slim --cache 1000 \
--database mapdb --host db --user mapuser \
/data/iraq-latest.osm.pbf
# ── Step 2b: Keep routing topology tables ─────────────────────────────────
# Approved roads must share real OSM node IDs with the base graph. Deleting
# nodes/ways makes Martin draw a road but leaves GraphHopper unable to connect it.
echo "🧭 Preserving OSM node/way topology for approved-road routing..."
docker compose exec -T db psql -U mapuser -d mapdb -c \
"DROP TABLE IF EXISTS planet_osm_rels;"
# ── Step 3: Merge all four PBFs into master_map.osm.pbf ────────────────────
# ✅ FIX: Old script wrote to region.osm.pbf — GraphHopper reads master_map.osm.pbf
echo "🗺️ Merging Jordan + Syria + Egypt + Iraq → ${MASTER_FILE}..."
osmium merge \
"${DATA_DIR}/jordan-latest.osm.pbf" \
"${DATA_DIR}/syria-latest.osm.pbf" \
"${DATA_DIR}/egypt-latest.osm.pbf" \
"${DATA_DIR}/iraq-latest.osm.pbf" \
-o "${MASTER_FILE}" --overwrite
echo "✅ Master PBF built: $(du -sh ${MASTER_FILE} | cut -f1)"
# ── Step 4: Apply approved-roads delta (survives each update) ────────────
# ✅ NEW: Export approved candidate_roads as OSM XML and merge into master
echo "🛣️ Applying approved-roads delta..."
if [ -f "${APP_DIR}/infrastructure/scripts/apply-delta.sh" ]; then
bash "${APP_DIR}/infrastructure/scripts/apply-delta.sh" "${APP_DIR}" "${MASTER_FILE}" "${DELTA_FILE}" || \
echo "⚠️ Delta apply failed (no approved roads yet?). Continuing without delta."
else
echo "⚠️ apply-delta.sh not found. Skipping delta step."
fi
# ── Step 5: Spatial integrity check for Geocoding (Landmarks) ────────────
echo "📍 Purging landmarks outside valid bounding boxes..."
docker compose exec -T db psql -U mapuser -d mapdb -t -c \
"DELETE FROM places_syria WHERE longitude < 34 OR longitude > 43 OR latitude < 29 OR latitude > 38;"
docker compose exec -T db psql -U mapuser -d mapdb -t -c \
"UPDATE places_syria SET location = ST_SetSRID(ST_MakePoint(longitude, latitude), 4326)
WHERE location IS NULL AND latitude IS NOT NULL;"
echo "✅ Landmark sync done."
# ── Step 6: Rebuild GraphHopper routing index ─────────────────────────────
# ذروة البناء لأربع دول ~3GB. على سيرفر بـ7.8GB الهامش ضيق، فنُخلي الذاكرة
# للحاويات غير الضرورية أثناء البناء فقط ثم نعيدها. db و redis يبقيان لأن
# الخطوات التالية تحتاجهما.
echo "🚗 Rebuilding GraphHopper routing graph (may take 5-10 min)..."
echo "⏸️ إيقاف مؤقت للحاويات غير الضرورية لتحرير الذاكرة أثناء البناء..."
docker compose stop api web dashboard martin || true
# نُعيدها مهما كانت نتيجة البناء — بما في ذلك الخروج المبكر عند الفشل
trap 'echo "▶️ إعادة تشغيل الحاويات المؤقتة..."; docker compose up -d api web dashboard martin || true' EXIT
docker compose stop routing
rm -rf "${DATA_DIR}/graph-cache" "${DATA_DIR}/default-gh"
docker compose up -d routing
echo "✅ GraphHopper restarting from ${MASTER_FILE}."
# ── Step 6b: بوابة تحقق — اتجاهات السير ──────────────────────────────────
# انحدار 26/07/2026: سقوط قاعدة "!car_access → 0" جعل المحرك يتجاهل كل oneway
# وكل دوار لأيام دون أن يلاحظ أحد. لا نُنهي التحديث دون إثبات أنها تعمل.
# التفاصيل: docs/ROUTING_ONEWAY_AR.md
echo "⏳ انتظار جهوزية المحرك قبل فحص الاتجاهات..."
GH_READY=0
for _ in $(seq 1 90); do
if curl -fsS http://localhost:8989/health >/dev/null 2>&1; then GH_READY=1; break; fi
sleep 10
done
if [ "$GH_READY" = "0" ]; then
echo "❌ المحرك لم يجهز خلال 15 دقيقة — راجع: docker compose logs -f routing"
echo " (السبب المتكرر: exited with code 137 أي نفاد ذاكرة أثناء البناء)"
exit 1
fi
if ! APP_DIR="${APP_DIR}" bash "${APP_DIR}/infrastructure/scripts/verify-oneway.sh"; then
echo ""
echo "❌❌ المحرك يتجاهل اتجاهات السير — التوجيه غير صالح للاستخدام."
echo " اقرأ: docs/ROUTING_ONEWAY_AR.md"
exit 1
fi
# ── Step 7: Cache flush ───────────────────────────────────────────────────
echo "🧹 Flushing Redis traffic cache..."
docker compose exec -T redis redis-cli flushall
echo ""
echo "✅ 10-day update complete — Jordan + Syria + Egypt + Iraq + approved delta applied."
echo " GraphHopper is rebuilding in the background. Allow 5-10 min for routing to be ready."