4

I have a line layer that seemingly consists of a single feature. I then ran QGIS's Multipart to Singleparts algorithm (same result as Extract Nodes), so then the result consists of 27 line features:

enter image description here

The problem is that the line is not ordered, so when I'm trying to calculate distance along this path (whether the line layer is dissolved or not), the results end up wrong.

My current workaround is to buffer the layer (with dissolve all option) then running v.voronoi.skeleton. This works ('resetting' the line completely into one feature), but for some line inputs produces no result. Can anyone come up with a solution to re-order line segments in QGIS?

Using QGIS 2.18, open to a PyQGIS solution! I must run this solution on hundreds of layers, so preferably no plugins.

2
  • What are you really trying to do? Commented Jan 23, 2018 at 11:49
  • I am trying to calculate the distance of each point in an intersecting point layer from the edge of the line (any edge), along the line. This is achieved using this user script: pythonfiddle.com/distance-along-line
    – 15Step
    Commented Jan 23, 2018 at 12:15

2 Answers 2

2

Try running the "merge lines" algorithm on your original multipart layer. This should turn multipart lines which consist of more than one joined part into a single linestring, as desired. Unfortunately, this will only work if the ends of your line parts exactly coincide.

An alternative approach which would work if they don't coincide is available for qgis 3.0 only: - split the layer using "multiparts to single parts" - snap the ends of the lines to each other using the "snap geometries" algorithm (snapping the single part layer back to itself), with an appropriate distance tolerance. - dissolve the snapped layer to get the single parts back into multiparts - run line merge on the snapped, dissolved layer

You could wrap this up in a model and then use the batch processor (or a python script) to run it over all your layers.

1
  • Since all of my line segments edge coincide, 'Merge Lines' worked great to calculate distance along lines with python. I feel silly about buffer->dissolve-->v.voronoi.skeleton now :)
    – 15Step
    Commented Jan 24, 2018 at 10:26
1

As you said open to a PyQGIS solution, I digitized a clone for your not ordered line layer; as it can be observed at following image:

enter image description here

and I used following PyQGIS code for ordering its features (where it's necessary to select manually first feature with selecting tool to facilitate processing):

layer = iface.activeLayer()

selected_feature = layer.selectedFeatures()

feats = [ feat for feat in layer.getFeatures() ]

new_feats = []

new_feats.append(selected_feature[0])

del feats[selected_feature[0].id()]

n = len(feats)

for k in range(n):
    for i, feat in enumerate(feats):
        dist = feat.geometry().distance(new_feats[-1].geometry())
        if dist == 0:
            new_feats.append(feats[i])
            del feats[i]
            break

epsg = layer.crs().postgisSrid()

uri = "LineString?crs=epsg:" + str(epsg) + "&field=id:integer""&index=yes"

mem_layer = QgsVectorLayer(uri,
                           'line',
                           'memory')

prov = mem_layer.dataProvider()

for i, feat in enumerate(new_feats):
    feat.setAttributes([i])

prov.addFeatures(new_feats)

QgsMapLayerRegistry.instance().addMapLayer(mem_layer)

After selecting first feature (id = 3):

enter image description here

above code was running and it was obtained a memory line layer with its features completely ordered as expected. This can be corroborated at following image:

enter image description here

1
  • This works too, with the only downfall having to select a feature prior to running the analysis (unlike the Merge Lines algorithm)
    – 15Step
    Commented Jan 24, 2018 at 10:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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