Created
September 23, 2012 12:15
-
-
Save Muximize/3770235 to your computer and use it in GitHub Desktop.
A category on MKPolyline adding a class method to create a new MKPolyline from a Google Maps Directions API encoded polyline string. See https://developers.google.com/maps/documentation/utilities/polylinealgorithm
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <MapKit/MapKit.h> | |
@interface MKPolyline (GMEncodedString) | |
+ (MKPolyline *)polylineWithGMEncodedString:(NSString *)encodedString; | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "MKPolyline+GMEncodedString.h" | |
@implementation MKPolyline (GMEncodedString) | |
+ (MKPolyline *)polylineWithGMEncodedString:(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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment