Het tekenen van een route in MapKit in iPhone SDK

stemmen
53

Ik wil een route te trekken tussen twee locaties op de kaart. Iets als een gids. Wanneer de toeristische klikt op een andere locatie, ik wil in staat zijn om een ​​route te trekken; alsmede de hoogte van de afstand vanaf de huidige locatie.

Ik ben me bewust van sites op het internet die vertellen hoe polylines tekenen op de kaart. Maar, de meeste van de voorbeelden had een voorgeladen CSV-bestand met diverse coördinaten.

Is er een alternatieve manier om de coördinaten van Google of een andere provider te krijgen, als de locatie dynamisch wordt geselecteerd.

Zo nee, hoe kan ik de informatie voor tussenliggende coördinaten te krijgen?

Heeft iOS 6 bieden geen directe manier voor dit probleem?

De vraag is gesteld op 14/05/2010 om 14:37
bron van user
In andere talen...                            


9 antwoorden

stemmen
61

Het volgende viewDidLoadzal (1) in te stellen twee locaties, (2) verwijder alle vorige annotaties, en (3) telefoonnummer van de gebruiker gedefinieerde helper functies (om de route punten te krijgen en trek de route).

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

Het volgende is de MKMapViewDelegatemethode, die overlay trekt (iOS 4.0 en hoger).

