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

后端 未结 13 1003
孤街浪徒
孤街浪徒 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:36

    I hope it's not against the rules to link to my own blog post if it's relevant to the question, but I've solved this problem in the past. Stand-alone answer from linked post:

    @implementation MKPolyline (MKPolyline_EncodedString)
    
    + (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;
    }
    
    @end
    

提交回复
热议问题