简体   繁体   English

MapKit中沿路线的注释

[英]Annotation along route in MapKit

I'm using MapKit to display directions between locations, and I'm looking for a way to add an annotation that works similarly to the route annotation in the Apple Maps app, where annotations are showing each route's travel time (as shown in the image below). 我正在使用MapKit显示位置之间的方向,并且正在寻找一种添加与Apple Maps应用程序中的路线注释类似的注释的方法,其中注释显示了每条路线的行驶时间(如图所示)下面)。 I am already drawing the directions correctly, the problem at hand is how to calculate a pair of coordinates along the route. 我已经正确绘制了方向,眼前的问题是如何沿着路线计算一对坐标。 That is, where to drop the annotation. 即在哪里放置注释。

I thought about somehow using the MKDirection (which contains complete directions, step by step) but I am not sure how I would generate a pair of coordinates that are somewhere in the middle of the route. 我考虑过使用MKDirection (逐步包含完整的方向)的方法,但是我不确定如何生成路线中间某处的一对坐标。

I have not been able to find any kind of support for this in the MapKit documentation. 我无法在MapKit文档中找到对此的任何支持。 Any ideas? 有任何想法吗?

在此处输入图片说明

This is how I generate the route and display it. 这就是我生成路线并显示它的方式。

- (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;
}

Questioner's edit: 发问者的编辑:

Finally made it work with the help of this answer. 最终在此答案的帮助下使其工作。 I added this to the code below, where it says Here do the magic : 我将其添加到下面的代码中,上面写着“神奇”

MKMapPoint middlePoint = route.polyline.points[route.polyline.pointCount/2];
[self createAndAddAnnotationForCoordinate:MKCoordinateForMapPoint(middlePoint)];

Original answer: 原始答案:

I don't know whether this will work or not. 我不知道这是否行得通。 Just my idea on your question. 只是我对您的问题的想法。

I guess you would have created the routes as following (Check my inline comments) 我想您会按照以下方式创建路线(检查我的内联评论)

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]
         }
     }
 }];

Adding Annotation 添加注释

-(void) createAndAddAnnotationForCoordinate : (CLLocationCoordinate2D) coordinate{
    MyAnnotation* annotation= [[MyAnnotation alloc] init];
    annotation.coordinate = coordinate;

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

   [yourMap addAnnotation: annotation];

}

Perhaps not the most efficient way, but should still likely be quick, would be to calculate the midpoint of your start and end points (ie, average their lats and longs). 也许不是最有效的方法,但仍然应该是快速的,它将是计算起点和终点的中点(即,将其经度和纬度进行平均)。 Then, iterate through your polyline points checking the distance from each to that midpoint. 然后,遍历折线点,检查每个折线到该中点的距离。 Take the closest match. 进行最接近的匹配。

Even if the line is wildly curved, the midpoint will be directly between the ends. 即使直线弯曲,中点也将直接位于端点之间。 Some point on the wild curve is the closest to that external midpoint and is likely a good place to put the annotation. 野曲线上的某个点最接近该外部中点,并且可能是放置注释的好地方。

Once you have an MKRoute , the approximate centre-point can be found using: 拥有MKRoute ,可以使用以下方法找到大概的中心点:

route.polyline.coordinate

This returns a CLLocationCoordinate2D that you can use to centre your annotation. 这将返回一个CLLocationCoordinate2D ,您可以使用它来定位注释的中心。

Appreciate this is an old question but I'd been searching for something like this for a while and ended up calculating the centre manually. 意识到这是一个古老的问题,但我一直在寻找类似的东西一段时间,最终还是手动计算了中心。 Turns out it's very straightforward since iOS 8. 事实证明,这自iOS 8起非常简单。

If you want to know the middle for swift you can use the following code : 如果您想快速了解中间部分,可以使用以下代码:

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

Exemple of use : 使用示例:

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)
    }
}

我建议您看一下 ,与路由集成。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM