| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195 |
- //
- // Models.swift
- // Runner
- //
- // Created by Groot on 2025/5/9.
- //
- import Foundation
- import MapKit
- extension Decodable {
- static func fromJson(json: Any) -> Self? {
- do {
- let data = try JSONSerialization.data(withJSONObject: json, options: [])
- return try JSONDecoder().decode(Self.self, from: data)
- } catch {
- print(error.localizedDescription)
- return nil
- }
- }
- }
- 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]
- }
- }
- struct ATMapCameraPosition: Codable {
- var latitude: CGFloat
- var longitude: CGFloat
- // 地图缩放比例,对应span
- var zoom: CGFloat
- }
- struct ATMapPadding: Codable {
- var top: CGFloat
- var left: CGFloat
- var bottom: CGFloat
- var right: CGFloat
- var padding: UIEdgeInsets {
- return UIEdgeInsets(top: top, left: left, bottom: bottom, right: right)
- }
- }
- class ATMapPolyline: NSObject, Codable {
- var id: String = UUID().uuidString
- var points: [CLLocationCoordinate2D]
-
- var mapPadding: ATMapPadding?
-
- var polyline: MKPolyline {
- return MKPolyline(coordinates: points, count: points.count)
- }
- enum CodingKeys: String, CodingKey {
- case points, mapPadding
- }
-
- required init(from decoder: Decoder) throws {
- let container = try decoder.container(keyedBy: CodingKeys.self)
-
- points = try container.decode([CLLocationCoordinate2D].self, forKey: .points)
-
- if container.contains(.mapPadding) {
- mapPadding = try container.decodeIfPresent(ATMapPadding.self, forKey: .mapPadding)
- }
- }
-
- func encode(to encoder: Encoder) throws {
- var container = encoder.container(keyedBy: CodingKeys.self)
- try container.encode(points, forKey: .points)
- try container.encodeIfPresent(mapPadding, forKey: .mapPadding)
- }
- }
- class ATMapMarker: NSObject, Codable {
- var id: String
- var markerName: String?
- var latitude: CGFloat
- var longitude: CGFloat
- var isSelected: Bool
- var markerType: any MapMarkerSupportType
- init(id: String, markerName: String?, location: CLLocationCoordinate2D, markerType: any MapMarkerSupportType, isSelected: Bool = false) {
- self.id = id
- self.markerName = markerName
- self.latitude = location.latitude
- self.longitude = location.longitude
- self.markerType = markerType
- self.isSelected = isSelected
- }
-
- func update(coordinate: CLLocationCoordinate2D, name: String? = nil, isSelect: Bool) {
- self.latitude = coordinate.latitude
- self.longitude = coordinate.longitude
- self.markerName = name
- self.isSelected = isSelect
- }
- enum CodingKeys: String, CodingKey {
- case id, markerName, latitude, longitude, isSelected, markerType
- }
- required init(from decoder: Decoder) throws {
- let container = try decoder.container(keyedBy: CodingKeys.self)
- id = try container.decode(String.self, forKey: .id)
- if id.isEmpty {
- id = "user_location"
- }
- if container.contains(.markerName) {
- markerName = try container.decodeIfPresent(String.self, forKey: .markerName)
- }
- latitude = try container.decode(CGFloat.self, forKey: .latitude)
- longitude = try container.decode(CGFloat.self, forKey: .longitude)
- isSelected = try container.decode(Bool.self, forKey: .isSelected)
-
- // 使用工厂方法创建正确类型的markerType
- let rawValue = try container.decode(Int.self, forKey: .markerType)
- markerType = MarkerTypeFactory.markerType(from: rawValue)
- }
- func encode(to encoder: Encoder) throws {
- var container = encoder.container(keyedBy: CodingKeys.self)
- try container.encode(id, forKey: .id)
- try container.encode(markerName, forKey: .markerName)
- try container.encode(latitude, forKey: .latitude)
- try container.encode(longitude, forKey: .longitude)
- try container.encode(isSelected, forKey: .isSelected)
- try container.encode(markerType.rawValue, forKey: .markerType)
- }
- }
- 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)
- }
- }
- class ATMapLocation: NSObject, Codable {
- var latitude: CGFloat?
- var longitude: CGFloat?
- var address: String?
- var errorCode: Int = 0
- var time: Int?
- var bearing: CGFloat?
- var speed: CGFloat?
- init(latitude: CGFloat? = nil, longitude: CGFloat? = nil, address: String? = nil, time: Int? = nil, bearing: CGFloat? = nil, speed: CGFloat? = nil) {
- self.latitude = latitude
- self.longitude = longitude
- self.address = address
- self.time = time
- self.bearing = bearing
- self.speed = speed
- super.init()
- }
- static func fromLocation(location: CLLocation) -> ATMapLocation {
- return ATMapLocation(
- latitude: CGFloat(location.coordinate.latitude),
- longitude: CGFloat(location.coordinate.longitude),
- address: nil,
- time: Int(location.timestamp.timeIntervalSince1970 * 1000),
- bearing: CGFloat(location.course),
- speed: CGFloat(location.speed)
- )
- }
- }
|