2

I have a polygon layer where every polygon has a unique "ID", and another polygon layer where those unique "ID"s can be found in a column in a one-to-many relation.

I would like to have QGIS draw lines from the polygons in the first layer to the polygons in the second layer in a way that reflects the one to many relation.

Any advice on tools?

1
1

Let's assume there are two polygon layer "poly_unique"(orange) and "poly_groups"(green), with its corresponding attribute tables accordingly, see image below.

input

Proceed with Plugins > Python Console > Show Editor and paste the script below

# function that converts a string into a list
def to_list(var):
    output = var.split(",") if isinstance(var,str) else ['']
    return output

# function that converts an integer into a string
def to_string(var):
    output = str(var) if isinstance(var,int) else ''
    return output

# accessing two layers with polygon features by their names
poly_from = QgsProject.instance().mapLayersByName("poly_unique")[0]
poly_to = QgsProject.instance().mapLayersByName("poly_groups")[0]

# defining attributes that establish relations between two layers
attr_unique = 'id' # attribute with unique ID, exists in both polygon layers
attr_group = 'Connect' # attribute that shows the one-to-many relations

# creating a virtual output layer with line strings
line_layer = QgsVectorLayer("LineString?crs={}&index=yes".format(poly_from.crs().authid()), "Spider", "memory")

# adding fields for the virtual output layer
provider = line_layer.dataProvider()
provider.addAttributes([QgsField("from", QVariant.String), QgsField("to", QVariant.String)])
line_layer.updateFields()

# looping over each feature from two layers and making all possible connections between them
for f1 in poly_from.getFeatures(): # looping over original polygons
    for f2 in poly_to.getFeatures(): # looping over destination polygons
        if to_string(f1[attr_unique]) in to_list(f2[attr_group]): # condition checks if unique id is in a column with relations
            connect = [f1.geometry().centroid().asPoint(), f2.geometry().centroid().asPoint()] # connection between two points
            line = QgsGeometry.fromPolylineXY(connect) # creating a line string from connection
            f = QgsFeature() # creating Qgs feature
            f.setGeometry(line) # setting new geometry as a line string
            f.setAttributes([f1[attr_unique], f2[attr_unique]]) # setting new attributes as from and to
            provider.addFeature(f) # adding Qgis feature to the output layer

# adding the virtual output layer to the map
QgsProject.instance().addMapLayer(line_layer)

Press Run script run script and get the output that will look like

result


References:

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.