Skip to main content
2 of 3
deleted 220 characters in body
Bera
  • 77.8k
  • 14
  • 78
  • 188

You can spatial join the dataframe to itself, intersect, the output will be the lines where two polygons share a border, and measure length:

import geopandas as gpd
import numpy as np
df = gpd.read_file(r"/home/bera/Desktop/GIStest/shared_length.shp")
#    id                                           geometry
# 0   1  POLYGON ((594912.796 7238961.152, 596731.160 7...
# 1   2  POLYGON ((594912.796 7238961.152, 595300.862 7...
# 2   3  POLYGON ((595300.862 7239216.167, 594912.796 7...
# 3   4  POLYGON ((598039.495 7240524.502, 598294.510 7...

df["geombackup"] = df.geometry
sj = gpd.sjoin(df[["id","geometry"]], df[["id","geombackup","geometry"]], how="left", predicate="intersects")
# sj[["id_left","id_right","geombackup"]].head()
#    id_left  id_right                                         geombackup
# 0        1         1  POLYGON ((594912.796 7238961.152, 596731.160 7...
# 0        1         2  POLYGON ((594912.796 7238961.152, 595300.862 7...
# 0        1         3  POLYGON ((595300.862 7239216.167, 594912.796 7...
# 1        2         1  POLYGON ((594912.796 7238961.152, 596731.160 7...
# 1        2         2  POLYGON ((594912.796 7238961.152, 595300.862 7...

#Drop self joins, like the first row above
sj = sj.loc[sj["id_left"]!=sj["id_right"]] 

#Drop duplicates, like the second row is the same as 4th. 1-2 and 2-1
sj = sj.loc[~sj.geombackup.duplicated()]

sj["borderline"] = sj.apply(lambda x: x["geometry"].intersection(x["geombackup"]), axis=1)
# sj[["id_left","id_right","borderline"]].head(1)
#    id_left  id_right                                         borderline
# 0        1         2  LINESTRING (594912.796 7238961.152, 596731.160...

sj["borderlength"] = sj["borderline"].length

sj = sj.set_geometry(col="borderline", crs=df.crs).drop(columns=["geometry","geombackup"])
sj.to_file(r"/home/bera/Desktop/GIStest/shared_borders.shp")

enter image description here

Bera
  • 77.8k
  • 14
  • 78
  • 188