swiftgps

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"