如何在经度的米级数值变化时触发alert提示?
问题分析与解决方案
核心问题1:米级变化的小数位判断错误
你误以为经度小数点后第三位对应米级,但实际换算关系是:
- 经度1度在赤道附近约等于111320米,0.001度≈111米,0.0001度才≈11米。所以行走10米时,变化的是小数点后第四位,第三位自然不会产生变动。
核心问题2:字符串截取不可靠
substr()方法依赖经度整数部分的位数(比如1位、2位、3位),一旦经度整数位发生变化,截取的位置就完全错误,必须用数值运算替代字符串操作。
解决方案:直接计算位置间的距离(更准确)
最可靠的方式是用Haversine公式计算两次定位的实际距离,当距离超过10米时触发提示,完全避开小数位和整数位的问题。
修正后的代码
JavaScript
// 存储上一次的位置坐标 let lastPosition = null; navigator.geolocation.watchPosition(function(position) { const currentLong = position.coords.longitude; const currentLat = position.coords.latitude; // 更新显示当前经度(保留7位小数) document.getElementById('currentLong').value = currentLong.toFixed(7); // 第一次定位时记录初始位置 if (!lastPosition) { lastPosition = { lat: currentLat, lng: currentLong }; document.getElementById('previousMeter').value = '初始位置'; return; } // 计算当前位置与上一次的距离(单位:米) const distance = calculateDistance( lastPosition.lat, lastPosition.lng, currentLat, currentLong ); // 距离≥10米时触发提示 if (distance >= 10) { alert('Meters differ'); // 更新上一次位置记录 lastPosition = { lat: currentLat, lng: currentLong }; document.getElementById('previousMeter').value = `距离上次: ${Math.round(distance)}米`; } }); // Haversine公式:计算两点间的球面距离(米) function calculateDistance(lat1, lng1, lat2, lng2) { const R = 6371000; // 地球半径(米) const dLat = (lat2 - lat1) * Math.PI / 180; const dLng = (lng2 - lng1) * Math.PI / 180; const a = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) * Math.sin(dLng/2) * Math.sin(dLng/2); const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); return R * c; }
HTML
<input type="text" id="currentLong" readonly> <label for="currentLong">Current Longitude:</label> <br> <input type="text" id="previousMeter" readonly> <label for="previousMeter">Previous Position Info:</label>
额外说明
- 为什么不用小数位判断?因为经度的米级换算和纬度强相关,高纬度地区经度1度的距离会大幅缩小,固定看某一位小数完全不准确。
- 可通过配置
watchPosition提升定位精度:
navigator.geolocation.watchPosition( successCallback, errorCallback, { enableHighAccuracy: true, timeout: 5000, maximumAge: 0 } );
内容的提问来源于stack exchange,提问作者Eslam
相关产品推荐
相关产品推荐

