Kreslení trasy v MapKit v iPhone SDK

hlasů
53

Chci nakreslit trasu mezi dvěma místy na mapě. Něco jako průvodcem. Když turista klikne na jiné místo, chci mít možnost čerpat cestu; jakož i informovat o vzdálenosti od aktuálního umístění.

Jsem si vědom stránek na internetu, které říkají, jak kreslit křivky na mapě. Ale většina z příkladů mělo předinstalovaný CSV soubor s různými souřadnicemi.

Existuje alternativa způsob, jak dostat souřadnic z Google nebo jakéhokoli jiného poskytovatele, jako je umístění vybráno dynamicky.

Pokud ne, jak mohu získat informace o mezilehlých souřadnic?

Má iOS 6 poskytnout žádnou přímou cestu k tomuto problému?

Položena 14/05/2010 v 14:37
zdroj uživatelem
V jiných jazycích...                            


9 odpovědí

hlasů
61

Vkládá viewDidLoadse (1) nastaven na dvou místech, (2) odstranit všechny předchozí poznámky, a (3) uživatelských volání definovány pomocné funkce (jak získat body trasy a kreslit trasy).

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

Dále je popsána MKMapViewDelegatemetoda, která vychází překrytí (IOS 4.0 a vyšší).

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

Následující funkce budou mít obě lokality a připravit URL získat všechny body trasy. A samozřejmě, bude volat 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]];
}

Následující kód je skutečná magie (dekodér pro odezvu jsme dostali od API). Já bych to změnit tento kód, pokud vím, co dělám :)

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

Tato funkce bude čerpat trasu a dodá překryv.

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

Následující kód bude střed zarovnat mapy.

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

Doufám, že to pomůže někdo.

Odpovězeno 12/08/2012 v 18:21
zdroj uživatelem

hlasů
24

To je ošemetná. Neexistuje žádný způsob, jak to udělat s MapKit: je to dost snadné kreslení čar, když víte, souřadnic, ale MapKit nebude vám umožní přístup k silnic nebo jiných informací směrování. Řekl bych, že je třeba volat externí rozhraní API, aby si svá data.

Byl jsem hrát s cloudmade.com API. Proud serveru vektor by měl vrátit to, co budete potřebovat, a pak můžete kreslit, že přes své mapy. Nicméně rozdíly mezi mapami Google a OSM map používaných CloudMade může chcete použít CloudMade mapuje všechny cestu: mají odpovídající MapKit.

PS: Ostatní poskytovatelé mapování - Google, Bing, atd. Mohou také poskytnout odpovídající zdroje dat. Nedávno jsem byl při pohledu na OSM / CloudMade nedávno.

PPS: Nic z toho není triviální nováček věci! Hodně štěstí!

Odpovězeno 14/05/2010 v 14:59
zdroj uživatelem

hlasů
12

Andiih je to mám právo. MapKit vás nenechá udělat. Bohužel, Google nebude vám to, co chcete dělat, a to buď.

Když Apple oznámila MapKit a všechny, které rovněž výslovně uvedeno, že všechny navigační aplikace by BYOM: Přineste si vlastní mapy, takže jakýkoliv navigační aplikace používá vlastní sadu mapovacích nástrojů.

Podmínky společnosti Google vás neomezuje v i zobrazení trasy na vrcholu svých map:

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

Licenční omezení:

10.9 pomocí služby či obsahu s jinými produkty, systémy nebo aplikacemi, nebo ve spojení s:

(A) v reálném čase pro navigaci a navádění, včetně, ale ne omezeno na turn-by-turn navádění, který je synchronizován na pozici snímacího zařízení s podporou uživatele;

(B) jakékoliv systémy nebo funkce pro automatické nebo autonomní řízení chování vozidla; nebo

