addRoute method
Calculates and draws a route between start and destination.
Calls the PowerMap Routing API, decodes the geometry, and adds the line to the map.
Implementation
Future<PowerMapRouteResult?> addRoute({
required LatLng start,
required LatLng destination,
required List<LatLng> waypoints,
required bool optimize,
required String profile,
required String language,
bool fitCamera = true,
}) async {
try {
final String baseUrl = PowerMapSDK.baseUrl;
final Map<String, String> headers = await PowerMapSDK.getServiceHeaders();
final List<LatLng> points = [start, ...waypoints, destination];
if (optimize && waypoints.isEmpty) {
throw PowerMapException(
code: PowerMapException.invalidRequest,
message: 'Optimization requires at least one waypoint.',
);
}
final String coordsParam = points
.map((p) => '${p.longitude},${p.latitude}')
.join(';');
dynamic data;
try {
if (optimize && profile == 'driving') {
data = await _requestOptimizedRoute(
start: start,
destination: destination,
waypoints: waypoints,
language: language,
baseUrl: baseUrl,
headers: headers,
);
} else {
final queryParams = {
'geometries': 'polyline6',
'steps': 'true',
'overview': 'full',
'roundabout_exits': 'true',
'voice_instructions': 'true',
'banner_instructions': 'true',
'language': language,
};
final uri = Uri.parse(
'$baseUrl/api/v2/map/route/$profile/$coordsParam',
).replace(queryParameters: queryParams);
final response = await http.get(uri, headers: headers);
if (response.statusCode != 200) {
if (response.statusCode == 401 || response.statusCode == 403) {
throw PowerMapException(
code: PowerMapException.auth,
message: 'Authentication failed for routing request.',
);
}
throw PowerMapException(
code: PowerMapException.serverError,
message: 'Routing API error: ${response.statusCode}',
details: response.body,
);
}
data = json.decode(response.body);
}
} catch (e) {
if (e is PowerMapException) rethrow;
throw PowerMapException(
code: PowerMapException.network,
message: 'Routing request failed due to a network error.',
details: e,
);
}
if (data != null &&
data['routes'] != null &&
(data['routes'] as List).isNotEmpty) {
final best = data['routes'][0];
// Decode geometry
List<LatLng> geometry;
if (best['geometry'] is String) {
geometry = _decodePolyline(best['geometry'] as String, precision: 6);
} else {
// Assume GeoJSON
final coords = (best['geometry']['coordinates'] as List);
geometry = coords
.map((c) => LatLng(c[1] as double, c[0] as double))
.toList();
}
final result = PowerMapRouteResult(
distance: (best['distance'] as num).toDouble(),
duration: (best['duration'] as num).toDouble(),
geometry: geometry,
steps: _parseSteps(best['legs'] as List),
raw: data,
profile: profile,
);
_drawRoute(result.geometry, fitCamera: fitCamera);
return result;
}
} catch (e) {
debugPrint('PowerMap Routing Error: $e');
rethrow;
}
return null;
}