geotools GeodeticCalculator - PullRequest
       79

geotools GeodeticCalculator

0 голосов
/ 28 февраля 2020

Имея две точки и расстояние, я пытаюсь вычислить азимут, а затем пересчитать обратно одну из точек.

Однако расстояние между вычисленной точкой и исходной точкой составляет более 50 метров, что является довольно большой ошибкой.

Вот код:

 public static void main(String[] args) {

 double startLongitude = -5.1085;
 double startLatitude = 40.6682667;
 double endLongitude = -4.000597497067124;
 double endLatitude = 41.49682079962159;
 double distance = 130947.51;

 try {
 CoordinateReferenceSystem crs = CRS.decode("EPSG:4326");
 GeodeticCalculator calculator = new GeodeticCalculator(crs);

 calculator.setStartingGeographicPoint(startLongitude, startLatitude);
 calculator.setDestinationGeographicPoint(endLongitude, endLatitude);
 double azimuth = calculator.getAzimuth();
 System.out.println("Azimuth=" + azimuth);

 calculator = new GeodeticCalculator(crs);
 calculator.setStartingGeographicPoint(startLongitude, startLatitude);
 calculator.setDirection(azimuth, distance);
 Point2D computedEndPoint = calculator.getDestinationGeographicPoint();
 System.out.println("computedEndPoint=" + computedEndPoint);

 calculator = new GeodeticCalculator(crs);
 calculator.setStartingGeographicPoint(endLongitude, endLatitude);
 calculator.setDestinationGeographicPoint(computedEndPoint);
 distance = calculator.getOrthodromicDistance();
 System.out.println("Distance=" + distance);

 } catch (FactoryException e) {
 e.printStackTrace();
 }

}

Выходные данные:

Азимут = 44,97189638988797

computedEndPoint = Point2D.Double [-4.00014170719737, 41,49715519864095]

Расстояние = 53,17698966547863 * 101

Я ожидаю, что computedEndPoint будет очень похоже (если не совсем) на объявленную конечную точку с самого начала. И расстояние между этими двумя точками должно быть близко к нулю.

Теперь мой вопрос: что я делаю не так? Или в GeodedicCalculator есть какая-то ошибка?

1 Ответ

0 голосов
/ 01 марта 2020

50 м на 130 км - это ошибка 0,04% - это очень хорошо для кругового обхода итерационного численного метода.

Вы используете GeodedicCalculator, который использует приближение формы Земли для это расчеты. GeoTools использует GeographicLib реализацию C. Ф. Ф. Карней, Алгоритмы для геодезических , Дж. Геодезия 87, 43–55 (2013), в котором объясняются приближения, используемые для решения задачи.

Этот ответ на gis.stackexchange.com объясняет уровень точности, который вы можете ожидать от различного числа десятичных знаков при использовании широты и долготы, а также в этом XKCD мультфильме :

enter image description here

Ваша точка наименьшей точности равна 4DP, поэтому вы не можете ожидать намного лучше, чем 10 метров от остальной части расчета. Вы вряд ли получите намного лучше, чем 5 DP фактических измерений даже в авиационной области, и с большей вероятностью будете работать с точностью 3DP и метрами 10–100 с.

Обновление

Дальнейшие исследования показывают, что это ваше исходное значение расстояния, которое является неправильным.

  calculator.setStartingGeographicPoint(startLongitude, startLatitude);
  calculator.setDestinationGeographicPoint(endLongitude, endLatitude);
  double azimuth = calculator.getAzimuth();
  System.out.println("Azimuth=" + azimuth);
  double fullDistance = calculator.getOrthodromicDistance();
  System.out.println("distance " + fullDistance);
  System.out.println("% error " + (Math.abs(fullDistance - distance) / fullDistance) * 100);
  calculator = new GeodeticCalculator(crs);
  calculator.setStartingGeographicPoint(startLongitude, startLatitude);
  calculator.setDirection(azimuth, fullDistance);
  Point2D computedEndPoint = calculator.getDestinationGeographicPoint();
  System.out.println("computedEndPoint=" + computedEndPoint);

  calculator = new GeodeticCalculator(crs);
  calculator.setStartingGeographicPoint(endLongitude, endLatitude);
  calculator.setDestinationGeographicPoint(computedEndPoint);
  distance = calculator.getOrthodromicDistance();
  System.out.println("Distance=" + distance);
  System.out.println("% error " + ((distance / fullDistance) * 100));

дает мне:

Azimuth=44.971973670068415
distance 130893.86215735915
% error 0.04098575880994952
computedEndPoint=Point2D.Double[-4.000599999999989, 41.49682]
Distance=9.64120596409175E-10
% error 7.365666964965247E-13

Как вы видите, все ошибки появляются в 1-м расчете, прямое / обратное отключение дает одинаковую точку и ошибку 9e-10m на расстоянии. Это должно быть хорошо для любого домена.

...