Using Geopandas, Shapely
Suppose I have a Linestring that represents a (cornered) street:
LineString([(1, 1), (2, 2), (3, 1)]
Note that the order of points in this linestring matters because LineString([(1, 1), (3, 1), (2, 2)] would represent a very different street.
Now, suppose I have list of points that belong to my street:
Point((1.9, 1.9))
Point((1.5, 1.5))
Point((2.5, 1.5))
Point((1.2, 1.2))
I want to create a new Linestring where all the Points are "merged" with the original street coordinates. This "merge" mechanism has to maintain the original street shape as follows:
LineString([(1, 1), (1.2, 1.2), (1.5, 1.5), (1.9, 1.9), (2, 2), (2.5, 1.5). (3, 1)]
Any ideas how to approach this?
import geopandas as gpd
from shapely.geometry import Point, LineString
street = gpd.GeoDataFrame({'street': ['st'], 'geometry': LineString([(1, 1), (2, 2), (3, 1)])})
pp = gpd.GeoDataFrame({'geometry': [Point((1.9, 1.9)), Point((1.5, 1.5)), Point((2.5, 1.5)), Point((1.2, 1.2))]})
print(street)
print(pp)
Best Answer
Here's a lengthy-ish approach if you already know which points belong to which streets:
Note how, in my code, the
street
variable isn't a GeoDataFrame but a simple shapelyLinestring
instead.The
final_geom
variable will contain the sorted points as you wanted, while thep_all
variable will contain a GeoDataFrame with the sorted list of all the points. I've also added a "origin" column so you can tell which points came from the originalstreet
geometry and which ones came from thepp
GeoDataFrame of external points.Caveat
Note that this approach will only work with
LineString
s. If some streets are coded asMultiLineString
s, you'll have to take care of them differently in theps = ....
statement.