2

I have a geopandas DataFrame (created from a shapefile) which represents the course of a public transport vessel.

Exemplary DataFrame:

| oid | geometry | |-----|---------------------| | 1 | LineString(1 1, 1 2)| | 2 | LineString(2 3, 3 4)| | 3 | LineString(1 2, 2 3)| | 4 | LineString(3 4, 5 6)|

The DataFrame contains segments of LineStrings in no given order of the object id oid. How can I sort the LineString segments by location to have the joined course segment by segment in geographic order (from example data I want to get the order 1 -> 3 -> 2 -> 4)?

I other words, I want to find the touchpoints row-wise.

Background: I have another DataFrame where I have a measured variable given only by the distance from the starting point of the course (of course along this course) and no GIS information.

1 Answer 1

2

You can create a multiline, merge it and split into lines again:

from shapely import geometry, ops
import geopandas as gpd

line1 = geometry.LineString([(1, 1), (1, 2)])
line2 = geometry.LineString([(2, 3), (3, 4)])
line3 = geometry.LineString([(1, 2), (2, 3)])
line4 = geometry.LineString([(3, 4), (5, 6), (8,9)])

df = gpd.GeoDataFrame(geometry=[line1,line2,line3,line4])

multitline = geometry.MultiLineString(df.geometry.tolist())
merged = ops.linemerge(multitline)

startstop = []
for line in multitline:
    coords = [c for c in line.coords]
    startstop.append((coords[0],coords[:-1]))

collection = ops.split(merged, geometry.MultiPoint(startstop))

df2 = gpd.GeoDataFrame(geometry=[line for line in Collection])

Results:

df
                     geometry
0       LINESTRING (1 1, 1 2)
1       LINESTRING (2 3, 3 4)
2       LINESTRING (1 2, 2 3)
3  LINESTRING (3 4, 5 6, 8 9)
df2
                     geometry
0       LINESTRING (1 1, 1 2)
1       LINESTRING (1 2, 2 3)
2       LINESTRING (2 3, 3 4)
3  LINESTRING (3 4, 5 6, 8 9)
11
  • 1
    Thanks!! Can I split the union into evenly distances, say 100m? Aug 24, 2018 at 11:39
  • With my data I get the error ` NotImplementedError: Multi-part geometries do not provide a coordinate sequence`, have to figure out how your sample data is different Aug 24, 2018 at 11:44
  • That error means that one of your lines is a MultiLineString, so you will have to go line by line, check if there is a MultiLineString, and then by segments in feature['geometry']['coordinates'] convert it to LineStrings
    – ImanolUr
    Aug 24, 2018 at 11:48
  • type() of element in 1st row says shapely.geometry.linestring.LineString. But I'll have to check all lines.. Aug 24, 2018 at 11:52
  • 1
    I see! I flattened the MultiLineString manually multicoords = [list(line.coords) for line in multiline] and simplecoords = shapely.geometry.MultiPoint([item for sublist in multicoords for item in sublist]) and the MultiPoint does the trick! NICE!! Aug 24, 2018 at 12:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.