【问题标题】:Postgres/PostGIS st_distance_sphere function with EntityManager.createQuery incomprehensible errorPostgres/PostGIS st_distance_sphere 函数与 EntityManager.createQuery 无法理解的错误
【发布时间】:2019-11-25 14:35:56
【问题描述】:

我尝试使用 PostGIS 计算两点之间的距离。我发现 postGIS 为此有st_distance_sphere function,并尝试了以下代码:

private fun getDeliveryDistance(areaCentroid: Point, buyerLocation: Point): Double {
    val query = em.createQuery(
        "select st_distance_sphere(st_makepoint(${areaCentroid.x}, ${areaCentroid.y}), st_makepoint(${buyerLocation.x}, ${buyerLocation.y}))",
        Double::class.java
    )
    val result = query.singleResult
    return result
}

但是我得到了以下错误,而不是正确的结果:

java.lang.IllegalArgumentException: org.hibernate.QueryException: No data type for node: org.hibernate.hql.internal.ast.tree.MethodNode 
 \-[METHOD_CALL] MethodNode: '('
    +-[METHOD_NAME] IdentNode: 'st_distance_sphere' {originalText=st_distance_sphere}
    \-[EXPR_LIST] SqlNode: 'exprList'
       +-[METHOD_CALL] MethodNode: '('
       |  +-[METHOD_NAME] IdentNode: 'st_makepoint' {originalText=st_makepoint}
       |  \-[EXPR_LIST] SqlNode: 'exprList'
       |     +-[NUM_DOUBLE] LiteralNode: '38.970335125923135'
       |     \-[NUM_DOUBLE] LiteralNode: '45.0543938370861'
       \-[METHOD_CALL] MethodNode: '('
          +-[METHOD_NAME] IdentNode: 'st_makepoint' {originalText=st_makepoint}
          \-[EXPR_LIST] SqlNode: 'exprList'
             +-[NUM_DOUBLE] LiteralNode: '38.97033512592316'
             \-[NUM_DOUBLE] LiteralNode: '45.05439383708615'
 [select st_distance_sphere(st_makepoint(38.970335125923135, 45.0543938370861), st_makepoint(38.97033512592316, 45.05439383708615))]]

不幸的是,我不知道这个错误。但是,当我在调用getSingleResult() 之前以调试模式或从堆栈跟踪的最后一行复制查询,然后在 pgAdmin 控制台中执行它时,我得到了正确的结果。有人知道我该如何解决吗?

【问题讨论】:

    标签: postgresql hibernate kotlin spring-data-jpa postgis


    【解决方案1】:
    @Query(
        """select topology.st_distance(topology.st_makepoint(:restaurantLat, :restaurantLong), topology.st_makepoint(:buyerLat, :buyerLong))""",
        nativeQuery = true
    )
    fun calculateDistance(
        @Param("restaurantLat") restaurantLat: Double,
        @Param("restaurantLong") restaurantLong: Double,
        @Param("buyerLat") buyerLat: Double,
        @Param("buyerLong") buyerLong: Double
    ): Double
    

    我刚刚明确指定了 postgres 架构,它解决了我的问题

    【讨论】:

    • 两件事:坐标必须先表示为经度,然后是纬度。如果您必须为 PostGIS 函数指定架构,它会比字母更快地失败。您必须在用户 path 中设置 PostGIS 架构。见stackoverflow.com/a/48422325/7635569
    • ST_Distance 与 long-lats 将返回以度为单位的距离(这是没有意义的),而不是以米为单位,除非您将几何图形转换为地理
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-20
    • 2016-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-09
    • 1970-01-01
    相关资源
    最近更新 更多