如何获取iOS中两个地址之间的路线

时间:2015-08-04 13:04:23

标签: ios iphone

我正在使用此代码尝试获取两个位置之间的路线。但它使用纬度和经度输出坐标。但我想要的是根据2个地址获取搜索方向。如何使用此代码处理地址?

MKPlacemark *source = [[MKPlacemark alloc]initWithCoordinate:CLLocationCoordinate2DMake(37.776142, -122.424774) addressDictionary:[NSDictionary dictionaryWithObjectsAndKeys:@"",@"", nil] ];

MKMapItem *srcMapItem = [[MKMapItem alloc]initWithPlacemark:source];
[srcMapItem setName:@""];

MKPlacemark *destination = [[MKPlacemark alloc]initWithCoordinate:CLLocationCoordinate2DMake(37.73787, -122.373962) addressDictionary:[NSDictionary dictionaryWithObjectsAndKeys:@"",@"", nil] ];

MKMapItem *distMapItem = [[MKMapItem alloc]initWithPlacemark:destination];
[distMapItem setName:@""];

MKDirectionsRequest *request = [[MKDirectionsRequest alloc]init];
[request setSource:srcMapItem];
[request setDestination:distMapItem];
[request setTransportType:MKDirectionsTransportTypeAny];

MKDirections *direction = [[MKDirections alloc]initWithRequest:request];

