TransWikia.com

How to densify LineString vertices in Shapely/GeoPandas

Geographic Information Systems Asked on May 6, 2021

I’m looking for an equivalent of densify tool in ArcGIS, but with GeoPandas or Shapely. I have a line that would like to be densified with a specific distance; how to add vertices of a line using Python?


Suppose I have a line that has 2 vertices (WKT)
LINESTRING (0 0, 9 0). how do I divide the line into an equal distance of 1 such that it returns the same line, but with instead of 2 vertices, it has 10 vertices? the result I expect:
LINESTRING (0 0, 1 0, 2 0, 3 0, 4 0, 5 0, 6 0, 7 0, 8 0, 9 0). I find this post which is similar to what I want, but it uses ArcGIS instead of GeoPandas and Shapely.

One Answer

I crafted a function for you. Here is your line, which I call old_line:

old_line=LineString([(0,0), (9,0)]) # your line with 2 vertices

Here is the function that takes a line geometry as main input, you assign a step (i.e the spacing along the old line) and and additional Coordinate Reference System (crs) to georeference the new densified line.

   def densify_geometry (line_geometry, step, crs=None):
        
        # crs: epsg code of a coordinate reference system you want your line to be georeferenced with
        # step: add a vertice every step in whatever unit your coordinate reference system use.
    
        length_m=line_geometry.length # get the length
    
        xy=[] # to store new tuples of coordinates
    
        for distance_along_old_line in np.arange(0,int(length_m),step): 
    
            point = line_geometry.interpolate(distance_along_old_line) # interpolate a point every step along the old line
            xp,yp = point.x, point.y # extract the coordinates
    
            xy.append((xp,yp)) # and store them in xy list
    
        new_line=LineString(xy) # Here, we finally create a new line with densified points.
        
        if crs != None:  #  If you want to georeference your new geometry, uses crs to do the job.
            new_line_geo=gpd.geoseries.GeoSeries(new_line,crs=crs) 
            return new_line_geo
    
        else:
            return new_line

Now, running:

densify_geometry(line_geometry=old_line, step= 0.5, crs= 32754)

returns:

LINESTRING (0.00000 0.00000, 0.50000 0.00000, ...
dtype: geometry

If you want to .apply it to a whole GeoDataFrame geometry column:

kwargs_dict={'step':0.5,
             'crs':32754}

your_gdf["new_geometry"]=your_gdf.geometry.apply(densify_geometry, kwargs=**kwargs_dict)

This should do the job.

Correct answer by Nick Pucino on May 6, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP