我希望创建与我在移动应用程序AroundMe Mobile App中看到的完全相同的指南针/箭头,它根据我的手机位置准确地指向地图上的一个点,并在我移动手机时更新箭头。
我非常烦恼,无法确切理解如何做到这一点,也找不到任何解释一点的指南或教程。
我在网上找到了一个方位函数,并创建了一个指令来围绕它进行操作:
app.directive('arrow', function () {
function bearing(lat1, lng1, lat2, lng2) {
var dLon = (lng2 - lng1);
var y = Math.sin(dLon) * Math.cos(lat2);
var x = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(dLon);
var rad = Math.atan2(y, x);
var brng = toDeg(rad);
return (brng + 360) % 360;
}
function toRad(deg) {
return deg * Math.PI / 180;
}
function toDeg(rad) {
return rad * 180 / Math.PI;
}
return {
restrict: 'E',
link: function (scope, element, attrs) {
var arrowAngle = bearing(scope.user.position.lat, scope.user.position.lng, attrs.lat, attrs.lng);
element.parent().css('transform', 'rotate(' + arrowAngle + 'deg)');
}
};
});
看起来箭头朝着一个方向更新了,但不幸的是这不是正确的方向,因为它没有使用移动设备的 magneticHeading
位置进行计算。
所以我添加了 ngCordova
插件用于设备方向,以获取 magneticHeading
,现在我不确定应该如何在 bearing
函数中使用它。
$cordovaDeviceOrientation.getCurrentHeading().then(function(result) {
var magneticHeading = result.magneticHeading;
var arrowAngle = bearing(scope.user.position.lat, scope.user.position.lng, attrs.lat, attrs.lng, magneticHeading);
element.parent().css('transform', 'rotate(' + arrowAngle + 'deg)');
});
我尝试将其添加到返回语句中:
return (brng - heading) % 360;
或者:return (heading - ((brng + 360) % 360));
使用监视器实现此代码时,我看到箭头移动了,但位置不准确...例如,从我的位置和引脚指向的位置上,箭头应该指向N,但它指向E。
我一直在网上搜索,但找不到任何教程/问题来查找lat/lng点
和magnetingHeading
之间的方位角。
也许我接近解决方案,但我无法独自前进。
我还试图搜索数学公式,但即使理解和实现它也是非常困难的。
希望您能帮助。
navigator.geolocation.watchPosition(function(position){ var heading = position.coords.heading;});
- StackSlavereturn (brng - heading - 90) % 360;
那样减去90度呢? - coyer