瀏覽代碼

add:添加轨迹的边框。

“HeShaoZe” 4 月之前
父節點
當前提交
0bbf18dad2

+ 63 - 40
plugins/map_mapkit_ios/ios/Classes/MapView/ArrowPolylineRenderer.swift

@@ -14,32 +14,63 @@ class ArrowPolylineRenderer: MKPolylineRenderer {
     // 箭头属性
     var arrowColor: UIColor = .red
     var arrowSize: CGFloat = 8
-    var arrowSpacing: CGFloat = 30   // 默认值
+    var arrowSpacing: CGFloat = 30
     
     // 边框属性
-    var borderWidth: CGFloat = 0
-    var borderColor: UIColor = .clear
+    var borderWidth: CGFloat = 0 {
+        didSet {
+            invalidatePath()
+        }
+    }
     
-    override func draw(_ mapRect: MKMapRect, zoomScale: MKZoomScale, in context: CGContext) {
-        // 1. 绘制边框
-        if borderWidth > 0 {
-            context.saveGState()
-            // 边框宽度 = 主线条宽度 + 2倍边框宽度(左右各扩展 borderWidth)
-            let borderLineWidth = lineWidth + borderWidth * 2
-            context.setLineWidth(borderLineWidth)
-            context.setStrokeColor(borderColor.cgColor)
-            context.setLineCap(lineCap)  // 保持与主线条一致的线帽样式
-            context.setLineJoin(lineJoin) // 保持与主线条一致的拐角样式
-            // 绘制边框线条
-            super.draw(mapRect, zoomScale: zoomScale, in: context)
-            context.restoreGState()
+    var borderColor: UIColor = .clear {
+        didSet {
+            invalidatePath()
         }
+    }
+    
+    override func draw(_ mapRect: MKMapRect, zoomScale: MKZoomScale, in context: CGContext) {
+         // 1. 绘制边框(如果启用)
+         if borderWidth > 0 {
+             context.saveGState()
+             
+             // 设置边框样式
+             context.setLineWidth(lineWidth + borderWidth * 2)
+             context.setStrokeColor(borderColor.cgColor)
+             context.setLineCap(lineCap)
+             context.setLineJoin(lineJoin)
+             
+             // 创建路径并描边
+             let path = createPath(for: polyline, in: mapRect, zoomScale: zoomScale)
+             context.addPath(path)
+             context.strokePath()
+             
+             context.restoreGState()
+         }
+         
+         // 2. 绘制主线条
+         super.draw(mapRect, zoomScale: zoomScale, in: context)
+         
+         // 3. 绘制箭头
+         drawArrows(mapRect: mapRect, zoomScale: zoomScale, in: context)
+     }
+    
+    
+    private func createPath(for polyline: MKPolyline, in mapRect: MKMapRect, zoomScale: MKZoomScale) -> CGPath {
+        let path = CGMutablePath()
+        let points = polyline.points()
         
-        // 2. 绘制主轨迹线
-        super.draw(mapRect, zoomScale: zoomScale, in: context)
+        // 添加第一个点
+        let firstPoint = self.point(for: points[0])
+        path.move(to: firstPoint)
         
-        // 3. 绘制箭头(数量减半)
-        drawArrows(mapRect: mapRect, zoomScale: zoomScale, in: context)
+        // 添加剩余点
+        for i in 1..<polyline.pointCount {
+            let point = self.point(for: points[i])
+            path.addLine(to: point)
+        }
+        
+        return path
     }
     
     private func drawArrows(mapRect: MKMapRect, zoomScale: MKZoomScale, in context: CGContext) {
@@ -51,10 +82,6 @@ class ArrowPolylineRenderer: MKPolylineRenderer {
         var distance: CGFloat = 0
         let points = polyline.points()
         
-        // 使用stride跳过每隔一个的箭头
-        let step = 2 // 跳过间隔
-        var arrowIndex = 0
-        
         for i in 0..<polyline.pointCount-1 {
             let startPoint = point(for: points[i])
             let endPoint = point(for: points[i+1])
@@ -68,22 +95,18 @@ class ArrowPolylineRenderer: MKPolylineRenderer {
             let arrowCount = Int(floor((distance + segmentLength) / scaledArrowSpacing))
             
             for j in 0..<arrowCount {
-                // 只绘制每隔step个箭头
-                if arrowIndex % step == 0 {
-                    let position = CGFloat(j) * scaledArrowSpacing - distance
-                    let ratio = position / segmentLength
-                    
-                    guard ratio >= 0 && ratio <= 1 else { continue }
-                    
-                    let arrowPoint = CGPoint(
-                        x: startPoint.x + dx * ratio,
-                        y: startPoint.y + dy * ratio
-                    )
-                    
-                    let angle = atan2(dy, dx)
-                    drawSingleArrow(at: arrowPoint, angle: angle, size: scaledArrowSize, in: context)
-                }
-                arrowIndex += 1
+                let position = CGFloat(j) * scaledArrowSpacing - distance
+                let ratio = position / segmentLength
+                
+                guard ratio >= 0 && ratio <= 1 else { continue }
+                
+                let arrowPoint = CGPoint(
+                    x: startPoint.x + dx * ratio,
+                    y: startPoint.y + dy * ratio
+                )
+                
+                let angle = atan2(dy, dx)
+                drawSingleArrow(at: arrowPoint, angle: angle, size: scaledArrowSize, in: context)
             }
             
             distance = (distance + segmentLength).truncatingRemainder(dividingBy: scaledArrowSpacing)

+ 62 - 0
plugins/map_mapkit_ios/ios/Classes/MapView/Extension/UIColor+Hex.swift

@@ -0,0 +1,62 @@
+//
+//  UIColor+Hex.swift
+//  map_mapkit_ios
+//
+//  Created by 诺诺诺的言 on 2025/7/15.
+//
+
+import UIKit
+
+extension UIColor {
+    /// 从十六进制字符串初始化颜色(支持 #RGB、#RGBA、#RRGGBB、#RRGGBBAA 格式)
+    /// - Parameter hex: 十六进制颜色字符串,例如 "#15CBA1"、"FF0088"、"#F0F"
+    convenience init?(hex: String) {
+        // 1. 预处理:移除空格、换行,并转为大写(避免大小写问题)
+        let cleanedHex = hex.trimmingCharacters(in: .whitespacesAndNewlines).uppercased()
+        // 2. 处理带 # 的情况
+        let hexString = cleanedHex.hasPrefix("#") ? String(cleanedHex.dropFirst()) : cleanedHex
+        let length = hexString.count
+        
+        // 3. 验证格式是否合法(支持 3、4、6、8 位)
+        guard [3, 4, 6, 8].contains(length) else {
+            print("无效的十六进制颜色格式:\(hex)")
+            return nil
+        }
+        
+        // 4. 扫描十六进制数值
+        let scanner = Scanner(string: hexString)
+        var rgbValue: UInt64 = 0
+        guard scanner.scanHexInt64(&rgbValue) else {
+            print("无法扫描十六进制值:\(hex)")
+            return nil
+        }
+        
+        // 5. 根据长度解析 RGB 和透明度
+        switch length {
+        case 3: // #RGB -> 扩展为 #RRGGBB(如 #F0F -> #FF00FF)
+            let r = CGFloat((rgbValue & 0xF00) >> 8) / 15.0
+            let g = CGFloat((rgbValue & 0x0F0) >> 4) / 15.0
+            let b = CGFloat(rgbValue & 0x00F) / 15.0
+            self.init(red: r, green: g, blue: b, alpha: 1.0)
+        case 4: // #RGBA -> 扩展为 #RRGGBBAA
+            let r = CGFloat((rgbValue & 0xF000) >> 12) / 15.0
+            let g = CGFloat((rgbValue & 0x0F00) >> 8) / 15.0
+            let b = CGFloat((rgbValue & 0x00F0) >> 4) / 15.0
+            let a = CGFloat(rgbValue & 0x000F) / 15.0
+            self.init(red: r, green: g, blue: b, alpha: a)
+        case 6: // #RRGGBB(如 #15CBA1)
+            let r = CGFloat((rgbValue & 0xFF0000) >> 16) / 255.0
+            let g = CGFloat((rgbValue & 0x00FF00) >> 8) / 255.0
+            let b = CGFloat(rgbValue & 0x0000FF) / 255.0
+            self.init(red: r, green: g, blue: b, alpha: 1.0)
+        case 8: // #RRGGBBAA
+            let a = CGFloat((rgbValue & 0xFF000000) >> 24) / 255.0
+            let r = CGFloat((rgbValue & 0x00FF0000) >> 16) / 255.0
+            let g = CGFloat((rgbValue & 0x0000FF00) >> 8) / 255.0
+            let b = CGFloat(rgbValue & 0x000000FF) / 255.0
+            self.init(red: r, green: g, blue: b, alpha: a)
+        default:
+            return nil
+        }
+    }
+}

+ 4 - 1
plugins/map_mapkit_ios/ios/Classes/MapView/MapViewController.swift

@@ -144,7 +144,7 @@ extension MapViewController: MKMapViewDelegate {
         renderer.arrowSize = 12      // 增大箭头大小
         renderer.arrowSpacing = 40   // 减小箭头间距
         renderer.borderWidth = 1
-        renderer.borderColor = UIColor(red: 0.35, green: 0.36, blue: 0.99, alpha: 1)//UIColor.hex(0x5A5DFD)
+        renderer.borderColor = UIColor(red: 0.35, green: 0.36, blue: 0.99, alpha: 1)
         
         //normal error selected color
         if polyline.associatedLineType == "normal" {
@@ -153,6 +153,9 @@ extension MapViewController: MKMapViewDelegate {
             renderer.strokeColor = UIColor(red: 1, green: 0.43, blue: 0.43, alpha: 1)
         } else  if polyline.associatedLineType == "selected" {
             renderer.strokeColor = UIColor(red: 0.08, green: 0.8, blue: 0.63, alpha: 1)
+        } else if polyline.associatedLineType == "color" {
+            renderer.strokeColor = UIColor(hex: polyline.associatedColor ?? "#4476FF")
+            renderer.lineWidth = polyline.associatedWidth ?? 0
         }
         return renderer
     }