const axios = require('axios'); const fs = require('fs'); const path = require('path'); require('dotenv').config({ path: '.env' }); const { _distKm } = require('./src/travel.js'); function distKm(lat1, lng1, lat2, lng2) { const dLat = (lat2 - lat1) * Math.PI / 180; const dLng = (lng2 - lng1) * Math.PI / 180; const a = Math.sin(dLat/2)**2 + Math.cos(lat1*Math.PI/180) * Math.cos(lat2*Math.PI/180) * Math.sin(dLng/2)**2; return 6371 * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); } async function testTollSegments() { const apiKey = process.env.API_MAPS; const resToll = await axios.post('https://routes.googleapis.com/directions/v2:computeRoutes', { travelMode: 'DRIVE', routingPreference: 'TRAFFIC_UNAWARE', origin: { address: "25 Impasse du Puits du Suc, Saint-Martin-en-Haut, France" }, destination: { address: "Nice, France" }, }, { headers: { 'Content-Type': 'application/json', 'X-Goog-Api-Key': apiKey, 'X-Goog-FieldMask': 'routes.legs.steps.navigationInstruction,routes.legs.steps.distanceMeters,routes.legs.steps.startLocation,routes.legs.steps.endLocation,routes.legs.steps.polyline.encodedPolyline' } }); const steps = resToll.data.routes[0].legs[0].steps; const rawCsv = fs.readFileSync(path.join(__dirname, 'travel', 'gares_peage_export.csv'), 'utf8'); const stations = []; const lines = rawCsv.split('\n'); for (let i = 1; i < lines.length; i++) { const l = lines[i].trim(); if (!l) continue; const parts = l.split(','); if (parts.length >= 4) { const idStr = String(parts[0]).padStart(5, '0'); stations.push({ id: idStr, operatorId: idStr.substring(0, 2), tollId: idStr.substring(2, 5), name: parts[1], lat: parseFloat(parts[2]), lon: parseFloat(parts[3]), }); } } function getClosestGate(lat, lng) { let minDist = Infinity; let closest = null; for(let s of stations) { const d = distKm(lat, lng, s.lat, s.lon); if(d < minDist) { minDist = d; closest = s; } } return minDist < 5 ? closest : null; } const segments = []; let currentSegment = null; for(let i=0; i { let minDist = Infinity; let minIndex = -1; for (let j = 0; j < segCoords.length; j++) { const d = distKm(s.lat, s.lon, segCoords[j][0], segCoords[j][1]); if (d < minDist) { minDist = d; minIndex = j; } } if (minDist < 2) { // must be within 2km of the segment candidates.push({ ...s, polyIndex: minIndex }); } }); candidates.sort((a, b) => a.polyIndex - b.polyIndex); let entry = null, exit = null; if (candidates.length > 0) { entry = candidates[0]; exit = candidates[candidates.length - 1]; } console.log(`Segment ${i+1}: points=${segCoords.length}, candidates=${candidates.length}, Entry=${entry?entry.name:'none'}, Exit=${exit?exit.name:'none'}`); if (entry && exit) { try { const passages = [ { operatorId: entry.operatorId, tollId: entry.tollId }, { operatorId: exit.operatorId, tollId: exit.tollId } ]; const payload = { vehicleCategory: "2", paymentOption: 2, tollPassages: passages.map((p) => ({ toll: { operatorId: p.operatorId, tollId: p.tollId }, passageDate: new Date().toISOString() })), }; const res = await axios.post('https://api-ulys.azure-api.net/tollstation/v1/rate', payload); const data = res.data; let price = 0; if (data.length === 1 && data[0].price > 0) price = data[0].price; if (data.length > 1) { const pItem = data.find(d => d.price > 0); if (pItem) price = pItem.price; } console.log(` -> Price: ${price}€`); totalToll += price; } catch(e) { console.log(` -> Ulys Error`); } } } console.log(`Total Toll: ${totalToll}€`); } testTollSegments();