1

I have two Shapely geometries:

I can compute their intersection by: multipoints.intersection(polyon) which results in all points that fall inside the polygon.

I'd like to compute their 'non intersection' to get the points which doesn't fall inside the polygon but there is no such: multipoints.notintersection(polyon) method:

Wanted result

I can use the symmetric_difference as: multipoints.symmetric_difference(polyon) but this gives a geometry collection with the points I'm searching for + the whole initial polygon (for which I don't care).

I need to have that done in either one line, or a function that can be plugged into a lambda function for applying it all over the rows of a GeoDataFrame containing MultiPoint geometry instances in each row.

Notice; I can use the boolean result of an intersects inside my lambda but it doesn't seem to work when I apply it on a GeoDataFrame:

gdf['nonintersectingpoints'] = gdf['my_multipoint_column'].apply(
    lambda multipoints: multipoints if not multipoints.intersects(polygon) \
    else None
)

(result is None every where).

1 Answer 1

2

One solution is to basically take the difference between the multipoints and the resulting intersection between the multipoints and the polygon, i.e.: multipoints.difference(multipoints.intersection(polygon))

Here is a piece of commented code for understanding:

import matplotlib.pyplot as plt
from shapely.geometry import Polygon, MultiPoint
import geopandas as gpd

# A Polygon feature
polygon = Polygon([(-0.2, -0.2), (-0.2, 1.2), (1.2, 1.2),
                    (1.2, -0.2), (-0.2, -0.2) ])

# A MultiPoint feature containing severa points:
multipoints = MultiPoint([(0, 0), (0, 1), (0, -1),
                          (1, 0), (1, 1), (1, -1),
                          (-1, 0), (-1, 1), (-1, -1) ])

# Intersecting features:
inter = multipoints.intersection(polygon)

# Here is the trick to get all the non-intersecting features:
noninter = multipoints.difference(multipoints.intersection(polygon))

# Prepare GeoSeries for plotting:
p = gpd.GeoSeries(polygon)     # the Polygon feature
m = gpd.GeoSeries(multipoints) # the MultiPoint feature
i = gpd.GeoSeries(inter)       # the intersecting features
n = gpd.GeoSeries(noninter)    # the non-intersectiing features

# Plotting
fig, ax = plt.subplots(figsize = (5,5))
p.plot(color='skyblue', alpha=0.4, ax=ax)
i.plot(color='red', markersize=256, ax=ax)
# Non-intersecting features are show in green:
n.plot(color='lime', markersize=256, ax=ax)
m.plot(color='blue', markersize=16, ax=ax)
plt.grid(zorder=-9)
plt.show()

And here is the resulting figure:

Figure resulting of the previous piece of code

It can also be applied using a lambda as:
.apply(lambda multipoints: multipoints.difference(multipoints.intersection(poly))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.