Search code examples
swiftgpsxcode6

Swift Convert decimal coordinate into degrees, minutes, seconds, direction


How can I covert this to swift? My best guess is that all the int get changed to a var. Removing all the @ that lead ". Also if any can point me to a good source to learn how things convert that would great.

- (NSString*)coordinateString {

int latSeconds = (int)(self.latitude * 3600);
int latDegrees = latSeconds / 3600;
latSeconds = ABS(latSeconds % 3600);
int latMinutes = latSeconds / 60;
latSeconds %= 60;

int longSeconds = (int)(self.longitude * 3600);
int longDegrees = longSeconds / 3600;
longSeconds = ABS(longSeconds % 3600);
int longMinutes = longSeconds / 60;
longSeconds %= 60;

NSString* result = [NSString stringWithFormat:@"%d°%d'%d\"%@ %d°%d'%d\"%@",
                    ABS(latDegrees),
                    latMinutes,
                    latSeconds,
                    latDegrees >= 0 ? @"N" : @"S",
                    ABS(longDegrees),
                    longMinutes,
                    longSeconds,
                    longDegrees >= 0 ? @"E" : @"W"];

return result;    
}

My attempt to convert it but Xcode proves me wrong. Reposted the fix suggest with the ABS. Does it look correct now?

func coordinateString {

var latSeconds = (Int8)(self.latitude * 3600);
var latDegrees = latSeconds / 3600;
latSeconds = abs(latSeconds % 3600);
var latMinutes = latSeconds / 60;
latSeconds %= 60;

var longSeconds = (Int8)(self.longitude * 3600);
var longDegrees = longSeconds / 3600;
longSeconds = abs(longSeconds % 3600);
var longMinutes = longSeconds / 60;
longSeconds %= 60;

    var result = (String(format: "%d°%d'%d\"%@ %d°%d'%d\"%@"),
abs(latDegrees),
latMinutes,
latSeconds,
latDegrees >= 0 ? "N" : "S",
abs(longDegrees),
longMinutes,
longSeconds,
longDegrees >= 0 ? "E" : "W",

return result;
}

Solution

  • Xcode 12 • Swift 5 or later

    extension BinaryFloatingPoint {
        var dms: (degrees: Int, minutes: Int, seconds: Int) {
            var seconds = Int(self * 3600)
            let degrees = seconds / 3600
            seconds = abs(seconds % 3600)
            return (degrees, seconds / 60, seconds % 60)
        }
    }
    

    extension CLLocation {
        var dms: String { latitude + " " + longitude }
        var latitude: String {
            let (degrees, minutes, seconds) = coordinate.latitude.dms
            return String(format: "%d°%d'%d\"%@", abs(degrees), minutes, seconds, degrees >= 0 ? "N" : "S")
        }
        var longitude: String {
            let (degrees, minutes, seconds) = coordinate.longitude.dms
            return String(format: "%d°%d'%d\"%@", abs(degrees), minutes, seconds, degrees >= 0 ? "E" : "W")
        }
    }
    

    let latitude = -22.9133950
    let longitude = -43.2007100
    let location = CLLocation(latitude: latitude, longitude: longitude)
    location.latitude  // "22°54'48"S"
    location.longitude // "43°12'2"W"
    location.dms       // "22°54'48"S 43°12'2"W"