使用 RGeo、PostGIS 和 ST_Contains 查找包含在多边形内的多边形
Find polygons contained inside polygon using RGeo, PostGIS and ST_Contains
我有两个模型:Search
(geom 保存在属性 area
上)和 Land
(geom 保存在属性 geom
上)。
Land
从外部服务导入并保存到具有特定 SRID 的数据库。例如:
SRID=28992;POLYGON((84078.122 444751.117,84076.78 444756.486,84074.578 444765.296,84073.017 444771.6,84072.863 444771.565,83990.385 444752.587,83983.081 444741.282,83973.47 444727.641,83977.639 444696.765,83977.795 444696.272,83978.017 444695.806,83978.303 444695.376,83978.645 444694.989,83979.038 444694.654,83979.474 444694.376,83979.944 444694.162,83980.439 444694.015,83980.849 444687.415,83980.059 444680.175,83981.009 444674.015,83990.579 444630.535,83991.039 444628.175,83992.959 444622.795,83993.499 444619.895,83996.899 444602.515,84008.879 444549.116,84012.229 444550.167,84008.676 444568.23,84006.244 444579.55,83996.923 444617.582,83994.764 444631.493,83990.631 444646.408,83982.258 444684.123,83981.276 444694.907,83977.284 444727.724,83982.965 444736.217,83992.091 444749.86,84017.353 444756.019,84019.237 444745.384,84019.439 444745.432,84064.525 444756.091,84065.019 444756.24,84065.528 444756.322,84066.044 444756.336,84066.557 444756.28,84067.058 444756.157,84067.539 444755.967,84067.989 444755.716,84068.402 444755.406,84068.77 444755.044,84069.086 444754.636,84069.345 444754.19,84069.542 444753.713,84069.674 444753.214,84070.354 444750.339,84070.689 444749.934,84071.073 444749.575,84071.5 444749.269,84071.963 444749.02,84072.455 444748.834,84072.966 444748.712,84073.489 444748.657,84074.014 444748.67,84074.533 444748.751,84075.038 444748.898,84083.199 444750.826,84082.865 444752.243,84078.122 444751.117))
保存在 Search
实例上的几何图形来自 OpenStreetMap 上的坐标,我相信它使用 SRID=4326
。在数据库中,我可以看到这些值是在没有 SRID=
部分的情况下保存的。例如:
POLYGON((4.270822 52.088838,4.271509 52.088324,4.271214 52.088232,4.270533 52.088235,4.270248 52.088637,4.270527 52.088822,4.270822 52.088838))
class Land < ActiveRecord::Base
def self.in_area(area)
sql = "SELECT * FROM #{self.table_name} WHERE ST_Contains(ST_Transform(ST_SetSRID(#{area},4326),4326), ST_Transform(geom,4326))"
result = Land.connection.execute(sql)
end
end
我这样称呼它:
Land.in_area(Search.last.area)
这给出了错误:
ActiveRecord::StatementInvalid (PG::SyntaxError: ERROR: syntax error at or near "52.19414")
Search.last.area.factory
returns a RGeo::Geos::CAPIFactory
,SRID 错误。所以我想把它变成一个正确的工厂:
factory = RGeo::Geos.factory(srid: 4326).parse_wkt(Search.last.area)
Land.in_area(factory) # however, this still returns the same error
我还尝试了一些其他的变体和组合,例如:
"SELECT * FROM #{self.table_name} WHERE ST_Contains(ST_Geomfromtext(#{area.to_s}), geom)"
里面都是return同样的错误。我一定错过了一些非常明显的东西。我错过了什么?
解决范围:
scope :in_area, -> (area_4326) { where("ST_Contains(ST_Transform(ST_SetSRID(ST_GeomFromText(?),4326),4326), ST_Transform(geom, 4326))", area_4326) }
其中 area_4326
是几何体的字符串表示形式
我有两个模型:Search
(geom 保存在属性 area
上)和 Land
(geom 保存在属性 geom
上)。
Land
从外部服务导入并保存到具有特定 SRID 的数据库。例如:
SRID=28992;POLYGON((84078.122 444751.117,84076.78 444756.486,84074.578 444765.296,84073.017 444771.6,84072.863 444771.565,83990.385 444752.587,83983.081 444741.282,83973.47 444727.641,83977.639 444696.765,83977.795 444696.272,83978.017 444695.806,83978.303 444695.376,83978.645 444694.989,83979.038 444694.654,83979.474 444694.376,83979.944 444694.162,83980.439 444694.015,83980.849 444687.415,83980.059 444680.175,83981.009 444674.015,83990.579 444630.535,83991.039 444628.175,83992.959 444622.795,83993.499 444619.895,83996.899 444602.515,84008.879 444549.116,84012.229 444550.167,84008.676 444568.23,84006.244 444579.55,83996.923 444617.582,83994.764 444631.493,83990.631 444646.408,83982.258 444684.123,83981.276 444694.907,83977.284 444727.724,83982.965 444736.217,83992.091 444749.86,84017.353 444756.019,84019.237 444745.384,84019.439 444745.432,84064.525 444756.091,84065.019 444756.24,84065.528 444756.322,84066.044 444756.336,84066.557 444756.28,84067.058 444756.157,84067.539 444755.967,84067.989 444755.716,84068.402 444755.406,84068.77 444755.044,84069.086 444754.636,84069.345 444754.19,84069.542 444753.713,84069.674 444753.214,84070.354 444750.339,84070.689 444749.934,84071.073 444749.575,84071.5 444749.269,84071.963 444749.02,84072.455 444748.834,84072.966 444748.712,84073.489 444748.657,84074.014 444748.67,84074.533 444748.751,84075.038 444748.898,84083.199 444750.826,84082.865 444752.243,84078.122 444751.117))
保存在 Search
实例上的几何图形来自 OpenStreetMap 上的坐标,我相信它使用 SRID=4326
。在数据库中,我可以看到这些值是在没有 SRID=
部分的情况下保存的。例如:
POLYGON((4.270822 52.088838,4.271509 52.088324,4.271214 52.088232,4.270533 52.088235,4.270248 52.088637,4.270527 52.088822,4.270822 52.088838))
class Land < ActiveRecord::Base
def self.in_area(area)
sql = "SELECT * FROM #{self.table_name} WHERE ST_Contains(ST_Transform(ST_SetSRID(#{area},4326),4326), ST_Transform(geom,4326))"
result = Land.connection.execute(sql)
end
end
我这样称呼它:
Land.in_area(Search.last.area)
这给出了错误:
ActiveRecord::StatementInvalid (PG::SyntaxError: ERROR: syntax error at or near "52.19414")
Search.last.area.factory
returns a RGeo::Geos::CAPIFactory
,SRID 错误。所以我想把它变成一个正确的工厂:
factory = RGeo::Geos.factory(srid: 4326).parse_wkt(Search.last.area)
Land.in_area(factory) # however, this still returns the same error
我还尝试了一些其他的变体和组合,例如:
"SELECT * FROM #{self.table_name} WHERE ST_Contains(ST_Geomfromtext(#{area.to_s}), geom)"
里面都是return同样的错误。我一定错过了一些非常明显的东西。我错过了什么?
解决范围:
scope :in_area, -> (area_4326) { where("ST_Contains(ST_Transform(ST_SetSRID(ST_GeomFromText(?),4326),4326), ST_Transform(geom, 4326))", area_4326) }
其中 area_4326
是几何体的字符串表示形式