BetterCallMe
BetterCallMe

Reputation: 768

Selecting polygons which shares a boundary with target polygon in python preferably using GeoPandas

I have a GeoDataFrame as gdf. I want to select polygons which touches the target geometry with id 4. But when i use GeoPandas's touches() it spits geometries sharing boundary along with geometries just touching a corner of target geometry (with id 4). I had bad luck with GeoPandas intersects()too such that it produced all the geometries which touches() produced including the target geometry.

I want to select only those geometries which actually share the boundaries with the target(id 4) such that output will be only geometries with ID's (3,7,5, 1). code:

import geopandas as gpd
gdf = ,Id,geometry
        0,0,"POLYGON ((-2247824.100899419 -4996167.43201861, -2247824.100899419 -4996067.43201861, -2247724.100899419 -4996067.43201861, -2247724.100899419 -4996167.43201861, -2247824.100899419 -4996167.43201861))"
        1,0,"POLYGON ((-2247724.100899419 -4996167.43201861, -2247724.100899419 -4996067.43201861, -2247624.100899419 -4996067.43201861, -2247624.100899419 -4996167.43201861, -2247724.100899419 -4996167.43201861))"
        2,0,"POLYGON ((-2247624.100899419 -4996167.43201861, -2247624.100899419 -4996067.43201861, -2247524.100899419 -4996067.43201861, -2247524.100899419 -4996167.43201861, -2247624.100899419 -4996167.43201861))"
        3,0,"POLYGON ((-2247824.100899419 -4996067.43201861, -2247824.100899419 -4995967.43201861, -2247724.100899419 -4995967.43201861, -2247724.100899419 -4996067.43201861, -2247824.100899419 -4996067.43201861))"
        4,0,"POLYGON ((-2247724.100899419 -4996067.43201861, -2247724.100899419 -4995967.43201861, -2247624.100899419 -4995967.43201861, -2247624.100899419 -4996067.43201861, -2247724.100899419 -4996067.43201861))"
        5,0,"POLYGON ((-2247624.100899419 -4996067.43201861, -2247624.100899419 -4995967.43201861, -2247524.100899419 -4995967.43201861, -2247524.100899419 -4996067.43201861, -2247624.100899419 -4996067.43201861))"
        6,0,"POLYGON ((-2247824.100899419 -4995967.43201861, -2247824.100899419 -4995867.43201861, -2247724.100899419 -4995867.43201861, -2247724.100899419 -4995967.43201861, -2247824.100899419 -4995967.43201861))"
        7,0,"POLYGON ((-2247724.100899419 -4995967.43201861, -2247724.100899419 -4995867.43201861, -2247624.100899419 -4995867.43201861, -2247624.100899419 -4995967.43201861, -2247724.100899419 -4995967.43201861))"
        8,0,"POLYGON ((-2247624.100899419 -4995967.43201861, -2247624.100899419 -4995867.43201861, -2247524.100899419 -4995867.43201861, -2247524.100899419 -4995967.43201861, -2247624.100899419 -4995967.43201861))"

shares_boundary = gdf[gdf.geometry.touches(gdf['geometry'][4])]

gdf

Upvotes: 1

Views: 948

Answers (1)

mgc
mgc

Reputation: 5443

You can write a function, using shapely methods, implementing your logic, like so:

def share_boundary(geom1, geom2):
    if geom1.touches(geom2):
        if not isinstance(geom1.intersection(geom2), Point):
            return True
    return False

Then apply it on your geometry column using apply:

result = gdf[gdf.geometry.apply(lambda x: share_boundary(x, gdf['geometry'][4]))]
print(result.index) # Int64Index([1, 3, 5, 7], dtype='int64')

Upvotes: 2

Related Questions