Skip to content

Instantly share code, notes, and snippets.

@jarrodnorwell
Last active February 4, 2026 16:05
Show Gist options
  • Select an option

  • Save jarrodnorwell/b165be16cf6475e68303f0806bce9459 to your computer and use it in GitHub Desktop.

Select an option

Save jarrodnorwell/b165be16cf6475e68303f0806bce9459 to your computer and use it in GitHub Desktop.
nonisolated struct Facility : Codable {
nonisolated struct GeographyPoints : Codable {
let latitude, longitude: Double
var coordinate: CLLocationCoordinate2D {
CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
}
enum CodingKeys: String, CodingKey {
case latitude = "lat",
longitude = "lon"
}
}
var id: String
var geographyPoints: GeographyPoints
var name: String
var address: String? = nil,
state: String? = nil,
town: String? = nil
var pointOfInterestName: String? = nil
var pointOfInterestCategory: String? = nil
var pointOfInterestStreet: String? = nil
var pointOfInterestSuburb: String? = nil
var babyChange: String? = nil,
babyCareRoom: String? = nil
var shower: String? = nil
var leftHandTransfer: String? = nil,
rightHandTransfer: String? = nil
var parking: String? = nil,
parkingAccessible: String? = nil
var sharpsDisposal: String? = nil,
drinkingWater: String? = nil,
sanitaryDisposal: String? = nil,
mensPadDisposal: String? = nil
var paymentRequired: String? = nil
var male, female, unisex, allgender, ambulant, accessible: String
enum CodingKeys: String, CodingKey {
case id = "facilityid"
case geographyPoints = "geo_points"
case name, address = "address1", state, town
case pointOfInterestName = "poi_name",
pointOfInterestCategory = "poi_category",
pointOfInterestStreet = "poi_street",
pointOfInterestSuburb = "poi_suburb"
case babyChange = "babychange",
babyCareRoom = "babycareroom"
case shower
case leftHandTransfer = "lhtransfer",
rightHandTransfer = "rhtransfer"
case parking,
parkingAccessible = "parkingaccessible"
case sharpsDisposal = "sharpsdisposal",
drinkingWater = "drinkingwater",
sanitaryDisposal = "sanitarydisposal",
mensPadDisposal = "menspaddisposal"
case paymentRequired = "paymentrequired"
case male, female, unisex, allgender, ambulant, accessible
}
}
nonisolated class FacilityAnnotation : NSObject, MKAnnotation, Comparable {
static func < (lhs: FacilityAnnotation, rhs: FacilityAnnotation) -> Bool {
lhs.distanceInMeters < rhs.distanceInMeters
}
dynamic var coordinate: CLLocationCoordinate2D
var title: String? = nil
dynamic var subtitle: String? = nil
dynamic var distanceInMeters: CLLocationDistance = 0
dynamic var facility: Facility
init(coordinate: CLLocationCoordinate2D, title: String? = nil, subtitle: String? = nil,
distanceInMeters: CLLocationDistance, facility: Facility) {
self.coordinate = coordinate
self.title = title
self.subtitle = subtitle
self.distanceInMeters = distanceInMeters
self.facility = facility
super.init()
}
}
extension MKMapView {
func addAnnotations(for facilities: [Facility], using location: CLLocation) {
for facility in facilities {
if annotations.contains(where: { $0.title == facility.name }) {
let annotation = annotations.first(where: { $0.title == facility.name })
if let annotation = annotation as? FacilityAnnotation {
let facilityLocation: CLLocation = CLLocation(latitude: facility.geographyPoints.latitude, longitude: facility.geographyPoints.longitude)
let distance: CLLocationDistance = facilityLocation.distance(from: location)
let measurement: Measurement = Measurement(value: distance, unit: UnitLength.meters)
let string: String = if distance >= 1000 {
String(format: "%.0lf km away", measurement.converted(to: .kilometers).value)
} else {
String(format: "%.0lf m away", measurement.value)
}
UIView.animate(withDuration: 1 / 3) {
annotation.coordinate = CLLocationCoordinate2D(latitude: facility.geographyPoints.latitude, longitude: facility.geographyPoints.longitude)
annotation.distanceInMeters = distance
annotation.subtitle = string
}
}
} else {
let facilityLocation: CLLocation = CLLocation(latitude: facility.geographyPoints.latitude, longitude: facility.geographyPoints.longitude)
let distance: CLLocationDistance = facilityLocation.distance(from: location)
let measurement: Measurement = Measurement(value: distance, unit: UnitLength.meters)
let string: String = if distance >= 1000 {
String(format: "%.0lf km away", measurement.converted(to: .kilometers).value)
} else {
String(format: "%.0lf m away", measurement.value)
}
let pointAnnotation: FacilityAnnotation = FacilityAnnotation(coordinate: CLLocationCoordinate2D(latitude: facility.geographyPoints.latitude, longitude: facility.geographyPoints.longitude),
title: facility.name.capitalized,
subtitle: string,
distanceInMeters: distance,
facility: facility)
addAnnotation(pointAnnotation)
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment