4

I've got an sqlite db with long and lat of shops and I want to find out the closest 5 shops.

So the following code works fine.

    if(sqlite3_prepare_v2(db, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {


    while (sqlite3_step(compiledStatement) == SQLITE_ROW) {

        NSString *branchStr = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 0)];
        NSNumber *fLat = [NSNumber numberWithFloat:(float)sqlite3_column_double(compiledStatement, 1)];
        NSNumber *fLong = [NSNumber numberWithFloat:(float)sqlite3_column_double(compiledStatement, 2)];

        NSLog(@"Address %@, Lat = %@, Long = %@", branchStr, fLat, fLong);
        CLLocation *location1 = [[CLLocation alloc] initWithLatitude:currentLocation.coordinate.latitude longitude:currentLocation.coordinate.longitude];
        CLLocation *location2 = [[CLLocation alloc] initWithLatitude:[fLat floatValue] longitude:[fLong floatValue]];

        NSLog(@"Distance i meters: %f", [location1 getDistanceFrom:location2]);
        [location1 release];
        [location2 release];
    }       
}

I know the distance from where I am to each shop. My question is.

  1. Is it better to put the distance back into the sqlite row, I have the row when I step thru the database. How do I do that? Do I use the UPDATE statement? Does someone have a piece of code to help me.

  2. I can read the sqlite into an array and then sort the array. Do you recommend this over the above approach? Is this more efficient?

Finally, if someone has a better way to get the closest 5 shops, love to hear it.

munchine
  • 479
  • 1
  • 9
  • 23

2 Answers2

5

The fastest way to find nearby locations in SQL is to use the Haversine formula in an SQL query. Do a Google search for sqlite and Haversine and you'll find an implementation.

Here's one I've used before:

http://www.thismuchiknow.co.uk/?p=71

nevan king
  • 112,709
  • 45
  • 203
  • 241
  • nevan, I like your answer. I had successfully implemented the solution using an array, but I definitely will use your suggestion in future. – munchine Jun 02 '10 at 02:44
  • AAA answer! I've used the following query to retrieve the distance result as well: "SELECT Hotel.*,distance(Hotel.Latitude, Hotel.Longitude, 123.45, 123.45) AS Distance FROM Hotel ORDER BY Distance" – Gilad Novik Dec 14 '11 at 05:30
  • @GiladNovik that Distance function might work on other SQL engines, but definitely not on SQLite. – xarlymg89 Aug 08 '18 at 15:17
  • Add an example instead of a link, which on this case is broken. – Marco Blos Apr 28 '22 at 06:35
0

you have to run through every element only once so the complexity is fairly good. you need a kind of fixed size Deque-container, a kind of linked list or a fixed size array, fixed by the size of 5, the number of shops you want to get from every point. add always the shop with the most minimal distance to the Deque. after running through your db you are have the nearest 5 shops in your deque.

OlimilOops
  • 6,747
  • 6
  • 26
  • 36
  • Hi Oopz, there's under 100 shops, so I decided to sort the entire array and drop the all the pins on the map. It's pretty fast. I then highlight the closest shop with a call out. Using this method, if the user zooms out or pan, they will see all the shops. – munchine Jun 02 '10 at 02:45