Swift Convert Decimal Coordinate into Degrees, Minutes, Seconds, Direction

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

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"

How to convert degrees, minutes, seconds and direction to longitude and latitude coordinates?

I don't know if there is a built-in function, but this will work:

func convert(degrees degrees: Double, minutes: Double, seconds: Double, direction: String) -> Double {
let sign = (direction == "W" || direction == "S") ? -1.0 : 1.0
return (degrees + (minutes + seconds/60.0)/60.0) * sign
}

let lattitude = convert(degrees: 40, minutes: 58, seconds: 36, direction: "N") // 40.9766666666667
let longitude = convert(degrees: 28, minutes: 49, seconds: 16, direction: "W") // -28.8211111111111

Convert decimal coordinate into degrees, minutes, seconds, direction

Standard way:

char lonLetter = (lon > 0) ? 'E' : 'W';
char latLetter = (lat > 0) ? 'N' : 'S';

Convert MapKit latitude and longitude to DMS format

Unfortunately there is no automatic conversion but you can easily create one as follow:

Swift 4 or later

func coordinateToDMS(latitude: Double, longitude: Double) -> (latitude: String, longitude: String) {
let latDegrees = abs(Int(latitude))
let latMinutes = abs(Int((latitude * 3600).truncatingRemainder(dividingBy: 3600) / 60))
let latSeconds = Double(abs((latitude * 3600).truncatingRemainder(dividingBy: 3600).truncatingRemainder(dividingBy: 60)))

let lonDegrees = abs(Int(longitude))
let lonMinutes = abs(Int((longitude * 3600).truncatingRemainder(dividingBy: 3600) / 60))
let lonSeconds = Double(abs((longitude * 3600).truncatingRemainder(dividingBy: 3600).truncatingRemainder(dividingBy: 60) ))

return (String(format:"%d° %d' %.4f\" %@", latDegrees, latMinutes, latSeconds, latitude >= 0 ? "N" : "S"),
String(format:"%d° %d' %.4f\" %@", lonDegrees, lonMinutes, lonSeconds, longitude >= 0 ? "E" : "W"))
}

let dms = coordinateToDMS(latitude: 48.8582487759147, longitude: 2.2945180844931)

print(dms.latitude) // "48° 51' 29.6956" N"
print(dms.longitude) // "2° 17' 40.2651" E"

You can also extend CLLocationCoordinate2D to get your latitude/longitude DMS description:

import MapKit
extension FloatingPoint {
var minutes: Self {
return (self*3600)
.truncatingRemainder(dividingBy: 3600)/60
}
var seconds: Self {
return (self*3600)
.truncatingRemainder(dividingBy: 3600)
.truncatingRemainder(dividingBy: 60)
}
}
extension CLLocationCoordinate2D {
var dms: (latitude: String, longitude: String) {
return (String(format:"%d° %d' %.4f\" %@",
Int(abs(latitude)),
Int(abs(latitude.minutes)),
abs(latitude.seconds),
latitude >= 0 ? "N" : "S"),
String(format:"%d° %d' %.4f\" %@",
Int(abs(longitude)),
Int(abs(longitude.minutes)),
abs(longitude.seconds),
longitude >= 0 ? "E" : "W"))
}
}

let coord = CLLocationCoordinate2D(latitude: 48.8582487759147, longitude: 2.2945180844931)

coord.dms.latitude // "48° 51' 29.6956" N"
coord.dms.longitude // "2° 17' 40.2651" E"

Better way to parse and convert DMS Coordinates from String to Double in Swift

When ahead with the reply from https://codereview.stackexchange.com/questions/153291/parsing-and-converting-dms-coordinates-from-string-to-double

struct PLNWaypointCoordinate {
var latitude: Double
var longitude: Double

init(latitude: Double, longitude: Double) {
self.latitude = latitude
self.longitude = longitude
}

init?(coordinateString: String) {
let components = coordinateString.components(separatedBy: ",")
guard components.count >= 2,
let latitude = PLNWaypointCoordinate.convertCoordinate(coordinate: components[0],
positiveDirection: "N",
negativeDirection: "S"),
let longitude = PLNWaypointCoordinate.convertCoordinate(coordinate: components[1],
positiveDirection: "E",
negativeDirection: "W")
else {
return nil
}
self.init(latitude: latitude, longitude: longitude)
}

private static func convertCoordinate(coordinate: String,
positiveDirection: String,
negativeDirection: String) -> Double? {
// Determine the sign from the first character:
let sign: Double
let scanner = Scanner(string: coordinate)
if scanner.scanString(positiveDirection, into: nil) {
sign = 1.0
} else if scanner.scanString(negativeDirection, into: nil) {
sign = -1.0
} else {
return nil
}

// Parse degrees, minutes, seconds:
var degrees = 0
var minutes = 0
var seconds = 0.0
guard scanner.scanInt(°rees), // Degrees (integer),
scanner.scanString("°", into: nil), // followed by °,
scanner.scanInt(&minutes), // minutes (integer)
scanner.scanString("'", into: nil), // followed by '
scanner.scanDouble(&seconds), // seconds (floating point),
scanner.scanString("\"", into: nil), // followed by ",
scanner.isAtEnd // and nothing else.
else { return nil }

return sign * (Double(degrees) + Double(minutes)/60.0 + seconds/3600.0)
}
}

Thanks for the help everybody!

Converting coordinates from decimal degrees to possibly EPSG 4326

(Disclaimer: I do not know this API, but I am certain that you should direct such questions to them. Nevertheless...)

If you visit the API root here, you'll find the following:

The spatial reference system is Spherical Mercator as used by Google and Bing: EPSG 3785 / 3857 / 900913.

Which is actually true! If you convert the example coordinates from EPSG:3857 to EPSG:4326, and take care to not reverse latitude and longitude, you'll see that the coordinates match up with the descriptions.

Just make sure that don't mix up longitude and latitude when looking up the results on a map.


To convert a WGS84 coordinate you get from iOS in the tool, you should:

  • select EPSG:4326 for input;
  • select EPSG:3857 for output;
  • and input coordinates as longitude;latitude (for example: -122.408917;37.782683).

To do this conversion programmatically, other SO questions will help. Porting any of those code fragments to Objective-C or Swift should be easy.

Convert Degrees/Minutes/Seconds to Decimal Coordinates

Try this:

public double ConvertDegreeAngleToDouble( double degrees, double minutes, double seconds )
{
//Decimal degrees =
// whole number of degrees,
// plus minutes divided by 60,
// plus seconds divided by 3600

return degrees + (minutes/60) + (seconds/3600);
}


Related Topics



Leave a reply



Submit