I have this situation in which I want to detect elements that ought to be contained on the boundary of a geometrical feature, but because of a variety of reason these point-wise objects can be "seen" within or outside the geometry. The within part is not an issue since I wish to use "contains" as a method. So, what I do is that I
buffer the geometries I have in order to "catch" elements that are just outside the boundary. But this is kind of an issue as well. Indeed, buffering might imply that an element belongs to two geometries when they actually can only be in one.
Here is an example (albeit very naïve, it still illustrate the problem).
import geopandas import pandas as pd %matplotlib inline import matplotlib.pyplot as plt from shapely.geometry import Point from geopandas import datasets, GeoDataFrame, read_file from geopandas.tools import overlay from shapely.geometry import Polygon, LineString, Point s = geopandas.GeoSeries( [ Point(1.05, 1.1), Point(0.1, 1.1), ], ) s2 = geopandas.GeoSeries( [ Polygon([(0, 0), (1, 1), (0, 1)]), Polygon([(1.25, 1), (2, 2), (1.25, 2)]), ], index=range(1, 3), ) envgdf1 = geopandas.GeoDataFrame(geometry=gpd.GeoSeries(s2)) envgdf2 = geopandas.GeoDataFrame(geometry=gpd.GeoSeries(s)) envgdf1 = envgdf1.rename_geometry('Object') envgdf2 = envgdf2.rename_geometry('Point')
Picture the triangle as my objects and the black points as these object that actually ought to be on either one of these triangle. As I explained above, I buffer the triangle in order to ingulf these points:
envgdf1['buffered_object'] = envgdf1['Object'].buffer(0.3) envgdf1 = envgdf1.set_geometry('buffered_object')
Which results in
Seen as a dataframe:
df = gpd.sjoin(envgdf1,envgdf2, how="inner", op='contains') Object \ 1 POLYGON ((0.00000 0.00000, 1.00000 1.00000, 0.... 1 POLYGON ((0.00000 0.00000, 1.00000 1.00000, 0.... 2 POLYGON ((1.25000 1.00000, 2.00000 2.00000, 1.... buffered_object index_right 1 POLYGON ((-0.30000 0.00000, -0.30000 1.00000, ... 1 1 POLYGON ((-0.30000 0.00000, -0.30000 1.00000, ... 0 2 POLYGON ((0.95000 1.00000, 0.95000 2.00000, 0.... 0
you can notice that there are two rows for the same object
index_right = 0, meaning that the point is in both polygons.
Is there a way to deal with this in a good way? That is:
- Ignoring anything where the inclusion is ambiguous
- Even better: "If the point is closer to one of the geometries, then it belong to that one"
- Any other method?