为了账号安全,请及时绑定邮箱和手机立即绑定

PostGis 查询在使用 Go 执行时返回无效的几何错误

PostGis 查询在使用 Go 执行时返回无效的几何错误

Go
智慧大石 2022-12-19 18:18:25
我尝试使用 pgx 库从一些带有 Go 的 PostGis (x,y) 1 公里以内id的表中选择它们。steps我测试了以下返回错误的代码:parse error - invalid geometry (SQLSTATE XX000)func search(lat float32, lng float32) return (string, error){    searchQuery   = "SELECT DISTINCT(id) FROM steps WHERE ST_Distance('SRID=4326;POINT($1 $2)'::geography, location) < 1000"    // GetSession returns *pgxpool.Pool    rows, err := postgres.GetSession().Query(context.Background(), searchQuery,    lat,    lng)    if err != nil {        // ERROR: parse error - invalid geometry (SQLSTATE XX000)        return nil, err    }    defer rows.Close()    ...}然后,我刚刚使用ST_SetSRID和ST_MakePoint更改了查询searchQuery   = "SELECT DISTINCT(id) FROM steps WHERE ST_Distance(ST_SetSRID(ST_MakePoint($1, $2), 4326)::geography, location) < 1000"... 但 ...1)我仍然不知道为什么我的第一版查询"SELECT DISTINCT(id) FROM steps WHERE ST_Distance('SRID=4326;POINT($1 $2)'::geography, location) < 1000"返回一个几何错误,而当我直接将它测试到pgadmin时它正在工作,用随机坐标值替换 $1 和 $2,例如"SELECT DISTINCT(id) FROM steps WHERE ST_Distance('SRID=4326;POINT(0.44 3.40)'::geography, location) < 1000"2) 我不确定将ST_Distance与 ST_SetSRID 和 ST_MakePoint 一起使用是否是检查一个点是否靠近另一个点的最有效方法。
查看完整描述

1 回答

?
米琪卡哇伊

TA贡献1998条经验 获得超6个赞

查询问题

SELECT DISTINCT(id) FROM steps WHERE ST_Distance('SRID=4326;POINT($1 $2)'::geography, location) < 1000


注意 $1 是 lng 而 $2 应该是 lat


为什么会发生?

'SRID=4326;POINT($1 $2)'是一个字符串文字,postgres 的序数参数占位符不应该在字符串文字中。这不是围棋的问题。这就是 postgres 处理字符串文字的方式。即'$1' != $1,一个是纯字符串,另一个是postgres(不是 Go)将替换为客户端发送到服务器的数据的参数占位符。


解决方案

..如果你想将字符串文字与参数占位符结合起来,请使用字符串连接:


ST_Distance(('SRID=4326;POINT(' || $1::text || ' ' || $2::text || ')')::geometry, location)

请注意字符串文字及其连接是如何包裹在额外的括号中的,这只是为了强制执行正确的评估顺序,即强制强制转换::geometry应用于连接后的文本。


优化

您最有可能使用st_dwithin和利用空间索引,您可以使用您的位置值和地理来构建它,他在帖子的结尾解释道。请参阅blog.cleverelephant.ca/2021/05/indexes-and-queries.html


固定 SQL 查询

SELECT DISTINCT(id) FROM steps WHERE ST_DWithin(('SRID=4326;POINT(' || $1::text || ' ' || $2::text || ')')::geometry, location, 1000);

固定围棋功能

func search(lat float32, lng float32) return (string, error){

    searchQuery   = "SELECT DISTINCT(id) FROM steps WHERE ST_DWithin(('SRID=4326;POINT(' || $1::text || ' ' || $2::text || ')')::geometry, location, 1000);"


    // GetSession returns *pgxpool.Pool

    rows, err := postgres.GetSession().Query(context.Background(), searchQuery,

    lng,

    lat)

    if err != nil {

        return nil, err

    }

    defer rows.Close()

    ...

}


查看完整回答
反对 回复 2022-12-19
  • 1 回答
  • 0 关注
  • 195 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号