Skip to main content
adding problem and more code
Source Link
Danny
  • 35
  • 5

I found this code for an QGIS Add-on (Merging adjacent lines in QGIS[https://gis.stackexchange.com/questions/228267/merging-adjacent-lines-in-qgis#][3]), but. I can'tcould make itthe first block running (see in Python for gdf's as it already throws me a "TypeError: 'LineString' object is not iterable" when executing the firstvery bottom) but struggle with the second block since I get a bunch of AttributeErrors and don't know how to translate them into pandas.

##Lines=vector line

from qgis.core import *

def find_adjacent(selected_ids): # for finding adjacent features
    outlist = []
    outinds = []
    outset = set()
    for j, l in enumerate(selected_ids):
        as_set = set(l)
        inds = []
        for k in outset.copy():
            if outlist[k] & as_set:
                outset.remove(k)
                as_set |= outlist[k]
                inds.extend(outinds[k])
        outset.add(j)
        outlist.append(as_set)
        outinds.append(inds + [j])
    outinds = [outinds[j] for j in outset]
    del outset, outlist
    result = [[selected_ids[j] for j in k] for k in outinds]
    return result

find_adjacent(gdf.geometry)

 

layer = processing.getObject(Lines)
crs = layer.crs().toWkt()

# Create the output layer
outLayer = QgsVectorLayer('Linestring?crs='+ crs, 'snapped' , 'memory')
prov = outLayer.dataProvider()
fields = layer.pendingFields()
prov.addAttributes(fields)
outLayer.updateFields()

already_processed = []
for feat in layer.getFeatures():
    attrs = feat.attributes()
    geom = feat.geometry()
    curr_id = feat["ID"]
    if curr_id not in already_processed:
        query = '"ID" = %s' % (curr_id)
        selection = layer.getFeatures(QgsFeatureRequest().setFilterExpression(query))
        selected_ids = [k.geometry().asPolyline() for k in selection]
        adjacent_feats = find_adjacent(selected_ids)
        for f in adjacent_feats:
            first = True
            for x in xrange(0, len(f)):
                geom = (QgsGeometry.fromPolyline([QgsPoint(w) for w in f[x]]))
                if first:
                    outFeat = QgsFeature()
                    outFeat.setGeometry(geom)
                    outGeom = outFeat.geometry()
                    first = False
                else:
                    outGeom = outGeom.combine(geom)
            outFeat.setAttributes(attrs)
            outFeat.setGeometry(outGeom)
            prov.addFeatures([outFeat])
        already_processed.append(curr_id)
    else:
        continue

# Add the layer to the Layers panel
QgsMapLayerRegistry.instance().addMapLayer(outLayer)

First block using pandas:

def find_adjacent(line): # for finding adjacent features
    outlist = []
    outinds = []
    outset = set()
    for j, l in line.iteritems():
        as_set = set(line.astype(str))
        inds = []
        for k in outset.copy():
            if outlist[k] & as_set:
                outset.remove(k)
                as_set |= outlist[k]
                inds.extend(outinds[k])
        outset.add(j)
        outlist.append(as_set)
        outinds.append(inds + [j])
    outinds = [outinds[j] for j in outset]
    del outset, outlist
    result = [[line[j] for j in k] for k in outinds]
    return result

lines = find_adjacent(trunk.geometry)

I found this code for an QGIS Add-on (Merging adjacent lines in QGIS), but I can't make it running in Python for gdf's as it already throws me a "TypeError: 'LineString' object is not iterable" when executing the first block.

##Lines=vector line

from qgis.core import *

def find_adjacent(selected_ids): # for finding adjacent features
    outlist = []
    outinds = []
    outset = set()
    for j, l in enumerate(selected_ids):
        as_set = set(l)
        inds = []
        for k in outset.copy():
            if outlist[k] & as_set:
                outset.remove(k)
                as_set |= outlist[k]
                inds.extend(outinds[k])
        outset.add(j)
        outlist.append(as_set)
        outinds.append(inds + [j])
    outinds = [outinds[j] for j in outset]
    del outset, outlist
    result = [[selected_ids[j] for j in k] for k in outinds]
    return result

find_adjacent(gdf.geometry)

layer = processing.getObject(Lines)
crs = layer.crs().toWkt()

# Create the output layer
outLayer = QgsVectorLayer('Linestring?crs='+ crs, 'snapped' , 'memory')
prov = outLayer.dataProvider()
fields = layer.pendingFields()
prov.addAttributes(fields)
outLayer.updateFields()

already_processed = []
for feat in layer.getFeatures():
    attrs = feat.attributes()
    geom = feat.geometry()
    curr_id = feat["ID"]
    if curr_id not in already_processed:
        query = '"ID" = %s' % (curr_id)
        selection = layer.getFeatures(QgsFeatureRequest().setFilterExpression(query))
        selected_ids = [k.geometry().asPolyline() for k in selection]
        adjacent_feats = find_adjacent(selected_ids)
        for f in adjacent_feats:
            first = True
            for x in xrange(0, len(f)):
                geom = (QgsGeometry.fromPolyline([QgsPoint(w) for w in f[x]]))
                if first:
                    outFeat = QgsFeature()
                    outFeat.setGeometry(geom)
                    outGeom = outFeat.geometry()
                    first = False
                else:
                    outGeom = outGeom.combine(geom)
            outFeat.setAttributes(attrs)
            outFeat.setGeometry(outGeom)
            prov.addFeatures([outFeat])
        already_processed.append(curr_id)
    else:
        continue

# Add the layer to the Layers panel
QgsMapLayerRegistry.instance().addMapLayer(outLayer)

I found this code for an QGIS Add-on ([https://gis.stackexchange.com/questions/228267/merging-adjacent-lines-in-qgis#][3]). I could make the first block running (see in the very bottom) but struggle with the second block since I get a bunch of AttributeErrors and don't know how to translate them into pandas.

##Lines=vector line

from qgis.core import *

def find_adjacent(selected_ids): # for finding adjacent features
    outlist = []
    outinds = []
    outset = set()
    for j, l in enumerate(selected_ids):
        as_set = set(l)
        inds = []
        for k in outset.copy():
            if outlist[k] & as_set:
                outset.remove(k)
                as_set |= outlist[k]
                inds.extend(outinds[k])
        outset.add(j)
        outlist.append(as_set)
        outinds.append(inds + [j])
    outinds = [outinds[j] for j in outset]
    del outset, outlist
    result = [[selected_ids[j] for j in k] for k in outinds]
    return result
 

layer = processing.getObject(Lines)
crs = layer.crs().toWkt()

# Create the output layer
outLayer = QgsVectorLayer('Linestring?crs='+ crs, 'snapped' , 'memory')
prov = outLayer.dataProvider()
fields = layer.pendingFields()
prov.addAttributes(fields)
outLayer.updateFields()

already_processed = []
for feat in layer.getFeatures():
    attrs = feat.attributes()
    geom = feat.geometry()
    curr_id = feat["ID"]
    if curr_id not in already_processed:
        query = '"ID" = %s' % (curr_id)
        selection = layer.getFeatures(QgsFeatureRequest().setFilterExpression(query))
        selected_ids = [k.geometry().asPolyline() for k in selection]
        adjacent_feats = find_adjacent(selected_ids)
        for f in adjacent_feats:
            first = True
            for x in xrange(0, len(f)):
                geom = (QgsGeometry.fromPolyline([QgsPoint(w) for w in f[x]]))
                if first:
                    outFeat = QgsFeature()
                    outFeat.setGeometry(geom)
                    outGeom = outFeat.geometry()
                    first = False
                else:
                    outGeom = outGeom.combine(geom)
            outFeat.setAttributes(attrs)
            outFeat.setGeometry(outGeom)
            prov.addFeatures([outFeat])
        already_processed.append(curr_id)
    else:
        continue

# Add the layer to the Layers panel
QgsMapLayerRegistry.instance().addMapLayer(outLayer)

First block using pandas:

def find_adjacent(line): # for finding adjacent features
    outlist = []
    outinds = []
    outset = set()
    for j, l in line.iteritems():
        as_set = set(line.astype(str))
        inds = []
        for k in outset.copy():
            if outlist[k] & as_set:
                outset.remove(k)
                as_set |= outlist[k]
                inds.extend(outinds[k])
        outset.add(j)
        outlist.append(as_set)
        outinds.append(inds + [j])
    outinds = [outinds[j] for j in outset]
    del outset, outlist
    result = [[line[j] for j in k] for k in outinds]
    return result

lines = find_adjacent(trunk.geometry)
added link and code from similar question
Source Link
Danny
  • 35
  • 5

I found this code for an QGIS Add-on (Merging adjacent lines in QGIS), but I can't make it running in Python for gdf's as it already throws me a "TypeError: 'LineString' object is not iterable" when executing the first block.

##Lines=vector line

from qgis.core import *

def find_adjacent(selected_ids): # for finding adjacent features
    outlist = []
    outinds = []
    outset = set()
    for j, l in enumerate(selected_ids):
        as_set = set(l)
        inds = []
        for k in outset.copy():
            if outlist[k] & as_set:
                outset.remove(k)
                as_set |= outlist[k]
                inds.extend(outinds[k])
        outset.add(j)
        outlist.append(as_set)
        outinds.append(inds + [j])
    outinds = [outinds[j] for j in outset]
    del outset, outlist
    result = [[selected_ids[j] for j in k] for k in outinds]
    return result

find_adjacent(gdf.geometry)

layer = processing.getObject(Lines)
crs = layer.crs().toWkt()

# Create the output layer
outLayer = QgsVectorLayer('Linestring?crs='+ crs, 'snapped' , 'memory')
prov = outLayer.dataProvider()
fields = layer.pendingFields()
prov.addAttributes(fields)
outLayer.updateFields()

already_processed = []
for feat in layer.getFeatures():
    attrs = feat.attributes()
    geom = feat.geometry()
    curr_id = feat["ID"]
    if curr_id not in already_processed:
        query = '"ID" = %s' % (curr_id)
        selection = layer.getFeatures(QgsFeatureRequest().setFilterExpression(query))
        selected_ids = [k.geometry().asPolyline() for k in selection]
        adjacent_feats = find_adjacent(selected_ids)
        for f in adjacent_feats:
            first = True
            for x in xrange(0, len(f)):
                geom = (QgsGeometry.fromPolyline([QgsPoint(w) for w in f[x]]))
                if first:
                    outFeat = QgsFeature()
                    outFeat.setGeometry(geom)
                    outGeom = outFeat.geometry()
                    first = False
                else:
                    outGeom = outGeom.combine(geom)
            outFeat.setAttributes(attrs)
            outFeat.setGeometry(outGeom)
            prov.addFeatures([outFeat])
        already_processed.append(curr_id)
    else:
        continue

# Add the layer to the Layers panel
QgsMapLayerRegistry.instance().addMapLayer(outLayer)

I found this code for an QGIS Add-on (Merging adjacent lines in QGIS), but I can't make it running in Python for gdf's as it already throws me a "TypeError: 'LineString' object is not iterable" when executing the first block.

##Lines=vector line

from qgis.core import *

def find_adjacent(selected_ids): # for finding adjacent features
    outlist = []
    outinds = []
    outset = set()
    for j, l in enumerate(selected_ids):
        as_set = set(l)
        inds = []
        for k in outset.copy():
            if outlist[k] & as_set:
                outset.remove(k)
                as_set |= outlist[k]
                inds.extend(outinds[k])
        outset.add(j)
        outlist.append(as_set)
        outinds.append(inds + [j])
    outinds = [outinds[j] for j in outset]
    del outset, outlist
    result = [[selected_ids[j] for j in k] for k in outinds]
    return result

find_adjacent(gdf.geometry)

layer = processing.getObject(Lines)
crs = layer.crs().toWkt()

# Create the output layer
outLayer = QgsVectorLayer('Linestring?crs='+ crs, 'snapped' , 'memory')
prov = outLayer.dataProvider()
fields = layer.pendingFields()
prov.addAttributes(fields)
outLayer.updateFields()

already_processed = []
for feat in layer.getFeatures():
    attrs = feat.attributes()
    geom = feat.geometry()
    curr_id = feat["ID"]
    if curr_id not in already_processed:
        query = '"ID" = %s' % (curr_id)
        selection = layer.getFeatures(QgsFeatureRequest().setFilterExpression(query))
        selected_ids = [k.geometry().asPolyline() for k in selection]
        adjacent_feats = find_adjacent(selected_ids)
        for f in adjacent_feats:
            first = True
            for x in xrange(0, len(f)):
                geom = (QgsGeometry.fromPolyline([QgsPoint(w) for w in f[x]]))
                if first:
                    outFeat = QgsFeature()
                    outFeat.setGeometry(geom)
                    outGeom = outFeat.geometry()
                    first = False
                else:
                    outGeom = outGeom.combine(geom)
            outFeat.setAttributes(attrs)
            outFeat.setGeometry(outGeom)
            prov.addFeatures([outFeat])
        already_processed.append(curr_id)
    else:
        continue

# Add the layer to the Layers panel
QgsMapLayerRegistry.instance().addMapLayer(outLayer)
Post Closed as "Not suitable for this site" by ahmadhanb, Vince, Kadir Şahbaz, TomazicM, Cyril Mikhalchenko
edited tags; edited title
Link
Danny
  • 35
  • 5

How to split up Linestrings based on type and connectivity using Python?

Improved English
Source Link
Hornbydd
  • 44.6k
  • 5
  • 42
  • 84
Loading
Source Link
Danny
  • 35
  • 5
Loading