У меня проблемы с Geotools, меняющие местами широту и долготу с помощью JTS.transform (). Это сводит меня с ума уже несколько дней.
У меня разные наборы данных, определенные в разных прогнозах. Цель состоит в том, чтобы я мог сопоставить любую координату в данной проекции WKT с координатой (долгота, широта) в WGS84. Вот моя утилита, которая выполняет преобразование:
public class TransformUtil {
private static CoordinateReferenceSystem wgs;
static {
wgs = DefaultGeographicCRS.WGS84;
}
private static double[] convert(String wkt, double x, double y) throws TransformException {
CoordinateReferenceSystem sourceCRS = CRS.parseWKT(wkt);
MathTransform transform = CRS.findMathTransform(sourceCRS, WGS, true);
Point point = geometryFactory.createPoint( new Coordinate( x, y ) );
Geometry targetGeometry = JTS.transform( point , transform);
Coordinate coord = targetGeometry.getCoordinate();
return new double[] {coord.x, coord.y};
}
}
и вот мои модульные тесты:
public class TestTransformUtil {
private double lon = 5;
private double lat = 50;
private double margin = 1E-5d;
@Test
public void testWgs() {
String wkt = "GEOGCS[\"WGS 84\",DATUM[\"WGS_1984\",SPHEROID[\"WGS 84\",6378137,298.257223563,AUTHORITY[\"EPSG\",\"7030\"]],AUTHORITY[\"EPSG\",\"6326\"]],PRIMEM[\"Greenwich\",0],UNIT[\"degree\",0.0174532925199433,AUTHORITY[\"EPSG\",\"9122\"]],AXIS[\"Latitude\",NORTH],AXIS[\"Longitude\",EAST],AUTHORITY[\"EPSG\",\"4326\"]]";
double[] res = TransformUtil.toLonLat(lon, lat, wkt);
Assert.assertEquals("Longitude", lon, res[0], margin);
Assert.assertEquals("Latitude", lat, res[1], margin);
}
@Test
public void testLaea() {
double x= 3962799.45096;
double y = 2999718.85316;
String wkt = "PROJCS[\"ETRS89-extended / LAEA Europe\",GEOGCS[\"ETRS89\",DATUM[\"European_Terrestrial_Reference_System_1989\",SPHEROID[\"GRS 1980\",6378137,298.257222101004,AUTHORITY[\"EPSG\",\"7019\"]],AUTHORITY[\"EPSG\",\"6258\"]],PRIMEM[\"Greenwich\",0],UNIT[\"degree\",0.0174532925199433,AUTHORITY[\"EPSG\",\"9122\"]],AUTHORITY[\"EPSG\",\"4258\"]],PROJECTION[\"Lambert_Azimuthal_Equal_Area\"],PARAMETER[\"latitude_of_center\",52],PARAMETER[\"longitude_of_center\",10],PARAMETER[\"false_easting\",4321000],PARAMETER[\"false_northing\",3210000],UNIT[\"metre\",1],AXIS[\"Easting\",EAST],AXIS[\"Northing\",NORTH]]";
double[] res = TransformUtil.toLonLat(x, y, wkt);
Assert.assertEquals("Longitude", lon, res[0], margin);
Assert.assertEquals("Latitude", lat, res[1], margin);
}
}
То, что происходит, действительно сбивает с толку. Для проекции testWgs () из WGS84 в WGS84 действие преобразования меняет координаты на противоположные. Coordinate.x становится широтой, Coordinate.y - долготой, поэтому утверждение не выполняется:
java.lang.AssertionError: Longitude expected:<5.0> but was:<50.0>
testLaea () проходит без проблем.
Я нашел этот совет в документации geotools: https://docs.geotools.org/stable/userguide/tutorial/geometry/geometrycrs.html#workarounds, в котором говорится, что вам следует использовать
private static CoordinateReferenceSystem wgs;
static {
try {
CRSAuthorityFactory factory = CRS.getAuthorityFactory(true);
wgs = factory.createCoordinateReferenceSystem("urn:ogc:def:crs:EPSG:6.6:4326");
} catch (FactoryException e) {
e.printStackTrace();
}
}
Когда я запускаю тесты сейчас, testWgs () проходит успешно, но теперь координаты для testLaea () меняются местами !!
Последнее, что я попробовал, - это использовать
static {
System.setProperty("org.geotools.referencing.forceXY", "true");
//wgs = ...
}
который вообще ничего не делает. Может ли кто-нибудь объяснить, что здесь происходит, и знает ли кто-нибудь, как я могу заставить результат преобразования всегда иметь x = долготу и y = широту? Спасибо!