Tegne en rute i MapKit i iPhone SDK

stemmer
53

Jeg ønsker å tegne en rute mellom to steder på kartet. Noe som en guide. Når turist klikker et annet sted, jeg ønsker å være i stand til å tegne en rute; samt informere om avstanden fra nåværende posisjon.

Jeg er klar over sider på Internett som forteller hvordan du kan tegne polylinjer på kartet. Men, de fleste av eksemplene hadde et forhåndslastet CSV-fil med ulike koordinater.

Finnes det en alternativ måte å få koordinatene fra Google eller noen annen leverandør, som plassering er valgt dynamisk.

Hvis nei, hvordan får jeg den informasjonen for mellom koordinater?

Har iOS 6 gi noen direkte måte for dette problemet?

Publisert på 14/05/2010 klokken 13:37
kilden bruker
På andre språk...                            


9 svar

stemmer
61

I det følgende viewDidLoadvil (1) anbragt to steder, (2) fjerne alle de tidligere merknader, og (3) call brukerdefinerte hjelpefunksjoner (for å få rutepunkter og trekker rute).

-(void)viewDidLoad
{
    [super viewDidLoad];

    // Origin Location.
    CLLocationCoordinate2D loc1;
    loc1.latitude = 29.0167;
    loc1.longitude = 77.3833;
    Annotation *origin = [[Annotation alloc] initWithTitle:@"loc1" subTitle:@"Home1" andCoordinate:loc1];
    [objMapView addAnnotation:origin];

    // Destination Location.
    CLLocationCoordinate2D loc2;
    loc2.latitude = 19.076000;
    loc2.longitude = 72.877670;
    Annotation *destination = [[Annotation alloc] initWithTitle:@"loc2" subTitle:@"Home2" andCoordinate:loc2];
    [objMapView addAnnotation:destination];

    if(arrRoutePoints) // Remove all annotations
        [objMapView removeAnnotations:[objMapView annotations]];

    arrRoutePoints = [self getRoutePointFrom:origin to:destination];
    [self drawRoute];
    [self centerMap];
}

Det følgende er den MKMapViewDelegatemetode, som trekker overlegget (iOS 4.0 og senere).

/* MKMapViewDelegate Meth0d -- for viewForOverlay*/
- (MKOverlayView*)mapView:(MKMapView*)theMapView viewForOverlay:(id <MKOverlay>)overlay
{
    MKPolylineView *view = [[MKPolylineView alloc] initWithPolyline:objPolyline];
    view.fillColor = [UIColor blackColor];
    view.strokeColor = [UIColor blackColor];
    view.lineWidth = 4;
    return view;
}

Følgende funksjon vil få både steder og forberede URL for å få alle rutepunktene. Og selvfølgelig vil kalle stringWithURL.

/* This will get the route coordinates from the Google API. */
- (NSArray*)getRoutePointFrom:(Annotation *)origin to:(Annotation *)destination
{
    NSString* saddr = [NSString stringWithFormat:@"%f,%f", origin.coordinate.latitude, origin.coordinate.longitude];
    NSString* daddr = [NSString stringWithFormat:@"%f,%f", destination.coordinate.latitude, destination.coordinate.longitude];

    NSString* apiUrlStr = [NSString stringWithFormat:@"http://maps.google.com/maps?output=dragdir&saddr=%@&daddr=%@", saddr, daddr];
    NSURL* apiUrl = [NSURL URLWithString:apiUrlStr];

    NSError *error;
    NSString *apiResponse = [NSString stringWithContentsOfURL:apiUrl encoding:NSUTF8StringEncoding error:&error];
    NSString* encodedPoints = [apiResponse stringByMatching:@"points:\\\"([^\\\"]*)\\\"" capture:1L];

    return [self decodePolyLine:[encodedPoints mutableCopy]];
}

Følgende kode er ekte magi (dekoder for responsen vi fikk fra API). Jeg ville ikke endre denne koden med mindre jeg vet hva jeg gjør :)

- (NSMutableArray *)decodePolyLine:(NSMutableString *)encodedString
{
    [encodedString replaceOccurrencesOfString:@"\\\\" withString:@"\\"
                                  options:NSLiteralSearch
                                    range:NSMakeRange(0, [encodedString length])];
    NSInteger len = [encodedString length];
    NSInteger index = 0;
    NSMutableArray *array = [[NSMutableArray alloc] init];
    NSInteger lat=0;
    NSInteger lng=0;
    while (index < len) {
        NSInteger b;
        NSInteger shift = 0;
        NSInteger result = 0;
        do {
            b = [encodedString characterAtIndex:index++] - 63;
            result |= (b & 0x1f) << shift;
            shift += 5;
        } while (b >= 0x20);
        NSInteger dlat = ((result & 1) ? ~(result >> 1) : (result >> 1));
        lat += dlat;
        shift = 0;
        result = 0;
        do {
            b = [encodedString characterAtIndex:index++] - 63;
            result |= (b & 0x1f) << shift;
            shift += 5;
       } while (b >= 0x20);
        NSInteger dlng = ((result & 1) ? ~(result >> 1) : (result >> 1));
        lng += dlng;
        NSNumber *latitude = [[NSNumber alloc] initWithFloat:lat * 1e-5];
        NSNumber *longitude = [[NSNumber alloc] initWithFloat:lng * 1e-5];
        printf("\n[%f,", [latitude doubleValue]);
        printf("%f]", [longitude doubleValue]);
        CLLocation *loc = [[CLLocation alloc] initWithLatitude:[latitude floatValue] longitude:[longitude floatValue]];
        [array addObject:loc];
    }
    return array;
}

