1

What I have:

A shapefile with multiple lines.

Example:

line 1: A -> B -> C with attributeX=5

line 2: A -> B -> D with attributeX=7

What I want

Lines between each nodes with added attributes.

Example:

A -> B with attributeX=12

B -> C with attributeX=5

B -> D with attributeX=7

(QGIS 2.0)

  • Can you draw a picture, what you have and what you want, I'm not understanding what you're trying to do. – Michael Stimson Jun 19 '15 at 23:47
1

NetworkX (http://cheeseshop.python.org/pypi/networkx/) is a Python package with many functions for graph and network analysis. In the suggested solution I use the MultiGraph object provided by the networkx module to model parallel edges between nodes.

Check, that your line layer is the active layer. Paste the following code into Python console:

from PyQt4.QtCore import QVariant
import networkx as nx

# get active layer
aLayer = qgis.utils.iface.activeLayer()

# create an empty MultiGraph object, then add all segments of all polylines in aLayer as edges to the graph
# with attribute attributeX as edge attribute
topol = nx.MultiGraph()
topol.add_edges_from([((line.geometry().asPolyline()[i][0], line.geometry().asPolyline()[i][1]),
                       (line.geometry().asPolyline()[i+1][0], line.geometry().asPolyline()[i+1][1]),
                       {'attributeX': line.attribute('attributeX')})
                      for line in aLayer.getFeatures()
                      for i in range(len(line.geometry().asPolyline())-1)])

# find multiple edges, and sum their attributeX values
# append them to a dict
segments = {}
for edge in topol.edges_iter(data=True):
    if (edge[0], edge[1]) in segments:
        segments[(edge[0], edge[1])] += edge[2]['attributeX']
    else:
        segments[(edge[0], edge[1])] = edge[2]['attributeX']

# define QGIS layer with some attributes
layer = QgsVectorLayer('LineString?crs=EPSG:4326', 'Result', 'memory')
prov = layer.dataProvider()
prov.addAttributes([QgsField("attributeX", QVariant.Double)])
QgsMapLayerRegistry.instance().addMapLayer(layer)

# create features
feats = []
layer.startEditing()

for segment in segments:
    feat = QgsFeature()
    feat.setGeometry(QgsGeometry.fromPolyline([QgsPoint(segment[0][0], segment[0][1]), QgsPoint(segment[1][0], segment[1][1])]))
    feat.setAttributes([segments[segment]])
    feats.append(feat)

# finally add all created features and save edits
prov.addFeatures(feats)
layer.updateExtents()
layer.commitChanges()

As result you get line segments between each nodes, with the sum of attributeX as values for attributeX.

Before Before

After After

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.