Zeichnen einer Route in MapKit in iPhone SDK

stimmen
53

Ich möchte eine Route zwischen zwei Orten auf der Karte zeichnen. So etwas wie ein Reiseleiter. Wenn die Touristen einen anderen Standort klickt, möchte ich in der Lage sein, einen Weg zu ziehen; sowie über die Entfernung vom aktuellen Standort informieren.

Ich bin mir bewusst, Websites im Internet, die sagen, wie Polylinien auf der Karte zu zeichnen. Aber die meisten Beispiele hatte ein vorinstalliertes CSV-Datei mit verschiedenen Koordinaten.

Gibt es eine alternative Möglichkeit, die Koordinaten von Google oder einem anderen Anbieter zu bekommen, da die Lage dynamisch ausgewählt wird.

Wenn nein, wie bekomme ich die Informationen für Zwischenkoordinaten?

Bietet iOS 6 eine direkte Art und Weise für dieses Problem?

Veröffentlicht am 14/05/2010 um 14:37
quelle vom benutzer
In anderen Sprachen...                            


9 antworten

stimmen
61

Im Folgenden viewDidLoadwird (1) Satz zwei Stellen, (2) entfernen alle vorhergehenden Anmerkungen, und (3) -Aufruf Benutzer definierten Hilfsfunktionen (zur Routenpunkte zu erhalten und um die Strecke ziehen).

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

Im Folgenden ist die MKMapViewDelegateMethode, die Überlagerung (IOS 4.0 und höher) zieht.

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

Die folgende Funktion erhalten sowohl die Standorte und URL bereiten alle Routenpunkte zu bekommen. Und natürlich wird stringWithURL nennen.

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

Der folgende Code ist die wirkliche Magie (Decoder für die Antwort, die wir von der API bekamen). Ich würde nicht diesen Code ändern, wenn ich weiß, was ich tue :)

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

Mit dieser Funktion wird eine Route ziehen und wird ein Overlay hinzufügen.

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

Der folgende Code wird zentriert die Karte auszurichten.

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

Ich hoffe, das jemand helfen würde.

Beantwortet am 12/08/2012 um 18:21
quelle vom benutzer

stimmen
24

Dies ist eine schwierige Sache. Es gibt keine Möglichkeit, das zu tun, mit MapKit: es einfach genug, um Linien zu zeichnen, wenn Sie die Koordinaten kennen, aber MapKit geben Sie nicht auf die Straße oder andere Routing-Informationen zugreifen. Ich würde sagen, dass Sie eine externe API aufrufen Ihre Daten zu erhalten.

Ich habe mit cloudmade.com API gespielt. Der Vektor - Stream - Server sollte zurückgeben , was Sie brauchen, und dann können Sie das über Ihre Karte ziehen. Allerdings Diskrepanzen zwischen den Google Maps und den OSM sie haben ein Äquivalent zu MapKit: Karten von Cloudmade verwendet werden , können Sie Cloudmade Karten den ganzen Weg verwenden möchten.

PS: Andere Kartierungsanbieter - Google, Bing etc. können auch äquivalente Daten-Feeds. Ich habe gerade Blick auf OSM / Cloudmade vor kurzem.

PPS: Nichts davon ist trivial Neuling stuff! Viel Glück!

Beantwortet am 14/05/2010 um 14:59
quelle vom benutzer

stimmen
12

Andiih hat all das zu Recht. MapKit lassen Sie nicht das tun. Leider Google lassen Sie nicht tun, was Sie entweder tun wollen.

Als Apple MapKit und alle angekündigt, auch erklärt sie ausdrücklich, dass alle Navigationsanwendungen BYOM würde: Holen Sie Ihre eigene Karte, so dass jeder Navigationsanwendung nutzt ihre eigene Reihe von Mapping-Tools.

Googles Nutzungsbedingungen beschränken Sie auch Routen auf ihre Karten anzuzeigen:

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

Lizenzbeschränkungen:

10.9 verwenden den Dienst oder Inhalt mit Produkten, Systemen oder Anwendungen für oder in Verbindung mit:

(A) Echtzeit-Navigation oder Routenführung, einschließlich, aber nicht beschränkt auf Turn-by-Turn-Routenführung, die auf die Position eines Benutzers Sensor-fähiges Geräts synchronisiert ist;

(B) alle Systeme oder Funktionen zur automatischen oder autonomen Steuerung des Fahrzeugverhaltens; oder

