How to build JPA Predicate for checking point belongs to given polygon

508 views Asked by At

I'm trying to build javax.persistence.criteria.Predicate which determines is point belongs to a given polygon.

That predicate I want to use to build the query. I want to use Criteria API to dynamically build queries on given params from a 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;
}

So I found JTSSpatialPredicates, but can't understand how to adopt it.

The problem with arguments:

That class provides only two variants for contains:

(..., Expression, Expression)

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>)

Or (..., Expression, 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)

But I need as understood (..., Geometry, Expression). Given polygon contains point from geom column.

How to figure it out?


geom is the column name in which point location stored (db type geometry).

Needed to select all rows which belongs to given polygon and do some additional filtering.

Env: Java 16, Spring Boot, Hibernate, Postgis, Postgresql.

1

There are 1 answers

0
Woland On

Just needed to wrap geometry into an expression via literal and change a bit 2nd arg too:

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)
);