在我的webapp中,有一个来自数据库查询的JSON数据响应,其中包括1到n个位置的纬度/经度坐标。我想计算从data[i]
位置到当前位置的方位。
我一直在修改这里的代码,但返回的方位不正确。
//starting lat/long along with converting lat to rads
var endLat = toRad(location.lat());
var endLong = location.lng();
//loop over response, calculate new headings for links and add link to array
for(var i=0; i<data.length; i++){
//this link's lat/long coordinates, convert lat to rads
var startLat = toRad(data[i].lat);
var startLong = data[i].lon;
//get the delta values between start and end coordinates in rads
var dLong = toRad(endLong - startLong);
//calculate
var y = Math.sin(dLong)*Math.cos(endLong);
var x = Math.cos(startLat)*Math.sin(endLat)-Math.sin(startLat)*Math.cos(endLat)*Math.cos(dLong);
var bearing = Math.atan(y, x);
bearing = (toDeg(bearing) + 360) % 360;
panoLinks.push({'heading': bearing, 'description': data[i].description, 'pano': data[i].description});
}
//radian/degree conversions
function toRad(convert){
return convert * Math.PI/180;
}
function toDeg(convert){
return convert * 180/Math.PI;
}
使用上述函数和值
startLat= 43.6822, converts to 0.7623982145146669 radians
startLong= -70.450769
endLat= 43.682211, converts to 0.7623984065008848 radians
endLong= -70.45070
dLong = startLong - endLong, converts to 0.0000011170107216805305 radians
导致的方位度
bearing= 0.000014910023935499339
这肯定是错的。我哪里错了?
试试看,我一辈子都记不起我是从哪里得到的。。。
/**
* Calculate the bearing between two positions as a value from 0-360
*
* @param lat1 - The latitude of the first position
* @param lng1 - The longitude of the first position
* @param lat2 - The latitude of the second position
* @param lng2 - The longitude of the second position
*
* @return int - The bearing between 0 and 360
*/
bearing : function (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 brng = this._toDeg(Math.atan2(y, x));
return 360 - ((brng + 360) % 360);
},
/**
* Since not all browsers implement this we have our own utility that will
* convert from degrees into radians
*
* @param deg - The degrees to be converted into radians
* @return radians
*/
_toRad : function(deg) {
return deg * Math.PI / 180;
},
/**
* Since not all browsers implement this we have our own utility that will
* convert from radians into degrees
*
* @param rad - The radians to be converted into degrees
* @return degrees
*/
_toDeg : function(rad) {
return rad * 180 / Math.PI;
},
这是对已接受答案的编辑,并进行了一些修改,使其对我有效(主要是对lat、lng值使用toRad函数)。
var geo = {
/**
* Calculate the bearing between two positions as a value from 0-360
*
* @param lat1 - The latitude of the first position
* @param lng1 - The longitude of the first position
* @param lat2 - The latitude of the second position
* @param lng2 - The longitude of the second position
*
* @return int - The bearing between 0 and 360
*/
bearing : function (lat1,lng1,lat2,lng2) {
var dLon = this._toRad(lng2-lng1);
var y = Math.sin(dLon) * Math.cos(this._toRad(lat2));
var x = Math.cos(this._toRad(lat1))*Math.sin(this._toRad(lat2)) - Math.sin(this._toRad(lat1))*Math.cos(this._toRad(lat2))*Math.cos(dLon);
var brng = this._toDeg(Math.atan2(y, x));
return ((brng + 360) % 360);
},
/**
* Since not all browsers implement this we have our own utility that will
* convert from degrees into radians
*
* @param deg - The degrees to be converted into radians
* @return radians
*/
_toRad : function(deg) {
return deg * Math.PI / 180;
},
/**
* Since not all browsers implement this we have our own utility that will
* convert from radians into degrees
*
* @param rad - The radians to be converted into degrees
* @return degrees
*/
_toDeg : function(rad) {
return rad * 180 / Math.PI;
},
};
/** Usage **/
var myInitialBearing = geo.bearing(0,0,45,45);
在以下网址查找理论和在线计算器:http://www.movable-type.co.uk/scripts/latlong.html
如果你想要一个非常粗略的短距离方法,你可以使用6378137m的地球半径(WGS84球体半长轴的长度)来根据纬度和经度的差异计算三角形的边。然后计算适当的轴承。这将是一个真正的方位,但可能在短距离内足够近。
你需要让用户计算出当地的磁偏角。
例如:
startLat = 43.6822
startLong = -70.450769
endLat = 43.682211
endLong = -70.45070
diff lat = 0.000011 = 1.22m
diff long = 0.000069 = 7.68m
终点位于起点的北部和东部,因此方位可以通过以下方式找到:
tan a = 7.68 / 1.22
a = 81°
所以方向大约是东偏北。
这可能应该在地图和测量线程中。一旦你算出了数学题,就来这里找答案。
编辑
要将纬度转换为米,首先计算赤道(或任何大圆)处的地球周长:
c = 2πR where r = 6378137m
= 40,075,000 (approx)
然后得到360°外圆周的比率:
dist = c * deg / 360
= 40,075,000m * 0.000011° / 360°
= 1.223m
对于经度,距离随着纬度接近极点而变窄,因此使用相同的公式,结果乘以纬度的余弦:
= 40,075,000m * 0.000069° / 360° * cos(0.000011°)
= 7.681m
地球半径的值不一定准确,地球不是一个完美的球体(它是一个扁球体,有点梨形)。为了获得更高的精度,在不同的地方使用了不同的近似值,但我使用的近似值应该足够好。