RouteDetails.fromMapboxRoute constructor
//////////// //////////// Builds RouteDetails from Mapbox route data with robust parsing
Implementation
// II.C - Factory Methods
///////////////
/// Builds RouteDetails from Mapbox route data with robust parsing
factory RouteDetails.fromMapboxRoute(Map<String, dynamic>? routeData) {
try {
if (routeData == null) {
throw StateError('Route data is null');
}
// Safely extract the first route
final routes = routeData['routes'] as List?;
if (routes == null || routes.isEmpty) {
throw StateError('No routes found in response');
}
final route = routes[0] as Map<String, dynamic>?;
if (route == null) {
throw StateError('Route data is invalid');
}
// Parse geometry with error handling
final geometry = route['geometry'] as Map<String, dynamic>? ?? {};
final coordinates = geometry['coordinates'] as List? ?? [];
// Parse route points with type conversion
final points = <RaliPosition>[];
for (final coord in coordinates) {
if (coord is List && coord.length >= 2) {
try {
points.add(RaliPosition(
(coord[0] as num?)?.toDouble() ?? 0.0,
(coord[1] as num?)?.toDouble() ?? 0.0
));
} catch (e) {
print('Error parsing coordinate: $e');
}
}
}
if (points.isEmpty) {
throw FormatException('No valid coordinates found');
}
// Parse first leg for steps and metadata
final legs = route['legs'] as List?;
if (legs == null || legs.isEmpty) {
throw StateError('No route legs found');
}
final leg = legs[0] as Map<String, dynamic>? ?? {};
// Parse navigation steps with error handling
final stepsList = leg['steps'] as List? ?? [];
final steps = <NavigationStep>[];
for (final step in stepsList) {
if (step is Map<String, dynamic>) {
try {
final navStep = NavigationStep.fromMapboxStep(step);
steps.add(navStep);
} catch (e) {
print('Error parsing navigation step: $e');
}
}
}
// Parse additional data
final speedLimits = _parseSpeedLimits(route['maxspeed'] as List?);
final hazards = _parseHazards(route['hazards'] as List?);
final landmarks = _parseLandmarks(route['landmarks'] as Map<String, dynamic>?);
// Calculate bounding box
final bounds = _calculateBounds(points);
return RouteDetails(
points: points,
distance: _safeConvertToDouble(leg['distance'], 0.0),
duration: _safeConvertToDouble(leg['duration'], 0.0),
steps: steps,
bounds: bounds,
trafficAnnotations: route['annotations'] as Map<String, dynamic>?,
speedLimits: speedLimits,
hazards: hazards,
landmarks: landmarks,
);
} catch (e) {
print('Error parsing route details: $e');
// Fallback to default route details
return RouteDetails(
points: [],
distance: 0.0,
duration: 0.0,
steps: [],
bounds: BoundingBox(
southwest: RaliPosition(0.0, 0.0),
northeast: RaliPosition(0.0, 0.0)
),
);
}
}