Skip to content

Instantly share code, notes, and snippets.

@hishma
Created February 15, 2021 22:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hishma/1a7e94063d37e6fec1c80ccd7f960216 to your computer and use it in GitHub Desktop.
Save hishma/1a7e94063d37e6fec1c80ccd7f960216 to your computer and use it in GitHub Desktop.
LocationDegreesFormatter.swift
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