首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用GeoTools MathTransform?

如何使用GeoTools MathTransform?
EN

Stack Overflow用户
提问于 2021-03-28 17:40:59
回答 1查看 460关注 0票数 0

我需要使用WGS84库将EPSG:4312中的点转换为GeoTools。但我不确定我是否正确地使用了它,也不确定它是否提供了正确的结果。

请参阅以下代码示例:

代码语言:javascript
运行
复制
    @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]);
    }

当运行上面的代码时,我得到以下结果:

代码语言:javascript
运行
复制
x,y=-81.00483829765083,-150.99434404015307

这是错误的,因为-150不是一个有效的纬度。

当我创建源对象时,我用经度初始化了X,用纬度初始化了Y,遵循了X实际上是经度,Y是纬度的基本原理(根据地理社区)。但是,如果我把它们颠倒过来:

代码语言:javascript
运行
复制
DirectPosition source = new DirectPosition2D(sourceCrs, latitude, longitude);

我现在得到一个看起来更真实的结果:

代码语言:javascript
运行
复制
x,y=29.003866857343915,-98.99222530180596

当然,我现在必须把X解释为纬度,Y解释为经度。

那么,问题1,我们是否应该用逆理性,把X当作纬度,Y当作经度呢?

接下来,我想验证结果。首先,尝试使用Oracle SQL SDO函数转换同一点:

代码语言:javascript
运行
复制
select sdo_cs.transform (
MDSYS.SDO_GEOMETRY(2001, 4312, MDSYS.SDO_POINT_TYPE(-99, 29, NULL), NULL, NULL),
8307
) from dual;

提供下列结果:

代码语言:javascript
运行
复制
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可靠吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-03-29 07:51:12

关于轴顺序的第一个问题,你陷入了一个普通初学者的问题,假设你知道投影的轴序是什么,在ESPG:4326的情况下,它是固定的。

例如,以下代码:

代码语言:javascript
运行
复制
CoordinateReferenceSystem targetCrs = CRS.decode("EPSG:4326");

System.out.println("EPSG:4326 - " + CRS.getAxisOrder(targetCrs));
System.out.println("WGS84 - " + CRS.getAxisOrder(DefaultGeographicCRS.WGS84));

给出这个输出:

代码语言:javascript
运行
复制
EPSG:4326 - NORTH_EAST
WGS84 - EAST_NORTH

但是,如果添加行Hints.putSystemDefault(Hints.FORCE_LONGITUDE_FIRST_AXIS_ORDER, Boolean.TRUE);,输出将变成:

代码语言:javascript
运行
复制
EPSG:4326 - EAST_NORTH
WGS84 - EAST_NORTH

因此,通常您不应该依赖代码中的“已知”轴顺序,而应该使用如下所示的方法:

代码语言:javascript
运行
复制
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转换,那么将其添加到项目中应该可以提高精度。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66844320

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档