How to decode the Google Directions API polylines field into lat long points in Objective-C for iPhone?

后端 未结 13 1001
孤街浪徒
孤街浪徒 2020-11-30 19:05

I want to draw routes on a map corresponding to directions JSON which I am getting through the Google Directions API: https://developers.google.com/maps/documentation/direct

13条回答
  •  青春惊慌失措
    2020-11-30 19:42

    - (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;
    }
    - (MKPolygonRenderer *)mapView:(MKMapView *)mapView viewForOverlay:(id )overlay {
      //  MKPolygonRenderer *polylineView = [[MKPolygonRenderer alloc] initWithOverlay:overlay];
        MKPolylineView *polylineView = [[MKPolylineView alloc] initWithPolyline:overlay];
        polylineView.strokeColor = [UIColor redColor];
        polylineView.lineWidth = 4.0;
        [self zoomToPolyLine:mapview polyline:overlay animated:YES];
        return polylineView;
    }
    -(void)zoomToPolyLine: (MKMapView*)map polyline: (MKPolyline*)polyline animated: (BOOL)animated
    {
        [map setVisibleMapRect:[polyline boundingMapRect] edgePadding:UIEdgeInsetsMake(25.0, 25.0, 25.0, 25.0) animated:animated];
    }
    - (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
    {
       // NSLog(@"didUpdateToLocation: %@", newLocation);
        CLLocation *currentLocation = newLocation;
        if (currentLocation != nil) {
          currlong  =  [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.longitude];
           currlt = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.latitude];
        }
        NSString *origin = [NSString stringWithFormat:@"%@%@%@",currlt,@",",currlong];
    
        //I have just mention static location
        NSString *drivein = @"23.0472963,72.52757040000006";
        NSString *apikey = [NSString stringWithFormat:@"https://maps.googleapis.com/maps/api/directions/json?origin=%@&destination=%@",origin,drivein];
    
        NSURL *url = [NSURL URLWithString:apikey];
        NSURLRequest *request = [NSURLRequest requestWithURL:url];
        NSURLResponse *response;
        NSError *error;
        NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
        NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
    
        if(!error)
        {
            NSData *data = [responseString dataUsingEncoding:NSUTF8StringEncoding];
            NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:data
                                                                         options:kNilOptions
                                                                           error:&error];
            NSArray *routesArray = [jsonResponse objectForKey:@"routes"];
            NSLog(@"route array %@",routesArray);
            if ([routesArray count] > 0)
            {
                NSDictionary *routeDict = [routesArray objectAtIndex:0];
                NSDictionary *routeOverviewPolyline = [routeDict objectForKey:@"overview_polyline"];
                NSString *points = [routeOverviewPolyline objectForKey:@"points"];
                MKPolyline *line = [self polylineWithEncodedString:points];
                [mapview addOverlay:line];
            }
        }
        MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(currentLocation.coordinate, 500, 500);
        MKCoordinateRegion adjustedRegion = [mapview regionThatFits:viewRegion];
        [mapview setRegion:adjustedRegion animated:YES];
        mapview.showsUserLocation = YES;
    
        MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
        point.coordinate = currentLocation.coordinate;
        point.title = @"Your current Locations";
        point.subtitle = @"You are here!";
        [mapview addAnnotation:point];
        [locationmanger stopUpdatingLocation];
    }
    

提交回复
热议问题