Search code examples
fluttermapquestgoogle-maps-flutter

How to use MapQuest Directions API To Draw Rout From One Location To Another in Flutter


I'm currently developing a flutter a taxi application and I want to use MapQuest API for the applications to get the locations names and to draw route from one point to another.

The problem is that calling the API and getting the locations works fine but the route is showing on the map in a really weird way.

Here is the provider code for calling the API and getting the route locations points:

class MapQuestDataProvider {
  Future<MapQuestDirection> getDirections(
      LatLng Source, LatLng Destination) async {
    try {
      MapQuestDirection result = MapQuestDirection(locations: []);

      var aPIKey = "[API_KEY]";
      var url =
          "https://www.mapquestapi.com/directions/v2/optimizedroute?key=$aPIKey&json={\"locations\":[\"${Source.latitude},${Destination.longitude}\",\"${Destination.latitude},${Source.longitude}\"]}";

      var uri = Uri.parse(url);
      final response = await http.get(uri);
      if (response.statusCode == 200) {
        final data = jsonDecode(response.body);
        var route = data["route"];
        var legs = route["legs"];
        var zero = legs[0];
        var maneuvers = zero["maneuvers"] as List;

        for (var element in maneuvers) {
          var startPoint = element["startPoint"];
          var lat = startPoint["lat"];
          var lng = startPoint["lng"];
          result.locations.add(LatLng(lat, lng));
        }

        return result;
      } else {
        throw Exception('Failed to load Locations');
      }
    } catch (e) {
      print("Exception throuwn $e");
      throw e;
    }
  }
}

Here is the code for my Map Widget:

class MapWidget extends StatefulWidget {
  MapWidget(
      {Key? key,
      this.currentLocation,
      required this.onTab,
      required this.markers,
      this.endLocation,
      required this.polylines})
      : super(key: key);
  LatLng? currentLocation;
  void Function(LatLng) onTab;
  Set<Marker> markers = {};
  LatLng? endLocation;
  Map<PolylineId, Polyline> polylines = {};

  @override
  State<MapWidget> createState() => _MapWidgetState();
}

class _MapWidgetState extends State<MapWidget> {
  GoogleMapController? mapController;
  final defaultMapZooming = 18.0;

  @override
  Widget build(BuildContext context) {
    return Container(child: mapView(context));
  }

  Widget mapView(BuildContext context) {
    if (mapController != null && widget.currentLocation != null) {
      mapController!.animateCamera(CameraUpdate.newLatLngZoom(
          LatLng(widget.currentLocation!.latitude,
              widget.currentLocation!.longitude),
          defaultMapZooming));
    }

    var map = GoogleMap(
      onMapCreated: onMapCreated,
      zoomControlsEnabled: false,
      myLocationEnabled: false,
      mapType: MapType.normal,
      onLongPress: (loc) {
        widget.onTab(loc);
      },
      markers: widget.markers,
      polylines: widget.polylines.values.toSet(),
      minMaxZoomPreference: const MinMaxZoomPreference(12, 25),
      initialCameraPosition: CameraPosition(
        target: getLocationOrDefault(),
        zoom: defaultMapZooming,
      ),
      onCameraMove: (CameraPosition cameraPosition) {
        print("ZOOOOOOOOOOOOOOOOOOOM IS : " + cameraPosition.zoom.toString());
      },
    );
    return map;
  }

  onMapCreated(GoogleMapController controller) {
    mapController = controller;
  }

  getLocationOrDefault() {
    return widget.currentLocation ??
        const LatLng(21.215415017175165, 72.8879595194489);
  }
}

And Here is the code that gets called by placing a new marker on the map which draws the polygon that will be sent to the Map Widget after state update:

  SetPathFromMapQuestData(List<LatLng> Locations) {
    PolylinePoints polylinePoints = PolylinePoints();
    Set<Marker> markers = Set(); //markers for google map

    LatLng startLocation = this.startLocation!;
    LatLng endLocation = this.endLocation!;

    double distance = 0.0;

    List<LatLng> polylineCoordinates = [];

    //polylineCoordinates.add(this.startLocation!);
    Locations.forEach((LatLng point) {
      polylineCoordinates.add(point);
    });

    polylineCoordinates.insert(0, this.startLocation!);
    polylineCoordinates.add(this.endLocation!);

    PolylineId id = PolylineId("poly");
    var poly = GetPloylineId(polylineCoordinates, id);

    polylines[id] = poly;

    setState(() {
      this.polylines = polylines;
    });
  }
  Polyline GetPloylineId(List<LatLng> polylineCoordinates, PolylineId id) {
    Polyline polyline = Polyline(
      polylineId: id,
      color: Colors.deepPurpleAccent,
      points: polylineCoordinates,
      width: 8,
    );
    return polyline;
  }

This is the result: The Result Map Image


Solution

  • After working for hours I moved to MapBox and it works perfectly. Here is the link for the Api: https://docs.mapbox.com/android/navigation/guides/