Shapely: pas possible de créer un objet galbé à partir de wkt

Créé le 6 févr. 2017  ·  7Commentaires  ·  Source: Toblerity/Shapely

Environnement : Win10 64 bits
Version:

>>> shapely.__version__
'1.6a1'

La création d'un objet galbé à partir de wkt fonctionne en cas de point et de ligne
de shapely.geometry importer asShape

>>> asShape({'type': 'Point', 'coordinates': (0.0, 0.0)}).buffer(1.0).area
3.1365484905459384
>>> asShape({'type': "LineString", "coordinates": [(-1,0),(0,0)]}).buffer(1.0).area
5.13654849054594

mais en cas de polygone, cela échoue. L'objet est apparemment créé,

>>> asShape({'type': "Polygon", "coordinates": [(0,0), (0,1), (1,1),(1,0),(0,0)]})
<shapely.geometry.polygon.PolygonAdapter object at 0x00000251C2CA7710>

cependant appeler toutes les méthodes lançant des exceptions

>>> asShape({'type': "Polygon", "coordinates": [(0,0), (0,1), (1,1),(1,0),(0,0)]}).area
Traceback (most recent call last):
  File "C:\Anaconda3\lib\site-packages\shapely\geometry\polygon.py", line 407, in geos_linearring_from_py
    array = ob.__array_interface__
AttributeError: 'tuple' object has no attribute '__array_interface__'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<pyshell#66>", line 1, in <module>
    asShape({'type': "Polygon", "coordinates": [(0,0), (0,1), (1,1),(1,0),(0,0)]}).area()
  File "C:\Anaconda3\lib\site-packages\shapely\geometry\base.py", line 431, in area
    return self.impl['area'](self)
  File "C:\Anaconda3\lib\site-packages\shapely\topology.py", line 55, in __call__
    self._validate(this)
  File "C:\Anaconda3\lib\site-packages\shapely\topology.py", line 17, in _validate
    if ob is None or ob._geom is None:
  File "C:\Anaconda3\lib\site-packages\shapely\geometry\proxy.py", line 49, in _geom
    self.__geom__, n = self.factory(self.context[0], self.context[1])
  File "C:\Anaconda3\lib\site-packages\shapely\geometry\polygon.py", line 526, in geos_polygon_from_py
    ret = geos_linearring_from_py(shell)
  File "C:\Anaconda3\lib\site-packages\shapely\geometry\polygon.py", line 468, in geos_linearring_from_py
    n = len(ob[0])
TypeError: object of type 'int' has no len()

Commentaire le plus utile

Ces exemples n'utilisent pas WKT. http://toblerity.org/shapely/manual.html#well-known-formats

Ils utilisent la représentation __geo_interface__ de la géométrie, ce qui est bien.

La raison pour laquelle votre polygone échoue est qu'il n'est pas valide. Les séquences de coordonnées de polygones doivent être une liste de listes de coordonnées, et non une liste de coordonnées comme vous l'avez fait. En effet, un polygone est composé de plusieurs anneaux linéaires - un anneau extérieur et plusieurs anneaux intérieurs facultatifs.

Le code suivant fonctionne. Notez les crochets supplémentaires dans les coordonnées.

>>> polygon = asShape({'type': "Polygon", "coordinates": [[(0,0), (0,1), (1,1),(1,0),(0,0)]]})
>>> polygon.is_valid

Notez également que si vous n'utilisez pas de tableaux numpy pour les coordonnées, vous pouvez tout aussi bien utiliser shape() au lieu de asShape() . Dans ce cas, l'erreur est déclenchée immédiatement, plutôt que lorsque vous essayez d'accéder aux données. http://toblerity.org/shapely/shapely.geometry.html#shapely.geometry.asShape

Tous les 7 commentaires

Ces exemples n'utilisent pas WKT. http://toblerity.org/shapely/manual.html#well-known-formats

Ils utilisent la représentation __geo_interface__ de la géométrie, ce qui est bien.

La raison pour laquelle votre polygone échoue est qu'il n'est pas valide. Les séquences de coordonnées de polygones doivent être une liste de listes de coordonnées, et non une liste de coordonnées comme vous l'avez fait. En effet, un polygone est composé de plusieurs anneaux linéaires - un anneau extérieur et plusieurs anneaux intérieurs facultatifs.

Le code suivant fonctionne. Notez les crochets supplémentaires dans les coordonnées.

>>> polygon = asShape({'type': "Polygon", "coordinates": [[(0,0), (0,1), (1,1),(1,0),(0,0)]]})
>>> polygon.is_valid

Notez également que si vous n'utilisez pas de tableaux numpy pour les coordonnées, vous pouvez tout aussi bien utiliser shape() au lieu de asShape() . Dans ce cas, l'erreur est déclenchée immédiatement, plutôt que lorsque vous essayez d'accéder aux données. http://toblerity.org/shapely/shapely.geometry.html#shapely.geometry.asShape

Okey, j'ai mal orthographié la liste, mais soit la forme correcte ne fonctionne pas :
polygon = asShape({'type': "Polygon", "coordinates": [(0,0), (0,1), (1,1),(1,0),(0,0)]})

>>> polygon.area
Traceback (most recent call last):
  File "C:\Anaconda3\lib\site-packages\shapely\geometry\polygon.py", line 407, in geos_linearring_from_py
    array = ob.__array_interface__
