galbé polygon_.buffer(0) « perd » la moitié de mon nœud papillon
-
22-12-2019 - |
Question
J'ai vu en ligne que buffer(0) devrait "réparer" les nœuds papillon.Shapely trouve le point d'intersection du nœud papillon, mais ne conserve que la partie supérieure droite.Cherchant une solution de contournement, j'ai essayé d'inverser l'ordre de mes points.Étonnamment (pour moi), la même partie supérieure droite du nœud papillon était toujours celle conservée.Je ne comprends pas.Toute aide appréciée.
Je voudrais conserver l'ensemble du nœud papillon sous forme de deux triangles (ou d'un polygone à six côtés - l'un ou l'autre serait utile).Vous cherchez une solution de contournement pour ce "problème".
#!/usr/bin/env python3
from shapely.geometry.polygon import Polygon
bowtie_plot = [(1, 0), (0, 1), (0, -1), (-1, 0)]
bowties = [
Polygon(bowtie_plot),
Polygon(bowtie_plot[::-1])
]
cleaned = [
bowties[0].buffer(0),
bowties[1].buffer(0)
]
print('cleaned[0] exterior = {}'.format(list(cleaned[0].exterior.coords)))
# cleaned[0] exterior = [(0.0, 0.0), (-1.0, 1.0), (1.0, 1.0), (0.0, 0.0)]
print('cleaned[1] exterior = {}'.format(list(cleaned[1].exterior.coords)))
# cleaned[1] exterior = [(0.0, 0.0), (-1.0, 1.0), (1.0, 1.0), (0.0, 0.0)]
# ADDITIONAL INFORMATION BELOW
# here's what shapely *can* do with intersecting lines:
# a star shape made of five intersecting lines and five points
from math import sin, cos, pi
star = Polygon(
[(cos(x*pi*4/5), sin(x*pi*4/5)) for x in range(5)]
).buffer(0)
# after buffering, becomes a star shape made out of ten lines and ten points
# shapely found all intersections and corrected the polygon.
print('list exterior = {}'.format(list(star.exterior.coords)))
Après y avoir réfléchi, je peux comprendre pourquoi un nœud papillon est traité différemment d'une étoile, mais je souhaite trouver une solution de contournement.
La solution
Votre nœud papillon n'est pas un galbe valide Polygone.Lisez cette documentation et la documentation de Anneau Linéaire (juste au-dessus du Polygon
Documentation).En particulier, notez les exemples de valides et invalides LinearRing
s.
Si vous créez le nœud papillon comme ceci :
In [46]: bt = [(1,0), (0,1), (0,0), (-1,0), (0, -1), (0,0)]
In [47]: poly = Polygon(bt)
alors buffer(0)
renvoie un MultiPolygone:
In [48]: poly.buffer(0)
Out[48]: <shapely.geometry.multipolygon.MultiPolygon at 0x4a40050>
Autres conseils
buffer(0)
ne produit pas toujours un MultiPolygon :
from shapely.wkt import loads
bt = loads('POLYGON ((0 0, 2 2, 2 0, 0 2, 0 0))')<br>
bt.buffer(0).wkt
produces 'POLYGON ((1 1, 2 2, 2 0, 1 1))'