3

I have a points layer in QGIS defined by a csv file in the following format:

group,name,lat,long
1,A,…,…
1,B,…,…
1,C,…,…
2,A,…,…
2,D,…,…
3,E,…,…
3,F,…,…

(lat and long are coordinates in WGS84)

How can I draw all of the possible lines between all of the points that are in the same group? So the above data would yield a triangle with vertices at A, B and C, a line with end points A and D, and another line with end points E and F.

I have tried a number of solutions suggested on these boards (PointsToPaths plugin, Points2One plugin, Connect Points plugin, GRASS v.to.lines, SAGA Convert lines to points) but all of these only draw the minimum number of lines to connect the points. This works fine when only two points need to be connected, but fails when there are more than two points. In the example above, group 1 comes out as a line from A to B to C, without the direct line from A to C. Sometimes there are up to eight points in the group, which should yield 28 lines.

4
  • You don't mention flow mapper, have you come across that plugin? gis.stackexchange.com/questions/141078/… see also qgis.nl/2014/10/27/stromen-weergeven-met-flowmapper/?lang=en Commented Aug 8, 2018 at 8:43
  • If you can do an SQL "join" of the table (a) onto itself (b), that gives you a row for every pair of points, with the group number from each. Then an SQL "select" of where group.a equals group.b gets you all the rows that represent lines in the same group. Construct a line from geom.a to geom.b. No time to go further than this outline but maybe someone else can flesh it out. Alternatively, you'll have to write a python script.
    – Spacedman
    Commented Aug 8, 2018 at 8:52
  • To start, in order to create a triangle for you in your table in group 1, you need to add one more point :-) ... Commented Aug 8, 2018 at 11:12
  • related: gis.stackexchange.com/questions/242524/…
    – JGH
    Commented Aug 8, 2018 at 12:39

1 Answer 1

1

I have achieved this by modifying the code linked to by JGH.

    from PyQt4.QtCore import QVariant

#Purpose: using the selected point layer, create a new scratch layer
#         containing a line between each pair of points in a group defined by an attribute in original point layer

#***********Constants
#
LINEID = 'ObvID'
POINTID = 'Mint'
#
#***********

srclayer = iface.activeLayer()
crs = srclayer.crs().toWkt()

# Create the output layer
outLayer = QgsVectorLayer('Linestring?crs='+ crs, 'connector_lines' , 'memory')
outdp = outLayer.dataProvider()

#add the ID field to new layer
outdp.addAttributes([QgsField(LINEID, QVariant.Int)])
outLayer.updateFields()

#get the field index
srcLineIDfldidx = srclayer.dataProvider().fieldNameIndex(LINEID)
srcPtIDfldidx = srclayer.dataProvider().fieldNameIndex(POINTID)
outLineIDfldidx = outdp.fieldNameIndex(LINEID)

#loop through the points (1st point)
for feat1 in srclayer.getFeatures():
    geom1 = feat1.geometry()

    #statement for selecting the points in same group
    exp = QgsExpression(LINEID + ' = ' + str(feat1.attributes()[srcLineIDfldidx]))
    request = QgsFeatureRequest(exp)
    #Select only the points having the specified value
    feat2lst=srclayer.getFeatures(request)

    #loop through the points in same group
    for feat2 in feat2lst:
        geom2 = feat2.geometry()

        #create the line
        connector = QgsFeature(outLayer.pendingFields())
        connector.setGeometry(QgsGeometry.fromPolyline([geom1.asPoint(),
                                                        geom2.asPoint()]))

        #record the line ID
        res = connector.setAttribute(outLineIDfldidx, feat1.attributes()[srcLineIDfldidx])

        #add the feature to the layer
        res = outdp.addFeatures([connector])


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

print "Done .. "

This creates a directed network (where A-B is considered different from B-A), and includes self-loops (A-A). To remove these, use Vector -> Geoprocessing Tools -> Dissolve, using the field 'group'. This leaves one feature in the new layer for each group in the original layer, connecting all points to each other.

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.