19

地理的な位置座標 (緯度と経度) を使用してオブジェクトを作成し、指定された座標から 5 km の距離 (半径) 内にあるすべてのオブジェクトを照会できる Python モジュールはありますか?

私は、緯度と経度をキーとして辞書に保存し(キーでインデックスが付けられているため)、距離検索アルゴリズムを使用してクエリを実行しようとしています。しかし、これは恐ろしいハックのように感じます。

基本的に PostGIS for PostgreSQL のようなものですが、すべて Python アプリのメモリ内にあります。

4

7 に答える 7

20

はい、geopyを試してください。

import geopy
import geopy.distance

pt1 = geopy.Point(48.853, 2.349)
pt2 = geopy.Point(52.516, 13.378)

dist = geopy.distance.distance(pt1, pt2).km
# 878.25

その後、ポイントのリストを照会できます。

[pt for pt in points if geopy.distance.distance(orig, pt).km < 5.]
于 2012-01-31T11:36:37.753 に答える
6

これはまさにあなたが意図したものではないことはわかっていますが、インメモリ SQLite データベースでGeoDjangoを使用できます。これは、Web アプリケーションとして公開される GIS ツールの完全なセットであり、GIS アプリケーション、特に小規模なアドホック クエリを迅速に開発するためのスイス アーミー ナイフとなります。

于 2012-01-31T12:00:14.890 に答える
2

GIS での通常のアプローチは、関心のあるポイントの周りにバッファーを作成し、交点をクエリすることです。@RyanDalton が示唆しているように、多くの地理位置情報を行う予定がある場合は、Python 用のGIS API であるShapely を使用してください。空間インデックスが必要な場合でも、Shapely について知っておくとよいでしょう (以下を参照)。Shapely でバッファを作成する方法は次のとおりです。

distance = 3
center = Point(1, 1)
pts = [Point(1.1, 1.2),Point(1.2,1.2)]
center_buf = a.buffer(distance)
#filters the points list according to whether they are contained in the list
contained = filter(center_buf.contains,pts)

ポイントが多くない場合は、自分でポイントにインデックスを付けることができます(たとえば、経度で言いましょう)。それ以外の場合は、Rtree パッケージを使用することもできます。Rtree を安価な空間データベースとして使用するというリンクを確認してください。

于 2012-02-01T13:53:18.410 に答える
1

辞書のアイデアはそれほど悪くはありませんが、「隣接する」辞書キーに該当するポイントもチェックする必要があります。

適切なツールが見つからない場合、およびコーディングアルゴリズムのように、バイナリスペースパーティションツリーを実装できます。これは、同様のことを実現するためのハックの少ない方法です。

于 2012-01-31T12:20:13.730 に答える
1

まさにその種のストレージとクエリを実行するためのRtree拡張機能を持つ SQLite を使用できます。このアプローチは、データが使用するメモリよりも大きい場合、またはプログラムの実行間でデータを保存して操作する場合に役立ちます。実際のストレージとクエリ コードは C で書かれているため、コンパイルする必要がありますが、geopy のような純粋な Python ソリューションよりも優れたパフォーマンスが得られるという利点があります。SQLite アクセスには、pysqlite または APSW のいずれかが機能します。(開示: 私は APSW の作成者です。)

于 2012-02-02T09:55:05.333 に答える
1

私は同様の問題を抱えており、SciPyのcKDTreeを地理的距離の計算に GeoPy と一緒に使用して高速な最近点検索を行うとうまくいくようです。

In [1]: import numpy as np
In [2]: from scipy.spatial import cKDTree
In [3]: from geopy import Point, distance
In [4]: points = np.random.sample((100000, 2)) * 180 - 90   # make 100k random lat-long points
In [5]: index = cKDTree(points)
In [6]: %time lat_long_dist, inds = index.query(points[234], 20)
CPU times: user 118 µs, sys: 164 µs, total: 282 µs
Wall time: 248 µs
In [7]: points_geopy = [Point(*p) for p in points]
In [8]: %time geo_dists = [distance.great_circle(points_geopy[234], points_geopy[i]) for i in inds]
CPU times: user 244 µs, sys: 218 µs, total: 462 µs
Wall time: 468 µs
In [9]: geo_dists
Out[9]: 
[Distance(0.0),
 Distance(29.661520907955524),
 ...
 Distance(156.5471729956897),
 Distance(144.7528417712309)]

半径内のすべてのポイントを取得するには、少し余分な作業が必要です。

私は Shapely の STRtree を試しましたが、はるかにパフォーマンスが低下しました (私は でインストールしましたpip install shapely[vectorized])。

于 2019-03-04T15:39:49.647 に答える
0

Shapelyを見たことがありますか?距離内のオブジェクトをクエリするためのいくつかのメソッドがあります。BinarySpatialPredicatesを見てください。それはあなたが探しているものかもしれません。

于 2012-01-31T23:52:39.867 に答える