Skip to content
Advertisement

geopandas midpoint on line

I have a geopandas dataframe of linestrings. Each line string is a single line.

I want to get the midpoint of the line and append the point geometry to geodataframe in a column centroid.

How do I achieve this?

Advertisement

Answer

  • LineString has a centroid, hence case of using it
  • solution demonstrates this with output as visual and as data
import geopandas as gpd
import shapely.geometry
import numpy as np

world = gpd.read_file(gpd.datasets.get_path("naturalearth_lowres"))

# pick a polygon and multipolygon to create line segments from
gdf = world.loc[world["iso_a3"].isin(["BEL", "GBR"])]


line_segs = gpd.GeoSeries(
    gdf["geometry"]
    .apply(
        lambda g: [g]
        if isinstance(g, shapely.geometry.Polygon)
        else [p for p in g.geoms]
    )
    .apply(
        lambda l: [
            shapely.geometry.LineString([c1, c2])
            for p in l
            for c1, c2 in zip(p.exterior.coords, list(p.exterior.coords)[1:])
        ]
    )
    .explode()
)

a = np.arange(0,10)
np.random.shuffle(a)
gdf2 = line_segs.to_frame().assign(centroid=line_segs.apply(lambda ls: ls.centroid),
                                  color=np.tile(a, len(line_segs)//10)[0:len(line_segs)])

# visualise it to check it out ...
ax = gdf2.plot(column="color", linewidth=3)
ax = gpd.GeoSeries(gdf2["centroid"]).plot(ax=ax, color="blue", markersize=50)

enter image description here

geometry centroid color
129 LINESTRING (6.15665815595878 50.80372101501058, 6.043073357781111 50.12805166279423) POINT (6.099865756869945 50.46588633890241) 1
129 LINESTRING (6.043073357781111 50.12805166279423, 5.782417433300907 50.09032786722122) POINT (5.912745395541009 50.10918976500773) 3
129 LINESTRING (5.782417433300907 50.09032786722122, 5.674051954784829 49.5294835475575) POINT (5.728234694042868 49.80990570738936) 8
129 LINESTRING (5.674051954784829 49.5294835475575, 4.799221632515724 49.98537303323637) POINT (5.236636793650277 49.75742829039694) 2
129 LINESTRING (4.799221632515724 49.98537303323637, 4.286022983425084 49.90749664977255) POINT (4.542622307970404 49.94643484150446) 5
129 LINESTRING (4.286022983425084 49.90749664977255, 3.588184441755658 50.37899241800356) POINT (3.937103712590371 50.14324453388806) 9
129 LINESTRING (3.588184441755658 50.37899241800356, 3.123251580425688 50.78036326761455) POINT (3.355718011090673 50.57967784280905) 7
129 LINESTRING (3.123251580425688 50.78036326761455, 2.658422071960274 50.79684804951575) POINT (2.890836826192981 50.78860565856515) 4
129 LINESTRING (2.658422071960274 50.79684804951575, 2.513573032246143 51.14850617126183) POINT (2.585997552103208 50.97267711038879) 0
129 LINESTRING (2.513573032246143 51.14850617126183, 3.314971144228537 51.34578095153609) POINT (2.91427208823734 51.24714356139896) 6
User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement