Skip to content

Instantly share code, notes, and snippets.

@valeriyvan
Last active August 19, 2019 12:35
Show Gist options
  • Save valeriyvan/a70e8af69662ed58caef to your computer and use it in GitHub Desktop.
Save valeriyvan/a70e8af69662ed58caef to your computer and use it in GitHub Desktop.
Geographic coordinate conversion from NSString in DMS format into decimal in CLLocationDegrees (aka double).http://en.wikipedia.org/wiki/Geographic_coordinate_conversion43° 36' 15.894" N => 43.60442
// http://en.wikipedia.org/wiki/Geographic_coordinate_conversion
// 43° 36' 15.894" N => 43.60442
#import "DMSToDecimal.h"
BOOL DMSToDecimal(NSString* dms, CLLocationDegrees *decimal) {
CLLocationDegrees degres=0, minutes=0, seconds=0;
NSScanner *scanner = [NSScanner scannerWithString:dms];
scanner.charactersToBeSkipped = [NSCharacterSet whitespaceAndNewlineCharacterSet];
if (![scanner scanDouble:&degres]) {
NSLog(@"%s wrong coordinate %@", __FUNCTION__, dms);
return NO;
}
if (![scanner scanString:@"°" intoString:NULL]) {
NSLog(@"%s wrong coordinate %@", __FUNCTION__, dms);
return NO;
}
if (![scanner scanDouble:&minutes]) {
NSLog(@"%s wrong coordinate %@", __FUNCTION__, dms);
return NO;
}
if (![scanner scanString:@"'" intoString:NULL]) {
NSLog(@"%s wrong coordinate %@", __FUNCTION__, dms);
return NO;
}
if (![scanner scanDouble:&seconds]) {
NSLog(@"%s wrong coordinate %@", __FUNCTION__, dms);
return NO;
}
if (![scanner scanString:@"\"" intoString:NULL]) {
NSLog(@"%s wrong coordinate %@", __FUNCTION__, dms);
return NO;
}
NSString* hemisphereOUmeridien = nil;
if (![scanner scanCharactersFromSet:[NSCharacterSet characterSetWithCharactersInString:@"EWNSewns"] intoString:&hemisphereOUmeridien]) {
NSLog(@"%s wrong coordinate %@", __FUNCTION__, dms);
return NO;
}
hemisphereOUmeridien = [hemisphereOUmeridien uppercaseString];
CLLocationDegrees sign;
if ([hemisphereOUmeridien isEqualToString:@"W"] || [hemisphereOUmeridien isEqualToString:@"S"]) {
sign = -1;
} else if ([hemisphereOUmeridien isEqualToString:@"E"] || [hemisphereOUmeridien isEqualToString:@"N"]) {
sign = 1;
} else {
NSLog(@"%s wrong coordinate %@", __FUNCTION__, dms);
return NO;
}
if (decimal)
*decimal = sign * (floor(degres) + floor(minutes)/60.0 + seconds/3600.0);
return YES;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment