我有一个代表用户路线的坐标数组。我希望能够重绘这条路线并让其他用户完全遵循它。虽然我只想在路线改变方向时保存重要的坐标(航路点)。
有没有办法可以将坐标数组转换为贝塞尔曲线并使用它,所以我只得到重要的坐标,而不是将每个坐标保存在一个数组中(大多数坐标方向相同且不需要)
我希望能够重建路线以提供航路点。这些航路点将用于引导用户沿着路线前进,因为最终我将使用MKDirections将它们引导到每个航路点。
答案 0 :(得分:2)
您不应该使用MKDirections,因为它不是为了遵循预先计算的路径,而是为您提供到达目的地的最快路线!因此我将改用MKMapOverlayRenderer!
有几件事你可以做到这一点。我想谈谈用于删除不必要的航路点的简单算法:
NSArray* path = YOURPATH
NSMutableArray* waypoints = [path mutableCopy];
CGFloat smoothness = 0.01;
for(NSInteger scale=1;scale<log2(waypoints.count);scale++)
{
for(NSInteger index = 0; index<waypoints.count-2;index++)
{
CLLocation *start = [waypoints objectAtIndex:index];
CLLocation *middle = [waypoints objectAtIndex:index+1];
CLLocation *end = [waypoints objectAtIndex:index+2];
CGFloat dist_start_end = [end distanceFromLocation:start];
CGFloat dist_start_middle_end = [middle distanceFromLocation:start]+[end distanceFromLocation:middle];
CGFloat diff = dist_start_end-dist_start_middle_end;
CGFloat ratio = diff/(dist_start_end);
if (ratio<1+smoothness) {
[waypoints removeObjectAtIndex:index+1];
index-=1;
}
}
}
这应该删除不需要的点。您应该使用'smoothness'变量进行游戏。值越大,删除的细节越多! (因此压缩效果更好)
现在使用此数组,您可以构建贝塞尔曲线路径!
我不会详细介绍如何将bezier路径实际放到地图上,在Stackoverflow上有很多其他问题,还有互联网上的教程。但我将简要介绍如何创建/使用贝塞尔路径的两个控制点:
鉴于我们在上面创建的航点阵列,您可能会添加一些额外的控制点,以避免驾驶方向在建筑物中使用快捷方式。因此,您应该计算路径上两个实际点之间的控制点,如下所示:
CGFloat cornerRadius = 5;
NSMutableArray* pathPoints = [NSMutableArray new];
if (waypoints.count>1) {
[pathPoints addObject:[waypoints objectAtIndex:0]];
[pathPoints addObject:[waypoints objectAtIndex:0]];
[pathPoints addObject:[waypoints objectAtIndex:1]];
[pathPoints addObject:[waypoints objectAtIndex:1]];
}
for (NSInteger index = 1;index<waypoints.count-1;index++) {
CLLocation* lastLocation = [waypoints objectAtIndex:index-1];
CLLocation* currentLocation = [waypoints objectAtIndex:index];
CLLocation* nextLocation = [waypoints objectAtIndex:index+1];
[pathPoints addObject:currentLocation];
CGFloat latDiff = currentLocation.coordinate.latitude - lastLocation.coordinate.latitude;
CGFloat longDiff = currentLocation.coordinate.longitude - lastLocation.coordinate.longitude;
CGFloat dist = [currentLocation distanceFromLocation:lastLocation];
CGFloat controlPointALat = cornerRadius*latDiff/dist;
CGFloat controlPointALong = cornerRadius*longDiff/dist;
CLLocation* controlPointA =
[[CLLocation alloc] initWithLatitude:controlPointALat longitude:controlPointALong];
[pathPoints addObject:controlPointA];
if (index<waypoints.count-2) {
CLLocation* nextNextLocation = [waypoints objectAtIndex:index+2];
latDiff = nextNextLocation.coordinate.latitude - nextLocation.coordinate.latitude;
longDiff = nextNextLocation.coordinate.longitude - nextLocation.coordinate.longitude;
dist = [nextNextLocation distanceFromLocation:nextLocation];
CGFloat controlPointBLat = cornerRadius*latDiff/dist;
CGFloat controlPointBLong = cornerRadius*longDiff/dist;
CLLocation* controlPointB =
[[CLLocation alloc] initWithLatitude:controlPointBLat longitude:controlPointBLong];
[pathPoints addObject:controlPointB];
}else{
[pathPoints addObject:controlPointA];
}
[pathPoints addObject:nextLocation];
}
现在您可以使用此pathArray通过简单的for循环构建bezierPaths:
for(NSInteger index=0;index<pathPoints.count-3;index+=4)
{
CLLocation *start = [pathPoints objectAtIndex:index];
CLLocation *controlPointA = [pathPoints objectAtIndex:index+1];
CLLocation *controlPointB = [pathPoints objectAtIndex:index+2];
CLLocation *end = [pathPoints objectAtIndex:index+3];
//BEZIER CURVE HERE
}
您可以使用UIBezierPath并使用CGPath属性创建MKMapOverlayRenderer,也可以直接使用CGPath。稍后将在此处描述添加地图路径: MKMapOverlayRenderer
此处描述了创建UIBezierPath: UIBezierPath
答案 1 :(得分:0)
您可以使用NSValues数组,因为您无法将CGPoint直接添加到数组中
这就是我们这样做的方式
NSMutableArray *arrayOfPoints = [[NSMutableArray alloc] init];
[arrayOfPoints addObject:[NSValue valueWithCGPoint:CGPointMake(10, 20)]];
// here point is the cgpoint you want to add
现在,您已将点添加到数组中,您可以执行的操作是遍历每个对象并将它们添加到您的UIBezierPath
NSInteger i = 0;
UIBezierPath _path1 = [UIBezierPath bezierPath];
for(NSValue *val in arrayOfPoints){
if (i==0){
[_path1 moveToPoint:[val CGPointValue]];
}
else{
[_path1 addLineToPoint:[val CGPointValue]];
}
i++;
}
我希望这有助于解决您的问题