web-dev-qa-db-ja.com

PythonでgeoJSONを使用してポリゴンをポイントします。

たくさんのポリゴン(具体的には国勢調査区)を含むgeoJSONデータベースがあり、長い緯度経度のポイントがたくさんあります。

与えられた座標がどの国勢調査区にあるかを特定するための効率的なPythonコードが存在することを願っていますが、これまでのところ、グーグルで何も明らかにしていません。

ありがとう!

31

私は興味深い article を見つけました。あなたが望んでいることを正確に行う方法を説明しています。

TL; DR: Shapely を使用

このコードは記事の最後にあります。

import json
from shapely.geometry import shape, Point
# depending on your version, use: from shapely.geometry import shape, Point

# load GeoJSON file containing sectors
with open('sectors.json') as f:
    js = json.load(f)

# construct point based on lon/lat returned by geocoder
point = Point(-122.7924463, 45.4519896)

# check each polygon to see if it contains the point
for feature in js['features']:
    polygon = shape(feature['geometry'])
    if polygon.contains(point):
        print 'Found containing polygon:', feature
42
Zebs

これらのタイプのデータを操作するための優れたオプションは、 PostgreSQL の空間データベースエクステンダーである PostGIS です。私は自分のすべての地理データをPostGISデータベースに個人的に保存し、次にpsycopg2を使用してpythonを使用して参照します。純粋なpythonではないことを知っていますが、信じられないほどのパフォーマンス上の利点があります。以下)純粋なpython上。

PostGISには、ポイントまたはシェイプが別のシェイプ内にあるかどうかを判別する機能が組み込まれています。 ST_Within 関数に関する優れたドキュメントは、この単純な例を拡張したものです。

SELECT
ST_WITHIN({YOUR_POINT},boundary)
FROM census;
-- returns true or false for each of your tracts

他の場所では達成できない可能性が高いPostGISから得られる利点はインデックス作成です。これにより、速度が1,000倍に向上し[1]、最高のCプログラムよりも優れたものになります(ただし、Cプログラムがあなたのデータ)。データベースは、適切に設定されると、トラクトに関する情報をキャッシュします。ポイントがトラクト内にあるかどうかを尋ねると、すべてを検索する必要はありません...インデックスを利用できます。

PostGRESとの間でデータを取得するのは非常に簡単です。 PostGISの基本を紹介する優れたチュートリアルであり、サンプルデータセットがあなたのものとそれほど変わらない場合は、こちらにあります。それはかなり長いですが、(私がそうであったように)PostGISを初めて使用する場合は、非常に楽しまれ、ずっと興奮します。

http://workshops.boundlessgeo.com/postgis-intro/

[1]インデックスを作成すると、私の巨大なデータベースの1つで最近傍検索が減少しました(20 mが53秒から8.2ミリ秒になりました)。

5
sAlexander

Pythonで本当に高速な幾何学的コードを持つことはできません。代わりに、通常のアプローチは、高速C/C++ライブラリをPythonラッパーで使用することです。

たとえば、非常に包括的なC++ジオメトリックライブラリであるCGALから始めることができます。 Pythonバインディングのほとんどのルーチンに対応しています。リンク http://code.google.com/p/cgal-bindings/ を参照してください。

2