Comment obtenir/extraire les points qui définissent un polygone shapely
? ?__. Merci!
Exemple de polygone arrondi
from shapely.geometry import Polygon
# Create polygon from lists of points
x = [list of x vals]
y = [list of y vals]
polygon = Polygon(x,y)
J'ai donc découvert que l'astuce consiste à utiliser une combinaison des méthodes de la classe Polygon
pour y parvenir.
Si vous voulez des coordonnées géodésiques, vous devez ensuite les reconvertir en WGS84 (via pyproj
, matplotlib
's basemap
ou quelque chose du genre).
from shapely.geometry import Polygon
#Create polygon from lists of points
x = [list of x vals]
y = [list of y vals]
some_poly = Polygon(x,y)
# Extract the point values that define the perimeter of the polygon
x, y = some_poly.exterior.coords.xy
Vous pouvez utiliser la fonction sinueuse mapping
:
>>> from shapely.geometry import Polygon, mapping
>>> sh_polygon = Polygon(((0,0), (1,1), (0,1)))
>>> mapping(sh_polygon)
{'type': 'Polygon', 'coordinates': (((0.0, 0.0), (1.0, 1.0), (0.0, 1.0), (0.0, 0.0)),)}
Il m'a fallu un certain temps pour apprendre qu'un polygone avait une limite extérieure et éventuellement plusieurs limites intérieures. Je poste ici parce que certaines des réponses ne reflètent pas cette distinction, bien que, pour être juste, la publication originale n’ait pas utilisé comme exemple un polygone avec des limites intérieures.
Les points formant la limite extérieure sont disposés dans une séquence CoordinateSequence, qui peut être obtenue en tant que
polygon.exterior.coords
Vous pouvez trouver la longueur de cet objet à l'aide de len(polygon.exterior.coords)
.__ et l'indexer comme une liste. Pour obtenir le premier sommet, par exemple, utilisez polygon.exterior.coords[0]
. Notez que les premier et dernier points sont les mêmes; Si vous voulez une liste composée des sommets sans ce point répété, utilisez polygon.exterior.coords[:-1]
.
Vous pouvez convertir la CoordinateSequence (y compris le sommet répété) en une liste de points, ainsi:
list(polygon.exterior.coords)
De la même manière, la séquence CoordinateSequence constituée des sommets formant la première limite intérieure est obtenue sous la forme polygon.interiors[0].coords
et la liste de ces sommets (sans le point répété) sous la forme polygon.interiors[0].coords[:-1]
.
J'ai utilisé ceci:
list(Zip(*p.exterior.coords.xy))
Polygone créé avec: p = Polygon([(0,0),(1,1),(1,0),(0,0)])
renvoie:
[(0.0, 0.0), (1.0, 1.0), (1.0, 0.0), (0.0, 0.0)]
Si vous voulez vraiment les objets galbés point qui constituent le polygone, et pas seulement des tuples de coordonnées, vous pouvez le faire comme suit:
points = MultiPoint(polygon.boundary.coords)
Vous pouvez convertir un polygone en un tableau NumPy à l'aide de NumPy.array. Je trouve l'utilisation des tableaux NumPy plus utiles que les tableaux renvoyés par coords.xy, car les coordonnées sont appariées, plutôt que dans deux tableaux unidimensionnels. Utilisez ce qui est le plus utile pour votre application.
import numpy as np
x = [1, 2, 3, 4]
y = [9, 8, 7, 6]
polygon = Polygon(x,y)
points = np.array(polygon)
# points is:
[[ 1 9]
[ 2 8]
[ 3 7]
[ 4 6]]
Vous pouvez utiliser l'une des deux méthodes suivantes.
1)
p = Polygon([(1,0),(1,1),(0,1),(0,0)])
for x,y in p.exterior.coords:
print(x,y)
Le code ci-dessus imprime ce qui suit. Notez que (1,0) est imprimé deux fois, puisque exterior.coords renvoie une séquence ordonnée complétant le polygone.
1.0 0.0
1.0 1.0
0.0 1.0
0.0 0.0
1.0 0.0
2)
p.exterior.coords.xy
Il délivre ce qui suit
(array('d', [1.0, 1.0, 0.0, 0.0, 1.0]), array('d', [0.0, 1.0, 1.0, 0.0, 0.0]))
Comme la dernière réponse semble ne plus fonctionner avec la nouvelle version de shapely, je propose cette mise à jour.
shapely fournit l'interface de tableau Numpy (comme le dit la doc: http://toblerity.org/shapely/project.html )
Soit donc poly
une géométrie polygonale bien définie:
In [2]: type(poly)
Out[2]: shapely.geometry.polygon.Polygon
Cette commande fera la conversion en un tableau numpy:
In [3]: coordinates_array = np.asarray(poly.exterior.coords)
Indice:
Il faut donner les codes extérieurs pour un polygone car donner la géométrie directe ne semble pas fonctionner non plus:
In [4]: coordinates_array = np.asarray(poly)
Out[4]: array(<shapely.geometry.polygon.Polygon object at 0x7f627559c510>, dtype=object)