Получить направление (компас) с двумя точками долготы / широты
Я работаю над "компасом" для мобильного устройства. У меня есть следующие моменты:
point 1 (current location): Latitude = 47.2246, Longitude = 8.8257
point 2 (target location): Latitude = 50.9246, Longitude = 10.2257
Также у меня есть следующая информация (с моего андроид-телефона):
The compass-direction in degree, wich bears to the north.
For example, when I direct my phone to north, I get 0°
Как я могу создать "подобную компасу" стрелку, которая показывает мне направление к точке?
Есть ли математическая проблема для этого?
Спасибо!
РЕДАКТИРОВАТЬ: Хорошо, я нашел решение, это выглядит так:
/**
* Params: lat1, long1 => Latitude and Longitude of current point
* lat2, long2 => Latitude and Longitude of target point
*
* headX => x-Value of built-in phone-compass
*
* Returns the degree of a direction from current point to target point
*
*/
function getDegrees(lat1, long1, lat2, long2, headX) {
var dLat = toRad(lat2-lat1);
var dLon = toRad(lon2-lon1);
lat1 = toRad(lat1);
lat2 = toRad(lat2);
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 = toDeg(Math.atan2(y, x));
// fix negative degrees
if(brng<0) {
brng=360-Math.abs(brng);
}
return brng - headX;
}
Это прекрасно работает для меня!
4 ответа
О забыл сказать, что я нашел ответ в конце концов. Приложение должно определить направление компаса транзитного транспортного средства и его пункт назначения. По сути, интересная математика для получения кривизны Земли, нахождения угла / показания компаса, а затем сопоставления этого угла с общим значением компаса. Конечно, вы можете просто сохранить compassReading и применить его как величину поворота для вашего изображения. Обратите внимание, что это усредненное определение направления движения автомобиля до конечной точки (автобусной станции), означающее, что он не может знать, что делает дорога (поэтому это, вероятно, лучше всего относится к самолетам или дерби на роликах).
//example obj data containing lat and lng points
//stop location - the radii end point
endpoint.lat = 44.9631;
endpoint.lng = -93.2492;
//bus location from the southeast - the circle center
startpoint.lat = 44.95517;
startpoint.lng = -93.2427;
function vehicleBearing(endpoint, startpoint) {
endpoint.lat = x1;
endpoint.lng = y1;
startpoint.lat = x2;
startpoint.lng = y2;
var radians = getAtan2((y1 - y2), (x1 - x2));
function getAtan2(y, x) {
return Math.atan2(y, x);
};
var compassReading = radians * (180 / Math.PI);
var coordNames = ["N", "NE", "E", "SE", "S", "SW", "W", "NW", "N"];
var coordIndex = Math.round(compassReading / 45);
if (coordIndex < 0) {
coordIndex = coordIndex + 8
};
return coordNames[coordIndex]; // returns the coordinate value
}
то есть: vehicleBearing(mybus, busstation) может вернуть "NW" означает, что он движется на северо-запад
Я нашел несколько полезных формул GPS-координат в математике здесь. Для этого случая здесь мое решение
private double getDirection(double lat1, double lng1, double lat2, double lng2) {
double PI = Math.PI;
double dTeta = Math.log(Math.tan((lat2/2)+(PI/4))/Math.tan((lat1/2)+(PI/4)));
double dLon = Math.abs(lng1-lng2);
double teta = Math.atan2(dLon,dTeta);
double direction = Math.round(Math.toDegrees(teta));
return direction; //direction in degree
}
Я не мог понять ваше решение, рассчитав уклон работал для меня. Чтобы изменить efwjames и ваш ответ. Это должно сделать -
import math
def getDegrees(lat1, lon1, lat2, lon2,head):
dLat = math.radians(lat2-lat1)
dLon = math.radians(lon2-lon1)
bearing = math.degrees(math.atan2(dLon, dLat))
return head-bearing
Вам нужно будет вычислить евклидов вектор между начальной и конечной точками, а затем рассчитать его угол (скажем, относительно положительного X), который будет углом, на который вы хотите повернуть стрелку.