geotools 大地测量计算器
geotools GeodeticCalculator
有两个点和一个距离,我正在尝试计算方位角,然后重新计算其中一个点。
但是计算出的点和原点之间的距离有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();
}
}
输出为:
Azimuth=44.97189638988797
computedEndPoint=Point2D.Double[-4.00014170719737, 41.49715519864095]
Distance=53.17698966547863
我希望 computedEndPoint 与从一开始就声明的终点非常相似(如果不完全相似的话)。
并且这两点之间的距离要接近于零。
现在我的问题是:我做错了什么?
还是 GeodedicCalculator 中存在一些错误?
50 米超过 130 公里是 0.04% 的误差 - 这对于迭代数值方法的往返来说非常好。
您正在使用 GeodedicCalculator
,它使用地球形状的近似值进行计算。 GeoTools uses the GeographicLib implementation of C. F. F. Karney, Algorithms for geodesics, J. Geodesy 87, 43–55 (2013),其中解释了用于解决问题的近似值。
这个answer on gis.stackexchange.com explains the level of accuracy you can expect from various numbers of decimal places when using latitude and longitude is also summarized in this XKCD cartoon:
您的最低精度点是 4DP,因此您不能期望从其余计算中得到比 10 米更好的精度。即使在航空领域,您也不太可能获得比 5 DP 更好的实际测量值,更有可能使用 3DP 和 10s-100s 米精度。
更新
进一步调查表明是您的原始距离值有误。
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
如您所见,所有错误都出现在第一次计算中,forward/reverse 行程给出了相同的点和 9e-10m 的距离误差。这对任何域都应该没问题。
有两个点和一个距离,我正在尝试计算方位角,然后重新计算其中一个点。
但是计算出的点和原点之间的距离有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();
}
}
输出为:
Azimuth=44.97189638988797
computedEndPoint=Point2D.Double[-4.00014170719737, 41.49715519864095]
Distance=53.17698966547863
我希望 computedEndPoint 与从一开始就声明的终点非常相似(如果不完全相似的话)。 并且这两点之间的距离要接近于零。
现在我的问题是:我做错了什么? 还是 GeodedicCalculator 中存在一些错误?
50 米超过 130 公里是 0.04% 的误差 - 这对于迭代数值方法的往返来说非常好。
您正在使用 GeodedicCalculator
,它使用地球形状的近似值进行计算。 GeoTools uses the GeographicLib implementation of C. F. F. Karney, Algorithms for geodesics, J. Geodesy 87, 43–55 (2013),其中解释了用于解决问题的近似值。
这个answer on gis.stackexchange.com explains the level of accuracy you can expect from various numbers of decimal places when using latitude and longitude is also summarized in this XKCD cartoon:
您的最低精度点是 4DP,因此您不能期望从其余计算中得到比 10 米更好的精度。即使在航空领域,您也不太可能获得比 5 DP 更好的实际测量值,更有可能使用 3DP 和 10s-100s 米精度。
更新
进一步调查表明是您的原始距离值有误。
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
如您所见,所有错误都出现在第一次计算中,forward/reverse 行程给出了相同的点和 9e-10m 的距离误差。这对任何域都应该没问题。