0

拥有 Table Neighborhoods,如下所示:

id: 1,
title: "Sun City",
state: "CA",
geometry: "MULTIPOLYGON (((-117.1935499999999 33.74306900000005, -117.1935729999999 33.74198700000005, -117.19369999999992 33.73596500000008, -117.18936799999994 33.73584000000005, -117.18935499999992 33.72862400000008, -117.18935399999992 33.72801800000008, -117.18925499999995 33.72163400000005, -117.18921699999993 33.719152000000065, -117.18921699999993 33.71860200000009, -117.18910699999992 33.717250000000035, -117.18907999999993 33.715738000000044, -117.18896999999993 33.71498200000008, -117.18896999999993 33.71418100000005, -117.18866899999995 33.712829000000056, -117.18855899999994 33.71266900000006, -117.18844899999993 33.711959000000036, ...

geometry- 是一大组 lon/lat 对。我希望能够通过latand找到 Neighborhood lon

现在我使用这种方法:

def is_within_or_intersects?(lat, lon)
  factory = RGeo::Cartesian.factory
  point = factory.point(lon, lat)
  boundary = factory.parse_wkt(self.geometry)
  point.intersects?(boundary) || point.within?(boundary)
end

但是这种方法很慢,要使用我需要全部加载并循环遍历每个Neighoborhood.

最好有一些 sql 查询来立即加载指定lat/lon的社区,而不是遍历所有。

我试过这个(例如,Lat Lon 是硬编码的):

ActiveRecord::Base.connection.execute("SELECT * FROM neighborhoods WHERE ST_Contains(ST_Transform(ST_SetSRID(geometry, 2263), 4326), ST_GeometryFromText('POINT(-117.18757899999991 33.709771000000046)', 4326))")

但我明白了:

ActiveRecord::StatementInvalid: PG::UndefinedFunction: ERROR:  function st_setsrid(character varying, integer) does not exist
LINE 1: ...FROM neighborhoods WHERE ST_Contains(ST_Transform(ST_SetSRID...
                                                             ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
4

1 回答 1

1

由于您的几何字段不是几何类型字段,因此返回错误。您的数据只是 WKT/EWKT 格式的文本字段。首先将您的文本字段转换为几何类型并且应该可以工作。

SELECT * 
  FROM neighborhoods 
 WHERE ST_Contains(ST_Transform(ST_SetSRID(st_geomfromtext(geometry), 2263), 4326), 
                   ST_GeometryFromText('POINT(-117.18757899999991 33.709771000000046)', 4326))")

如果我可以建议您应该将几何数据的数据类型(作为 WKT 文本提交的文本)更改为 GEOGRAPHY 类型(当您使用 SRID 4326 时,这将是使用 PostGIS 函数的最佳和最简单的方法)您可以使用 PostGIS 函数 st_astext() st_asewkt() 轻松地将 GEOGRAPHY/GEOMETRY 类型的数据返回到 WKT/EWKT。

使用 GEOGRAPHY/GEOMETRY 格式,您可以使用 GIST 索引,这将大大加快您的 SQL 语句。

更多关于 PostGis 数据磁带的信息在这里

于 2018-08-20T22:47:49.840 回答