Search code examples
iosfirebasefirebase-realtime-databasegisgeofire

Finding points with various radiuses around user location


I'm using Firebase for one of my projects and was wondering if the following would be possible to achieve using Geofire.

I have a list of points with radiuses in which they are available (lat, lng, radius). In the image attached, the blue circle is created by the point and its radius.

I want to find all of the circles that reach user's location (red circle - just a point). The final effect I want to achieve is similar to seeing all the wifi networks around you - some of which might have a stronger signal.

Can it be done using Geofire? If yes, how should I approach the query?

enter image description here


Solution

  • Firebase can't handle a query like this, as you can't have logic in an orderBy. I'm not sure geofire can get around that limitation (from the docs I've browsed it cannot) so then we must come up with another way of doing it. If you know the max size one of the circles can be we might be able to figure out roughly which circles to select.

    (Side note, I'm going to assume you only want things in the top hemisphere, there's a bit more math if you want to handle both but I won't go into details here)

    I'm going to describe roughly how to do it, latitude/longitude are tricky as you move closer to poles and radius does not always translate 1 - 1 with a circle near the equator as it does farther north. For the most part this idea will work but the math for determining the min/max will change as well as the final step where you loop.

    1. Based on the red point and max circle radius create the following variables
      • minLatitude: (red circle latitude) - (max circle radius)
      • maxLatitude: (red circle latitude) + (max circle radius)
      • minLongitutde: (red circle longitude) - (max circle radius)
      • maxLongitutde: (red circle longitude) + (max circle radius)
    2. you'll have to update your databse to have an index that is searchable for each of the blue circles that contains both latitude and longitude with a certain decimal precision.
      • Something like LATITUDE_LONGITUDE.
    3. Do a query like: ... orderByChild('_latitude_longitude').startAt(minLatitude + '_' + minLatitude).endAt(maxLatitude + '_' + maxLongitutde) (don't forget to make sure these all have the same precision)
    4. This will return to you all circles that will be within a max radius of your red circle
    5. You'll then have to loop through all of the circles returned and see if based on their own radius if the red circle is contained (very simple math formula here, plenty of examples online)

    That's the only method I can think of that has no server side processing.