// // Models.swift // Runner // // Created by Groot on 2025/5/9. // import Foundation import MapKit extension Decodable { static func fromJson(json: [String: Any]) -> Self? { guard let data = try? JSONSerialization.data(withJSONObject: json, options: []) else { return nil } return try? JSONDecoder().decode(Self.self, from: data) } } extension Encodable { func toJson() -> [String: Any] { guard let data = try? JSONEncoder().encode(self) else { return [:] } return try! JSONSerialization.jsonObject(with: data, options: []) as! [String: Any] } } enum ATMapMarkerType: Int, CaseIterable { case mine = 1 case friend = 2 case traceStartPoint = 3 case traceEndFriendPoint = 4 case traceEndMinePoint = 5 } struct ATMapCameraPosition: Codable { var latitude: CGFloat var longitude: CGFloat // 地图缩放比例,对应span var zoom: CGFloat } class ATMapPolyline: NSObject, Codable { var id: String = UUID().uuidString var points: [CLLocationCoordinate2D] var polyline: MKPolyline { return MKPolyline(coordinates: points, count: points.count) } init(points: [CLLocationCoordinate2D]) { self.points = points } } class ATMapMarker: NSObject, Codable { var id: String var markerName: String var latitude: CGFloat var longitude: CGFloat var isSelected: Bool } extension ATMapMarker: MKAnnotation { var coordinate: CLLocationCoordinate2D { return CLLocationCoordinate2D(latitude: latitude, longitude: longitude) } } extension CLLocationCoordinate2D: Codable { enum CodingKeys: String, CodingKey { case latitude case longitude } public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) let latitude = try container.decode(Double.self, forKey: .latitude) let longitude = try container.decode(Double.self, forKey: .longitude) self.init(latitude: latitude, longitude: longitude) } public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(latitude, forKey: .latitude) try container.encode(longitude, forKey: .longitude) } }