优化两个嵌套数组中的坐标计算

时间:2018-01-01 11:05:22

标签: ios objective-c arrays xcode google-maps

我正在处理一个应用程序,其中Google地图上有一个坐标数组,用于绘制路线。第二组加油站坐标。在10,000个点的两个阵列中。我需要显示第二个阵列中落在路线上的点,偏差为5英里。我在嵌套数组中提出了这个要求,但这个计算非常冗长,大约需要五分钟。如何优化并加快计算速度?我将非常感谢任何建议:

这是我的代码

- (void)addRandomPointsOnMap {
CGFloat upperBoundLatitude = 46.80;
CGFloat lowerBoundLatitude = 29.76;
CGFloat upperBoundLongitude = -118.64;
CGFloat lowerBoundLongitude = -75.6;

for (int i = 0; i < 10000; i++) {
    TSPoint *randomPoint = [[TSPoint alloc] init];
    randomPoint.latitude = [self randomFloatBetween:upperBoundLatitude
                                          and:lowerBoundLatitude];
    randomPoint.longitude = [self randomFloatBetween:upperBoundLongitude
                                           and:lowerBoundLongitude];
    CLLocation *randomPointLocation = [[CLLocation alloc] initWithLatitude:randomPoint.latitude longitude:randomPoint.longitude];

    for (int i = 0; i < _routePoints.count; i++) {
        TSPoint *routePoint = _routePoints[i];
        CLLocation *routePointLocation = [[CLLocation alloc] initWithLatitude:routePoint.latitude longitude:routePoint.longitude];
        NSInteger distanceInMeters = [routePointLocation distanceFromLocation:randomPointLocation];

        NSInteger distanceInMiles = distanceInMeters / 1609.344;
        if (distanceInMiles < 5) {

            GMSMarker *markerT1 = [[GMSMarker alloc] init];
            markerT1.position = CLLocationCoordinate2DMake(randomPoint.latitude, randomPoint.longitude);
            markerT1.icon = [UIImage imageNamed:@"blue_pin"];
            markerT1.groundAnchor = CGPointMake(0.5, 0.5);
            markerT1.map = _mapView;
        }
    }
} }

和计算有界范围内随机坐标的方法:

- (float)randomFloatBetween:(float)lowerBound and:(float)upperBound {
float diff = upperBound - lowerBound;
return (((float) (arc4random() % ((unsigned)RAND_MAX + 1)) / RAND_MAX) * diff) + lowerBound; }

1 个答案:

答案 0 :(得分:0)

您有一系列确定路线的点。我的假设是,鉴于5英里的偏差,有很多点位于彼此无关紧要的距离。

以下是一个例子: 路线中的第一个点位于给定位置。您路线的第二个点距离之前的位置3英尺。考虑到您找到了距离第一个位置5英里范围内的加油站,可以安全地假设它也将落在距离第二个位置5英里的范围内。因此,不再需要为第二个位置检查已经为第一个位置验证的所有站点。

我想你看到我想要用这个去哪里。尝试使用适合您的距离减少路线中的点数。

您可以从偏差的1/20开始。这意味着路线上距离已经验证过的另一个位置0.25英里范围内的每个位置将不再验证电台,因为它将假设将有与验证电台相同的电台。

以下是减少的方式:

- (NSArray *)reducePointsInArray:(NSArray*)locations withinDistance:(CGFloat)distance {
     NSMutableArray *mutableLocations = [locations mutableCopy];

     //This array will hold the indexes of insignificant locations
     NSMutableArray *reduceIndexes = [NSMutableArray array];

     //Start with a reference location
     CLLocation referenceLocation = [locations firstObject];
     [locations enumerateObjectsUsingBlock:^(CLLocation *location, NSUInteger idx, BOOL *stop) {
         //Don't compare first location to first location
         if (idx == 0) {
             return;
         }
         //Compare location with reference location
         if([locations distanceFromLocation:referenceLocation] < distance) {
             [reduceIndexes addObject:[NSIndexSet indexSetWithIndex:idx]];
         } else {
             referenceLocation = location;
         }
    }];
    [mutableLocations removeObjectsAtIndexes:reduceIndexes];
    return mutableLocations;
}

如果你认为0.25英里对于减少路线位置来说太多了,你可以少花钱,我认为它仍会减少一些位置。尝试使用不同的值并记录减少前后的位置数。根据您的路线点之间的距离,我猜您甚至可以减少多达80%的路线点,而不会显着影响您的结果。