web-dev-qa-db-fra.com

Point dans Polygon avec geoJSON dans Python

J'ai une base de données geoJSON avec beaucoup de polygones (secteurs de recensement en particulier) et j'ai beaucoup de longs points lat.

J'espère qu'il existerait un code Python efficace pour identifier dans quel secteur de recensement se trouve une coordonnée donnée, mais jusqu'à présent, ma recherche sur Google n'a rien révélé.

Merci!

31
Benjamin Horowitz

J'ai trouvé un intéressant article décrivant comment faire exactement ce que vous cherchez à faire.

TL; DR: Utilisez Shapely

Vous trouverez ce code à la fin de l'article:

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

PostGIS , une extension de base de données spatiale pour PostgreSQL est une excellente option pour travailler avec ces types de données. Personnellement, je garde toutes mes données géographiques dans une base de données PostGIS, puis je les référence dans python en utilisant psycopg2. Je sais que ce n'est pas du python pur, mais il a des avantages de performance incroyables (discutés ci-dessous) par rapport au python pur.

PostGIS dispose d'une fonctionnalité intégrée pour déterminer si un point ou une forme se trouve dans une autre forme. La bonne documentation sur la fonction ST_Within développe cet exemple simple:

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

Le bénéfice que vous gagnerez de PostGIS que vous n'obtiendrez probablement pas ailleurs est l'indexation, qui peut améliorer votre vitesse de 1 000x [1], ce qui le rend même meilleur que le meilleur programme C écrit (à moins que le programme C ne crée également un index pour vos données). La base de données, lorsqu'elle est correctement configurée, mettra en cache les informations sur vos tracts, et lorsque vous demandez si un point se trouve dans un tract, elle n'aura pas à tout rechercher ... elle peut profiter de son index.

Faire entrer et sortir des données de PostGRES est assez simple. Un excellent tutoriel qui vous guidera à travers les bases de PostGIS avec des exemples de jeux de données pas trop différents des vôtres peut être trouvé ici. C'est assez long, mais si vous êtes nouveau sur PostGIS (comme moi), vous serez très diverti et excité tout le temps:

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

[1] L'indexation a diminué une recherche de voisin le plus proche dans l'une de mes énormes bases de données (20 m de 53 secondes à 8,2 millisecondes.

5
sAlexander

On ne peut pas avoir de code géométrique vraiment rapide en Python. Au lieu de cela, l'approche habituelle consiste à utiliser une bibliothèque C/C++ rapide avec des wrappers Python.

Par exemple, vous pouvez commencer avec CGAL - une bibliothèque géométrique C++ très complète. Il a des liaisons Python pour la plupart de ses routines, voir le lien http://code.google.com/p/cgal-bindings/ .

2
Michael Simbirsky