Files
EM2_ERP/em2rp/functions/test_segments.js
T

131 lines
5.1 KiB
JavaScript

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<steps.length; i++) {
const step = steps[i];
const inst = step.navigationInstruction ? step.navigationInstruction.instructions : '';
const isToll = inst.toLowerCase().includes('péage') || inst.toLowerCase().includes('toll');
if (isToll) {
if (!currentSegment) {
currentSegment = { steps: [] };
}
currentSegment.steps.push(step);
} else {
if (currentSegment) {
segments.push(currentSegment);
currentSegment = null;
}
}
}
if (currentSegment) segments.push(currentSegment);
const polylineLib = require('@mapbox/polyline');
let totalToll = 0;
for (let i=0; i<segments.length; i++) {
const seg = segments[i];
let segCoords = [];
for(let step of seg.steps) {
if(step.polyline && step.polyline.encodedPolyline) {
segCoords = segCoords.concat(polylineLib.decode(step.polyline.encodedPolyline, 5));
}
}
const candidates = [];
stations.forEach(s => {
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();