iOS Swift中Google Maps已行驶折线移除方案咨询
解决Google Maps中动态移除用户已行驶折线的问题
我来帮你搞定这个在用户行驶过程中动态去掉已走过折线部分的需求,这在导航类App里确实是很实用的功能,咱们一步步来实现:
核心思路
要实现这个效果,关键是实时获取用户当前位置,然后在原折线路径中找到用户已经走过的部分,只保留从当前位置到终点的剩余路径,再重新绘制折线。
具体实现步骤
1. 配置位置监听(获取实时位置)
首先得确保能拿到用户的实时位置,所以需要用CLLocationManager来监听位置更新。如果你的代码里还没加,先把这部分补上:
import CoreLocation // 让你的ViewController遵守CLLocationManagerDelegate协议 class YourMapVC: UIViewController, CLLocationManagerDelegate { let locationManager = CLLocationManager() // 你已有的变量:mapView、polyline、path var mapView: GMSMapView! var polyline: GMSPolyline? var path: GMSPath? override func viewDidLoad() { super.viewDidLoad() // 初始化位置管理器 locationManager.delegate = self locationManager.desiredAccuracy = kCLLocationAccuracyBest // 请求位置权限(记得在Info.plist里配置NSLocationWhenInUseUsageDescription) locationManager.requestWhenInUseAuthorization() locationManager.startUpdatingLocation() // 你原有的绘制折线代码(就是你提供的那段请求Directions API并绘制折线的代码) drawRoute() } // 把你原有的绘制折线代码封装成方法 func drawRoute() { let origin = "\(24.96487181552221),\(67.06045475052892)" let destination = "\(24.96485719),\(67.06699558)" let url = "https://maps.googleapis.com/maps/api/directions/json?origin=\(origin)&destination=\(destination)&mode=driving&key=[Google-API-Key]" Alamofire.request(url).responseJSON { response in do{ let json = try JSON(data: response.data!) let routes = json["routes"].arrayValue for route in routes { let routeOverviewPolyline = route["overview_polyline"].dictionary let points = routeOverviewPolyline?["points"]?.stringValue self.path = GMSPath.init(fromEncodedPath: points!) self.polyline = GMSPolyline(path: self.path) self.polyline?.strokeColor = UIColor(hexString: "19C90E") self.polyline?.strokeWidth = 3.0 self.polyline?.map = self.mapView } } catch let error { print(error) } } } }
2. 处理位置更新,动态更新折线
接下来实现CLLocationManager的位置更新回调方法,在这里完成折线的动态截取:
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { // 确保能拿到当前位置和完整路径 guard let currentLocation = locations.last, let fullPath = self.path else { return } // 找到当前位置在折线路径上的最近点索引(搜索半径设为100米,可根据需求调整) let nearestIndex = fullPath.index(of: currentLocation.coordinate, closestTo: 0, radius: 100) // 如果当前位置不在路径附近,跳过处理 guard nearestIndex != NSNotFound else { return } // 如果已经到达终点,移除折线并停止位置更新 if nearestIndex == fullPath.count() - 1 { self.polyline?.map = nil self.polyline = nil locationManager.stopUpdatingLocation() return } // 截取从最近点到终点的剩余路径 let remainingPath = GMSPath() for i in nearestIndex...fullPath.count() - 1 { let coordinate = fullPath.coordinate(at: i) remainingPath.add(coordinate) } // 更新折线:先移除旧折线,再添加新的剩余折线 self.polyline?.map = nil self.polyline = GMSPolyline(path: remainingPath) self.polyline?.strokeColor = UIColor(hexString: "19C90E") self.polyline?.strokeWidth = 3.0 self.polyline?.map = self.mapView // 更新全局path为剩余路径,方便下次位置更新时使用 self.path = remainingPath }
关键细节说明
index(of:closestTo:radius:)方法:这是GMSPath提供的API,用来在路径中查找离目标坐标最近的点的索引,radius参数控制搜索范围,比如设置100米可以允许用户稍微偏离路径时也能正确匹配。- 折线更新逻辑:每次更新时必须先把旧折线从地图上移除(
self.polyline?.map = nil),再添加新的剩余折线,避免地图上出现多条折线重叠。 - 终点判断:当用户到达路径的最后一个点时,直接移除折线并停止位置更新,节省资源。
内容的提问来源于stack exchange,提问作者Faraz Ahmed Khan
相关产品推荐
相关产品推荐

