gpt4 book ai didi

java - 在 Maven 中测试地理转换失败,在 Eclipse 中有效

转载 作者:搜寻专家 更新时间:2023-11-01 02:12:16 24 4
gpt4 key购买 nike

在我们当前的项目中,我们使用 Maven 设置来管理依赖项和运行单元测试。在开发的某个时刻,我们的一项测试停止工作(我们不确定确切的时间点,所以我们不知道到底发生了什么变化)。具体失败的是使用 geotools(9 和 9.1 尝试过)从笛卡尔坐标到地理坐标的转换。有趣的是,相同的测试在 Eclipse 中运行良好。我们投入了大量精力来分析问题并创建了一个最小的示例来展示我们所看到的行为,我们(合理地)确定这不是类路径问题。

例子

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example.geotest</groupId>
<artifactId>geotest</artifactId>
<name>geotest</name>
<version>1.0.0</version>
<description></description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<geotools.version>9.1</geotools.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-main</artifactId>
<version>${geotools.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.0</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>com.example.geotest.Geotest</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>maven2-repository.dev.java.net</id>
<name>Java.net repository</name>
<url>http://download.java.net/maven/2</url>
</repository>
<repository>
<id>osgeo</id>
<name>Open Source Geospatial Foundation Repository</name>
<url>http://download.osgeo.org/webdav/geotools/</url>
</repository>
</repositories>
</project>

测试器.java

package com.example.geotest;

import java.awt.geom.Point2D;
import java.util.Collections;
import java.util.Map;

import org.geotools.referencing.CRS;
import org.geotools.referencing.ReferencingFactoryFinder;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.geotools.referencing.cs.DefaultCartesianCS;
import org.geotools.referencing.factory.ReferencingFactoryContainer;
import org.geotools.referencing.operation.DefaultConversion;
import org.geotools.referencing.operation.DefiningConversion;
import org.junit.Test;
import org.opengis.parameter.ParameterValueGroup;
import org.opengis.referencing.crs.CRSFactory;
import org.opengis.referencing.crs.GeographicCRS;
import org.opengis.referencing.crs.ProjectedCRS;
import org.opengis.referencing.cs.CartesianCS;
import org.opengis.referencing.operation.Conversion;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.MathTransformFactory;
import org.opengis.referencing.operation.TransformException;

public class Tester {

@Test
public void testtesttest() throws Exception {

// prepare actuall action
final MathTransformFactory mtFactory = ReferencingFactoryFinder.getMathTransformFactory(null);
final ReferencingFactoryContainer factories = new ReferencingFactoryContainer(null);
final GeographicCRS geoCRS = DefaultGeographicCRS.WGS84;
final CartesianCS cartCS = DefaultCartesianCS.GENERIC_2D;

ProjectedCRS projCRS;
MathTransform transformGeoToCrs;
MathTransform transformCrsToGeo;


ParameterValueGroup parameters = mtFactory.getDefaultParameters("Transverse_Mercator");
parameters.parameter("central_meridian").setValue(9);
parameters.parameter("latitude_of_origin").setValue(0.0);
//0.9996 (a reduction of 1:2500); (40 cm/km)
parameters.parameter("scale_factor").setValue(0.9996);
//500 km for north hemisphere
parameters.parameter("false_easting").setValue(500000.0);
//10,0000 km for south hemisphere
parameters.parameter("false_northing").setValue(0.0);

Map<String, String> properties = Collections.singletonMap("name", "WGS 84 / UTM Zone 32");

CRSFactory crsFactory = factories.getCRSFactory();
DefiningConversion conv = new DefiningConversion("test", parameters);
projCRS = crsFactory.createProjectedCRS(properties, geoCRS, conv, cartCS);
transformGeoToCrs = CRS.findMathTransform(geoCRS, projCRS);
transformCrsToGeo = CRS.findMathTransform(projCRS, geoCRS);

// execute actual test
double[] src = new double[] {5838597.0, 807147.75};
double[] dest = new double[2];

try {
// this fails in maven
transformCrsToGeo.transform(src, 0, dest, 0, 1);
} catch (TransformException e) {
throw new RuntimeException(e);
}

Point2D.Double geo = new Point2D.Double(dest[0], dest[1]);
}
}

如果我们对此调用“mvn test”,我们会得到以下异常:

Tests in error:
testtesttest(com.example.geotest.Tester): org.geotools.referencing.operation.projection.ProjectionException: The transform result may be 9.478,277 meters away from the expected position. Are you sure that the input coordinates are inside this map projection area of validity? The point is located 43°20.6'E away from the central meridian and 5°19.1'N away from the latitude of origin. The projection is "Transverse_Mercator".

如果我们从 eclipse 运行 JUnit 测试,这将完美运行。知道为什么会发生这种情况或我们如何避免这种情况吗?


作为旁注:以下三行是已弃用的 factory.createProjectedCRS(properties, geoCRS, null, parameters, cartCS) 方法的变通方法,如果有人有更好的解决方案,欢迎留言:)

CRSFactory crsFactory = factories.getCRSFactory();
DefiningConversion conv = new DefiningConversion("test", parameters);
projCRS = crsFactory.createProjectedCRS(properties, geoCRS, conv, cartCS);

最佳答案

正如 Werner 所说,问题可以通过在 surefire 测试运行期间禁用断言来解决。如果您想在其余代码中启用断言,您只能通过修改 POM 来禁用 MapProjection 类中的断言:

    <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>-da:org.geotools.referencing.operation.projection.MapProjection</argLine>
</configuration>
</plugin>

或者在 Java 中:

MapProjection.class.getClassLoader().setClassAssertionStatus(MapProjection.class.getName(), false);

由于 geotools 估计其准确性的方式存在错误 (https://osgeo-org.atlassian.net/browse/GEOT-4207),即使转换点与 UTM 带中央子午线的偏差在 3 度以内(并且实际转换误差可以忽略不计),也会发生此错误。该错误与 OP 的情况无关,因为这里的点远离 UTM 区(距中央子午线约 40 度)并且转换误差(约 10 公里)不可忽略(对于某些应用程序)。

关于java - 在 Maven 中测试地理转换失败,在 Eclipse 中有效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16525478/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com