Utkarsh Singh
Utkarsh Singh

Reputation: 377

Unable to find the distance between current location and destination location

I am stuck in handling future and getting distance on extracting address from Firebase and displaying on the marker, though I have managed to write some code for getting the current user location, calculating the distance, and converting the address to LatLng but still I am facing difficulties.

Below I have attached my code and also highlighted where I want to calculate the distance( Inside widget setMapPins() )

I have stored the addresses inside collection shops and document named Address in firebase

Please help me to calculate the distance inside Streambuilder and display it on the marker. Thanks in Advance.

This is the link to my complete map.dart file

'necessary imports'
'necessary initialization'

  _getCurrentLocation() async {
    await _geolocator
        .getCurrentPosition(desiredAccuracy: LocationAccuracy.high)
        .then((Position position) async {
      setState(() {
        _currentPosition = position;
        sourceLocation =
            LatLng(_currentPosition.latitude, _currentPosition.longitude);
        print('CURRENT POS: $_currentPosition');
        mapController.animateCamera(
          CameraUpdate.newCameraPosition(
            CameraPosition(
              target: LatLng(position.latitude, position.longitude),
              zoom: 14.0,
            ),
          ),
        );
      });
      await _getAddress();
    }).catchError((e) {
      print(e);
    });
  }

  // Method for retrieving the address
  _getAddress() async {
    try {
      List<Placemark> p = await _geolocator.placemarkFromCoordinates(
          _currentPosition.latitude, _currentPosition.longitude);

      Placemark place = p[0];

      setState(() {
        _currentAddress =
            "${place.name}, ${place.locality}, ${place.postalCode}, ${place.country}";
        startAddressController.text = _currentAddress;
        _startAddress = _currentAddress;
      });
    } catch (e) {
      print(e);
    }
  }

  // Method for calculating the distance between two places
  Future<bool> _calculateDistance() async {
    try {
      // Retrieving placemarks from addresses
      List<Placemark> startPlacemark =
          await _geolocator.placemarkFromAddress(_startAddress);
      List<Placemark> destinationPlacemark =
          await _geolocator.placemarkFromAddress(_destinationAddress);

      if (startPlacemark != null && destinationPlacemark != null) {

        Position startCoordinates = _startAddress == _currentAddress
            ? Position(
                latitude: _currentPosition.latitude,
                longitude: _currentPosition.longitude)
            : startPlacemark[0].position;
        Position destinationCoordinates = destinationPlacemark[0].position;

        await _createPolylines(startCoordinates, destinationCoordinates);

        double totalDistance = 0.0;

        // Calculating the total distance by adding the distance
        // between small segments
        for (int i = 0; i < polylineCoordinates.length - 1; i++) {
          totalDistance += _coordinateDistance(
            polylineCoordinates[i].latitude,
            polylineCoordinates[i].longitude,
            polylineCoordinates[i + 1].latitude,
            polylineCoordinates[i + 1].longitude,
          );
        }

        setState(() {
          _placeDistance = totalDistance.toStringAsFixed(2);
        return true;
      }
    } catch (e) {
      print(e);
    }
    return false;
  }
 // formula

  double _coordinateDistance(lat1, lon1, lat2, lon2) {
    var p = 0.017453292519943295;
    var c = cos;
    var a = 0.5 -
        c((lat2 - lat1) * p) / 2 +
        c(lat1 * p) * c(lat2 * p) * (1 - c((lon2 - lon1) * p)) / 2;
    return 12742 * asin(sqrt(a));
  }

  // Create the polylines for showing the route between two places
  _createPolylines(start, destination) async {
    polylinePoints = PolylinePoints();
    List<PointLatLng> result = await polylinePoints.getRouteBetweenCoordinates(
      googleAPIKey, // Google Maps API Key
      start.latitude, start.longitude,
      destination.latitude, destination.longitude,
    );

    if (result.isNotEmpty) {
      result.forEach((PointLatLng point) {
        polylineCoordinates.add(LatLng(point.latitude, point.longitude));
      });
    }
  }

  Widget setMapPins() {

    return StreamBuilder(
        stream: Firestore.instance.collection('shops').snapshots(),
        builder: (context, snapshot) {
          if (!snapshot.hasData) return Text('Loading maps... Please Wait');
          for (int i = 0; i < snapshot.data.documents.length; i++) {
            print(snapshot.data.documents[i]);


         ///  here i want to calculate distance by extracting address from Firebase and then displaying on marker 

          }
          return Container();
        });
  }


  @override
  void initState() {
    super.initState();
    _getCurrentLocation();
  }

Upvotes: 1

Views: 1694

Answers (1)

Madhavam Shahi
Madhavam Shahi

Reputation: 1192

To reduce the complexity of your code,you can use this function to calculate the distance between 2 points.(..in GeoLocator package)

double distanceInMeters =Geolocator().distanceBetween(lat1, long1,lat2,long2);

UPDATE 2:-

make a function to do the async task,

var distInMeters;

getDist({var latt,var longg}) async{


distanceInMeters = await Geolocator().distanceBetween(latt, longg,lat2,long2);// lat2 and long2 are global variables with current user's location


}

In your Streambuilder,

StreamBuilder(
    stream: Firestore.instance.collection('shops').snapshots(),
    builder: (BuildContext context,
        AsyncSnapshot<List<DocumentSnapshot>> snapshots) {
      if (snapshots.connectionState == ConnectionState.active &&
          snapshots.hasData) {
        print(snapshots.data);
        return ListView.builder(
          itemCount: snapshots.data.length,
          itemBuilder: (BuildContext context, int index) {
            DocumentSnapshot doc = snapshots.data[index];
Map yourdata= doc.data; 
/*
Here, you can get latitude and longitude from firebase, using keys,based on your document structure.
Example, var lat=yourdata["latitude"];
var long=yourdata["longitude"];

Now, you can calculate the distance,

getDist(latt:lat,longg:long);

 here lat2 and long2 are current user's latitude and longitude.
print(distInMeters);
*/
            return Text("please upvote and accept this as the answer if it helped :) "),
            );
          },
        );
      } else {
        return Center(child: CircularProgressIndicator());
      }
    },
  ),

Upvotes: 2

Related Questions