Estoy intentando capturar todos los polígonos no superpuestos que se indican a continuación utilizando Shapely (dados los polígonos A,B y C). Además, espero hacerlo sin iteración, pruebas de intersección, etc. La respuesta aceptada a este pregunta expresa el método PostGIS, pero parece que "unión" significa cosas diferentes para personas diferentes.
Respuestas
¿Demasiados anuncios?Necesitas iterar a cierto nivel. ( Actualización : He editado para eliminar todos los bucles "for", excepto uno comprensión de la lista )
# imports used throughout this example
from shapely.geometry import Point
from shapely.ops import cascaded_union
from itertools import combinations
# Here are your input shapes (circles A, B, C)
A = Point(3, 6).buffer(4)
B = Point(6, 2).buffer(4)
C = Point(1, 2).buffer(4)
# list the shapes so they are iterable
shapes = [A, B, C]
Primero necesita la unión de todas las intersecciones (utilice un unión en cascada ), utilizando el combinación par de cada forma. A continuación, elimine (mediante difference
) las intersecciones de la unión de todas las formas.
# All intersections
inter = cascaded_union([pair[0].intersection(pair[1]) for pair in combinations(shapes, 2)])
# Remove from union of all shapes
nonoverlap = cascaded_union(shapes).difference(inter)
Esto es lo que nonoverlap
(a través de JTS Test Builder):
Después de unos años parece que hay una solución mejor a través de shapely
:
# imports used throughout this example
from shapely.geometry import Point
from shapely.ops import polygonize, unary_union
# Here are your input shapes (circles A, B, C)
A = Point(3, 6).buffer(4)
B = Point(6, 2).buffer(4)
C = Point(1, 2).buffer(4)
...
# list the shapes so they are iterable
shapes = [A, B, C, ...]
# generate the overlay
list(polygonize(unary_union(list(x.exterior for x in shapes))))
Soporta cualquier longitud de la geometría, el único problema es sobre el tiempo de cálculo, y no apoyar polígono con agujeros.