Расчет маршрутов с несколькими пинами - PullRequest
1 голос
/ 13 марта 2012

В моем приложении у меня есть mapView с несколькими пользовательскими выводами.

Я пытаюсь сделать это: на showCallout появляется AlertView и сообщает, хотите ли вы рассчитать маршрут. Это работает, но только для одного места. Или лучше, только один метод вызывается, поэтому у меня только один пункт назначения.

Вот мой код (у меня 9 пунктов назначения, но я выкладываю только 2, чтобы сделать код короче):

- (void)viewDidLoad
{
[super viewDidLoad];

[mapView setMapType:MKMapTypeStandard];
[mapView setZoomEnabled:YES];
[mapView setScrollEnabled:YES];
[mapView setDelegate:(id)self];

MKCoordinateRegion TavernaCongiura = { {0.0, 0.0} , {0.0, 0.0} };
TavernaCongiura.center.latitude = 40.380784;
TavernaCongiura.center.longitude = 15.541373;
TavernaCongiura.span.longitudeDelta = 0.004f;
TavernaCongiura.span.latitudeDelta = 0.004f;
[mapView setRegion:TavernaCongiura animated:YES];
mapView.showsUserLocation = YES;

TeggianoAnnotation *ann0 = [[TeggianoAnnotation alloc] init];
ann0.title = @"Taverna de la Congiura";
ann0.subtitle = @"Antipasto";
ann0.coordinate = TavernaCongiura.center;
[mapView addAnnotation: ann0];

MKCoordinateRegion TavernaDeiMori = { {0.0, 0.0} , {0.0, 0.0} };
TavernaDeiMori.center.latitude = 40.380535;
TavernaDeiMori.center.longitude = 15.542028;
TavernaDeiMori.span.longitudeDelta = 0.004f;
TavernaDeiMori.span.latitudeDelta = 0.004f;
[mapView setRegion:TavernaDeiMori animated:YES];

TeggianoAnnotation *ann1 = [[TeggianoAnnotation alloc] init];
ann1.title = @"Taverna dei Mori";
ann1.subtitle = @"Parmatieddi";
ann1.coordinate = TavernaDeiMori.center;
[mapView addAnnotation: ann1];

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation    
*)newLocation fromLocation:(CLLocation *)oldLocation {
if (newLocation.horizontalAccuracy == oldLocation.horizontalAccuracy) {
    [self->locationManager stopUpdatingLocation];
    CLLocationCoordinate2D coords = newLocation.coordinate;
    NSString *stringURL = [NSString stringWithFormat:@"http://maps.google.com 
/maps?saddr=%g,%g&daddr=40.380784,15.541373", coords.latitude, coords.longitude];
    NSURL *url = [NSURL URLWithString:stringURL];
    [[UIApplication sharedApplication] openURL:url];
}
}

- (void)locationManagerMori:(CLLocationManager *)manager didUpdateToLocation: 
(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
if (newLocation.horizontalAccuracy == oldLocation.horizontalAccuracy) {
    [self->locationManager stopUpdatingLocation];
    CLLocationCoordinate2D coords = newLocation.coordinate;
    NSString *stringURL = [NSString stringWithFormat:@"http://maps.google.com
/maps?saddr=%g,%g&daddr=40.380535,15.542028", coords.latitude, coords.longitude];
    NSURL *url = [NSURL URLWithString:stringURL];
    [[UIApplication sharedApplication] openURL:url];
}
}

-(MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:    
(id<MKAnnotation>)annotation {
MKAnnotationView *MyPin=[[MKAnnotationView alloc] initWithAnnotation:annotation   
reuseIdentifier:@"current"];

UIButton *advertButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
if ([[annotation title] isEqualToString:@"Taverna de la Congiura"]) {
    [advertButton addTarget:self action:@selector(buttonCongiura:) 
forControlEvents:UIControlEventTouchUpInside];
    MyPin.image = [UIImage imageNamed:@"CongiuraMappa.png"];    
}
if ([[annotation title] isEqualToString:@"Taverna dei Mori"]) {
    [advertButton addTarget:self action:@selector(buttonMori:) 
forControlEvents:UIControlEventTouchUpInside];
    MyPin.image = [UIImage imageNamed:@"MoriMappa.png"];    
}
MyPin.rightCalloutAccessoryView = advertButton;
MyPin.draggable = NO;
MyPin.highlighted = YES;
MyPin.canShowCallout = YES;
return MyPin;
}

-(void)buttonCongiura:(id)sender {
UIAlertView *alertViewCongiura;
alertViewCongiura = [[UIAlertView alloc] initWithTitle:@"Taverna de la Congiura" 
message:@"Calcola Percorso" delegate:self cancelButtonTitle:@"Annulla"   
otherButtonTitles:@"Calcola", nil];
[alertViewCongiura show];
}

-(void)buttonMori:(id)sender {
UIAlertView *alertViewMori;
alertViewMori = [[UIAlertView alloc] initWithTitle:@"Taverna dei Mori" 
message:@"Calcola Percorso" delegate:self cancelButtonTitle:@"Annulla" 
otherButtonTitles:@"Calcola", nil];
[alertViewMori show];
}

-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex 
{   
if (buttonIndex == 1) {
  self->locationManager = [[CLLocationManager alloc] init];
  self->locationManager.delegate = (id)self;
  [self->locationManager startUpdatingLocation];
}

if (buttonIndex == 2) {
    self->locationManagerMori = [[CLLocationManager alloc] init];
    self->locationManagerMori.delegate = (id)self;
    [self->locationManagerMori startUpdatingLocation];
}
}

Проблема в том, что только первый

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation    
*)newLocation fromLocation:(CLLocation *)oldLocation

называется.

1 Ответ

1 голос
/ 14 марта 2012

Нельзя использовать разные имена для методов делегата для каждого используемого вами экземпляра диспетчера местоположений.Каждый менеджер местоположения по-прежнему будет вызывать методы, определенные протоколом CLLocationManagerDelegate.

Вы можете проверить, какой менеджер вызывает, проверив, равен ли параметр manager одному из экземпляров.вы создаете (например, if (manager == locationManagerMori)).

Но вам не нужно создавать отдельный экземпляр диспетчера местоположений для каждой аннотации.


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

- (void)locationManager:(CLLocationManager *)manager 
    didUpdateToLocation:(CLLocation *)newLocation 
    fromLocation:(CLLocation *)oldLocation 
{
    if (newLocation.horizontalAccuracy == oldLocation.horizontalAccuracy) 
      //the above if-condition looks a little suspicious by the way
    {
        if (mapView.selectedAnnotations.count == 0)
        {
            //no annotation selected, do nothing
            return;
        }

        //there can only be one selected annotation so get the one at index 0
        id<MKAnnotation> selectedAnnotation = 
            [mapView.selectedAnnotations objectAtIndex:0];


        [self->locationManager stopUpdatingLocation];
        CLLocationCoordinate2D coords = newLocation.coordinate;

        NSString *stringURL = [NSString stringWithFormat:
            @"http://maps.google.com/maps?saddr=%g,%g&daddr=%g,%g", 
            coords.latitude, coords.longitude, 
            selectedAnnotation.coordinate.latitude, 
            selectedAnnotation.coordinate.longitude];

        NSURL *url = [NSURL URLWithString:stringURL];

        //stop updating location to avoid possible endless loop
        //when user comes back to this app...
        [manager stopUpdatingLocation];

        [[UIApplication sharedApplication] openURL:url];
    }
}

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

Другая проблема заключается в методе просмотра предупреждений clickedButtonAtIndex.Похоже, вы проверяете, какая это аннотация, посмотрев на индекс кнопки представления предупреждений.Этим индексом будет кнопка Annulla или Calcola (а не какая аннотация).

Поскольку вам не нужно создавать отдельный диспетчер местоположений для каждой аннотации, вам не нужно будет знать, какая аннотация для просмотра предупрежденийдля.Вам просто нужно проверить, нажал ли пользователь Annulla или Calcola:

if (buttonIndex == alertView.firstOtherButtonIndex)
{
    self->locationManager = [[CLLocationManager alloc] init];
    self->locationManager.delegate = (id)self;
    self->locationManager startUpdatingLocation];
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...