beerstorm-net / GeoFlutterFire2

🔥GeoFlutterFire2🔥 is an open-source library that allows you to store and query firestore documents based on their geographic location.
https://pub.dev/packages/geoflutterfire2
MIT License
14 stars 40 forks source link

radius isn't working perfectly #20

Open Kalyanb447-github opened 1 year ago

Kalyanb447-github commented 1 year ago

i have 2 location wich difference is 37km but in searching the query where radius is 5 the data is showing

pawlowskim commented 1 year ago

This happen because there is certain level of precision when you split the map into geohashes. More letters geohash contains more precision you get. The library is configured to support certain thresholds, you can find it here Utils.setPrecision from library.

So, if you want to have better precision and actually not querying location from ~ 80km2 you need to lower the radius.

    /*
      * 1   ≤ 5,000km   ×   5,000km
      * 2   ≤ 1,250km   ×   625km
      * 3   ≤ 156km ×   156km
      * 4   ≤ 39.1km    ×   19.5km
      * 5   ≤ 4.89km    ×   4.89km
      * 6   ≤ 1.22km    ×   0.61km
      * 7   ≤ 153m  ×   153m
      * 8   ≤ 38.2m ×   19.1m
      * 9   ≤ 4.77m ×   4.77m
      *
     */

You should use 4.89 radius.

Nanaika commented 1 year ago

How this table of radius working? how can i get items within 1km radius?

pawlowskim commented 1 year ago

You cannot have exact precision, geohashes doesn't work with circular radius. Used radius is taken to calculate closest precision that could be used to get as precise location set as it could be provided. You can play around with this map, and check how it builds the geohash for particular location: https://geohash.softeng.co/ Precision, is basically how many selection you pick. When you stop at 5 selection, you will have rectangle with side length of 4.89 x 4.89. So this is the size of rectagle for each of 9 rectangles that will crop the map to find location in given area. If you go with one more selection, you will end up with rectangle with size 1.22km x 0.61km. And so on. Given that, you want to have 1km radius, I would use 1.22km which will give you rectangle area of 3.66km x 1.83km in which you will find your locations (because there are 1 middle rectangle and 8 surrounding it in the queries under the hood). If. you go one level deeper, you will end up with square of 153m x 153m, which will end up with square area of 459m x 459m, which is half of your requirements.

Geogashes isn't perfect in it's nature, because you cannot have exact values for given range from the center point, unless you will have a high precision and plenty queries shifted by 3 rectangles in each sides until you get your desired results (opposite to calculating distance from lat, long and center point). This is works for firestore, because you don't need to read each document in the database to calculate the distance and return results, which will be too costly if your dataset is big enough. Geohashes allows you to use firestore within it limitations and have decent results.

So, depends on the use case, you need to know how geogashes works and limitations of your database to pick proper solution @Nanaika