Denne funksjonen vil trekke en rute og vil legge et overlegg.

- (void)drawRoute
{
    int numPoints = [arrRoutePoints count];
    if (numPoints > 1)
    {
        CLLocationCoordinate2D* coords = malloc(numPoints * sizeof(CLLocationCoordinate2D));
        for (int i = 0; i < numPoints; i++)
        {
            CLLocation* current = [arrRoutePoints objectAtIndex:i];
            coords[i] = current.coordinate;
        }

        self.objPolyline = [MKPolyline polylineWithCoordinates:coords count:numPoints];
        free(coords);

        [objMapView addOverlay:objPolyline];
        [objMapView setNeedsDisplay];
    }
}

Følgende kode vil sentrere justere kartet.

- (void)centerMap
{
    MKCoordinateRegion region;

    CLLocationDegrees maxLat = -90;
    CLLocationDegrees maxLon = -180;
    CLLocationDegrees minLat = 90;
    CLLocationDegrees minLon = 180;

    for(int idx = 0; idx < arrRoutePoints.count; idx++)
    {
        CLLocation* currentLocation = [arrRoutePoints objectAtIndex:idx];

        if(currentLocation.coordinate.latitude > maxLat)
            maxLat = currentLocation.coordinate.latitude;
        if(currentLocation.coordinate.latitude < minLat)
            minLat = currentLocation.coordinate.latitude;
        if(currentLocation.coordinate.longitude > maxLon)
            maxLon = currentLocation.coordinate.longitude;
        if(currentLocation.coordinate.longitude < minLon)
            minLon = currentLocation.coordinate.longitude;
    }

    region.center.latitude     = (maxLat + minLat) / 2;
    region.center.longitude    = (maxLon + minLon) / 2;
    region.span.latitudeDelta  = maxLat - minLat;
    region.span.longitudeDelta = maxLon - minLon;

    [objMapView setRegion:region animated:YES];
}

Jeg håper dette vil hjelpe noen.

Svarte 12/08/2012 kl. 17:21
kilden bruker

stemmer
24

Dette er en vanskelig en. Det er ingen måte å gjøre det med MapKit: det er lett nok til å trekke linjer når du vet koordinatene, men MapKit vil ikke gi deg tilgang til veier eller annen ruteinformasjon. Jeg vil si at du trenger å ringe en ekstern API for å få dataene.

Jeg har spilt med cloudmade.com API. Vektoren stream serveren skal returnere det du trenger, og så kan du trekke at over kartet. Men avvik mellom Google maps og OSM kan kartene som brukes ved cloudmade gjøre du ønsker å bruke cloudmade maps hele veien: de har en tilsvarende MapKit.

PS: Andre kartlegging leverandører - Google, Bing, etc. kan også gi tilsvarende data feeds. Jeg har nettopp vært å se på OSM / Cloudmade nylig.

PPS: Ingenting av dette er trivielt nybegynner ting! Lykke til!

Svarte 14/05/2010 kl. 13:59
kilden bruker

stemmer
12

Andiih oss fikk det til. MapKit vil ikke la deg gjøre det. Dessverre, Google vil ikke la deg gjøre hva du vil gjøre heller.

Når Apple annonserte MapKit og alle, de også eksplisitt uttalt at eventuelle navigasjonsapplikasjoner vil være BYOM: Ta med dine egne kart, slik at alle navigasjonsprogrammet bruker sitt eget sett av kartleggingsverktøy.

Googles vilkår for bruk begrense deg fra selv vise rute på toppen av sine kart:

http://code.google.com/intl/de/apis/maps/iphone/terms.html

Lisensbegrensninger:

10.9 bruke tjenesten eller innholdet med produkter, systemer eller programmer for eller i forbindelse med:

(A) sanntid navigasjon eller navigeringen, inkludert, men ikke begrenset til, sving-for-trinnvis navigering som er synkronisert med posisjonen til en brukers sensor-aktivert enhet;

(B) systemer eller funksjoner for automatisk eller autonomt kontroll over kjøretøyet; eller

