I'm trying to get data from a polyline layer into a grid (I've created this with regular points, points to polylines). I guess at first I have to cut all polyline segments at the grid lines and then I have to spatially join (which only works for the first feature found) all of them into each grid cell. I want to find out road network length differences in different areas.
[GIS] Sum line lengths for each grid cell in QGIS
grids-graticulesqgisspatial-joinvector-grid
Related Solutions
To me, the simplest approach is to probably convert your XY datapoints to the polar coordinate system that defines your circular 'arena'.
Be sure to convert your XY coordinates such that the center of your circle is the origin of your Cartesian grid before converting to polar coordinates. Almost all math texts would provide these straightforward conversion equations, but this Wikipedia entry would definitely suffice.
Each of your equal area sectors are bounded by specific values for R and theta in the polar coordinate system.
Once you convert your Cartesian coordinates, simply round the calculated polar coordinates for each of your points to the nearest R and theta values that define your arena sectors.
This solution may be 'inelegant', but it strikes me as being about as straightforward as you could get.
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
)
Best Answer
Create a polygon grid using the
Vector Grid
tool instead of lines. Make sure to check the polygon output.Once you have a polygon grid (also known as fishnet), you can use the
Sum line length
tool in the QGIS Vector analysis tools. This will result in a new field for each cell with the total road length inside itHere's a simple example of a vector polygon grid with overlayed line layer.
And after the sum lines in polygons tool, with symbology based on the summed length field.