AttributeError: 'tuple' object has no attribute '__array_interface__'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<pyshell#8>", line 1, in <module>
    polygon.area
  File "C:\Anaconda3\lib\site-packages\shapely\geometry\base.py", line 431, in area
    return self.impl['area'](self)
  File "C:\Anaconda3\lib\site-packages\shapely\topology.py", line 55, in __call__
    self._validate(this)
  File "C:\Anaconda3\lib\site-packages\shapely\topology.py", line 17, in _validate
    if ob is None or ob._geom is None:
  File "C:\Anaconda3\lib\site-packages\shapely\geometry\proxy.py", line 49, in _geom
    self.__geom__, n = self.factory(self.context[0], self.context[1])
  File "C:\Anaconda3\lib\site-packages\shapely\geometry\polygon.py", line 526, in geos_polygon_from_py
    ret = geos_linearring_from_py(shell)
  File "C:\Anaconda3\lib\site-packages\shapely\geometry\polygon.py", line 468, in geos_linearring_from_py
    n = len(ob[0])
TypeError: object of type 'int' has no len()

même si j'utilise un tableau numpy:
arr = numpy.array([(0,0), (0,1), (1,1),(1,0),(0,0)])

ss = asShape({'type': "Polygon", "coordinates": arr})
>>> ss.area
Traceback (most recent call last):
  File "<pyshell#16>", line 1, in <module>
    ss.area
  File "C:\Anaconda3\lib\site-packages\shapely\geometry\base.py", line 431, in area
    return self.impl['area'](self)
  File "C:\Anaconda3\lib\site-packages\shapely\topology.py", line 55, in __call__
    self._validate(this)
  File "C:\Anaconda3\lib\site-packages\shapely\topology.py", line 17, in _validate
    if ob is None or ob._geom is None:
  File "C:\Anaconda3\lib\site-packages\shapely\geometry\proxy.py", line 49, in _geom
    self.__geom__, n = self.factory(self.context[0], self.context[1])
  File "C:\Anaconda3\lib\site-packages\shapely\geometry\polygon.py", line 526, in geos_polygon_from_py
    ret = geos_linearring_from_py(shell)
  File "C:\Anaconda3\lib\site-packages\shapely\geometry\polygon.py", line 408, in geos_linearring_from_py
    assert len(array['shape']) == 2
AssertionError

@ pythonfun0 Votre définition de polygone n'est pas tout à fait correcte. Essaye ça:

polygon = shape({'type': "Polygon", "coordinates": [[(0,0), (0,1), (1,1),(1,0),(0,0)]]})

Notez l'ensemble supplémentaire de crochets autour des coordonnées. La structure d'un GeoJSON Polygon est :

Pour le type "Polygon", le membre "coordinates" doit être un tableau de tableaux de coordonnées LinearRing. Pour les polygones à plusieurs anneaux, le premier doit être l'anneau extérieur et tous les autres doivent être des anneaux ou des trous intérieurs.

En d'autres termes:

{
    "type": "Polygon",
    "coordinates": [
        [<outer ring: (x, y), (x, y), ...>],
        [<hole 1 ring: (x, y), (x, y), ...>],
        [<hole 2 ring: (x, y), (x, y), ...>],
    ]
}

mais vous n'avez pas de trous, vous avez donc besoin de :

{
    "type": "Polygon",
    "coordinates": [
        [<outer ring: (x, y), (x, y), ...>],
    ]
}

Votre exemple LineString fonctionne parce que l'anneau extérieur seul _est_ un LineString valide, mais ce n'est pas un Polygon valide seul à moins qu'il ne soit imbriqué correctement.

Si vous lisez attentivement mon commentaire ultérieur, j'ai écrit que ce n'est pas une liste imbriquée, je l'ai mal orthographié !
Donc, encore une fois, j'ai essayé de créer un polygone à partir de wkt de cette façon :
polygon = asShape({'type': "Polygon", "coordinates": [(0,0), (0,1), (1,1),(1,0),(0,0)]})

Je ne veux pas créer d'objet polygone imbriqué !

S'il vous plaît, collez un vrai exemple de code fonctionnel, si vous pouvez l'avoir !

Merci!

Si vous lisez attentivement mon commentaire ultérieur, j'ai écrit que ce n'est pas une liste imbriquée, je l'ai mal orthographié !
Donc, encore une fois, j'ai essayé de créer un polygone à partir de wkt de cette façon :
polygon = asShape({'type': "Polygon", "coordinates": [(0,0), (0,1), (1,1),(1,0),(0,0)]})

ça ne marche pas avec les crochets
polygon = asShape({'type':'Polygon', 'coordinates':[[0,0],[0,1],[1,1],[1,0]]})

Je ne veux pas créer d'objet polygone imbriqué !

S'il vous plaît, collez un vrai exemple de code fonctionnel, si vous pouvez l'avoir !

Merci!

@ pythonfun0 Vous ne voyez pas ce que nous essayons de signaler.

Vous tapez ceci :

polygon = asShape({'type': "Polygon", "coordinates": [(0,0), (0,1), (1,1), (1,0), (0,0)]})

Vous devriez taper ceci :

polygon = asShape({'type': "Polygon", "coordinates": [[(0,0), (0,1), (1,1), (1,0), (0,0)]]})

Même si votre polygone n'a qu'un anneau extérieur et aucun anneau intérieur, vous devez toujours passer une liste imbriquée.

J'ai déjà compris, désolé j'ai lu distraitement vos réponses. Une liste de liste de coordonnées fonctionne parfaitement.
Merci!

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

dopplershift picture dopplershift  ·  3Commentaires

doctor-ian picture doctor-ian  ·  4Commentaires

chivasblue picture chivasblue  ·  3Commentaires

MarkWieczorek picture MarkWieczorek  ·  4Commentaires

jrobichaud picture jrobichaud  ·  3Commentaires