I have a large dataset consisting of lines/polylines where I would like to join/merge the lines that touch / intersect. Each line has an individual ID and there are no common attributes I can use for a join operation. Is there a way to (spatially) join lines into segments of touching lines?
Screenshot of a selected line in a line segment (current situation):
It can be done in ArcGIS according to this post (link) among others.
FYI, the dataset is an extract from a pipeline network and I will examine which line segments that cross the most properties / parcels of land.
I'm using QGIS 2.14.0. I have no experience with python or GRASS yet.
Answer
In QGIS Plugins you'll find a 'merge lines' plugin, which at first sight seems to accomplish what you are after.
cited from description:
MergeLines
Simplifies the topology of a line network by merging adjacent lines
This plugin merges segments of a line network (e.g. river network) in order to simplify its topology. Two merging methods are currently available : length (a segment is merged with its longest neighbor) and alignment (a segment is merged with its best aligned neighbor).
UPDATE:
Below you find a geoprocessing script of which I hope that it does what you want. For testing purposes I created a shapefile with a bunch of irregularly intersecting lines and no attributes (network):
The standard dialog when executing the script looks like this (in this case the result is a memory layer):
Running the script produces a 'copy' of the input data with a field 'subnet' distinguishing to which subnet a feature belongs. With a categorized style the result looks like this:
This can be dissolved using the field 'subnet'.
Create a new geoprocessing script, copy the code in the editor, save it and things should work.
##Networking=group
##lIn=vector
##lOut=output vector
from qgis.core import *
from qgis.utils import *
from qgis.gui import *
from PyQt4.QtCore import *
from PyQt4.QtGui import QColor
#from processing.core.VectorWriter import VectorWriter
c=iface.mapCanvas()
rubberBand = []
v = processing.getObject(lIn)
#generate a list of all features in the layer
subNets = []
flist = []
for f in v.getFeatures():
flist.append(f)
def makeSubnets(featureList):
#print "making subnet ---------------------------------------------------"
if len(featureList) > 1:
print [featureList[0]]
print featureList[1:]
#print "start finding a subnet"
fTest, fRest = findSubnet([featureList[0]], featureList[1:])
#print "finished finding a subnet"
subNets.append(fTest)
makeSubnets(fRest)
else:
subNets.append(featureList)
def findSubnet(featTest, featRest):
found = True
while found:
newTestList = []
#print "candidates: ", len(featTest)
#print "search in: ", len(featRest)
#print "-------------"
for fT in featTest:
for fR in featRest:
if not fT.geometry().disjoint(fR.geometry()):
#print "!"
newTestList.append(fR)
#addRubberBand(fR.geometry())
featTest += newTestList
if newTestList == []:
found = False
else:
#print "Found (undis)joining segments"
for fn in newTestList:
if fn in featRest:
featRest.remove(fn)
#print "removed ", fn
else:
pass
#print "allready removed ", fn
return featTest, featRest
def addRubberBand(theGeom):
rubberBand.append(QgsRubberBand(c, False))
rubberBand[-1].setToGeometry(theGeom, None)
rubberBand[-1].setColor(QColor(255,0,0))
rubberBand[-1].setWidth(3)
makeSubnets(flist)
fields = QgsFields()
fields.append(QgsField('subnet', QVariant.Int))
writer = QgsVectorFileWriter(lOut, None, fields, QGis.WKBLineString, v.crs())
net = 0
for sn in subNets:
for f in sn:
#print net, f
feat = QgsFeature()
feat.setFields(fields)
feat.setGeometry(f.geometry())
feat.setAttribute('subnet', net)
writer.addFeature(feat)
net += 1
del writer
UPDATE #2:
To create a geoprocessing script do the following (I've got the german gui, so I try to translate in en):
A: Menu 'Processing' -> 'Toolbox' (appears as a dock on the right)
B: Under 'Scripts [...]' -> 'Tools' doubleclick 'create new script'
An Editor with a little toolbar appears, in wich you copy the code above. Herein you can:
C: Save the script. It appears (in this case) in the group 'Networking' or in whatever group you write in the first line of the script ##MyGroup=group
. Be aware not to write blanks in the ##
-lines!!!
D: Start the script with the two little gears. A gui appears (cp. above) with the in- and output layers defined in the script line 2 and 3. When saved, alteratively start the script by doubleclicking its name under 'scripts' > 'mygroup' > 'myscriptname' (if saved under myscriptname.py
)
No comments:
Post a Comment