(C) levering, flåtestyring, business sporing av eiendeler, eller tilsvarende bedriftsapplikasjoner (Google Maps API kan brukes til å spore eiendeler (for eksempel biler, busser eller andre kjøretøyer) så lenge sporings søknaden er gjort tilgjengelig for allmennheten uten avgift. For eksempel kan du tilby en gratis, offentlig Maps API implementering som viser sanntid kollektivtransport eller annen transport statusinformasjon.

Dessverre, dette inkluderer hva du ønsker å gjøre. Forhåpentligvis en dag MapKit vil bli utvidet til å tillate slike funksjoner ... selv usannsynlig.

Lykke til.

Svarte 14/05/2010 kl. 18:54
kilden bruker

stemmer
5

Du ønsker kanskje å ta en titt på https://github.com/leviathan/nvpolyline Denne løsningen er spesielt rettet mot iPhone OS-versjoner før v.4.0

Selv om det kan også brukes i v.4.0 Håper dette hjelper.

Svarte 01/07/2010 kl. 14:22
kilden bruker

stemmer
4

Prøv MapKit-Route-beskrivelser ( GitHub ).

Svarte 05/01/2011 kl. 07:06
kilden bruker

stemmer
3

Innhenting og tegne en rute på kartet er super enkelt med iOS 7 API:

MKDirectionsRequest *directionsRequest = [[MKDirectionsRequest alloc] init];

// Set the origin of the route to be current user location
[directionsRequest setSource:[MKMapItem mapItemForCurrentLocation]];

// Set the destination point of the route
CLLocationCoordinate2D destinationCoordinate = CLLocationCoordinate2DMake(34.0872, 76.235);
MKPlacemark *destinationPlacemark = [[MKPlacemark alloc] initWithCoordinate:destinationCoordinate addressDictionary:nil];
[directionsRequest setDestination:[[MKMapItem alloc] initWithPlacemark:destinationPlacemark]];

MKDirections *directions = [[MKDirections alloc] initWithRequest:directionsRequest];

// Requesting route information from Apple Map services
[directions calculateDirectionsWithCompletionHandler:^(MKDirectionsResponse *response, NSError *error) {
    if (error) {
        NSLog(@"Cannot calculate directions: %@",[error localizedDescription]);
    } else {
        // Displaying the route on the map
        MKRoute *route = [response.routes firstObject];
        [mapView addOverlay:route.polyline];
    }
}];
Svarte 14/02/2015 kl. 16:46
kilden bruker

stemmer
3

Bare for å avklare, ser det ut som det er et par ting som blir diskutert. Den ene er en måte å få punktene av en rute, og den andre er å trekke et overlegg på kartet ved hjelp av disse hjørnene. Jeg vet MapQuest APIer, så jeg har noen linker for de under - Google og Bing har ekvivalenter tror jeg.

1) Å få punktene av en rute
Hvis du leter etter de nye koordinatene til en rute for å tegne en rute overlegg, kan du enten bruke en web-tjeneste samtale til en routing webtjeneste - Jeg antar du bruker Java her for å vise kartet. Hvis du bruker egen kode, kan du likevel treffe en webtjeneste eller du kan bruke en innfødt samtale (som er, har MapQuest iPhone SDK opprinnelig rute samtalen i det).

De fleste av de retningene tjenester skal returnere "shapepoints" av ruten, slik at du kan tegne.

Her er noen eksempler som bruker MapQuest- Veibeskrivelse Web Service for å få shapepoints (se Shape retur objekt) - http://www.mapquestapi.com/directions/

2) Tegning et overlegg
Når du har topp-punkt, må du trekke dem. Jeg tror de fleste Javascript kart APIer vil ha et overlegg klasse av noe slag. Her er MapQuest en: http://developer.mapquest.com/web/documentation/sdk/javascript/v7.0/overlays#line

3) Gjør det med en samtale
MapQuest har også noen praktiske funksjoner for å gjøre ruten samtalen og trekke linjen for deg - jeg kan ikke legge inn mer enn to linker! Så gå til linken over og se etter "routing" i navigasjonsfeltet til venstre.

Svarte 12/03/2012 kl. 16:09
kilden bruker

stemmer
3

MapQuest har en SDK som er en drop-in erstatning for MapKit. Det er foreløpig i beta, men under aktiv utvikling.

Den lar overlegg, ruting, og geokoding.

MapQuest iOS Maps API

Svarte 04/03/2012 kl. 23:45
kilden bruker

stemmer
2

For å oppdatere dette spørsmålet, er det ikke behov for ekstern apk siden iOS 7.

Her en meget enkel og effektiv løsning:

http://technet.weblineindia.com/mobile/draw-route-between-2-points-on-map-with-ios7-mapkit-api/2/

Jeg vet at spørsmålet var om iOS 6, men jeg tror at denne løsningen vil være nyttig for mange mennesker.

Det eneste som mangler i denne løsningen er å gjennomføre følgende delegat metode for å vise begynnelsen og slutten pin

-(MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
Svarte 25/02/2015 kl. 08:30
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more