首页 > 解决方案 > 如何为检查点建立JPA谓词属于给定的多边形

问题描述

我正在尝试构建javax.persistence.criteria.Predicate确定点属于给定多边形的方法。

我想用来构建查询的谓词。我想使用 Criteria API 从 dto 动态构建对给定参数的查询。

import org.geolatte.geom.codec.Wkt;
import org.hibernate.spatial.predicate.JTSSpatialPredicates;
import javax.persistence.criteria.Predicate;

public List<EComparable> searchByParams(SearchFormDto searchFormDto) {
    var cb = entityManager.getCriteriaBuilder();
    var query = cb.createQuery(EComparable.class);
    var root = query.from(EComparable.class);
    Predicate[] predicates = new Predicate[10];
    predicates[0] = JTSSpatialPredicates.contains(
            cb,
            Wkt.fromWkt("POLYGON ((10 10, 10 20, 20 20, 20 15, 10 10))"), // Hardcoded for test, will be given from dto
            root.get("geom").type() // I'm really not shure about that part too
    );
    // predicates[...] = ...
    query.select(root).where(predicates);
    var resultList = entityManager.createQuery(query).getResultList();
    return resultList;
}

所以我找到JTSSpatialPredicates了,但不明白如何采用它。

论据的问题:

该类仅提供两种变体contains

(...,表达,表达)

org.hibernate.spatial.predicate.JTSSpatialPredicates#contains(javax.persistence.criteria.CriteriaBuilder, javax.persistence.criteria.Expression<? extends org.locationtech.jts.geom.Geometry>, javax.persistence.criteria.Expression<? extends org.locationtech.jts.geom.Geometry>)

或(...,表达式,几何)

org.hibernate.spatial.predicate.JTSSpatialPredicates#contains(javax.persistence.criteria.CriteriaBuilder, javax.persistence.criteria.Expression<? extends org.locationtech.jts.geom.Geometry>, org.locationtech.jts.geom.Geometry)

但我需要理解(...,几何,表达式)。给定多边形包含geom列中的点。

如何弄清楚?


geom是存储点位置的列名(db type geometry)。

需要选择属于给定多边形的所有行并进行一些额外的过滤。

环境:Java 16、Spring Boot、Hibernate、Postgis、Postgresql。

标签: javasqljpahibernate-spatialjpa-criteria

解决方案


只需要将几何图形包装到表达式中literal并更改第二个参数:

import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.io.WKTReader;

//...

predicates[0] = JTSSpatialPredicates.contains(
        cb,
        cb.literal(wktReader.read("POLYGON ((0 0, 0 70, 70 70, 70 0, 0 0))")),
        root.get("geom").as(Geometry.class)
);

推荐阅读