(C) odeslání, správa vozového parku, sledování obchodního majetku, nebo podobné podnikových aplikací (API Google Maps lze použít ke sledování majetku (například automobily, autobusy a jiná vozidla) tak dlouho, dokud aplikace pro sledování je zpřístupněno veřejnosti, aniž náboj. například můžete nabídnout bezplatnou veřejnou Maps API implementace, který zobrazuje v reálném čase, veřejnou dopravu nebo jiné informace o stavu dopravy.

Je smutné, že to zahrnuje to, co byste chtěli dělat. Doufejme, že jeden den MapKit bude rozšířen, aby tyto funkce ... i když nepravděpodobné.

Hodně štěstí.

Odpovězeno 14/05/2010 v 19:54
zdroj uživatelem

hlasů
5

Možná budete chtít, aby se podívat na https://github.com/leviathan/nvpolyline Toto řešení je zaměřena zejména na verzi iPhone OS před v.4.0

Ačkoli to může být také použita v v.4.0, že to pomůže.

Odpovězeno 01/07/2010 v 15:22
zdroj uživatelem

hlasů
4

Zkuste MapKit-route-Directions ( GitHub ).

Odpovězeno 05/01/2011 v 08:06
zdroj uživatelem

hlasů
3

Získání a čerpání trasu na mapě je super snadné 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];
    }
}];
Odpovězeno 14/02/2015 v 16:46
zdroj uživatelem

hlasů
3

Jen pro upřesnění, vypadá to, že existuje několik věcí projednávána. Jedním z nich je způsob, jak získat vrcholů cesty a druhá je nakreslit překrytí na mapě pomocí těchto vrcholů. Znám API MapQuest, takže mám nějaké odkazy na ty dole - Google a Bing mají ekvivalenty myslím.

1) Získání vrcholů cesty
Pokud hledáte pro nové souřadnic trase nakreslit trasy překrytí můžete buď použít webové služby volání směrování webové služby - já jsem za předpokladu, že používáte JavaScript zde zobrazení mapy. Pokud používáte nativní kód, můžete stále zasáhnout webovou službu, nebo můžete použít nativní volání (to znamená, že MapQuest iPhone SDK obsahuje nativní volání trasy v něm).

Většina služeb směrech by měl vrátit „shapepoints“ na cestě, takže můžete čerpat.

Zde jsou některé příklady použití MapQuest- Directions webové služby získat shapepoints (viz návratový Tvar objektu) - http://www.mapquestapi.com/directions/

2) Kreslení překrytí
Jakmile budete mít své vrcholy, je nutné k jejich tažení. Myslím, že většina mapa JavaScript API bude mít třídu překryvné nějakého druhu. Tady je jedna MapQuest: http://developer.mapquest.com/web/documentation/sdk/javascript/v7.0/overlays#line

3) Dělat to s jedním voláním
MapQuest mají také některé komfortní funkce pro uskutečnění hovoru trasy a nakreslit čáru pro vás - nemohu po více než dva odkazy! Takže jít na výše uvedený odkaz a podívejte se na „směrování“ v navigačním panelu na levé straně.

Odpovězeno 12/03/2012 v 17:09
zdroj uživatelem

hlasů
3

MapQuest má SDK, který je drop-in náhrada za MapKit. To je v současné době v beta verzi, ale pod aktivním vývojem.

Umožňuje překryvy, směrování a geokódování.

MapQuest iOS Maps API

Odpovězeno 05/03/2012 v 00:45
zdroj uživatelem

hlasů
2

Chcete-li aktualizovat na tuto otázku, není třeba externí APK od iOS7.

Zde velmi jednoduché a efektivní řešení:

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

Vím, že tato otázka byla asi iOS 6, ale domnívám se, že toto řešení bude užitečná pro mnoho lidí.

Jediné, co chybí v tomto roztoku je provádění následující metody delegáta zobrazit počáteční a koncové čep

-(MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
Odpovězeno 25/02/2015 v 08:30
zdroj uživatelem

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