(C) Versand, Flottenmanagement, Business-Asset-Tracking oder ähnliche Unternehmensanwendungen (die Google Maps API verwendet werden kann Vermögenswerte (wie Autos, Busse oder andere Fahrzeuge), solange die Tracking-Anwendung zu verfolgen, wird die Öffentlichkeit zugänglich gemacht, ohne Gebühr. Zum Beispiel können Sie eine kostenlose, öffentliche Karten-API-Implementierung bieten, die Öffentlichkeit in Echtzeit zeigt Transit oder andere Transportstatusinformationen.

Leider enthält das, was Sie tun mögen. Hoffentlich eines Tages MapKit wird erweitert, um solche Funktionen zu ermöglichen ... wenn auch unwahrscheinlich.

Viel Glück.

Beantwortet am 14/05/2010 um 19:54
quelle vom benutzer

stimmen
5

Vielleicht haben Sie einen Blick auf haben wollen https://github.com/leviathan/nvpolyline Diese Lösung ist besonders gezielt auf iPhone OS Versionen vor v.4.0

Obwohl es auch in v.4.0 Hoffnung verwendet werden kann, das hilft.

Beantwortet am 01/07/2010 um 15:22
quelle vom benutzer

stimmen
4

Versuchen MapKit-Route-Route ( GitHub ).

Beantwortet am 05/01/2011 um 08:06
quelle vom benutzer

stimmen
3

Beziehen und eine Route auf der Karte zeichnen ist super einfach mit 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];
    }
}];
Beantwortet am 14/02/2015 um 16:46
quelle vom benutzer

stimmen
3

Nur um zu klären, es sieht aus wie es ein paar Dinge diskutiert. Eine davon ist ein Weg , um die Eckpunkte einer Strecke zu bekommen und die andere ist eine Überlagerung auf der Karte zu ziehen , diese Eckpunkte verwenden. Ich kenne die MapQuest APIs, so habe ich einige Links für die unten - Google und Bing Äquivalente haben , denke ich.

1) Erste Eckpunkte einer Route
Wenn Sie sich für die neuen Koordinaten einer Route suchen eine Route Overlay zu zeichnen, können Sie entweder eine Web - Service - Aufruf zu einem Routing - Web - Service verwenden - ich nehme an, Sie verwenden JavaScript hier Zeigt die Karte. Wenn Sie nativen Code verwenden, haben Sie immer einen Web - Service treffen kann , oder Sie können einen nativen Aufruf verwenden (das heißt, hat das MapQuest iPhone SDK eine native Route Anruf in it).

Die meisten der Richtungen Dienste sollten die „shapepoints“ der Route zurückkehren, so dass Sie ziehen können.

Hier sind einige Beispiele MapQuest- Anfahrt Web Service mit shapepoints zu erhalten (siehe das Shape - Return - Objekt) - http://www.mapquestapi.com/directions/

2) Zeichnen eines Overlay
Sobald Sie Ihre Ecken haben, müssen Sie sie zeichnen. Ich denke , die meisten JavaScript Karte APIs wird eine Overlay - Klasse irgendeine Art hat. Hier ist der MapQuest ein: http://developer.mapquest.com/web/documentation/sdk/javascript/v7.0/overlays#line

3) tut es mit einem Anruf
MapQuest auch einige Komfortfunktionen haben , um die Strecke Anruf und die Linie für Sie zeichnen - ich kann nicht mehr als zwei Links posten! Also gehen Sie auf den oberen Link und suchen Sie nach „Routing“ in der Navigationsleiste auf der linken Seite.

Beantwortet am 12/03/2012 um 17:09
quelle vom benutzer

stimmen
3

MapQuest hat ein SDK, das ein Drop-in-Ersatz für MapKit ist. Es ist derzeit in der Beta, aber unter aktiver Entwicklung.

Es ermöglicht Overlays, Routing und Geokodierung.

MapQuest iOS Maps API

Beantwortet am 05/03/2012 um 00:45
quelle vom benutzer

stimmen
2

Um diese Frage zu aktualisieren, gibt es keine Notwendigkeit, externen apk seit iOS7.

Hier ist eine sehr einfache und effektive Lösung:

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

Ich weiß, die Frage war, über iOS 6 aber ich glaube, dass diese Lösung für viele Menschen nützlich sein wird.

Das einzige, was in dieser Lösung fehlt die Umsetzung der folgenden Delegatmethode den Anfang und das Ende Stift angezeigt werden

-(MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
Beantwortet am 25/02/2015 um 08:30
quelle vom benutzer

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