google.maps.geometry.computeOffset是否存在Bug?恒向线绘制异常问询
谷歌地图恒向线绘制偏差问题分析
我尝试在谷歌地图上绘制一条始终指向东北方向(45度)的恒向线(rhumb line)——沿此线航行时罗盘始终指向东北方向(注:原描述笔误,前文东北/后文西北统一修正为东北)。基于Google Maps API编写了JS代码(测试时需替换API密钥),原本以为无论用多大间隔绘制,线条都应该完全重叠,但实际结果是:绘制的点越多,线条越接近屏幕的45度方向。

这是精度问题还是存在Bug?google.maps.geometry.computeOffset功能是否正常?我是否可以信任该函数?
测试代码
JavaScript 代码
function initMap() { var mapOptions = { zoom: 1, center: { lat: 30.363, lng: 250.044 } }; var map = new google.maps.Map(document.getElementById('map'), mapOptions); var origin = new google.maps.LatLng(-25.363, 214.044); var fineLoxo = drawRhumbLine(origin.lat(), origin.lng(), 45, 1000); var fineDrawingPath = new google.maps.Polyline({ path: fineLoxo, geodesic: false, // 设为false,因为恒向线不是测地线 strokeColor: '#000', strokeOpacity: 1.0, strokeWeight: 5 }); fineDrawingPath.setMap(map); var brokenLoxoPath = drawRhumbLine(origin.lat(), origin.lng(), 45, 4000000); var mediumDrawingPath = new google.maps.Polyline({ path: brokenLoxoPath, geodesic: false, // 设为false,因为恒向线不是测地线 strokeColor: '#FF0000', strokeOpacity: 1.0, strokeWeight: 2 }); mediumDrawingPath.setMap(map); var oneLoxoPath = drawRhumbLine(origin.lat(), origin.lng(), 45, 16000000); var straightDrawingPath = new google.maps.Polyline({ path: oneLoxoPath, geodesic: false, // 设为false,因为恒向线不是测地线 strokeColor: '#00F', strokeOpacity: 1.0, strokeWeight: 2 }); straightDrawingPath.setMap(map); } function drawRhumbLine(startLat, startLng, bearingDegrees, interval) { var dots = [] dots.push({ lat: startLat, lng: startLng }); for (let i = 0; i < 16000000 / interval; i++) { var tempOrigin = new google.maps.LatLng(startLat, startLng) var dest = google.maps.geometry.spherical.computeOffset(tempOrigin, interval, bearingDegrees); startLat = dest.lat(); startLng = dest.lng(); dots.push({ lat: startLat, lng: startLng }); } return dots; }
HTML 代码
<div id="map" style="height: 180px; width: 100%;"></div> <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&libraries=geometry&callback=initMap" async defer></script>
问题原因与解答
1. 核心问题:用错了计算函数
google.maps.geometry.spherical.computeOffset是基于**测地线(大圆航线)**计算的偏移,而非恒向线。测地线是地球表面两点间的最短路径,它的方位角是持续变化的;而恒向线的方位角固定,路径在非赤道/经线区域是螺旋线,只有在墨卡托投影上才呈现直线。
2. 点越多越接近45度的原因
当你用小间隔多次调用computeOffset时,每一段短测地线会近似恒向线的局部路径,叠加后整体效果更接近你预期的固定方位角;而大间隔(甚至一次偏移)时,直接画出的是两点间的测地线,和恒向线偏差自然明显。
3. 函数可靠性与修正方案
computeOffset本身功能正常,只是你用错了场景。要绘制真正的恒向线,需要实现专门的恒向线计算逻辑,比如基于墨卡托投影的特性推导坐标:
function drawRhumbLine(startLat, startLng, bearingDegrees, interval) { const R = 6378137; // 地球半径(米) const bearing = bearingDegrees * Math.PI / 180; const dots = [{lat: startLat, lng: startLng}]; let lat = startLat * Math.PI / 180; let lng = startLng * Math.PI / 180; const distancePerStep = interval; const totalDistance = 16000000; const steps = Math.floor(totalDistance / distancePerStep); for (let i = 0; i < steps; i++) { const d = distancePerStep / R; const dLat = d * Math.cos(bearing); const dLng = d * Math.sin(bearing) / Math.cos(lat); lat += dLat; lng += dLng; dots.push({ lat: lat * 180 / Math.PI, lng: lng * 180 / Math.PI }); } return dots; }
这个函数基于恒向线的数学公式计算,无论间隔大小,生成的路径都会完全重叠,符合固定方位角的需求。
内容的提问来源于stack exchange,提问作者Hoy Cheung
相关产品推荐
相关产品推荐

