diff --git a/apps/api/src/maps/maps.service.ts b/apps/api/src/maps/maps.service.ts index 65026cd..30ed8bd 100644 --- a/apps/api/src/maps/maps.service.ts +++ b/apps/api/src/maps/maps.service.ts @@ -7,55 +7,36 @@ export class MapsService { private readonly graphHopperUrl: string; constructor(private configService: ConfigService) { - this.graphHopperUrl = this.configService.get('GRAPH_HOPPER_URL', 'http://map-routing:8080'); + this.graphHopperUrl = this.configService.get('GRAPH_HOPPER_URL', 'http://routing:8080'); } async getRoute(from: [number, number], to: [number, number]) { - // Proxy routing request to GraphHopper - // تحويل طلب حساب المسارم إلى GraphHopper try { - const response = await axios.get(`${this.graphHopperUrl}/route`, { - params: { - point: [`${from[0]},${from[1]}`, `${to[0]},${to[1]}`], - profile: 'car', - locale: 'en', - calc_points: true, - points_encoded: false, - elevation: false, - type: 'json', - }, - paramsSerializer: (params) => { - const searchParams = new URLSearchParams(); - Object.entries(params).forEach(([key, value]) => { - if (Array.isArray(value)) { - value.forEach(v => searchParams.append(key, v)); - } else { - searchParams.append(key, value as any); - } - }); - return searchParams.toString(); - }, - }); - - console.log('Routing Successful:', response.request.path); + const payload: any = { + points: [[from[1], from[0]], [to[1], to[0]]], + profile: 'car', + locale: 'en', + calc_points: true, + points_encoded: true, + }; + + console.log(`Routing Request: ${from} -> ${to} via ${this.graphHopperUrl}`); + const response = await axios.post(`${this.graphHopperUrl}/route`, payload, { timeout: 5000 }); + console.log('Routing SUCCESS'); const route = response.data.paths[0]; - if (!route) { - throw new HttpException('No route found', HttpStatus.NOT_FOUND); - } + if (!route) throw new HttpException('No route found', HttpStatus.NOT_FOUND); return { - distance: route.distance, // In meters - duration: route.time / 1000, // In seconds - points: route.points.coordinates, // Array of [lng, lat] + distance: route.distance, + duration: route.time / 1000, + points: route.points, bbox: route.bbox, }; } catch (error) { - console.error('Routing Error:', error.message); - if (error.response) { - console.error('GraphHopper Response:', error.response.data); - } - throw new HttpException('Error calculating route', HttpStatus.BAD_GATEWAY); + const msg = error.response ? `GH Error: ${JSON.stringify(error.response.data)}` : `DNS/Connection Error: ${error.message}`; + console.error('CRITICAL ROUTING FAILURE:', msg); + throw new HttpException(`Routing Failure: ${msg}`, HttpStatus.BAD_GATEWAY); } } diff --git a/apps/web/public/map-demo.html b/apps/web/public/map-demo.html new file mode 100644 index 0000000..b790b87 --- /dev/null +++ b/apps/web/public/map-demo.html @@ -0,0 +1,163 @@ + + + + + + Intaleq Premium Map - خرائط انطلاقة الذكية + + + + + + + + +
+
جاري معالجة المسار...
+ +
+ Logo + POWERED BY INTALEQ +
+ +
+

🗺️ خرائط انطلاقة الذكية

+

المسار المعتمد: عمان ➔ دمشق

+ + + +
+
+ + + + diff --git a/docker-compose.yml b/docker-compose.yml index 2ca9f33..25aea1d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -25,9 +25,9 @@ services: redis: image: redis:7-alpine container_name: map-redis - platform: linux/arm64 + platform: linux/amd64 ports: - - "6380:6379" + - "6381:6379" volumes: - redis_data:/data healthcheck: @@ -46,7 +46,7 @@ services: volumes: - ./infrastructure/osm-data:/data - ./infrastructure/docker/graphhopper/config.yml:/graphhopper/config.yml - command: ["-i", "/data/jordan-latest.osm.pbf", "-c", "config.yml"] + command: ["-i", "/data/region.osm.pbf", "-c", "config.yml"] healthcheck: test: ["CMD-SHELL", "curl -f http://localhost:8080/health || exit 1"] interval: 30s @@ -80,7 +80,7 @@ services: context: . dockerfile: ./infrastructure/docker/api/Dockerfile container_name: map-api - platform: linux/arm64 + platform: linux/amd64 ports: - "3200:3200" environment: @@ -102,7 +102,7 @@ services: container_name: map-martin platform: linux/amd64 ports: - - "3001:3000" + - "3202:3000" environment: - WATCH_DB=true command: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB} @@ -121,7 +121,7 @@ services: environment: - DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB} - PGPASSWORD=${POSTGRES_PASSWORD} - command: ["osm2pgsql", "--create", "--slim", "--cache", "1000", "--database", "${POSTGRES_DB}", "--host", "db", "--user", "${POSTGRES_USER}", "/data/jordan-latest.osm.pbf"] + command: ["osm2pgsql", "--create", "--slim", "--cache", "1000", "--database", "${POSTGRES_DB}", "--host", "db", "--user", "${POSTGRES_USER}", "/data/region.osm.pbf"] depends_on: db: condition: service_healthy @@ -134,9 +134,11 @@ services: context: . dockerfile: ./infrastructure/docker/web/Dockerfile container_name: map-web - platform: linux/arm64 + platform: linux/amd64 ports: - "3201:5173" + volumes: + - ./apps/web/public:/app/public depends_on: - api - martin diff --git a/infrastructure/scripts/update-data.sh b/infrastructure/scripts/update-data.sh new file mode 100644 index 0000000..357839c --- /dev/null +++ b/infrastructure/scripts/update-data.sh @@ -0,0 +1,60 @@ +#!/bin/bash +# -------------------------------------------------------------------------- +# Intaleq Map Platform - 10-Day Update Script +# سكربت تحديث خرائط انطلاقة - التحديث الدوري (كل 10 أيام) +# -------------------------------------------------------------------------- + +set -e # Exit on error + +echo "🚀 Starting 10-day map update..." + +# 1. Configuration (From .env or defaults) +PBF_FILE="/data/jordan-latest.osm.pbf" +SOURCE_URL="https://download.geofabrik.de/asia/jordan-latest.osm.pbf" +APP_DIR="/home/hamzadoctor/app" + +cd "$APP_DIR" + +# 2. Download latest OSM data (Running on Host) +# تحميل أحدث البيانات للأردن وسوريا +echo "🌍 Downloading latest OpenStreetMap data for Jordan & Syria..." +wget -O "infrastructure/osm-data/jordan-latest.osm.pbf.new" "https://download.geofabrik.de/asia/jordan-latest.osm.pbf" +wget -O "infrastructure/osm-data/syria-latest.osm.pbf.new" "https://download.geofabrik.de/asia/syria-latest.osm.pbf" + +mv "infrastructure/osm-data/jordan-latest.osm.pbf.new" "infrastructure/osm-data/jordan-latest.osm.pbf" +mv "infrastructure/osm-data/syria-latest.osm.pbf.new" "infrastructure/osm-data/syria-latest.osm.pbf" + +# 3. Import new data to PostGIS +# استيراد البيانات إلى قاعدة البيانات +echo "💾 Importing Jordan (Create)..." +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 (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 + +# 4. Merge Data (Jordan + Syria) +OSM_FILE="infrastructure/osm-data/region.osm.pbf" +echo "🗺️ Merging Jordan and Syria data into $OSM_FILE..." +osmium merge infrastructure/osm-data/jordan-latest.osm.pbf infrastructure/osm-data/syria-latest.osm.pbf -o $OSM_FILE --overwrite + +# 5. Spatial Integrity check for Geocoding (Landmarks) +# Purge any legacy landmarks outside the expanded region +echo "📍 Syncing user-submitted landmarks and purging invalid coordinates..." +DELETED_COUNT=$(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;") +echo " ✅ Purged ${DELETED_COUNT//[[:space:]]/} invalid landmarks outside the expanded region." + +# Force Spatial Geometry Update +docker compose exec -T db psql -U mapuser -d mapdb -c "UPDATE places_syria SET location = ST_SetSRID(ST_MakePoint(longitude, latitude), 4326) WHERE location IS NULL OR latitude IS NOT NULL;" + +# 6. Rebuild Routing Index (GraphHopper) +echo "🚗 Rebuilding GraphHopper routing index (This may take ~5-8 minutes)..." +docker compose stop routing +# Delete old cache - VERY IMPORTANT to force full re-index +rm -rf infrastructure/osm-data/graph-cache infrastructure/osm-data/default-gh +docker compose up -d routing + +# 7. Final Cleanup & Cache Flush +echo "🧹 Clearing Redis traffic cache..." +docker compose exec -T redis redis-cli flushall + +echo "Done! Map platform is now fully synchronized with Jordan & Syria roads (including Damascus)."