【问题标题】:iPhone: Sorting based on locationiPhone:根据位置排序
【发布时间】:2012-02-16 08:45:16
【问题描述】:

我一直在开发一个 iPhone 应用程序,其中我有一个 NSMutableArray 中的用户列表,如下所示。

myMutableArray: (
    {
        FirstName = Getsy;
        LastName = marie;
        Latitude = "30.237314";
        Longitude = "-92.461008";
    },
    {
        FirstName = Angel;
        LastName = openza;
        Latitude = "30.260329";
        Longitude = "-92.450414";
    },
    {
        FirstName = Sara;
        LastName = Hetzel;
        Latitude = "30.2584499";
        Longitude = "-92.4135357";
    }
)

我需要通过计算纬度和经度,根据我所在位置附近的位置对用户进行排序。直到现在我都无法做到这一点。有人可以帮我提供一些样品吗?

更新:按照 Mr.sch 的建议,我正在尝试如下所示。请检查我更新的代码。还好吗?

    NSArray *orderedUsers = [myMutableArray sortedArrayUsingComparator:^(id a,id b) {
    NSArray *userA = (NSArray *)a;
    NSArray *userB = (NSArray *)b;
    CGFloat aLatitude = [[userA valueForKey:@"Latitude"] floatValue];
    CGFloat aLongitude = [[userA valueForKey:@"Longitude"] floatValue];
    CLLocation *participantALocation = [[CLLocation alloc] initWithLatitude:aLatitude longitude:aLongitude];

    CGFloat bLatitude = [[userA valueForKey:@"Latitude"] floatValue];
    CGFloat bLongitude = [[userA valueForKey:@"Longitude"] floatValue];
    CLLocation *participantBLocation = [[CLLocation alloc] initWithLatitude:bLatitude longitude:bLongitude];

    CLLocation *myLocation = [[CLLocation alloc] initWithLatitude:locationCoordinates.latitude longitude:locationCoordinates.longitude];

    CLLocationDistance distanceA = [participantALocation distanceFromLocation:myLocation];
    CLLocationDistance distanceB = [participantBLocation distanceFromLocation:myLocation];
    if (distanceA < distanceB) {
        return NSOrderedAscending;
    } else if (distanceA > distanceB) {
        return NSOrderedDescending;
    } else {
        return NSOrderedSame;
    }
}];

谢谢!

【问题讨论】:

  • 嘿,Getsy,请参阅下面的我的答案..
  • 您能否验证 myMutableArray 是否为 nil,或者在您添加的代码的第一行之前是否为空。
  • 你太棒了!非常感谢!
  • 不,bLatitude 和 bLongitude 需要使用 userB。

标签: iphone ios sorting


【解决方案1】:
NSArray *orderedUsers = [users sortedArrayUsingComparator:^(id a,id b) {
     User *userA = (User *)a;
     User *userB = (User *)b;
     CLLocationDistance distanceA = [userA.location getDistanceFromLocation:myLocation];
     CLLocationDistance distanceB = [userB.location getDistanceFromLocation:myLocation];
     if (distanceA < distanceB) {
         return NSOrderedAscending
     } else if (distanceA > distanceB) {
         return NSOrderedDescending;
     } else {
         return NSOrderedSame;
     }
}];

【讨论】:

  • 嗨,好的..在我的情况下,(用户 *)a,(用户 *)b 会是什么。我有一组数据。
  • ab 是要比较的两个对象。所以你应该找到一种方法来访问每个对象中的位置,但这取决于你放在数组中的对象类型。
  • OK.. 我有两个问题,1. 'getDistanceFrom' 只不过是 'distanceFromLocation' ? 2. 由于我在 NSMuableArray 中有数据,你认为这段代码会遍历其中的所有数组吗? (或)我必须在里面添加任何 for 循环?
  • 是的,你是对的。 getDistanceFrom 应该是 distanceFromLocation。而关于第二个问题,您不必进行 for 循环,sortedArrayUsingComparator 将遍历所有项目并返回一个排序数组。
  • 好的,那么这是我的问题,我有一个 mutablearray,那么如果我不能循环它(或)像 userB = [mymutablearray objectAtIndex:i] 之类的东西,我该如何给 userB?
【解决方案2】:

首先,您需要计算当前位置与其他用户位置之间的距离。

从数学上讲,这里是Wolfram|Alpha example

现在“programmatic-ally”,你可以使用CLLocation类,这里是一个例子:

(CLLocationDistance)getDistanceFrom:(const CLLocation *)location

但首先您需要根据纬度和经度创建位置对象。您可以使用:

(id)initWithLatitude:(CLLocationDegrees)latitude longitude:(CLLocationDegrees)longitude

【讨论】:

  • 非常感谢!我如何遍历所有用户并将他们的位置与我当前的位置进行比较并整理出来?
  • 您可以使用普通的for loop 遍历所有对象并使用方法:[array objectAtIndex:theIndex];
  • 是的,但是迭代的意思,我需要整理一下。
【解决方案3】:

您可以计算您的位置与每个项目的位置之间的distance (geographical, not flat plane!),并按该值排序。

【讨论】:

  • 您好,感谢您的回复。甚至没有计算,我也想知道如何遍历所有用户并实现这一目标。
【解决方案4】:
You may solve your problem in following way
1)Firstly store all above values in separate array Like latArray ,longArray,nameArray
2)Now get the distance between location(longArray,latArray) from your current location.
Then store these distances in separate Array(distanceArray).

