HibernateException: позиции коллинеарны в 2D

Я использую Hibernate Spatial версии 5.0.7.Final в качестве ORM. Иногда, когда я выполняю запрос с использованием параметра Geometry as named, я получаю следующее исключение:

org.hibernate.HibernateException: Positions are collinear in 2D

Я понимаю, что иногда мои геометрии коллинеарны, и модуль NumericalMethods в библиотеке Geolatte проверяет, isCounterClockwise ли моя геометрия вызывает это исключение.

Интересно, почему он это делает, но более того, что я могу сделать, чтобы избежать этой ошибки.

Код Hibernate ниже в NumericalMethods.java проверяет только первые три координаты. В моем случае иногда эти три первые координаты коллинеарны, но четвертая сделает его действительным многоугольником. Я не могу понять, почему он не будет перебирать остальные координаты, чтобы определить, против часовой стрелки или нет.

Полная трассировка стека:

org.hibernate.HibernateException: Positions are collinear in 2D
at org.hibernate.spatial.dialect.oracle.SDOGeometryValueBinder.toNative(SDOGeometryValueBinder.java:71)
at org.hibernate.spatial.dialect.oracle.SDOGeometryValueBinder.bind(SDOGeometryValueBinder.java:52)
at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:257)
at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:252)
at org.hibernate.param.NamedParameterSpecification.bind(NamedParameterSpecification.java:52)
at org.hibernate.loader.hql.QueryLoader.bindParameterValues(QueryLoader.java:627)
at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1944)
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1897)
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1875)
at org.hibernate.loader.Loader.doQuery(Loader.java:919)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:336)
at org.hibernate.loader.Loader.doList(Loader.java:2611)
at org.hibernate.loader.Loader.doList(Loader.java:2594)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2423)
at org.hibernate.loader.Loader.list(Loader.java:2418)
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:501)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:371)
at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:216)
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1326)
at org.hibernate.internal.QueryImpl.list(QueryImpl.java:87)

person krause    schedule 19.01.2016    source источник
comment
Я только что увидел, что тикет обрабатывается: hibernate.atlassian.net/browse/HHH-10410 Может быть, люди из Hibernate могут что-то с этим сделать, или тем временем я могу найти обходной путь.   -  person krause    schedule 20.01.2016


Ответы (1)


Судя по комментариям, это ошибка в Hibernate. При попытке создать полигон с коллинеарными широтами спящий пространственный режим выдает исключение. Он был зарегистрирован как тикет Jira:

https://hibernate.atlassian.net/browse/HHH-10410

Похоже, виновником является функция isCounterClockwise в NumericalMethods.java , библиотека Geolatte. Вероятно, это происходит с первой версии Hibernate 5.

Если кому-то это покажется полезным, я вставлю ниже код, чтобы создать вашу собственную версию этой библиотеки, которая предотвратит возникновение этой ошибки. Я также отправлю запрос на извлечение, если они решат объединить его (или что-то подобное) со своим мастером:

https://github.com/GeoLatte/geolatte-geom/pull/43

/**
 * Determines whether the specified {@code PositionSequence} is counter-clockwise.
 * <p/>
 * <p>Only the first three positions, are inspected to determine whether the sequence is counter-clockwise.
 * In case are less than three positions in the sequence, the method returns true.</p>
 *
 * @param positions a {@code PositionSequence}
 * @return true if the positions in the specified sequence are counter-clockwise, or if the sequence contains
 * less than three elements.
 */
public static boolean isCounterClockwise(PositionSequence<?> positions) {
    if (positions.size() < 3) return true;
    Position p0 = positions.getPositionN(0);
    Position p1 = positions.getPositionN(1);
    double det = 0;
    int positionsSize = positions.size();
    int i = 2;
    while(i < positionsSize && det == 0) {
        Position p2 = positions.getPositionN(i);
        det = deltaDeterminant(p0, p1, p2);
        i++;
    }
    if (det == 0) {
        throw new IllegalArgumentException("Positions are collinear in 2D");
    }
    return det > 0;
}

Обновление: запрос на вытягивание был объединен с основным, поэтому в конечном итоге он будет выпущен.

person krause    schedule 07.04.2016