I have a cluster of seven overlapping circles and ellipses that I'm trying to combine into one shape, but when I run cascaded_union()
I get the error:
ValueError: No Shapely geometry can be created from null value
Here's what I have written so far:
import numpy as np
import matplotlib.pyplot as plt
from shapely.geometry import Polygon
from shapely.ops import cascaded_union
x = [-1.86203523, -1.91255406, -2.03575331, -2.16247874, -2.22159676, -2.17992322,
-2.06085035, -1.93121615, -1.86378696, -1.89641216, -1.838166, -1.88166833,
-1.98775658, -2.09688125, -2.14778844, -2.1119029, -2.00936791, -1.89773847,
-1.83967446, -1.86776838, -1.55136662, -1.60188546, -1.72508471, -1.85181013,
-1.91092815, -1.86925461, -1.75018174, -1.62054755, -1.55311836, -1.58574355,
-1.29187795, -1.33538028, -1.44146853, -1.5505932, -1.60150039, -1.56561485,
-1.46307986, -1.35145041, -1.2933864, -1.32148032, -1.07173048, -1.11382951,
-1.21649555, -1.32210007, -1.37136508, -1.33663714, -1.23740975, -1.12938125,
-1.07319027, -1.10037793, -1.87340556, -1.79563936, -1.5818673, -1.35208399,
-1.23527147, -1.29699902, -1.50261769, -1.73670954, -1.86787402, -1.82248584,
-1.98180156, -1.89591919, -1.66476691, -1.4180952, -1.29436593, -1.36303087,
-1.58554696, -1.83701142, -1.97627207, -1.92515911]
y = [0.80459679, 0.9296353, 0.98448714, 0.93836285, 0.81715295, 0.68889502,
0.62558285, 0.66275485, 0.77954562, 0.91039814, 0.63006386, 0.73773591,
0.78496944, 0.74525131, 0.6408761, 0.53043177, 0.47591296, 0.50792219,
0.60849203, 0.72117057, 0.6981317, 0.82317021, 0.87802205, 0.83189777,
0.71068786, 0.58242993, 0.51911776, 0.55628977, 0.67308054, 0.80393305,
0.60213859, 0.70981064, 0.75704417, 0.71732605, 0.61295084, 0.50250651,
0.44798769, 0.47999693, 0.58056676, 0.6932453, 0.77841685, 0.8826156,
0.92832546, 0.88988856, 0.78888032, 0.6819987, 0.62923856, 0.66021523,
0.75754088, 0.86658463, 0.84706981, 0.76282008, 0.69418295, 0.67968584,
0.7274663, 0.81070415, 0.88267631, 0.90298332, 0.86022645, 0.77840601,
0.56517702, 0.48654992, 0.41794253, 0.39786557, 0.43758864, 0.51481438,
0.5861944, 0.61166165, 0.57692084, 0.50147268]
m = 7
n = 10
x_1 = np.zeros(shape=(m,n))
y_1 = np.zeros(shape=(m,n))
for i in range(m):
for j in range(n):
x_1[i][j] = x[j+(n*i)]
y_1[i][j] = y[j+(n*i)]
plt.plot(x_1[i],y_1[i])
plt.axis('scaled')
plt.show()
Poly1 = Polygon(zip(x_1[0],y_1[0]))
Poly2 = Polygon(zip(x_1[1],y_1[1]))
Poly3 = Polygon(zip(x_1[2],y_1[2]))
Poly4 = Polygon(zip(x_1[3],y_1[3]))
Poly5 = Polygon(zip(x_1[4],y_1[4]))
Poly6 = Polygon(zip(x_1[5],y_1[5]))
Poly7 = Polygon(zip(x_1[6],y_1[6]))
polygons = [Poly1,Poly2,Poly3,Poly4,Poly5,Poly6,Poly7]
boundary = cascaded_union(polygons)
My goal is to get something like the picture on the right:
where the rest of my code will determine how many points in a random distribution fall within the boundaries of an irregular shape. I'm confused on what the error is referring to when it returns the "null value" comment. Am I not accounting for the overlap of individual shapes in the right way? From what I've searched for already cascaded_union
takes an input of an array of shapes but for some reason that isn't working in this case.
All of your geometries are invalid.
[p.is_valid for p in polygons] # [False, False, False, ...]
If you look closely at your plot, the lines used for each LinearRing cross near the start and end. This makes Polygons invalid, which inevitably yield unpredictable results.
Here's my version of what you are doing:
# Discard the first and last points from each list of coordinates
x_2 = x_1[:, 1:-1]
y_2 = y_1[:, 1:-1]
# Build a list of polygons
polygons = [Polygon(zip(x_2[i], y_2[i])) for i in range(x_2.shape[0])]
boundary = cascaded_union(polygons) # POLYGON ((-1.343821678336245 0.4932102...