[direction calculateDirectionsWithCompletionHandler:^(MKDirectionsResponse *response, NSError *error) {

    NSLog(@"response = %@",response);
    NSArray *arrRoutes = [response routes];
    [arrRoutes enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {

        MKRoute *rout = obj;

        MKPolyline *line = [rout polyline];
        [mapview addOverlay:line];
        NSLog(@"Rout Name : %@",rout.name);
        NSLog(@"Total Distance (in Meters) :%f",rout.distance);

        NSArray *steps = [rout steps];

        NSLog(@"Total Steps : %lu",(unsigned long)[steps count]);
        NSMutableArray *stepsArray=[[NSMutableArray alloc] init];
        [steps enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
            NSLog(@"Rout Instruction : %@",[obj instructions]);
            NSLog(@"Rout Distance : %f",[obj distance]);
            [stepsArray addObject:[obj instructions]];
        }];

        [self myShowDirections:response];
        self.steps.text=[NSString stringWithFormat:@"%@",stepsArray];

2 个答案:

答案 0 :(得分:2)

首先,您需要在视图执行中检查ios8

 locationManager = [[CLLocationManager alloc]init];
    locationManager.delegate = self;
   // self.map.showsUserLocation=YES;
    locationManager.desiredAccuracy = kCLLocationAccuracyBest;
    [locationManager setDistanceFilter:kCLDistanceFilterNone];
    if([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0){
        NSUInteger code = [CLLocationManager authorizationStatus];
        if (code == kCLAuthorizationStatusNotDetermined && ([locationManager respondsToSelector:@selector(requestAlwaysAuthorization)] || [locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)])) {
            // choose one request according to your business.
            if([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationAlwaysUsageDescription"]){
                [locationManager requestAlwaysAuthorization];
            } else if([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationWhenInUseUsageDescription"]) {
                [locationManager  requestWhenInUseAuthorization];
            } else {
                NSLog(@"Info.plist does not contain NSLocationAlwaysUsageDescription or NSLocationWhenInUseUsageDescription");
            }
        }





-(void) centerMapForCoordinateArray:(CLLocationCoordinate2D *)routes andCount:(int)count{
    MKCoordinateRegion region;

    CLLocationDegrees maxLat = -90;
    CLLocationDegrees maxLon = -180;
    CLLocationDegrees minLat = 90;
    CLLocationDegrees minLon = 180;
    for(int idx = 0; idx <count; idx++)
    {
        CLLocationCoordinate2D currentLocations = routes[idx];
        if(currentLocations.latitude > maxLat)
            maxLat = currentLocations.latitude;
        if(currentLocations.latitude < minLat)
            minLat = currentLocations.latitude;
        if(currentLocations.longitude > maxLon)
            maxLon = currentLocations.longitude;
        if(currentLocations.longitude < minLon)
            minLon = currentLocations.longitude;
    }


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

    [self.map setRegion:region animated:YES];
}

- (MKPolyline *)polylineWithEncodedString:(NSString *)encodedString {
    const char *bytes = [encodedString UTF8String];
    NSUInteger length = [encodedString lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
    NSUInteger idx = 0;

    NSUInteger count = length / 4;
    CLLocationCoordinate2D *coords = calloc(count, sizeof(CLLocationCoordinate2D));
    NSUInteger coordIdx = 0;

    float latitude = 0;
    float longitude = 0;
    while (idx < length) {
        char byte = 0;
        int res = 0;
        char shift = 0;

        do {
            byte = bytes[idx++] - 63;
            res |= (byte & 0x1F) << shift;
            shift += 5;
        } while (byte >= 0x20);

        float deltaLat = ((res & 1) ? ~(res >> 1) : (res >> 1));
        latitude += deltaLat;

        shift = 0;
        res = 0;

        do {
            byte = bytes[idx++] - 0x3F;
            res |= (byte & 0x1F) << shift;
            shift += 5;
        } while (byte >= 0x20);

        float deltaLon = ((res & 1) ? ~(res >> 1) : (res >> 1));
        longitude += deltaLon;

        float finalLat = latitude * 1E-5;
        float finalLon = longitude * 1E-5;

        CLLocationCoordinate2D coord = CLLocationCoordinate2DMake(finalLat, finalLon);
        coords[coordIdx++] = coord;

        if (coordIdx == count) {
            NSUInteger newCount = count + 10;
            coords = realloc(coords, newCount * sizeof(CLLocationCoordinate2D));
            count = newCount;
        }
    }

    MKPolyline *polyline = [MKPolyline polylineWithCoordinates:coords count:coordIdx];
    free(coords);

    return polyline;
}


- (void)getDirections {

    CLLocation *newLocation = [[CLLocation alloc] initWithLatitude:currentLocation.coordinate.latitude longitude:currentLocation.coordinate.longitude];
    MKPointAnnotation *provider = [[MKPointAnnotation alloc] init];
    provider.coordinate = CLLocationCoordinate2DMake(newLocation.coordinate.latitude, newLocation.coordinate.longitude);
    provider.title = [self getAddress];
    [self.map addAnnotation:provider];
   // 13.069166  80.191388
    CLLocationCoordinate2D  location;
//    location.latitude =12.982672000000000000; // change to your coordinate latitude
//    location.longitude =80.263380999999980000;
    location.latitude =[self.Latitude doubleValue]; // change to your coordinate latitude
    location.longitude =[self.Longtitude doubleValue];
    CLLocation *keyPlace = [[CLLocation alloc] initWithLatitude:location.latitude longitude:location.longitude];
    MKPointAnnotation *user = [[MKPointAnnotation alloc] init];
    user.coordinate = CLLocationCoordinate2DMake(keyPlace.coordinate.latitude, keyPlace.coordinate.longitude);
    NSString *add=[NSString stringWithFormat:@"%f %f",location.latitude,location.longitude];
    NSString *tit=[self getAddressFromLatLong:add];

    user.title=tit;
    [self.map addAnnotation:user];

    CLLocationCoordinate2D endCoordinate;

    NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"https://maps.googleapis.com/maps/api/directions/json?origin=%f,%f&destination=%f,%f&sensor=false&mode=driving", newLocation.coordinate.latitude, newLocation.coordinate.longitude, keyPlace.coordinate.latitude, keyPlace.coordinate.longitude]];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    NSURLResponse *response = nil;
    NSError *error = nil;
    NSData *responseData =  [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
    if (!error) {
        NSDictionary *responseDict = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingAllowFragments error:&error];
        if ([[responseDict valueForKey:@"status"] isEqualToString:@"ZERO_RESULTS"]) {
            [[[UIAlertView alloc] initWithTitle:@"Error"
                                        message:@"Could not route path from your current location"
                                       delegate:nil
                              cancelButtonTitle:@"Close"
                              otherButtonTitles:nil, nil] show];
            return;
        }
        int points_count = 0;
        if ([[responseDict objectForKey:@"routes"] count])
            points_count = (int)[[[[[[responseDict objectForKey:@"routes"] objectAtIndex:0] objectForKey:@"legs"] objectAtIndex:0] objectForKey:@"steps"] count];


        if (!points_count) {
            [[[UIAlertView alloc] initWithTitle:@"Error"
                                        message:@"Could not route path from your current location"
                                       delegate:nil
                              cancelButtonTitle:@"Close"
                              otherButtonTitles:nil, nil] show];
            return;
        }
        CLLocationCoordinate2D points[points_count];
        NSLog(@"routes %@", [[[[responseDict objectForKey:@"routes"] objectAtIndex:0]objectForKey:@"overview_polyline"] objectForKey:@"points"]
              );
        MKPolyline *polyline = [self polylineWithEncodedString:[[[[responseDict objectForKey:@"routes"] objectAtIndex:0]objectForKey:@"overview_polyline"] objectForKey:@"points"]];
        [self.map addOverlay:polyline];
        int j = 0;
        NSArray *steps = nil;

        if (points_count && [[[[responseDict objectForKey:@"routes"] objectAtIndex:0] objectForKey:@"legs"] count])
            steps = [[[[[responseDict objectForKey:@"routes"] objectAtIndex:0] objectForKey:@"legs"] objectAtIndex:0] objectForKey:@"steps"];
        for (int i = 0; i < points_count; i++) {

            double st_lat = [[[[steps objectAtIndex:i] objectForKey:@"start_location"] valueForKey:@"lat"] doubleValue];
            double st_lon = [[[[steps objectAtIndex:i] objectForKey:@"start_location"] valueForKey:@"lng"] doubleValue];
            //NSLog(@"lat lon: %f %f", st_lat, st_lon);
            if (st_lat > 0.0f && st_lon > 0.0f) {
                points[j] = CLLocationCoordinate2DMake(st_lat, st_lon);
                j++;
            }
            double end_lat = [[[[steps objectAtIndex:i] objectForKey:@"end_location"] valueForKey:@"lat"] doubleValue];
            double end_lon = [[[[steps objectAtIndex:i] objectForKey:@"end_location"] valueForKey:@"lng"] doubleValue];

            //NSLog(@"lat %f lng %f",end_lat,end_lon);
            //if (end_lat > 0.0f && end_lon > 0.0f) {
            points[j] = CLLocationCoordinate2DMake(end_lat, end_lon);
            endCoordinate = CLLocationCoordinate2DMake(end_lat, end_lon);
            j++;
            //}
        }
        NSLog(@"points Count %d",points_count);
        //        MKPolyline *polyline = [MKPolyline polylineWithCoordinates:points count:points_count];
        //        [self.mapView addOverlay:polyline];
        [self centerMapForCoordinateArray:points andCount:points_count];
    }
}
- (MKPolylineRenderer *)mapView:(MKMapView *)mapView
                 viewForOverlay:(id<MKOverlay>)overlay {

    MKPolylineRenderer *polylineView = [[MKPolylineRenderer alloc] initWithOverlay:overlay];
    polylineView.lineWidth = 3;
    polylineView.strokeColor = [[UIColor alloc] initWithRed:5.0/255 green:102.0/255 blue:48.0/255 alpha:1];
    return polylineView;
}

编辑:

-(void)showRoute:(MKDirectionsResponse *)response
{
    for (MKRoute *route in response.routes){
        [mapView addOverlay:route.polyline level:MKOverlayLevelAboveRoads];
    }
}
-(void)getPathDirections:(CLLocationCoordinate2D)source withDestination:(CLLocationCoordinate2D)destination{

    MKPlacemark *placemarkSrc = [[MKPlacemark alloc] initWithCoordinate:source addressDictionary:nil];
    MKMapItem *mapItemSrc = [[MKMapItem alloc] initWithPlacemark:placemarkSrc];
    MKPlacemark *placemarkDest = [[MKPlacemark alloc] initWithCoordinate:destination addressDictionary:nil];
    MKMapItem *mapItemDest = [[MKMapItem alloc] initWithPlacemark:placemarkDest];
    [mapItemSrc setName:@"name1"];
    [mapItemDest setName:@"name2"];

    MKDirectionsRequest *request = [[MKDirectionsRequest alloc] init];
    [request setSource:mapItemSrc];
    [request setDestination:mapItemDest];
    [request setTransportType:MKDirectionsTransportTypeAutomobile];
    request.requestsAlternateRoutes = NO;

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

    [directions calculateDirectionsWithCompletionHandler:
     ^(MKDirectionsResponse *response, NSError *error) {
         if (error) {
             // Handle Error
             //             UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"ShareMyTable" message:@"Root Map not available to your location." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
             //             [alert show];
         } else {
             [mapView removeOverlays:mapView.overlays];
             [self showRoute:response];
         }
     }];

}

    - (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay
{
   // 41,142,175
    if ([overlay isKindOfClass:[MKPolyline class]]) {
        MKPolyline *route = (MKPolyline *)overlay;
        MKPolylineRenderer *routeRenderer = [[MKPolylineRenderer alloc] initWithPolyline:route];
        routeRenderer.strokeColor = [UIColor colorWithRed:(41/255.0) green:(142/255.0) blue:(175/255.0) alpha:0.6f];
        routeRenderer.lineWidth = 2.5;
        return routeRenderer;
    }
    else return nil;
}

您可以阅读支持的国家/地区列表 link

答案 1 :(得分:0)

当您在两个地方之间发现任何溃败时,请始终使用不同的来源和目的地。 在您的代码中,您使用相同的纬度和经度,因此 MKDirections 没有Rout来指示方向。 所以在你的代码中使用不同的Lat。和龙。 像...

 KPlacemark *source = [[MKPlacemark alloc]initWithCoordinate:CLLocationCoordinate2DMake(37.776142, -122.424774) addressDictionary:[NSDictionary dictionaryWithObjectsAndKeys:@"",@"", nil] ];
 MKMapItem *srcMapItem = [[MKMapItem alloc]initWithPlacemark:source];
 [srcMapItem setName:@""];
 MKPlacemark *destination=[[MKPlacemarkalloc]initWithCoordinate:CLLocationCoordinate2DMake(40.73787, -142.373962) addressDictionary:[NSDictionary dictionaryWithObjectsAndKeys:@"",@"", nil] ];

使用此纬度和经度后,您可以在任何两个地方绘制路径。 我希望我的回答对你有所帮助。