Неверный результат с использованием Geometry.reverse() для координат XYM

Мы используем jts-core (org.locationtech.jts:jts-core:jar:1.19.0) вместе с hibernate-spatial (org.hibernate:hibernate-spatial:jar:5.6.10.Final:compile) для извлечения геометрии с измеренными размерами из базы данных PostGis (14.3).

Запрос выглядит примерно так:

Geometry geometry = (Geometry) entityManager
    .createNativeQuery("SELECT st_locatebetween(geom, :p1, :p2) as geom FROM GEOMS WHERE id = :id")
    .setParameter("id", id)
    .setParameter("p1", p1)
    .setParameter("p2", p2)
    .unwrap(NativeQuery.class)
    .addScalar("geom", new JTSGeometryType(INSTANCE_WKB_2))
    .getSingleResult();

Этот запрос отлично работает для получения геометрии, возвращая координаты XYM. Однако, когда мы пытаемся изменить геометрию с помощью org.locationtech.jts.geom.Geometry#reverse, M-координаты теряются. Все координаты, кроме средней, имеют значение NaN для m.

При попытке этого с помощью простого модульного теста с использованием массива org.locationtech.jts.geom.CoordinateXYM это работает нормально. При отладке запроса, похоже, используется org.geolatte.geom.PackedPositionSequence, который возвращает неверный перевернутый массив.

Мы делаем что-то не так? Или это ошибка?

Если мы попытаемся сделать это с помощью org.geolatte.geom.Geometry напрямую, мы получим ту же проблему:

Geometry geometry = JTS.to(Wkt.fromWkt("LINESTRING M (1 1 1, 2 2 2, 3 3 3)"));

stream(geometry.getCoordinates()).forEach(System.out::println);
stream(geometry.reverse().getCoordinates()).forEach(System.out::println);

дает ниже вывод:

(1.0, 1.0 m=1.0)
(2.0, 2.0 m=2.0)
(3.0, 3.0 m=3.0)

(3.0, 3.0 m=NaN)
(2.0, 2.0 m=2.0)
(1.0, 1.0 m=NaN)
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
0
53
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это определенно ошибка. Существует несоответствие между JTS reverse() и org.geolatte.geom.PackedCoordinateSequence. CoordinateSequence не возвращает правильное значение координаты M.

Для этого я создал задачу в проекте geolatte-geom.

В то же время вы можете использовать в качестве обходного пути геометрию XYZM с Z-координатами, установленными на 0,0. Тогда несоответствие исчезнет и реверс будет работать корректно.

Спасибо! В качестве обходного пути я уже сделал что-то подобное, что, похоже, тоже помогает: geometryFactory.createLineString(geometry.getCoordinates()).‌​reverse().

wjans 23.11.2022 10:47

Другие вопросы по теме