2

I've got a collection in my firebase firestore database called 'bakeries' and inside the collection has a series of documents, each with a geopoint field, where I typed in their latitudes and longitudes. To access them and see the nearest bakeries to the users, I created a ListView.builder. But, I'm trying to sort the bakeryList by its geopoint in relation to the user's current location and it's not working. I've tried this:

bakeryList.sort((a, b){
  return a['geopoint'].compareTo(myLocation);
});

But it's not returning the nearest bakeries. Any ideas would be hugely appreciated!

  final userLocation = Geolocator().getCurrentPosition(desiredAccuracy: LocationAccuracy.high);

StreamSubscription<QuerySnapshot> subscription;
  List <DocumentSnapshot> bakeryList;

  final Query collectionReference = Firestore.instance.collection(('bakeries'));

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

    final myLocation = Geolocator().getCurrentPosition(desiredAccuracy: LocationAccuracy.high);

    subscription = collectionReference.snapshots().listen((data) {
      setState(() {
        bakeryList = data.documents;

      });
    });

  }



  @override
  Widget build(BuildContext context) {


    return bakeryList != null ?

    ListView.builder(

            itemCount: bakeryList.length,
            itemBuilder: (context, index){

          String imgPath = bakeryList[index].data['image'];
          String bakeryTextPath = bakeryList[index].data['name'];
          String locationNamePath = bakeryList[index].data['location name'];
          GeoPoint geoPointPath = bakeryList[index].data['geopoint'];
          final geolocation = Text('${geoPointPath.latitude}, ${geoPointPath.longitude}');

          return BakeryCard(
            etaText: '${geoPointPath.latitude}, ${geoPointPath.longitude}',
            locationText: locationNamePath,
            merchantText: bakeryTextPath,
            assetImage: Image.network(imgPath),

            function: (){});
        })
        : Center(child: CircularProgressIndicator(),
    );

  }
James Piner
  • 199
  • 1
  • 4
  • 17

3 Answers3

4

I think your problem is in your sort function:

bakeryList.sort((a, b){
  return a['geocode'].compareTo(myLocation);
});

Here you are just comparing the position of the first bakery with the user's location. I think what you really want is something like:

bakeryList.sort((a, b){
  return distance(a['geocode'], myLocation).compareTo(distance(b['geocode'], myLocation));
});

where the function distance gives you the distance between two points.

Diviloper
  • 41
  • 4
2

In addition to Diviloper's answer, please use the following function to sort items as per distance :

    double calculateDistance(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));
  }

This will ensure accurate results.

Note : Import following

import 'dart:math' show cos, sqrt, asin;
ishallwin
  • 300
  • 2
  • 17
0

Sorry, it’s not a straight answer to your question, but you may want to try a GeoFlutterFire. It’s super optimized to work with this type of data, and getting a list of the nearest locations is very simple. Link to the package GeoFlutterFire.

i6x86
  • 1,557
  • 6
  • 23
  • 42