//getDistance Between currentLocation and desired Location
-(void *)getDistanceFromCurrentLocation{  
for(int val=0;val<[latArray count];val++){
NSString *dis_From_Current_Location;
dis_From_Current_Location =nil;

CGFloat str_Longitude=[[defaults objectForKey:@"long"]floatValue];
CGFloat str_Latitude=[[defaults objectForKey:@"lati"]floatValue]; 
   //Suppose this is your current location 

CGFloat lat1= [[latArray objectAtIndex:val]floatValue];
    //these array for lat
CGFloat long1=[[longArray objectAtIndex:val]floatValue];
    //these array for longArray
CLLocation *location1 = [[CLLocation alloc] initWithLatitude:lat1 longitude:long1];
CLLocation *location2 = [[CLLocation alloc] initWithLatitude:str_Latitude longitude:str_Longitude];
CLLocationDistance dist=[location1 distanceFromLocation:location2];
NSLog(@"Distance i meters: %f", [location1 distanceFromLocation:location2]);
long long v = llabs(dist/1000);
dis_From_Current_Location=[NSString stringWithFormat:@"%lld km",v];
[location1 release];
[location2 release];
[distanceArray addObject: dis_From_Current_Location];
//distanceArray is Global NsMutableArray.

}
}

现在您应该应用排序方法(选择,气泡)来对距离进行排序。

需要注意的一点是,当您对 distanceArray 进行排序时 请根据 distanceArray 调整 nameArray 的值 请参阅下面的代码对 distanceArray 进行排序并调整 nameArray 的值。

-(void)getSoretdArray{
NSString * tempStr,*tempStr2;
for(int i=0;i<[distanceArray count]; i++){
    for(int j=i+1;j<[distanceArray count]; j++){
        if([distanceArray objectAtIndex:j]>[distanceArray objectAtIndex:j+1]){
            tempStr=[distanceArray objectAtIndex:j];
            NSString* str= [distanceArray objectAtIndex:j+1];
            [ distanceArray insertObject:str atIndex:j];
            [distanceArray insertObject:tempStr atIndex:j+1] ;
            //also change the name of corresponding location.
            //you have to adjust the stored names in namArray for storing names of Corresponding Distances 
            tempStr2=[nameArray objectAtIndex:j];
            NSString* str1= [nameArray objectAtIndex:j+1];
            [ nameArray insertObject:str1 atIndex:j];
            [nameArray insertObject:tempStr2 atIndex:j+1] ;


        }
    }
}

}

This will definitely work just try to use carefully

【讨论】:

  • 谢谢..但我只是举了一个例子,例如名字,姓氏,纬度和经度等四个字段。实际上我在一个数组中有大约 20 个字段,而可变数组中有大约 50 个这样的数组。
  • 没问题,您可以按照上面的代码进行相同的操作。它会工作的。除此之外,如果您真的认为该答案符合您的要求,请接受或投票。
【解决方案5】:
- (void)viewDidLoad {
    [super viewDidLoad];
// This Array Taken Globally
List_of_locationsArray =[[NSMutableArray alloc]initWithObjects:
  @{@"latitude" : @"17.415045",@"logitude":@"78.421424"} ,@{@"latitude" : @"17.415045",@"logitude":@"78.421424"},@{@"latitude" : @"17.415045",@"logitude":@"78.421424"},@{@"latitude" : @"17.415045",@"logitude":@"78.421424"},@{@"latitude" : @"17.415045",@"logitude":@"78.421424"}
 ,nil];

}

-(void)sortingLocationsArray{
//    CLLocation* currentLocation =[[CLLocation alloc]initWithLatitude:[currentLatitude doubleValue] longitude:[currentLogitude doubleValue]];
      CLLocation* currentLocation =[[CLLocation alloc]initWithLatitude: currentLatitudeHere longitude:CurrentLogHere];

   NSMutableArray* tempLocationsArr = [[NSMutableArray alloc]initWithCapacity:[locationsArray count]];
    for (int i=0; i<[locationsArray count]; i++) {
        CLLocationDegrees latValue = [[locationsArray[i] objectForKey:@"latitude"] doubleValue];
        CLLocationDegrees longValue = [[locationsArray[i] objectForKey:@"logitude"] doubleValue];
        CLLocation* location = [[CLLocation alloc]initWithLatitude:latValue longitude:longValue];
        [tempLocationsArr addObject:location];

        NSArray* sortLocationArry = [tempLocationsArr sortedArrayUsingComparator:^NSComparisonResult(CLLocation* location1, CLLocation* location2) {
            CLLocationDistance distA = [location1 distanceFromLocation:currentLocation];
            CLLocationDistance distB = [location2 distanceFromLocation:currentLocation];
            if (distA < distB) {
                return NSOrderedAscending;
            } else if ( distA > distB) {
                return NSOrderedDescending;
            } else {
                return NSOrderedSame;
            }
        }];

      //ArrayAfterSorting is another mutable Array to Store Sorting Data
        [ArrayAfterSorting removeAllObjects];
        [sortLocationArry enumerateObjectsUsingBlock:^(CLLocation* location, NSUInteger idx, BOOL *stop) {
            NSMutableDictionary *tempDict = [[NSMutableDictionary alloc]init];
            [tempDict setObject:[NSString stringWithFormat:@"%f",location.coordinate.latitude] forKey:@"latitude"];
            [tempDict setObject:[NSString stringWithFormat:@"%f",location.coordinate.longitude] forKey:@"logitude"];
            [ArrayAfterSorting addObject:tempDict];


        }];
     NSLog(@"sortedArray : %@", ArrayAfterSorting);
    }

}

【讨论】:

  • 问题是什么?
  • 这里我将位置列表与当前位置相对应...
猜你喜欢
  • 2016-10-03
  • 1970-01-01
  • 2021-06-10
  • 2023-03-31
  • 2015-12-09
  • 2012-09-14
  • 2011-09-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多