Reputation:
Currently i have an iPhone app for which is basically a city guide. It shows the user different things around them and lists them in order of distance.
At the moment the data for the app is in an online MySQL database, a php script then converts different parts of this database, such as banks, into XML documents, so i have an XML document for banks, one for bars etc. Each XML document has its own URL.
My iPhone app then reads the XML document from the URL, parses the XML document, and then using CoreLocation calculates the distance between each location in the XML document and the user, then puts the data into TableViews sorted by distance, with closest first. (It may be worth noting that each piece of data (bar, bank etc) in the database has coordinates attached).
This is working fine and there are no problems when there is up to a few hundred locations to parse and calculate distances. However once you start getting into the thousands it starts to take a long time.
Basically i am wondering if anyone knows a method where rather than downloading all the data then calculating distances i could send the phones GPS location to the server/database or whatever and then it returns the closest 20 locations which i could then parse and display as before.
I know this is a BIG question im not looking for someone to help me create everything i just need to know a method on how this can be done. Or if anyone has done anything similar to this.
Thanks in advance.
Upvotes: 0
Views: 859
Reputation: 5157
You've pretty much defined the method for doing this right in your question. What you need is to pass the user's coordinates into the web service. The web service or stored procedure should implement the logic to filter the results to only things nearby. If there is a specific part of that you need advice on, please clarify.
You should really let the database engine do the heavy lifting here. In mySQL you'd use something like this:
SELECT ((ACOS(SIN($lat * PI() / 180) * SIN(lat * PI() / 180) +
COS($lat * PI() / 180) * COS(lat * PI() / 180) * COS(($lon - lon) *
PI() / 180)) * 180 / PI()) * 60 * 1.1515) AS distance
FROM members
HAVING distance<='10' ORDER BY distance ASC
Here is some AFNetworking code for a get request for JSON with parameters NOTE (This is a snippet of the most relevant code and will not execute stand-alone):
NSString *latString = [NSString stringWithFormat:@"%f", lastLocation.coordinate.latitude];
NSString *lonString = [NSString stringWithFormat:@"%f", lastLocation.coordinate.longitude];
NSString *accString = [NSString stringWithFormat:@"%f", lastLocation.horizontalAccuracy];
NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:[defaults valueForKeyPath:@"sessionRP"] , @"sessionRP", [defaults valueForKeyPath:@"partnerID"], @"pid", appointment.scheduleRowPointer, @"srp", latString, @"lat", lonString, @"long", status, @"stat", @"0", @"cached", accString, @"acc", nil];
NSMutableURLRequest *request = [httpClient requestWithMethod:@"GET" path:myPath parameters:params];
[request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
Upvotes: 1