MAUI获取精准位置问题:轨迹不准确及未移动时异常漂移
位置轨迹绘制问题求助
我用以下代码获取用户当前位置:
public class GetCurrentLocations { private CancellationTokenSource _cancelTokenSource; private bool _isCheckingLocation; public async Task GetCurrentLocation() { try { _isCheckingLocation = true; GeolocationRequest request = new GeolocationRequest(GeolocationAccuracy.High, TimeSpan.FromSeconds(10)); _cancelTokenSource = new CancellationTokenSource(); Location location = await Geolocation.Default.GetLocationAsync(request, _cancelTokenSource.Token); if (location != null) Preferences.Default.Set("latitude", location.Latitude); Preferences.Default.Set("longitude", location.Longitude); Utility.DebugAndLog("Values:>>", $"Latitude: {location.Latitude}, Longitude: {location.Longitude}, Altitude: {location.Altitude}"); } catch (Exception ex) { // 无法获取位置 Utility.SendCrashReport(ex); } finally { _isCheckingLocation = false; } } public void CancelRequest() { try { if (_isCheckingLocation && _cancelTokenSource != null && _cancelTokenSource.IsCancellationRequested == false) _cancelTokenSource.Cancel(); } catch (Exception exception) { Utility.SendCrashReport(exception); } } }
使用该类时,我会对比新旧位置,只有不同时才通过API上传到服务器:
GetCurrentLocations getcurrentLocations = new GetCurrentLocations(); await getcurrentLocations.GetCurrentLocation(); string latitude = Preferences.Default.Get("latitude", ""); string longitude = Preferences.Default.Get("longitude", ""); string oldLatitude = Preferences.Default.Get("oldLatitude", ""); string oldLongitude = Preferences.Default.Get("oldLongitude", ""); if (latitude != oldLatitude && longitude != oldLongitude) { Preferences.Default.Set("oldLatitude", latitude); Preferences.Default.Set("oldLongitude", longitude); // 调用API保存新位置信息 } else { // 无操作 }
每10秒共享一次位置,并用以下代码绘制轨迹:
Polyline polyline = new Polyline { StrokeColor = Color.FromArgb("#ea4333"), StrokeWidth = 5, }; int step = Math.Max(1, validCoordinates.Count / 50); for (int i = 0; i < validCoordinates.Count; i += step) { polyline.Geopath.Add(validCoordinates[i]); } map.MapElements.Add(polyline);
XAML地图布局:
<maps:Map x:Name="map" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" MapClicked="MapClicked" IsScrollEnabled="True" IsTrafficEnabled="False" MapType="Street" IsZoomEnabled="True"> </maps:Map>
现在遇到两个问题:
- 部分设备轨迹绘制不准确,另一部分设备运行正常;
- 部分设备中用户未移动,但轨迹仍显示变化,想了解用户静止时是否会出现位置坐标变更。
用户未移动时的错误轨迹截图:


问题原因及解决方案
用户未移动却出现位置变更的原因
这是定位技术的正常误差导致:
- GPS、基站定位本身存在精度范围(GPS一般3-10米,基站定位误差更大),哪怕用户静止,每次获取的坐标也会在真实位置周围小幅波动;
- 代码直接对比字符串形式的经纬度,小数点后几位的微小差异都会被判定为“位置变化”,进而上传并绘制无效轨迹。
轨迹不准确的优化方案
设置位置变化距离阈值
不要直接对比经纬度字符串,计算两次位置的实际直线距离,只有超过设定阈值(比如5米)时,才判定为有效移动:// 将存储的字符串转为数值类型 if (double.TryParse(latitude, out double newLat) && double.TryParse(longitude, out double newLng) && double.TryParse(oldLatitude, out double oldLat) && double.TryParse(oldLongitude, out double oldLng)) { // 计算两点距离(单位:米) var distance = Location.CalculateDistance(new Location(newLat, newLng), new Location(oldLat, oldLng), DistanceUnits.Meters); // 设定5米为有效移动阈值 if (distance > 5) { Preferences.Default.Set("oldLatitude", latitude); Preferences.Default.Set("oldLongitude", longitude); // 调用上传API } }优化定位请求逻辑
- 若场景允许,可将
GeolocationAccuracy.High调整为Medium,平衡精度与设备性能; - 增加位置精度过滤,只保留精度符合要求的坐标:
if (location != null && location.Accuracy <= 10) // 只保留精度在10米以内的位置数据 { Preferences.Default.Set("latitude", location.Latitude); Preferences.Default.Set("longitude", location.Longitude); Utility.DebugAndLog("Values:>>", $"Latitude: {location.Latitude}, Longitude: {location.Longitude}, Altitude: {location.Altitude}"); }
- 若场景允许,可将
修复代码逻辑漏洞
获取位置的代码中,if (location != null)未加大括号,导致设置经度的代码永远执行,哪怕location为null,会引发空引用异常,修正如下:if (location != null) { Preferences.Default.Set("latitude", location.Latitude); Preferences.Default.Set("longitude", location.Longitude); Utility.DebugAndLog("Values:>>", $"Latitude: {location.Latitude}, Longitude: {location.Longitude}, Altitude: {location.Altitude}"); }轨迹绘制优化
- 当前步长计算可能跳过过多有效点,导致轨迹失真,若坐标量不大可直接去掉步长,添加所有点;
- 对轨迹点使用道格拉斯-普克算法做抽稀处理,过滤冗余的波动点,让轨迹更贴合真实路径。
内容的提问来源于stack exchange,提问作者Matthew Pans
相关产品推荐
相关产品推荐

