Last active
February 4, 2026 16:05
-
-
Save jarrodnorwell/b165be16cf6475e68303f0806bce9459 to your computer and use it in GitHub Desktop.
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
| 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