Аннотация по маршруту в MapKit

Я использую MapKit для отображения направлений между местоположениями, и я ищу способ добавить аннотацию, которая работает аналогично аннотации маршрута в приложении Apple Maps, где аннотации показывают время в пути каждого маршрута (как показано на рисунке ниже). Я уже правильно рисую направления, проблема в том, как вычислить пару координат вдоль маршрута. То есть, куда бросить аннотацию.

Я думал как-то использовать MKDirection (который содержит полные направления, шаг за шагом), но я не уверен, как я буду генерировать пару координат, которые находятся где-то посередине маршрута.

Я не смог найти никакой поддержки для этого в документации MapKit. Есть идеи?

enter image description here

вот как я генерирую маршрут и отображаю его.

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

5 ответов


редактирование вопрошающего:

наконец-то заставил его работать с помощью этого ответа. Я добавил Это в код ниже, где говорится здесь делают магию:

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

}

возможно, не самый эффективный способ, но все же, вероятно, будет быстрым, будет вычислять среднюю точку вашей начальной и конечной точек (т. е. усреднять их латы и лонги). Затем выполните итерацию через точки полилинии, проверяя расстояние от каждой до этой средней точки. Возьмите ближайший матч.

даже если линия дико изогнута, средняя точка будет находиться непосредственно между концами. Некоторая точка на дикой кривой ближе всего к этой внешней средней точке и, вероятно, является хорошим местом поставить аннотацию.


после MKRoute, приблизительную центральную точку можно найти, используя:

route.polyline.coordinate

возвращает CLLocationCoordinate2D что вы можете использовать для центрирования аннотации.

ценю, что это старый вопрос, но я искал что-то подобное некоторое время и в конечном итоге вычислял центр вручную. Оказывается, это очень просто, так как iOS 8.


Если вы хотите знать середину для 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)
    }
}

Я предлагаю вам посмотреть этой , интегрированный с маршрутизации.