Postgis 地理函数使用

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Postgis 地理函数使用相关的知识,希望对你有一定的参考价值。

最近使用postgis的地理函数做一些区域查询判断,SQL代码如下:

<sql id="region_condition_geo">
        <if test="geog != null">
            <if test="geog.type == ‘circle‘ ">
                AND ST_Intersects ( ST_Buffer (ST_GeomFromText (‘POINT(${geog.centerString})‘, ${geog.srid}) ::
                geography, ${geog.radiusMetre} ) :: geography, position )
            </if>
            <if test="geog.type == ‘rectangle‘ ">
                and ST_Intersects(ST_GeomFromText(‘POLYGON((${geog.pointArr}))‘,
                ${geog.srid})::geography,
                position )
            </if>
            <if test="geog.type == ‘polygon‘ ">
                and ST_Intersects(ST_GeomFromText(‘POLYGON((${geog.pointArr}))‘,
                ${geog.srid})::geography,
                position )
            </if>
        </if>
    </sql>

执行时报错:

bad SQL grammar []; nested exception is org.postgresql.util.PSQLException: ERROR: function st_geomfromtext(unknown, integer) does not exist
  建议:No function matches the given name and argument types. You might need to add explicit type casts.

查看PostgrelSQL的官方手册(ST_GeogFromText)关于函数的解释如下:

技术图片

初步怀疑是mybatis参数传递导致,将‘POINT()‘部分整个作为参数传递,修改后SQL如下:

AND ST_Intersects ( ST_Buffer (ST_GeomFromText (${geog.centerString}, ${geog.srid}) :: geography, ${geog.radiusMetre} ) :: geography, position )

执行继续报错:

bad SQL grammar []; nested exception is org.postgresql.util.PSQLException: ERROR: function st_geomfromtext(variable char, integer) does not exist
  建议:No function matches the given name and argument types. You might need to add explicit type casts.

进一步排查:
将navicat客户可执行的sql写死代码里测试:

select ST_GeomFromText(‘POINT(123.480833 35.643900)‘,4326);

依旧是上面的错误, 时间已经过去2小时...

此时,曾经用hibernate实现postgis函数查询的同事过来指点江山,于是开始找各种mybatis转换驱动, 尝试各种自定义TypeHandler,时间又过去了1小时...

为了避免hibernate和mybatis优劣的讨论,尝试直接用jdbcTemplate调用函数,依旧是同样的错误。

检查postgrelSQL驱动版本,直到想到schema。

当前项目是一库下多schema,jdbc连接时,指定了currentSchema=xxx,但是这个schema不是public,也没有设置searchPath,所以无法正确执行public的function。将函数统一加上public.前缀,sql执行通过!

进一步优化,怎么用searchPath,有一篇参考文章介绍的挺好(PostgreSQL模式),奈何尝试了几次设置,都未成功,后经公司DBA架构师指点,直接在jdbcurl上,设置currentSchema=xxx,public, 即优雅的解决此问题。

以上是关于Postgis 地理函数使用的主要内容,如果未能解决你的问题,请参考以下文章

PostGIS中数据类型地理(点,4326)的大小?

postgis经常使用函数介绍

PostGIS 错误:类型“地理”不存在

将地理 PostGIS 功能与 H2GIS 结合使用

如何在postgis中找到几何半径?

震惊,PostGIS还可以这样用!!!