RouteDetails.fromMapboxRoute constructor

RouteDetails.fromMapboxRoute(
  1. Map<String, dynamic>? routeData
)

//////////// //////////// 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)
      ),
    );
  }
}