first commit
This commit is contained in:
98
lib/helpers/miler_router.dart
Normal file
98
lib/helpers/miler_router.dart
Normal file
@@ -0,0 +1,98 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:latlong2/latlong.dart' show LatLng;
|
||||
|
||||
// ── Routing ─────────────────────────────────────────────────────────────────
|
||||
|
||||
/// A driving route between two points, from OSRM's public router.
|
||||
///
|
||||
/// Replaces the Directions API call, which needed the revoked key. Same shape
|
||||
/// of answer — an ordered list of coordinates — so the callers' route drawing,
|
||||
/// distance table and camera fitting are untouched.
|
||||
class MilerRouter {
|
||||
static const String _host = 'https://router.project-osrm.org';
|
||||
|
||||
/// Sent with every request. OSRM's demo server, like OSM's tile server,
|
||||
/// blocks anonymous clients first.
|
||||
static const String _agent = 'com.doormile.partner';
|
||||
|
||||
/// The road geometry from [start] to [end], or an empty list.
|
||||
///
|
||||
/// Never throws: a route screen with no line is a degraded screen, but a
|
||||
/// route screen that crashed is a rider standing in the street with nothing.
|
||||
/// Callers fall back to the direct line on an empty answer.
|
||||
static Future<List<LatLng>> route(LatLng start, LatLng end) async {
|
||||
final uri = Uri.parse(
|
||||
'$_host/route/v1/driving/'
|
||||
'${start.longitude},${start.latitude};${end.longitude},${end.latitude}'
|
||||
'?overview=full&geometries=geojson',
|
||||
);
|
||||
|
||||
try {
|
||||
final res = await http
|
||||
.get(uri, headers: const {'User-Agent': _agent})
|
||||
.timeout(const Duration(seconds: 8));
|
||||
if (res.statusCode != 200) {
|
||||
debugPrint(
|
||||
'[MAP] OSRM ${res.statusCode} — falling back to a direct line.',
|
||||
);
|
||||
return const [];
|
||||
}
|
||||
|
||||
final body = jsonDecode(res.body) as Map<String, dynamic>;
|
||||
if (body['code'] != 'Ok') {
|
||||
debugPrint('[MAP] OSRM said ${body['code']} — direct line instead.');
|
||||
return const [];
|
||||
}
|
||||
|
||||
final routes = body['routes'] as List<dynamic>?;
|
||||
if (routes == null || routes.isEmpty) return const [];
|
||||
|
||||
final coords =
|
||||
(routes.first as Map<String, dynamic>)['geometry']['coordinates']
|
||||
as List<dynamic>;
|
||||
|
||||
// GeoJSON is [longitude, latitude] — the opposite order to everything
|
||||
// else in this app, and a silent way to end up routing through the sea.
|
||||
return [
|
||||
for (final c in coords)
|
||||
LatLng((c[1] as num).toDouble(), (c[0] as num).toDouble()),
|
||||
];
|
||||
} catch (e) {
|
||||
debugPrint('[MAP] OSRM unreachable ($e) — direct line instead.');
|
||||
return const [];
|
||||
}
|
||||
}
|
||||
|
||||
/// Road distance in metres between two points, or null when the router
|
||||
/// cannot answer.
|
||||
///
|
||||
/// Replaces a direct call to the Google Directions API in
|
||||
/// `PickupsController`, which was reading the same revoked key and therefore
|
||||
/// silently falling back to straight-line distance on every trip — the number
|
||||
/// riders are *paid* on.
|
||||
static Future<double?> roadDistanceMetres(LatLng start, LatLng end) async {
|
||||
final uri = Uri.parse(
|
||||
'$_host/route/v1/driving/'
|
||||
'${start.longitude},${start.latitude};${end.longitude},${end.latitude}'
|
||||
'?overview=false',
|
||||
);
|
||||
try {
|
||||
final res = await http
|
||||
.get(uri, headers: const {'User-Agent': _agent})
|
||||
.timeout(const Duration(seconds: 6));
|
||||
if (res.statusCode != 200) return null;
|
||||
final body = jsonDecode(res.body) as Map<String, dynamic>;
|
||||
if (body['code'] != 'Ok') return null;
|
||||
final routes = body['routes'] as List<dynamic>?;
|
||||
if (routes == null || routes.isEmpty) return null;
|
||||
final d = (routes.first as Map<String, dynamic>)['distance'];
|
||||
return d is num ? d.toDouble() : null;
|
||||
} catch (e) {
|
||||
debugPrint('[ROUTE] OSRM distance unavailable ($e)');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user