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'변수로 playaround를해야합니다. 값이 클수록 더 많은 세부 사항이 제거됩니다! (따라서 더 나은 압축)
이제이 배열을 사용하여 베 지어 경로를 구성 할 수 있습니다!
지도에 베 지어 경로를 실제로 두는 방법에 대한 세부 정보는 들어 가지 않습니다. Stackoverflow 및 인터넷 자습서에 대한 다른 많은 질문이 있습니다. 그러나 베 지어 경로의 두 조절 점을 어떻게 만들고 사용해야하는지 잠시 만질 것입니다 :
우리가 위에서 작성한 중간 점 배열을 감안할 때, 운전 방향을 피하기 위해 추가 제어점을 추가 할 것입니다. 건물을 지름길. 하나
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
}
당신은 할 수 있습니다
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];
}
은 이제 간단한 for 루프와 bezierPaths를 구축하기 위해이 pathArray를 사용할 수 있습니다 따라서이 같은 경로에 두 개의 실제 지점 사이 제어점을 계산한다 UIBezierPath를 사용하고 CGPath 속성을 사용하여 MKMapOverlayRenderer를 만들거나 직접 CGPath를 사용할 수 있습니다.나중에지도에 경로를 추가하는 것은 여기에 설명하십시오 UIBezierPath를 Createing 이 MKMapOverlayRenderer
여기에 설명되어 있습니다 : UIBezierPath
의 중복 가능성 【부드러운 곡선 그리기 - 방법을 필요로했다] (http://stackoverflow.com/questions/8702696/drawing-smooth-curves-methods-needed) – Caleb