fix: polyline decoding bug with large bounds and fix ulys API toll pricing precision

This commit is contained in:
ElPoyo
2026-06-04 16:40:50 +02:00
parent 555629760d
commit 0744665fe2
4 changed files with 91 additions and 35 deletions
+7 -1
View File
@@ -49,8 +49,14 @@ function loadTollStations() {
// ───────────────────────────────────────────── // ─────────────────────────────────────────────
async function getUlysTollLegs(encodedPolyline) { async function getUlysTollLegs(encodedPolyline) {
try { try {
// La polyline Google est encodée avec une précision de 5.
// L'API Ulys (precision=6) attend une précision de 6.
// On la décode (precision 5) puis on la réencode (precision 6).
const decodedCoords = polylineLib.decode(encodedPolyline, 5);
const polyline6 = polylineLib.encode(decodedCoords, 6);
const url = 'https://api-ulys.azure-api.net/placemark/v2/legs?precision=6&includeLayersIds=GaresPeage'; const url = 'https://api-ulys.azure-api.net/placemark/v2/legs?precision=6&includeLayersIds=GaresPeage';
const body = JSON.stringify(encodedPolyline); const body = JSON.stringify(polyline6);
const res = await axios.post(url, body, { const res = await axios.post(url, body, {
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
+40
View File
@@ -0,0 +1,40 @@
import 'package:latlong2/latlong.dart';
List<LatLng> safeDecodePolyline(String encoded) {
if (encoded.isEmpty) return [];
try {
List<LatLng> poly = [];
int index = 0, len = encoded.length;
int lat = 0, lng = 0;
while (index < len) {
int b, shift = 0, result = 0;
do {
if (index >= len) break;
b = encoded.codeUnitAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
lat += dlat;
shift = 0;
result = 0;
do {
if (index >= len) break;
b = encoded.codeUnitAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
lng += dlng;
double finalLat = (lat / 1e5).clamp(-90.0, 90.0);
double finalLng = (lng / 1e5).clamp(-180.0, 180.0);
poly.add(LatLng(finalLat, finalLng));
}
return poly;
} catch (e) {
return [];
}
}
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart'; import 'package:flutter_map/flutter_map.dart';
import 'package:latlong2/latlong.dart'; import 'package:latlong2/latlong.dart';
import 'package:em2rp/models/route_result_model.dart'; import 'package:em2rp/models/route_result_model.dart';
import '../../../utils/polyline_utils.dart';
/// Affiche 1 ou 2 itinéraires sur une carte OpenStreetMap. /// Affiche 1 ou 2 itinéraires sur une carte OpenStreetMap.
/// Route TOLL = bleu, Route TOLL_FREE = vert. /// Route TOLL = bleu, Route TOLL_FREE = vert.
@@ -15,41 +16,8 @@ class RouteMapWidget extends StatelessWidget {
this.selectedRoute, this.selectedRoute,
}); });
/// Décode une polyline Google encodée en liste de LatLng.
List<LatLng> _decode(String encoded) { List<LatLng> _decode(String encoded) {
if (encoded.isEmpty) return []; return safeDecodePolyline(encoded);
try {
final result = <LatLng>[];
int index = 0, lat = 0, lng = 0;
final len = encoded.length;
while (index < len) {
int shift = 0, result0 = 0;
int b;
do {
b = encoded.codeUnitAt(index++) - 63;
result0 |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
final dlat = (result0 & 1) != 0 ? ~(result0 >> 1) : (result0 >> 1);
lat += dlat;
shift = 0;
result0 = 0;
do {
b = encoded.codeUnitAt(index++) - 63;
result0 |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
final dlng = (result0 & 1) != 0 ? ~(result0 >> 1) : (result0 >> 1);
lng += dlng;
result.add(LatLng(lat / 1e5, lng / 1e5));
}
return result;
} catch (e) {
return [];
}
} }
LatLngBounds? _computeBounds(List<List<LatLng>> allPoints) { LatLngBounds? _computeBounds(List<List<LatLng>> allPoints) {
File diff suppressed because one or more lines are too long