// // MapKit+E.swift // Pods // // Created by Groot on 2025/5/14. // import MapKit import Foundation extension MKMapView { // 按比例 按padding适应annotation public func fitsAllPoints( points: [MKMapPoint], padding: UIEdgeInsets, aspectRatio: Double? = nil, animated: Bool = true ) { var zoomRect: MKMapRect = .null for point in points { let pointRect = MKMapRect(x: point.x, y: point.y, width: 0, height: 0) if zoomRect.isNull { zoomRect = pointRect } else { zoomRect = zoomRect.union(pointRect) } } // Calculate the desired size based on the aspect ratio let aspectRatio = aspectRatio ?? 1.0 let width = zoomRect.size.width let height = zoomRect.size.height let desiredWidth = max(width, height * aspectRatio) let desiredHeight = max(height, width / aspectRatio) // Calculate the center of the annotations let center = MKMapPoint(x: zoomRect.midX, y: zoomRect.midY) // Create a new MKMapRect with the desired aspect ratio and centered on the annotations let newMapRect = MKMapRect( x: center.x - desiredWidth / 2, y: center.y - desiredHeight / 2, width: desiredWidth, height: desiredHeight ) setVisibleMapRect(newMapRect, edgePadding: padding, animated: animated) } func calculateMapRect(points: [MKMapPoint], padding: UIEdgeInsets = .zero) -> MKMapRect { var zoomRect: MKMapRect = .null for point in points { let pointRect = MKMapRect(x: point.x, y: point.y, width: 0, height: 0) if zoomRect.isNull { zoomRect = pointRect } else { zoomRect = zoomRect.union(pointRect) } } return mapRectThatFits(zoomRect, edgePadding: padding) } func takeSnapShot(option: MKMapSnapshotter.Options, completion: @escaping (MKMapSnapshotter.Snapshot?) -> Void) { let shotter = MKMapSnapshotter(options: option) shotter.start(with: .global()) { shot, _ in completion(shot) } } ///移动至多个点的位置,并提供设置padding距离 func moveToSuitableLocation(points: [CLLocationCoordinate2D], padding: ATMapPadding? = nil) { // 检查是否有足够的点 guard points.count > 0 else { print("Error: No points provided to calculate suitable location") return } // 1. 计算所有点的边界 var minLat = points[0].latitude var maxLat = points[0].latitude var minLng = points[0].longitude var maxLng = points[0].longitude for point in points { minLat = min(minLat, point.latitude) maxLat = max(maxLat, point.latitude) minLng = min(minLng, point.longitude) maxLng = max(maxLng, point.longitude) } // 2. 创建包含所有点的区域 let centerLat = (minLat + maxLat) / 2 let centerLng = (minLng + maxLng) / 2 let center = CLLocationCoordinate2D(latitude: centerLat, longitude: centerLng) // 计算区域跨度,添加一些额外空间 let spanLat = (maxLat - minLat) * 1.1 // 增加10%的边距 let spanLng = (maxLng - minLng) * 1.1 // 确保跨度不为0且不过大 let safeSpanLat = max(min(spanLat, 100.0), 0.001) // 设置合理的最大跨度 let safeSpanLng = max(min(spanLng, 100.0), 0.001) // 创建初始区域 let span = MKCoordinateSpan(latitudeDelta: safeSpanLat, longitudeDelta: safeSpanLng) print("初始区域: center=\(center), span=\(span)") // 3. 创建区域并应用padding var region = MKCoordinateRegion(center: center, span: span) // 应用padding(如果有) if let padding = padding { // 检查地图视图尺寸是否有效 let mapViewWidth = max(self.bounds.width, 1.0) // 确保宽度至少为1 let mapViewHeight = max(self.bounds.height, 1.0) // 确保高度至少为1 // 基于地图视图尺寸和padding计算经纬度调整量 let latPadding = span.latitudeDelta * (padding.top + padding.bottom) / mapViewHeight let lngPadding = span.longitudeDelta * (padding.left + padding.right) / mapViewWidth // 调整区域跨度以应用padding,并确保不会导致无穷大 region.span.latitudeDelta = min(region.span.latitudeDelta + latPadding, 180.0) region.span.longitudeDelta = min(region.span.longitudeDelta + lngPadding, 360.0) print("应用padding后的区域: span=\(region.span)") } // 4. 验证最终区域是否有效 if !isValidRegion(region) { //print("无效区域,使用默认区域") region = defaultRegion() } print("最终使用的区域: \(region)") // 设置地图区域 self.setRegion(self.regionThatFits(region), animated: true) } // 辅助方法:检查区域是否有效 private func isValidRegion(_ region: MKCoordinateRegion) -> Bool { let center = region.center let span = region.span return !center.latitude.isNaN && !center.longitude.isNaN && !span.latitudeDelta.isNaN && !span.longitudeDelta.isNaN && !span.latitudeDelta.isInfinite && !span.longitudeDelta.isInfinite && isValidCoordinate(center) && span.latitudeDelta > 0 && span.latitudeDelta <= 180 && span.longitudeDelta > 0 && span.longitudeDelta <= 360 } // 辅助方法:提供默认有效区域 private func defaultRegion() -> MKCoordinateRegion { return MKCoordinateRegion( center: CLLocationCoordinate2D(latitude: 37.7749, longitude: -122.4194), span: MKCoordinateSpan(latitudeDelta: 0.1, longitudeDelta: 0.1) ) } // 辅助方法:检查坐标是否有效 private func isValidCoordinate(_ coordinate: CLLocationCoordinate2D) -> Bool { return coordinate.latitude >= -90 && coordinate.latitude <= 90 && coordinate.longitude >= -180 && coordinate.longitude <= 180 } ///是否隐藏地图图标 func mapLogoVisible(isHiddenLogo : Bool) { for subview in self.subviews { if let logo = subview as? UIImageView, logo.bounds.size.width <= 100, logo.bounds.size.height <= 20 { logo.isHidden = isHiddenLogo } } } }