Does Google Firestore and/or their Realtime DB have the querying capability to get posts by location (within x miles), order by date, and limit? - ios

I am currently using Firestore for my iOS app and I need to implement a scalable solution for my posts feed. I need to get posts within say 20 miles, order them by date, and limit the amount of posts fetched for pagination. Any and all database solutions would very much appreciated! Thank you!

As a low budget/time alternative to libraries, we have implemented storing the first few digits of lat/long coordinates as a document or collection name and then accessed data that way. The first decimal place gives resolution to around 10 miles or so (exact values for longitude change depending on what latitude you are at). So in your database you could have a collection or document named something like +33.6-112.0. This would mark a reference in Firestore to put all data within (33.8 N, 112.0 W). Be careful with how you round the exact location data before placing it in the respective document or collection.
Then you can retrieve all data at any location you want. This may not give you exactly 20 miles, but some client side sorting can handle that. Note you could make the reference go to any decimal place necessary to achieve the level of precision you are looking for to minimize data base calls (to save you money) and minimize impact on the user's cell data plan.
This is a rather simple solution with limitations, maybe for an MVP, and if not careful could pull way more data than anticipated.
Below is a chart showing the approximate physical distance between each decimal place at the equator. So for example, the distance between (33.3 N, 0 W) and (33.5 N, 0 W) would be about 14 miles.

Neither of those databases have native geospatial querying capabilities. You would have to use some sort of add-on library to help with that. Geofire and Geofirestore are popular for this.

Related

Fast/Efficient way to determine closest location from collection

I am thinking about how to structure the data within my app and one of the most important lookups will be closest location from a collection of location (10,000+ locations) and I'm looking for the fastest and most efficient way to do this.
Ideas I have:
Use Core Data and store cllocations or doubles, query with a predicate to order by closest to reference location
Store them in an sqlite database and use the distance formula in sql query
Load all locations into memory into some sort of a data structure (array, linked list, hashmap, etc.) and compute the distance a different way
Of these solustions, which would be the fastest/most efficient? Or is there another solution you would recommend?
As others have mentioned, you can't sort by a calculated value with Core Data, so a query for the closest location is unfortunately out. I've used the following "boxing" approach to approximate that, which might or might not meet your needs:
Calculate a box around the target location. The offset in degrees is something you'll need to work out, but the Wikipedia article on decimal degrees can be a good starting point. Offset your target by +/- some number of degrees to get a rough rectangle.
Fetch every location within that rectangle.
Sort the results in memory to find the closest result.
If you want to make one request for the closest location, you'll probably have to work with SQLite directly. I wouldn't load all of the points into memory without a careful examination of the total memory impact of doing so, and an understanding of how much memory your app is using for other reasons at the same time.

Is it possible to create a choropleth map solely from a set of long/lat coordinates?

I'd like to visualize a number of points on a map. Unfortunately, there is no consistent address associated with each one. I've used Google Fusion tables to get a rough read on where the points are, and am relatively satisfied with the approximate locations of most points (sometimes Google figures out where they're located based on a landmark, sometimes based on an intersection provided, sometimes by street address, etc.).
My goal, then, is to create a choropleth map of a city (NYC, in this case), showing the number of points located in each neighbourhood. Is it possible to do this by somehow counting the number of points that fall within each neighbourhood?
I suspect that if fusion tables give me a passable visual, I may be able to use google's geocoding service in the same manner to figure out the number of points in each area, and use this to then build a choropleth (not a heat map — I'm after some level of interaction, like tooltips over each neighbourhood).
Is there any way to do this, or am I way, way off?

Splitting a city into zones, is it a good idea?

I'm working on a geolocation based personal project where I'd like to fetch the suppliers based on the user's latitude & longitude value. And the deal is suppliers have variable supply radius, few suppliers supply only within 5km of their radius while some may supply across the entire city.
The general way to go about this is for each supplier calculate the distance between the supplier & the user. If it is less than or equal to it's supply radius then display that supplier in the results.
But this might be very slow, so I thought I'd split the city into four zones(pick four latitude & longitude values from google maps for North East West South) & whenever a supplier is added I'll do the math & assign the zones to which they can supply in the database. Now whenever I get the user's latitude & longitude I'd determine the zone & fetch suppliers that can supply to that zone, do the distance calculation & filter them out. This way I do the calculation on less number of suppliers instead of the entire list.
But is it a good idea or can I do better ?
In you are using Postgres/Postgis, you can make use of spatial indexes, and then use ST_DWithin(geom1, geom2, distance) type queries see ST_DWithin docs. The spatial index will partition the space for you, making this kind of query very efficient and avoid you having to come up with any spatial partitioning scheme of your own.
Another operator you can use is the <-> operator, which is very efficient with a spatial index and is used in the order by clause, to get the nearest y things to some point x, (k nearest neighbour search) see <-> operator docs. One caveat for this operator to work properly with the index, the point you are searching for, needs to be a constant, as it sounds like it would be in your case.

