在MapKit中沿路标注

12
我正在使用MapKit显示两个位置之间的方向,并寻找一种类似于Apple地图应用程序中路线注释的方法,其中每条路线都显示旅行时间(如下图所示)。我已经正确地绘制了方向,问题是如何计算沿路线的一对坐标。换句话说,要放置注释的位置。
我考虑过某种方式使用MKDirection(其中包含完整的逐步说明),但我不确定如何生成某些位于路径中间的坐标对。
我在MapKit文档中没有找到任何这方面的支持。有什么想法吗?
这是我生成和显示路线的方法。
- (void)generateRoute {
    MKDirectionsRequest *request = [[MKDirectionsRequest alloc] init];
    request.source = [MKMapItem mapItemForCurrentLocation];
    request.destination = self.destinationMapItem;
    MKDirections *directions = [[MKDirections alloc] initWithRequest:request];

    [directions calculateDirectionsWithCompletionHandler:
     ^(MKDirectionsResponse *response, NSError *error) {
         if (error) {
             // Handle Error
         } else {
             [self showRoute:response];
         }
     }];
}

- (void)showRoute:(MKDirectionsResponse *)response {
    [self.mapView removeOverlays:self.mapView.overlays];
    for (MKRoute *route in response.routes)
    {
        [self.mapView addOverlay:route.polyline level:MKOverlayLevelAboveRoads];
    }
    [self fitRegionToRoute];
}

- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id < MKOverlay >)overlay
{
    MKPolylineRenderer *renderer = [[MKPolylineRenderer alloc] initWithOverlay:overlay];
    renderer.strokeColor = [UIColor blueColor];
    renderer.alpha = 0.7;
    renderer.lineWidth = 4.0;

    return renderer;
}

你想要绘制路线,同时在路线中间放置注释吗? - ipraba
我也想绘制路线(这是我已经在做的)。 - Daniel Larsson
我不明白为什么需要向叠加层添加注释。你知道叠加层本身也是注释吗? - Desdenova
请在此处查看:https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/LocationAwarenessPG/AnnotatingMaps/AnnotatingMaps.html#//apple_ref/doc/uid/TP40009497-CH6-SW23 - Desdenova
@DanielLarsson 你救了我的一天 :) :* - V.D
显示剩余5条评论
5个回答

8
问者的编辑:
最后在这个回答的帮助下搞定了。我把以下代码添加到下面,其中写着“在这里进行操作”:
MKMapPoint middlePoint = route.polyline.points[route.polyline.pointCount/2];
[self createAndAddAnnotationForCoordinate:MKCoordinateForMapPoint(middlePoint)];

我不知道这是否有效,只是对你问题的看法。
我猜你创建了以下路由(请检查我的内联注释)。
MKDirectionsRequest *request = 
       [[MKDirectionsRequest alloc] init];
request.source = [MKMapItem mapItemForCurrentLocation];
request.destination = _destination;
request.requestsAlternateRoutes = NO;
MKDirections *directions = 
       [[MKDirections alloc] initWithRequest:request];

    [directions calculateDirectionsWithCompletionHandler:
 ^(MKDirectionsResponse *response, NSError *error) {
     if (error) {
         // Handle error
     } else {
         for (MKRoute *route in response.routes)
         {
             [_routeMap addOverlay:route.polyline level:MKOverlayLevelAboveRoads];
             //Here do the magic
             //MKPolyline confronts to MKOverlay so you can get the coordinate like 
             //route.polyline.coordinate once you get the coordinate then you can build
             //a annotation. A annotation is nothing but a coordinate with some title.
             //According to MKOverlay coordinate property it justs gives you the 
             //center point of the overlay area
             [self createAndAddAnnotationForCoordinate:route.polyline.coordinate]
         }
     }
 }];

添加注释。
-(void) createAndAddAnnotationForCoordinate : (CLLocationCoordinate2D) coordinate{
    MyAnnotation* annotation= [[MyAnnotation alloc] init];
    annotation.coordinate = coordinate;

    annotation.title = @"Any Title";
    annotation.subtitle = @"Any Subtitle";

   [yourMap addAnnotation: annotation];

}

太棒了。等待结果。 - ipraba
好的。现在尝试另一个MKOverlay属性boundingMapRect。这将给你MapRect。MapRect包含MKMapPoints,而MKMapPoint可以使用MKCoordinateForMapPoint转换为坐标。因此,如果您能够检索到覆盖层的任何起始点,那么它可以成为您的注释。检查从route.polyline获取坐标的所有可能性。 - ipraba
它正在工作!我所做的是通过MKMapPoint middlePoint = route.polyline.points[route.polyline.pointCount/2];来获取中间点,然后 [self createAndAddAnnotationForCoordinate:MKCoordinateForMapPoint(middlePoint)];。将其放入您的答案中,我将接受它! - Daniel Larsson
1
此外,仅当折线中的线段长度大致相等时,使用来自点数组的“中点”坐标解决方案才是合理的。例如,如果您有一个由3个点(2个线段)组成的折线,并且第一个线段比第二个线段短得多,则使用数组中点处的坐标将不会在折线“中间位置”放置注释。 - user467105
但是目的地是什么? - Siten
显示剩余7条评论

1
如果您想了解Swift的中间值,可以使用以下代码:

MKCoordinateForMapPoint(route.polyline.points()[route.polyline.pointCount/2])

使用示例:

directions.calculateDirectionsWithCompletionHandler ({
     (response: MKDirectionsResponse?, error: NSError?) in

     if error == nil {
        self.showRoute(response!)
     }
     else{
        print("some error")    
     }
})

func showRoute(response:MKDirectionsResponse){
    for route in response.routes {
        self.map.addOverlay(route.polyline, level: MKOverlayLevel.AboveRoads)
        self.map.setCenterCoordinate(route.polyline.coordinate, animated: true)
        self.map.setRegion(MKCoordinateRegionMakeWithDistance(route.polyline.coordinate, route.distance*0.75, route.distance*0.75), animated: true)

        let routeAnnotation = MKPointAnnotation()
        routeAnnotation.coordinate = MKCoordinateForMapPoint(route.polyline.points()[route.polyline.pointCount/2])
        map.addAnnotation(routeAnnotation)
    }
}

0

一旦你有了一个MKRoute,可以使用以下方法找到大致的中心点:

route.polyline.coordinate

这将返回一个CLLocationCoordinate2D,您可以使用它来定位您的注释。

请注意,这是一个旧问题,但我已经搜索了一段时间类似的内容,并最终手动计算中心点。后来发现自iOS 8以来,这非常简单。


0

也许不是最有效的方法,但仍然可能很快,就是计算起点和终点的中点(即平均纬度和经度)。然后,迭代您的折线点,检查每个点到该中点的距离。取最接近的匹配项。

即使线路非常弯曲,中点也将直接位于两端之间。野曲线上的某些点最接近外部中点,并且很可能是放置注释的好地方。


-2

我建议你看一下this,它集成了路由功能。


1
谢谢,看起来是一个很棒的框架。不过对于这个任务来说有点过于复杂了,因为我已经自己实现了其中许多功能。 - Daniel Larsson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接