/* 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;
}

De volgende functie zal zowel de locaties te krijgen en voor te bereiden URL om alle routepunten te krijgen. En natuurlijk, zal stringWithURL bellen.

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

De volgende code is de echte magie (decoder voor de reactie die we kregen van de API). Ik zou die code niet wijzigen, tenzij ik weet wat ik doe :)

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

Deze functie zal een route te trekken en zal een overlay toe te voegen.

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

De volgende code zal centreren uitlijnen van de kaart.

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

Ik hoop dat dit zou iemand te helpen.

antwoordde op 12/08/2012 om 18:21
bron van user

stemmen
24

Dit is een lastige. Er is geen manier om dat te doen met MapKit: het is makkelijk genoeg om lijnen te trekken als je weet dat de coördinaten, maar MapKit zal niet geven u toegang tot de wegen of andere route-informatie. Ik zou zeggen dat je nodig hebt om een ​​externe API bellen om uw gegevens op te halen.

Ik speel met cloudmade.com API. De vector stroom server moet terugkeren wat je nodig hebt, en dan kun je die stellen over uw kaart. Echter, verschillen tussen de Google maps en de OSM kan kaarten gebruikt door Cloudmade je wilt Cloudmade gebruiken kaarten helemaal: ze hebben een equivalent voor MapKit.

PS: Andere mapping providers - Google, Bing, enz. Kunnen ook gelijkwaardige gegevens feeds. Ik heb net gekeken naar OSM / Cloudmade onlangs.

PPS: Niets van dit alles is triviaal newbie dingen! Veel succes!

antwoordde op 14/05/2010 om 14:59
bron van user

stemmen
12

Andiih's kreeg het recht. MapKit zal niet toestaan ​​dat je dat doet. Helaas zal Google je niet laten doen wat je wilt ook niet.

Toen Apple MapKit en al aangekondigd, maar ook expliciet vermeld dat alle navigatie-applicaties BYOM zou zijn: Bring Your Own Maps, dus elke navigatie applicatie maakt gebruik van een eigen set van mapping tools.

Google's Servicevoorwaarden beperken u zelfs in het weergeven van routes op de top van hun kaarten:

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

Licentiebeperkingen:

10.9 gebruik maken van de diensten of content met producten, systemen of toepassingen die voor of in verband met:

(A) real time navigatie of routebegeleiding, inclusief maar niet beperkt tot gedetailleerde stapsgewijze navigatie die is gesynchroniseerd met de positie van de sensor-apparaat van een gebruiker;

(B) systemen of functies voor automatische of autonome controle gedrag van het voertuig; of

(C) berichtgeving, vlootbeheer, business asset tracking, of soortgelijke toepassingen enterprise (de Google Maps API kan worden gebruikt om activa (zoals auto's, bussen en andere voertuigen te volgen), zolang de toepassing voor het bijhouden wordt ter beschikking gesteld aan het publiek zonder kosten. bijvoorbeeld, kunt u een gratis, openbare Maps API-implementatie die real-time het openbaar vervoer of andere vormen van vervoer statusinformatie weergeeft bieden.

Helaas, dit omvat wat je zou willen doen. Hopelijk op een dag MapKit zal worden uitgebreid om dergelijke functies kunt ... hoewel onwaarschijnlijk.

Succes.

antwoordde op 14/05/2010 om 19:54
bron van user

stemmen
5

Misschien wil je een kijkje nemen op zijn https://github.com/leviathan/nvpolyline Deze oplossing is vooral gericht op iPhone OS-versies voorafgaand aan v.4.0

Maar het kan ook gebruikt worden in v.4.0 Hope helpt dit.

antwoordde op 01/07/2010 om 15:22
bron van user

stemmen
4

Probeer MapKit-Route-richtingen ( GitHub ).

antwoordde op 05/01/2011 om 08:06
bron van user

stemmen
3

Het verkrijgen en een route op de kaart tekenen is super eenvoudig met 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];
    }
}];
antwoordde op 14/02/2015 om 16:46
bron van user

stemmen
3

Gewoon om te verduidelijken, het lijkt alsof er zijn een paar dingen worden besproken. Een daarvan is een manier om de hoekpunten van een route te berekenen en de andere is om een overlay te tekenen op de kaart met behulp van deze hoekpunten. Ik weet dat de MapQuest API's, dus ik heb een aantal links warmste - Google en Bing hebben equivalenten denk ik.

1) Het krijgen van hoekpunten van een route
Als u op zoek bent naar de nieuwe coördinaten van een route naar een route overlay te trekken, kunt u ofwel een webservice oproep naar een routing web service te gebruiken - ik neem aan dat je JavaScript gebruiken hier de kaart weergeven. Als u gebruik maakt native code, kunt u nog steeds raakte een webservice of u kunt een native call gebruiken (dat wil zeggen, de MapQuest iPhone SDK heeft een native route oproep in het).

Het merendeel van de richtingen diensten moeten de "shapepoints" van de route terug, zodat u kunt tekenen.

Hier zijn enkele voorbeelden van het gebruik MapQuest- richtingen Web Service om shapepoints te krijgen (zie de Shape return object) - http://www.mapquestapi.com/directions/

2) Opstellen van een overlay
Zodra u uw hoekpunten, moet je ze tekenen. Ik denk dat de meeste JavaScript kaart API zal een overlay klasse van een soort te hebben. Hier is de MapQuest één: http://developer.mapquest.com/web/documentation/sdk/javascript/v7.0/overlays#line

3) doen het met één telefoontje
MapQuest hebben ook een aantal comfortfuncties om de route te bellen en trek de lijn voor u - ik kan niet meer dan twee koppelingen te plaatsen! Dus ga naar de bovenstaande link en kijk voor "routing" in de navigatiebalk aan de linkerkant.

antwoordde op 12/03/2012 om 17:09
bron van user

stemmen
3

MapQuest heeft een SDK dat is een drop-in vervanger voor MapKit. Het is momenteel in beta, maar onder actieve ontwikkeling.

Het laat overlays, routing en geocodering.

MapQuest iOS Maps API

antwoordde op 05/03/2012 om 00:45
bron van user

stemmen
2

Om deze vraag te werken, is er geen behoefte aan externe apk sinds iOS7.

Hier een zeer eenvoudige en effectieve oplossing:

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

Ik weet dat de vraag ging over iOS 6 maar ik denk dat deze oplossing geschikt voor veel mensen zal zijn.

Het enige wat ontbreekt in deze oplossing is de uitvoering van de volgende afgevaardigde methode om het begin en einde pin weer te geven

-(MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
antwoordde op 25/02/2015 om 08:30
bron van user

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