How to determine which city a given long and latitude points represent?

I'm currently using a very large geo-ip database that i've built as a mixture from many freeware sites.
The problem is - the mapping of all those database is : map: (ip) -> (latitude,long)
I'm looking for a way that will deduce the location of those latitude and long points by resolution of a city and if possible - offline.
thanks
You may want to try Google Geocoding http://code.google.com/intl/en/apis/maps/documentation/geocoding/
to do it offline, you'll need a database of long/lat coordinates, such as this: http://www.maxmind.com/app/worldcities
then to match the long/lat to the cities, you'll have to build an algorithm which narrows it down to within a margin of error.
a brute-force method might be to measure the distance by using pythagoras' theorem, but that would rapidly kill your CPU. a better way may be to start by excluding results that are 1 or more above or below your target lat/long, then do your measurements on the remaining results.
you can get city and region lat/lon information from citycsv.com if you really need your info offline. It would be easy to query the data for lat/lon and get a city or region back. However as stated google would be able to take a lot of overhead off your hands with their online geocoding tools.
you could run google's geocode in burst-mode (2.500 max per day) through a cron job and fill up your offline database over the course of ....

Lookup telephone area code by latitude and longitude

Looking for a way to get a list of telephone area codes for a given latitude and longitude (and if necessary a given intl. code.) Note, I'm not talking about international dialing prefixes but the area codes within them.
For example, Denver Colorado is covered by the area codes 303 and 720. It's at 39.739 -104.985 and is in NANP 1. So given 39.739,-104.985,1 I'd like to get back [303,720].
Libraries, web services, DB's, or raw data that needs to be parsed into a DB, e.g., a web page of shape points, are all fine and the more global coverage the better, but just NANP 1 would be a great help.
Note I already use MaxMind and could turn the lat-lng into a fake IP and use that as the lookup key, but MaxMind claims only U.S. area codes (whether they truly mean U.S. or actually NANP I haven't tested) and seemingly only 1 per location (e.g. just 303 for Denver.) So it's a possibility, just not a great one.
UPDATE: I found some more relevant information, but no definitive solutions so I'm listing it here rather than in an answer:
I was able to find two U.S. databases http://www.area-codes.com/area-code-database.asp and http://www.nationalnanpa.com/area_codes/index.html (50% down the page, MS Access file.) The former includes lat/lng for $450 and the latter would require nearest-neighbor matching as KeithS talks about (it's probably the same DB underlying the NANPA City Query he found.)
Additionally I found information that implies Teleatlas has area code boundary maps and that ESRI includes area code shape files with copies of ArcGIS. Maponics seems to have data available: there's a Google Maps implementation of Maponics' data at http://www.usnaviguide.com/areacode.htm.
Wow. You'll definitely need some sort of pre-existing database of points. My first thought was ZIPList5 Geocode. It includes lat-long data for each active U.S. ZIP code, so you can throw this data in a DB table, index the hell out of it, and search by just about any geographic info you'd have access to. You can buy one copy for $40, with enterprise-level use for $100. Only problem is that this DB has only the "primary" area code for each ZIP code, so metro areas that have more than one (Dallas, Chicago, NYC) aren't going to show all of them.
You could try a two-pronged approach with some free data I found: for a given latitude and longitude, do a nearest-neighbors search of the data in the USGS Geographic Names Information System; it includes information on every human habitation center, and every named landmark feature, with lat/long coordinates of their centers. You now have your lat/long point mapped to the nearest town/city, ZIP code, county, and state. Now, you can compare that against this list of U.S. Area Codes, to find area codes matching any or all of the identifying information from the USGS. This is all free, and will eventually get you what you need, but you'll probably have to do some work to "massage" the two sets of data into something you can efficiently cross-reference, and/or you'll need to implement a good "search engine" that will accurately find nearest-neighbor named points, and then find area codes for locations matching the names.
One more thing to look at is NANPA, which administers area code assignment to begin with. I'm sure they have a more comprehensive downloadable DB, but the only free public access I could find was this search page, which will find area codes for any city with >20k people. You could turn your lat/long data into a city and state, and then hit this search page: NANPA City Query
Here is an option:
http://geocoder.ca/39.739,-104.985?geoit=xml
<TimeZone>America/Denver</TimeZone>
<AreaCode>720,303</AreaCode

Resources