我需要使用WGS84库将EPSG:4312中的点转换为GeoTools。但我不确定我是否正确地使用了它,也不确定它是否提供了正确的结果。
请参阅以下代码示例:
@Test
public void testSingle4312ToWGS84() throws FactoryException, TransformException {
double latitude = 29.0;
double longitude = -99.0;
CoordinateReferenceSystem sourceCrs = CRS.decode("EPSG:4312");
CoordinateReferenceSystem targetCrs = CRS.decode("EPSG:4326");
MathTransform engine = CRS.findMathTransform(sourceCrs, targetCrs, false);
DirectPosition source = new DirectPosition2D(sourceCrs, longitude, latitude);
DirectPosition target = new DirectPosition2D(targetCrs);
engine.transform(source, target);
System.out.println("x,y=" + target.getCoordinate()[0] + "," + target.getCoordinate()[1]);
}当运行上面的代码时,我得到以下结果:
x,y=-81.00483829765083,-150.99434404015307这是错误的,因为-150不是一个有效的纬度。
当我创建源对象时,我用经度初始化了X,用纬度初始化了Y,遵循了X实际上是经度,Y是纬度的基本原理(根据地理社区)。但是,如果我把它们颠倒过来:
DirectPosition source = new DirectPosition2D(sourceCrs, latitude, longitude);我现在得到一个看起来更真实的结果:
x,y=29.003866857343915,-98.99222530180596当然,我现在必须把X解释为纬度,Y解释为经度。
那么,问题1,我们是否应该用逆理性,把X当作纬度,Y当作经度呢?
接下来,我想验证结果。首先,尝试使用Oracle SQL SDO函数转换同一点:
select sdo_cs.transform (
MDSYS.SDO_GEOMETRY(2001, 4312, MDSYS.SDO_POINT_TYPE(-99, 29, NULL), NULL, NULL),
8307
) from dual;提供下列结果:
MDSYS.SDO_GEOMETRY(2001, 8307, MDSYS.SDO_POINT_TYPE(-98.9924748682774, 29.0036029261273, NULL), NULL, NULL)转换点与GeoTools产生的转换点相似,但相差约40米。
接下来,我尝试了这个网站提供的转换,它提供了与Oracle相同的结果。我还使用了Luciad,这是一个GML的图形表示工具,这也显示了我在Oracle计算的位置上的位置。
因此,我有3个独立的工具,提供了相同的结果点,距离GeoTools计算的结果点40米。问题2,为什么Geotools会失败?对于CRS转换来说,Geotools可靠吗?
发布于 2021-03-29 07:51:12
关于轴顺序的第一个问题,你陷入了一个普通初学者的问题,假设你知道投影的轴序是什么,在ESPG:4326的情况下,它是固定的。
例如,以下代码:
CoordinateReferenceSystem targetCrs = CRS.decode("EPSG:4326");
System.out.println("EPSG:4326 - " + CRS.getAxisOrder(targetCrs));
System.out.println("WGS84 - " + CRS.getAxisOrder(DefaultGeographicCRS.WGS84));给出这个输出:
EPSG:4326 - NORTH_EAST
WGS84 - EAST_NORTH但是,如果添加行Hints.putSystemDefault(Hints.FORCE_LONGITUDE_FIRST_AXIS_ORDER, Boolean.TRUE);,输出将变成:
EPSG:4326 - EAST_NORTH
WGS84 - EAST_NORTH因此,通常您不应该依赖代码中的“已知”轴顺序,而应该使用如下所示的方法:
double latitude = 29.0;
double longitude = -99.0;
CoordinateReferenceSystem sourceCrs = CRS.decode("EPSG:4312");
CoordinateReferenceSystem targetCrs = CRS.decode("EPSG:4326");
MathTransform engine = CRS.findMathTransform(sourceCrs, targetCrs, false);
DirectPosition2D source;
if (CRS.getAxisOrder(sourceCrs).equals(org.geotools.referencing.CRS.AxisOrder.EAST_NORTH)) {
source = new DirectPosition2D(sourceCrs, longitude, latitude);
} else {
source = new DirectPosition2D(sourceCrs, latitude, longitude);
}
DirectPosition target = new DirectPosition2D(targetCrs);
engine.transform(source, target);
if (CRS.getAxisOrder(targetCrs).equals(org.geotools.referencing.CRS.AxisOrder.EAST_NORTH)) {
System.out.println("lon,lat=" + target.getCoordinate()[0] + "," + target.getCoordinate()[1]);
} else {
System.out.println("lon,lat=" + target.getCoordinate()[1] + "," + target.getCoordinate()[0]);
}至于转换的准确性,这取决于您导入的引用模块以及Oracle使用的CRS定义。在加载了gt-epsg-hsql模块之后,我看到了与EPSG登记处中提供的最精确的转换相同的ToWGS84[601.705, 84.263, 485.227, 4.7354, -1.3145, -5.393, -2.3887]矩阵。如果有可用的NTv2转换,那么将其添加到项目中应该可以提高精度。
https://stackoverflow.com/questions/66844320
复制相似问题