私はpostgisとrgeoにまったく慣れていません。私は間違った方法で物事に取り組んでいる可能性があると思いますが、いくつかの操作、特に包含と範囲内が球ベースのオブジェクトでは不可能であることを知って少し驚いています。
郵便番号などに基づいてグループ化したい地理的に分散したオブジェクトがたくさんあります。これらのグループごとに境界があり、オブジェクトがその境界内にあるかどうかを確認し、ある境界が別の境界内にあるかどうかも確認したいと考えています。Rails を使用しています。これは、コレクション モデルのセットアップに使用される移行です。
class CreateGeoCollectionDefinition < ActiveRecord::Migration[5.0]
def change
create_table :geo_collection_definitions do |t|
t.string :name
t.string :geo_place_id
t.string :geo_place_types, array: true, default: []
t.st_polygon :boundary, geographic: true
t.jsonb :boundary_json
t.st_point :latlng, geographic: true
end
end
end
現在、境界は Google リバース ジオコード ルックアップから取得されています。北東と南西のバウンディング ボックスの座標は、オブジェクトの作成時にこのメソッドに渡されます。
GEO_FACTORY = RGeo::Geographic.spherical_factory(srid: 4326)
def self.createBoundary(pointOne, pointTwo)
point1 = GEO_FACTORY.point(pointOne['lat'], pointOne['lng'])
point2 = GEO_FACTORY.point(pointTwo['lat'], pointTwo['lng'])
boundingBox = RGeo::Cartesian::BoundingBox.create_from_points(point1, point2).to_geometry
boundingBox
end
すべてが期待どおりに動作していることを確認するために、いくつかの仕様を作成しました。単純な距離ベースのテストはすべて期待どおりに合格しますが、境界機能のテストに使用されるテストには問題があります。私は次のことに遭遇します
# ------------------
# --- Caused by: ---
# PG::UndefinedFunction:
# ERROR: function st_contains(geography, geography) does not exist
# LINE 1: ...COUNT(*) FROM "geo_collection_definitions" WHERE (ST_Contain...
# ^
# HINT: No function matches the given name and argument types. You might need to add explicit type casts.
次のようなクエリを実行しようとすると(少しばかげていることはわかっています)
GeoCollectionDefinition.where("ST_Contains(boundary, boundary)")
またはrgeoオブジェクトを直接使用しようとすると
it "should be possible to test is points belong in GeoCollection.boundary" do
factory = RGeo::Geographic.spherical_factory(srid: 4326)
externalPoint = factory.point(EmptyGeocodeLatLag['lng'], EmptyGeocodeLatLag['lat'])
expect(someplace_def.boundary.contains?(someplace_def.latlng)).to be_truthy
expect(someplace_def.boundary.contains?(externalPoint)).to be_falsy
end
私は得る
RGeo::Error::UnsupportedOperation:
Method Geometry#contains? not defined.
掘り下げてみると、このrgeoの問題と、これらの操作が球形のファクトリベースのオブジェクトではサポートされていないという他の証拠が見つかりました
ちょっと思ったんです;
- これは間違いないか
- 移行で説明した方法で境界とオブジェクトの位置をモデル化することは、私には理にかなっているように思えますが、それについては間違っていると思いますか?
- postgis、rgeo、およびアクティブなレコード アダプターを使用して、多数のポイントがポリゴン内にあるかどうかを調べるにはどうすればよいですか?
- あるポリゴンが別のポリゴンの中にあるかどうかを確認することはできますか?
編集:
私は傾斜の提案をフォローアップし、データベースで直接いくつかのクエリを実行しました。まず、セットアップを確認するだけです
SELECT PostGIS_full_version();
NOTICE: Function postgis_topology_scripts_installed() not found. Is topology support enabled and topology.sql installed? postgis_full_version
POSTGIS="2.1.7 r13414" GEOS="3.5.0-CAPI-1.9.0 r4084" PROJ="Rel. 4.9.2, 08 September 2015" GDAL="GDAL 1.11.5, released 2016/07/01" LIBXML="2.9.2" LIBJSON="UNKNOWN" RASTER
また、いくつかのクエリを実行しました。
SELECT name FROM geo_collection_definitions WHERE st_contains(latlng, boundary);
ERROR: function st_contains(geography, geography) does not exist
LINE 1: ...ELECT name FROM geo_collection_definitions WHERE st_contain...
したがって、含まれていると推測すると、地域では機能しません。私は周りを掘り下げて、st_coversを見つけました
SELECT name FROM geo_collection_definitions WHERE st_covers(boundary, latlng);
name
------
(0 rows)
SELECT name FROM geo_collection_definitions WHERE st_covers(boundary, ST_GeomFromText('POINT(12.9549709 55.5563043)', 4326));
name
------
(0 rows)
latlng が境界の中心点であるため、これは本当に驚くべきことです。私はかなり混乱していて、かなりばかげたことをしていると確信しています。どんな助けでも大歓迎です