根据 lat 和 long 得到错误的排序距离

Posted

技术标签:

【中文标题】根据 lat 和 long 得到错误的排序距离【英文标题】:Getting the wrong sorted distance on the basis of lat and long 【发布时间】:2013-06-03 12:12:49 【问题描述】:

我在我的应用程序中遇到了非常奇怪的问题,有一个部分我正在从服务器收集数据,作为回应,我通过使用这些 lat 和 long 我得到了附近所有餐馆的 lat 和 long我正在获取每个用户与当前用户位置的距离,并且我已经在收集的数据上应用了像壁橱一样的排序,使其离当前用户位置更远,一切正常,但是每当客户在他的最后测试这个时,排序就不会不行。我在这里附上了代码。

- (void)viewDidLoad

    [super viewDidLoad];

    myDelegate= (AppDelegate *)[[UIApplication sharedApplication] delegate];

    NSLog(@"Lat %f", [[myDelegate.myLocation objectForKey:@"LATITUDE"]floatValue]);
    NSLog(@"Long %f",[[myDelegate.myLocation objectForKey:@"LONGITUDE"]floatValue]);

    self.coordArray= [[NSMutableArray alloc]init];
    // Do any additional setup after loading the view from its nib.


    timer=[NSTimer scheduledTimerWithTimeInterval:(10.0) target:self selector:@selector(upateLocation) userInfo:nil repeats:YES];

    float dist;

    for (int i=0; i<[myDelegate.placeArray count]; i++) 

        dist=(6371 * acos(cos(RADIANS_TO_DEGREES([[myDelegate.myLocation objectForKey:@"LATITUDE"]floatValue]) ) *
                                     cos(RADIANS_TO_DEGREES([[[myDelegate.placeArray objectAtIndex:i] latitude] floatValue] ) ) * cos( RADIANS_TO_DEGREES([[[myDelegate.placeArray objectAtIndex:i] longitude] floatValue] ) - RADIANS_TO_DEGREES([[myDelegate.myLocation objectForKey:@"LONGITUDE"]floatValue]) ) + sin( RADIANS_TO_DEGREES([[myDelegate.myLocation objectForKey:@"LATITUDE"]floatValue])) * sin( RADIANS_TO_DEGREES([[[myDelegate.placeArray objectAtIndex:i] latitude] floatValue] ) ) ) );

        //int distVal=(int)dist;
        distStr= [NSString stringWithFormat:@"%.2f",dist];
        NSLog(@"new---%@",distStr);
        [self.coordArray addObject:distStr];
    
    NSMutableDictionary *tmpDict;

    for (int i=0; i<[myDelegate.placeArray count]; i++) 

        tmpDict = [[NSMutableDictionary alloc]initWithObjectsAndKeys:[[myDelegate.placeArray objectAtIndex:i] ids],@"contentId",[[myDelegate.placeArray objectAtIndex:i] restaurantname],@"contentTitle",//contentAdd
                   [[myDelegate.placeArray objectAtIndex:i] res_type],@"contentType",
                   [[myDelegate.placeArray objectAtIndex:i] user_image],@"contentImg",[[myDelegate.placeArray objectAtIndex:i] address],@"contentAdd",[[myDelegate.placeArray objectAtIndex:i] phone],@"contentPhone",
                   [self.coordArray objectAtIndex:i],@"contentDist",nil];

        [self.dataArray addObject:tmpDict];
        [tmpDict release];
        tmpDict = nil;


        //  NSLog(@"self.dataArray---%f",[[[self.dataArray objectAtIndex:i] valueForKey:@"contentDist"] floatValue]);
    

    NSMutableArray *tempArray = [[NSMutableArray alloc] init];
    [tempArray removeAllObjects];
    [tempArray addObjectsFromArray: self.dataArray];

    NSString *key = @"contentDist";
    NSSortDescriptor *brandDescriptor = [[NSSortDescriptor alloc] initWithKey:key ascending:YES];
    NSArray *sortDescriptors = [NSArray arrayWithObjects:brandDescriptor,nil];
    NSArray *sortedArray = [tempArray sortedArrayUsingDescriptors:sortDescriptors];
    [brandDescriptor release];
    [tempArray removeAllObjects];
    tempArray = (NSMutableArray*)sortedArray;
    [self.dataArray removeAllObjects];
    [self.dataArray addObjectsFromArray:tempArray];

    /*haversine=[[Haversine alloc] init];
     [haversine initWithLat1:28.618095 lon1:77.390228 lat2:28.635860 lon2:77.506226];
     [haversine toKilometers];
     NSLog(@"haversine--- %f",[haversine toKilometers]);*/
