umpire274
umpire274

Reputation: 23

Sort a NSMutableArray of location with my GPS position

I want to sort a NSMutableArray, where each row is a NSMutableDictionary, with my GPS position from CoreLocation framework.

This is an example of my array of POI

arrayCampi = (
{
    cap = 28100;
    "cell_phone" = "";
    championship = "IBL 1D";
    citta = Novara;
    division = "";
    email = "";
    fax = 0321457933;
    indirizzo = "Via Patti, 14";
    latitude = "45.437174";
    league = "";
    longitude = "8.596029";
    name = "Comunale M. Provini";
    naz = Italy;
    prov = NO;
    reg = Piemonte;
    sport = B;
    surname = "Elettra Energia Novara 2000";
    telefono = 03211816389;
    webaddress = "http://www.novarabaseball.it/";
})

I need to sort this array with my location (lat and long) with field 'latitude' and 'longitude' of each row in ascending mode (first row is POI nearest to me).

I have tried this solution without success:

+ (NSMutableArray *)sortBallparkList:(NSMutableArray *)arrayCampi location:(CLLocation *)myLocation  {

    if ([arrayCampi count] == 0) {
        return arrayCampi;
    }

    if (myLocation.coordinate.latitude == 0.00 &&
        myLocation.coordinate.longitude == 0.00) {
        return arrayCampi;
    }

    NSMutableArray *sortedArray = [NSMutableArray arrayWithArray:arrayCampi];

    BOOL finito = FALSE;
    NSDictionary *riga1, *riga2;

    while (!finito) {
        for (int i = 0; i < [sortedArray count] - 1; i++) {

            finito = TRUE;
            riga1 = [sortedArray objectAtIndex: i];
            riga2 = [sortedArray objectAtIndex: i+1];

            CLLocationDistance distanceA = [myLocation distanceFromLocation:
                                            [[CLLocation alloc]initWithLatitude:[[riga1 valueForKey:@"latitude"] doubleValue]                                             
                                                                      longitude:[[riga1 valueForKey:@"longitude"] doubleValue]]];
            CLLocationDistance distanceB = [myLocation distanceFromLocation:
                                            [[CLLocation alloc]initWithLatitude:[[riga2 valueForKey:@"latitude"] doubleValue]
                                                                      longitude:[[riga2 valueForKey:@"longitude"] doubleValue]]];
            if (distanceA > distanceB) {
                [riga1 retain];
                [riga2 retain];

                [sortedArray replaceObjectAtIndex:i+1 withObject:riga2];
                [sortedArray replaceObjectAtIndex:i withObject:riga1];

                [riga1 release];
                [riga2 release];

                finito = FALSE;
            }
        }
    }

    return sortedArray;
}

Can anyone help me, also with other solution?

Alex.

Upvotes: 0

Views: 493

Answers (3)

Mundi
Mundi

Reputation: 80273

Sorting by lat and long will not give you the nearest location from any given coordinates. As an approximation*) you could use Pythagoras (you learned that in high school, remember?):

float distance = sqrtf(powf((origLat-destLat),2)+powf((origLon-destLon), 2));

Simply add that to your dictionary with key @"distance" and sort with

NSArray *sorted = [arrayOfDictionaries sortedArrayUsingDescriptors:
     @[[NSSortDescriptor sortDescriptorWithKey:@"distance" ascending:YES]]];

*) It's an approximation because theoretically distance between two points is a curved line on the surface of an ellipsoid.

Upvotes: 2

makaron
makaron

Reputation: 1615

I think there's no need to implement your own sorting algorithm. There are the ready ones out there :-) I would suggest to look at NSSortDescriptor.

And since you keep your geo coordinates in NSString format, and not the NSNumber, you probably would need to write your own NSPredicate for NSString objects comparison in your class. (I don't remember if @"123" is greater than @"1.23", I mean special symbol '.')

Upvotes: 0

Parag Bafna
Parag Bafna

Reputation: 22930

[arrayCampi sortedArrayUsingSelector:@selector(compare:)];

   - (NSComparisonResult)compare:(NSDictionary *)otherObject {

    if ([[self objectForKey:@"key"] isEqual:[otherObject objectForKey:@"key"]]) {
        return NSOrderedSame;
    }
    else if (//condition) {
        return NSOrderedAscending;
    }
    else {
        return NSOrderedDescending;
    }
}

Take a look at How to sort an NSMutableArray with custom objects in it?

Upvotes: 0

Related Questions