J'obtiens cette erreur en utilisant cascaded_union (j'ai également essayé unary_union qui produit la même erreur):

ValueError: No Shapely geometry can be created from null value

J'ai validé que mes polygones sont valides. Initialement, polyB n'est pas valide, mais il est converti en un polygone valide à l'aide de buffer(0).

Une idée de ce que je fais mal? Voici mon code:

from shapely.geometry import Polygon
from shapely.ops import cascaded_union

def combineBorders(a, b):
    polyA = Polygon(a)
    polyB = Polygon(b)
    pols = [polyA, polyB]

    for p in pols:
        if p.is_valid == False:
            p = p.buffer(0)
        print(p.is_valid)
True
True
    newShape = cascaded_union(pols) # THIS IS WHERE THE ERROR KEEPS SHOWING UP
    return newShape

Voici un lien vers les valeurs de polyA, polyB et pols (après confirmation de leur validité) . J'ai les versions suivantes installées sur mon serveur Ubuntu 14.04:

  • python-galbé 1.3.0
  • libgeos 3.4.2
  • python 2.7
4
Mark Hebert 13 juil. 2015 à 21:52

2 réponses

Meilleure réponse

Le problème dans la question est que le polygone tamponné n'a pas été remis dans la liste pols, donc la géométrie invalide a été passée à cascaded_union

Vous pouvez rendre cela beaucoup plus simple et polyvalent avec ce qui suit, qui peut prendre n'importe quel nombre de géométries de polygones (pas seulement deux).

def combineBorders(*geoms):
    return cascaded_union([
        geom if geom.is_valid else geom.buffer(0) for geom in geoms
    ])

polyC = combineBorders(polyA, polyB)
7
Mike T 14 juil. 2015 à 21:57

Découvrez le problème. Je ne sais pas pourquoi c'est important (j'ai vu des exemples le montrant dans les deux sens), mais cela fonctionne après avoir placé les polygones directement dans cascaded_union comme ceci: newShape = cascaded_union([polyA, polyB]). Voici le code entièrement révisé qui fonctionne:

from shapely.geometry import Polygon
from shapely.ops import cascaded_union

def combineBorders(a, b):
    polyA = Polygon(a)
    polyB = Polygon(b)
    polyBufA = polyA.buffer(0)
    polyBufB = polyB.buffer(0)
    newShape = cascaded_union([polyBufA, polyBufB])
    return newShape

Cela fonctionne également avec unary_union

1
Mark Hebert 13 juil. 2015 à 20:26