Created
February 15, 2021 22:35
-
-
Save hishma/1a7e94063d37e6fec1c80ccd7f960216 to your computer and use it in GitHub Desktop.
LocationDegreesFormatter.swift
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import CoreLocation | |
class LocationDegreesFormatter: Formatter { | |
enum Direction { | |
case none | |
case latitude | |
case longitude | |
} | |
enum Format { | |
case degrees | |
case degreesMinutes | |
case degreesMinutesSeconds | |
} | |
var direction: Direction = .none | |
var format: Format = .degreesMinutesSeconds | |
var minimumFractionDigits = 1 | |
var maximumFractionDigits = 5 // accurate to 1.1132 meters | |
lazy var degreesFormatter: NumberFormatter = { | |
let formatter = NumberFormatter() | |
formatter.locale = Locale.current | |
formatter.numberStyle = .decimal | |
formatter.minimumFractionDigits = minimumFractionDigits | |
formatter.maximumFractionDigits = maximumFractionDigits | |
return formatter | |
}() | |
lazy var minutesFormatter: NumberFormatter = { | |
let formatter = NumberFormatter() | |
formatter.locale = Locale.current | |
formatter.numberStyle = .decimal | |
formatter.minimumFractionDigits = 3 | |
formatter.maximumFractionDigits = 3 | |
formatter.paddingCharacter = "0" | |
formatter.paddingPosition = .afterPrefix | |
formatter.minimumIntegerDigits = 2 | |
formatter.maximumIntegerDigits = 2 | |
return formatter | |
}() | |
override func string(for obj: Any?) -> String? { | |
guard let degrees = obj as? CLLocationDegrees else { return nil } | |
return string(from: degrees) | |
} | |
func string(from: CLLocationDegrees) -> String? { | |
var degrees = from | |
var suffix: String? | |
switch direction { | |
case .none: | |
break | |
case .latitude: | |
guard(-90.0...90.0).contains(degrees) else { return nil } | |
suffix = degrees >= 0.0 ? "N" : "S" | |
case .longitude: | |
guard(-180.0...180.0).contains(degrees) else { return nil } | |
suffix = degrees >= 0.0 ? "E" : "W" | |
} | |
if direction != .none { degrees = abs(degrees) } | |
let minutes = (abs(degrees) * 60.0).truncatingRemainder(dividingBy: 60.0) | |
let seconds = (abs(degrees) * 3600.0).truncatingRemainder(dividingBy: 60.0) | |
var string = "" | |
switch format { | |
case .degrees: | |
let degreesString = degreesFormatter.string(from: NSNumber(value: degrees)) ?? "\(degrees)" | |
string = "\(degreesString)°" | |
case .degreesMinutes: | |
let minutesString = minutesFormatter.string(from: NSNumber(value: minutes)) ?? "\(minutes)" | |
string = "\(Int(floor(degrees)))° \(minutesString)′" | |
case .degreesMinutesSeconds: | |
string = "\(Int(floor(degrees)))° \(Int(floor(minutes)))′ \(Int(round(seconds)))″" | |
} | |
if let suffix = suffix { | |
string.append(" " + suffix) | |
} | |
return string | |
} | |
override func getObjectValue(_ obj: AutoreleasingUnsafeMutablePointer<AnyObject?>?, for string: String, errorDescription error: AutoreleasingUnsafeMutablePointer<NSString?>?) -> Bool { | |
error?.pointee = "Not implemented" | |
return false | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment