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

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)
  • 1
    Thanks!! Can I split the union into evenly distances, say 100m? – Andi Anderle Aug 24 '18 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 – Andi Anderle Aug 24 '18 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 '18 at 11:48
  • type() of element in 1st row says shapely.geometry.linestring.LineString. But I'll have to check all lines.. – Andi Anderle Aug 24 '18 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!! – Andi Anderle Aug 24 '18 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.