如何从标记池中筛选出距离当前位置最近的标记作为折线终点
如何从标记池中筛选出距离当前位置最近的标记作为折线终点
Hey 兄弟,我看了你遇到的问题——要从一堆充电站标记里挑出离你当前位置最近的那个,当作折线的终点,对吧?这事儿其实没那么复杂,我给你拆解成几步来搞:
第一步:先搞定「计算两点距离」的工具函数
你需要一个能算出两个经纬度(你的当前位置和每个充电站)之间实际距离的方法。Flutter里有个很方便的包叫geolocator,它自带了distanceBetween方法,直接就能算米数,不用自己写复杂的球面公式。当然如果你不想加包,也可以自己实现Haversine公式,不过用现成的包省事儿多了。
如果用geolocator的话,先在pubspec里加依赖,然后用这个方法:
import 'package:geolocator/geolocator.dart'; // 计算两个LatLng之间的距离(单位:米) double calculateDistance(LatLng start, LatLng end) { return Geolocator.distanceBetween( start.latitude, start.longitude, end.latitude, end.longitude, ); }
要是不想加包,我也可以给你写个手动实现的Haversine公式版本,不过还是推荐用现成的,不容易出错。
第二步:遍历所有充电站,找出最近的那个
有了计算距离的方法,接下来就是遍历你的evStations列表,挨个算距离,然后记录下距离最小的那个Station就行。
写个这样的函数:
Station? findNearestStation(LatLng currentLocation, List<Station> stations) { if (stations.isEmpty) return null; // 空列表直接返回null Station nearestStation = stations.first; double shortestDistance = calculateDistance(currentLocation, nearestStation.locationCoords); for (Station station in stations) { double currentDistance = calculateDistance(currentLocation, station.locationCoords); if (currentDistance < shortestDistance) { shortestDistance = currentDistance; nearestStation = station; } } return nearestStation; }
这个函数的逻辑很简单:先把第一个充电站当作初始的“最近点”,然后逐个对比后面的,只要发现更近的,就更新最近的Station和最短距离,最后返回那个最近的。
第三步:把最近的充电站传给你的折线函数
现在你可以在调用getDirections的地方,先拿到当前位置,然后调用上面的函数找出最近的充电站,再把它的坐标传进去:
// 先获取当前位置(注意处理null的情况!) LatLng? currentPos = LocationManager.shared.currentPos; if (currentPos == null) { // 这里可以加个提示,比如Toast或者弹窗,告诉用户还没获取到位置 return; } // 找出最近的充电站 Station? nearestStation = findNearestStation(currentPos, evStations); if (nearestStation == null) { // 没有充电站的情况,也要处理 return; } // 现在调用getDirections,把最近的充电站坐标当终点 Directions? directions = await getDirections( origin: currentPos, destination: nearestStation.locationCoords, );
对了,你原来的getDirections函数里有两个小坑我帮你填上:
- 你已经在参数里接收了
origin,就别再内部从LocationManager拿了,直接用传进来的参数就行 - Google Maps Directions API的
origin和destination参数需要是"纬度,经度"格式的字符串,不能直接传LatLng对象,所以改一下你的getDirections:
Future<Directions?> getDirections({ required LatLng origin, required LatLng destination, }) async { final response = await _dio.get( _baseURL, queryParameters: { 'origin': '${origin.latitude},${origin.longitude}', 'destination': '${destination.latitude},${destination.longitude}', 'key': google_API_Key, }, ); if (response.statusCode == 200) { return Directions.fromMap(response.data); } return null; }
最后补个小提示
如果你的充电站列表特别大(比如几百上千个),遍历一遍可能有点慢,这时候可以考虑用一些空间索引的算法(比如KD-Tree)来优化,但一般小列表的话,直接遍历完全够用,不用搞那么复杂。
内容来源于stack exchange
相关产品推荐
相关产品推荐

