Это продолжение этого вопроса.
Кажется, я застрял на этом. В принципе, мне нужно иметь возможность конвертировать туда и обратно, ссылаясь на координаты либо в системе стандартного градуса ИЛИ, измеряя расстояние на север от южного полюса вдоль международной линии дат, а затем на восток, начиная с этого момента на дате линия. Для этого (а также некоторых более общих измерений расстояния) у меня есть один метод определения расстояния между двумя точками lat/lon и другой метод, который принимает точку lat/lon, заголовок и расстояние и возвращает точка lat/lon в конце этого курса.
Вот два статических метода, которые я определил:
/* Takes two lon/lat pairs and returns the distance between them in kilometers.
*/
public static double distance (double lat1, double lon1, double lat2, double lon2) {
double theta = toRadians(lon1-lon2);
lat1 = toRadians(lat1);
lon1 = toRadians(lon1);
lat2 = toRadians(lat2);
lon2 = toRadians(lon2);
double dist = sin(lat1)*sin(lat2) + cos(lat1)*cos(lat2)*cos(theta);
dist = toDegrees(acos(dist)) * 60 * 1.1515 * 1.609344 * 1000;
return dist;
}
/* endOfCourse takes a lat/lon pair, a heading (in degrees clockwise from north), and a distance (in kilometers), and returns
* the lat/lon pair that would be reached by traveling that distance in that direction from the given point.
*/
public static double[] endOfCourse (double lat1, double lon1, double tc, double dist) {
double pi = Math.PI;
lat1 = toRadians(lat1);
lon1 = toRadians(lon1);
tc = toRadians(tc);
double dist_radians = toRadians(dist / (60 * 1.1515 * 1.609344 * 1000));
double lat = asin(sin(lat1) * cos(dist_radians) + cos(lat1) * sin(dist_radians) * cos(tc));
double dlon = atan2(sin(tc) * sin(dist_radians) * cos(lat1), cos(dist_radians) - sin(lat1) * sin(lat));
double lon = ((lon1-dlon + pi) % (2*pi)) - pi;
double[] endPoint = new double[2];
endPoint[0] = lat; endPoint[1] = lon;
return endPoint;
}
И вот функция, которую я использую для ее проверки:
public static void main(String args[]) throws java.io.IOException, java.io.FileNotFoundException {
double distNorth = distance(0.0, 0.0, 72.0, 0.0);
double distEast = distance(72.0, 0.0, 72.0, 31.5);
double lat1 = endOfCourse(0.0, 0.0, 0.0, distNorth)[0];
double lon1 = endOfCourse(lat1, 0.0, 90.0, distEast)[1];
System.out.println("end at: " + lat1 + " / " + lon1);
return;
}
Значения "end at" должны быть appx. 72,0/31,5. Но вместо этого я получаю примерно 1,25/0,021.
Я предполагаю, что я должен упустить что-то глупое, забыв конвертировать единицы где-то или что-то в этом роде. Любая помощь будет принята с благодарностью!
ОБНОВЛЕНИЕ 1:
Я (правильно) написал функцию расстояния, чтобы возвращать метры, но написал килограммы в комментариях по ошибке... что, конечно, смутило меня, когда я вернулся к нему сегодня. Во всяком случае, теперь это исправлено, и я исправил ошибку факторинга в методе endOfCourse, и я также понял, что забыл преобразовать обратно в градусы от радианов в этом методе. Во всяком случае: пока он появляется, я теперь получаю правильное число широты (71.99...), долгота - это путь (я получаю 3.54 вместо 11.5).
ОБНОВЛЕНИЕ 2: Как указано ниже, у меня была опечатка. Теперь он исправлен в коде. Однако число долготы все еще не так: я теперь получаю -11.34 вместо 11.5. Я думаю, что в этих строках должно быть что-то не так:
double dlon = atan2(sin(tc) * sin(dist_radians) * cos(lat1), cos(dist_radians) - sin(lat1) * sin(lat));
double lon = ((lon1-dlon + pi) % (2*pi)) - pi;