Функция для пересчета географических координат - Swift

Есть массив с географическими координатами [широта, долгота], координаты - в формате DD.DDDDDDD (Double).

Есть задача конвертировать их в форматы DD° MM' SS.SS" и в DD° MM.MMM', например:

54.6673498° = N54° 40' 2,5" = N54° 40.041'
-32.6764837° = W032° 40' 35.3" = W032° 40.589'

Пока для разминки поигралась в Playground c суфиксами и префиксами для широты, но это, конечно же, не рабочий вариант:

var lat = "54.6673498"

var gg = String(lat.prefix(2))
var mmString100 = String(lat.suffix(7))

var mmFull = (Double(mmString100) ?? 0) * 0.000006
var mm = String(mmFull).prefix(2)

var ssString100 = String(mmFull).suffix(7)
var ssFull = (Double(ssString100) ?? 0) * 0.00006
var ss = String(ssFull).prefix(5)

var lat2 = "N" + gg + "° " + mm + "' " + ss + "\""


print("Degrees = \(gg)")
print("Дробный остаток от Degrees = \(mmString100)")
print("Full Minutes = \(mmFull)")
print("Minutes = \(mm)")
print("Дробный остаток от Minutes = \(ssString100)")
print("Full Seconds = \(ssFull)")
print("Seconds = \(ss)")
print (lat2)

Надо, скорее всего, использовать Оператор целочисленного деления, но первые тесты показали, что Swift не позволяет использовать % для Double.


Ответы (1 шт):

Автор решения: Max Raskolnikov

По наводке @schmidt9 был взят код, но доработан до соответствия "стандартного" отображения координат:

// функции пересчета координат из DD.DDDDDD в DD MM SS.SS:

// Широта:
func latCoordConvertDDtoDMS(latitude: Double) -> String {
    var latSeconds = latitude * 3600
    let latDegrees = Int(latSeconds / 3600)
    latSeconds = abs(latSeconds.truncatingRemainder (dividingBy: 3600))
    let latMinutes = Int(latSeconds / 60)
    latSeconds = latSeconds.truncatingRemainder (dividingBy: 60)
    return String(
        format: "%@%02d° %02d' %05.2f\"",
        //format: "%@ %.2f° %.2f' %.2f",
        latDegrees >= 0 ? "N" : "S",
        abs(latDegrees),
        latMinutes,
        latSeconds
    )
}

// Долгота:
func lonCoordConvertDDtoDMS(longitude: Double) -> String {
    var longSeconds = longitude * 3600
    let longDegrees = Int(longSeconds / 3600)
    longSeconds = abs(longSeconds.truncatingRemainder (dividingBy: 3600))
    let longMinutes = Int(longSeconds / 60)
    longSeconds = longSeconds.truncatingRemainder (dividingBy: 60)
    return String(
        format: "%@%03d° %02d' %05.2f\"",
        longDegrees >= 0 ? "E" : "W",
        abs(longDegrees),
        longMinutes,
        longSeconds
    )
}

В результате получим в таком виде: N23° 04' 12.28" E013° 43' 02.49" Постоянная разрядность чисел и автозаполнение нулями, где нужно.

→ Ссылка