在rails查询中调用postgis ST_DWithin

在rails查询中调用postgis ST_DWithin,postgis,postgresql-9.3,ruby-on-rails-4.2,Postgis,Postgresql 9.3,Ruby On Rails 4.2,正在控制台中为启用postgis的rails4.2应用程序尝试以下操作 @target = Target.last @meter_radius = 1000 @valid_points = Target.where("ST_DWithin(#{@target.lat}, #{@target.lon}, #{@meter_radius})) lat和lon定义为十进制值。这将转换为以下查询 SELECT "targets".* FROM "targets" WHERE (ST_DWithin

正在控制台中为启用postgis的rails4.2应用程序尝试以下操作

@target = Target.last
@meter_radius = 1000
@valid_points = Target.where("ST_DWithin(#{@target.lat}, #{@target.lon},  #{@meter_radius}))
lat和lon定义为十进制值。这将转换为以下查询

SELECT "targets".* FROM "targets"  WHERE (ST_DWithin(38.656679, 15.984094, 1000))
错误如下:
PG::UndefinedFunction:错误:函数st_dwithin(数字、数字、整数)不存在

我认为我需要为这些值声明数据类型(几何或地理),但不确定如何声明。我还想知道ST_DWithin函数是否可以处理3857数据类型,即使文档中没有说明

注意@target对象还具有一个
lonlat
属性,该属性在postgresql中定义为空间值,并定义了:srid=>3857,:type=>point

更新

@valid_points = Target.where("ST_DWithin(lonlat, ST_PointFromText('#{@target.lonlat}',  #{@meter_radius}))
返回一个结果,因此在语法上是有效的

SELECT "targets".* FROM "targets"  WHERE (ST_DWithin(lonlat, ST_PointFromText('POINT (15.984094 38.656679)', 3857), 1000))
SELECT "targets".* FROM "targets"  WHERE (ST_DWithin(lonlat, ST_PointFromText('POINT (15.984094 38.656679)', 3857), 0.2249))

然而,结果是不正确的。它基本上找到了表中的所有点。由于是SRID类型,这需要以度而不是米表示。

一个答案,利用存储的lonlat空间点:

@target = Target.last
@degree_radius = 0.2249
@valid_points = Target.where("ST_DWithin(lonlat, ST_PointFromText('#{@target.lonlat}',  #{@degree_radius}))
它返回一个结果,因此在语法上是有效的

SELECT "targets".* FROM "targets"  WHERE (ST_DWithin(lonlat, ST_PointFromText('POINT (15.984094 38.656679)', 3857), 1000))
SELECT "targets".* FROM "targets"  WHERE (ST_DWithin(lonlat, ST_PointFromText('POINT (15.984094 38.656679)', 3857), 0.2249))

一个答案是,利用存储的lonlat空间点:

@target = Target.last
@degree_radius = 0.2249
@valid_points = Target.where("ST_DWithin(lonlat, ST_PointFromText('#{@target.lonlat}',  #{@degree_radius}))
它返回一个结果,因此在语法上是有效的

SELECT "targets".* FROM "targets"  WHERE (ST_DWithin(lonlat, ST_PointFromText('POINT (15.984094 38.656679)', 3857), 1000))
SELECT "targets".* FROM "targets"  WHERE (ST_DWithin(lonlat, ST_PointFromText('POINT (15.984094 38.656679)', 3857), 0.2249))