//    [self performSelector:@selector(upateLocation) withObject:nil afterDelay:10.0];


    


这里是上面代码的解释。 1-有一个数组(放置数组),其中所有经纬度都对应于每个餐厅。 2-从这个数组中,通过使用 Harvest 方法,我得到了以公里为单位的距离,然后将它们添加到另一个名为(coordArray)的数组中。 3-然后创建一个最终数组,即(我已应用排序的 dataArray

这在我的最终工作正常,但在我在 iPhone 5 上测试后就无法工作。 谁能建议我这个我没有得到的代码有什么问题。

请帮我解决这个问题,感谢大家付出宝贵的时间。

【问题讨论】:

【参考方案1】:

不是一个真正的答案,但我相信您可以重新格式化您的代码以删除许多不必要的循环。只需将代码与您的代码相似,您就可以将距离存储为 NSNumber。您还可以使用快速枚举来消除大量冗长。

self.dataArray = [NSMutableArray array];
for (int i=0; i<[myDelegate.placeArray count]; i++) 

    float dist=(6371 * acos(cos(RADIANS_TO_DEGREES([[myDelegate.myLocation objectForKey:@"LATITUDE"]floatValue]) ) *
                      cos(RADIANS_TO_DEGREES([[[[myDelegate.placeArray objectAtIndex:i] latitude] floatValue] ) ) * cos( RADIANS_TO_DEGREES([[[myDelegate.placeArray objectAtIndex:i] longitude] floatValue] ) - RADIANS_TO_DEGREES([[myDelegate.myLocation objectForKey:@"LONGITUDE"]floatValue]) ) + sin( RADIANS_TO_DEGREES([[myDelegate.myLocation objectForKey:@"LATITUDE"]floatValue])) * sin( RADIANS_TO_DEGREES([[[myDelegate.placeArray objectAtIndex:i] latitude] floatValue] ) ) ) );

    //int distVal=(int)dist;
    NSString *distStr= [NSString stringWithFormat:@"%.2f",dist];

    NSDictionary *tmpDict = @@"contentId":[[myDelegate.placeArray objectAtIndex:i] ids],
                              @"contentTitle":[[myDelegate.placeArray objectAtIndex:i] restaurantname],
                              @"contentType":[[myDelegate.placeArray objectAtIndex:i] res_type],
                              @"contentImg":[[myDelegate.placeArray objectAtIndex:i] user_image],
                              @"contentAdd":[[myDelegate.placeArray objectAtIndex:i] address],
                              @"contentPhone":[[myDelegate.placeArray objectAtIndex:i] phone],
                              @"contentDist":distStr;

    [self.dataArray:tmpDict];


NSSortDescriptor *brandDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"contentDist"
                                                                  ascending:YES];

[self.dataArray sortUsingDescriptors:@[brandDescriptor]];

【讨论】:

感谢 Anup,它在我们端工作,因为它在 alriaer 工作,但在客户端它不工作。它正确排序了一些值,但在某些值上它不起作用。你能建议一下。 @FlexsinFlex 因为排序是基于距离的。仔细检查它的值。我的建议是删除许多冗长的步骤,以提高可读性和易于调试。由于您有一个用于存储的模型对象,因此您可以将字典的创建移至该类。然后你只需要添加距离来创建 tmpDict(formed from model)。【参考方案2】:

如果您将距离存储为字符串

distStr= [NSString stringWithFormat:@"%.2f",dist];
NSLog(@"new---%@",distStr);
[self.coordArray addObject:distStr];

然后它们将被排序为字符串而不是数字,例如11.00 &lt; 2.00

您应该将距离存储为 NSNumber 对象:

[self.coordArray addObject:[NSNumber numberWithFloat:dist]];

(请注意,CLLocation 有一个distanceFromLocation: 您可以使用的方法来代替您自己的计算。)

【讨论】:

以上是关于根据 lat 和 long 得到错误的排序距离的主要内容,如果未能解决你的问题,请参考以下文章

根据距离排列记录的 PHP 代码

查找提供的纬度和经度的最近距离记录的程序[重复]

计算 2 lat longs 之间的距离

laravel 的 sql 查询中的语法错误

PHP,Mysql根据经纬度计算距离并排序

PHP,Mysql根据经纬度计算距离并排序