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?

Taras
  • 32,823
  • 4
  • 66
  • 137
Encomium
  • 3,133
  • 2
  • 14
  • 41
  • This sounds like a spider diagram. You might start by looking at http://gis.stackexchange.com/questions/2823/ and its Related questions on the right side of the page. – Chris W Nov 09 '15 at 17:58

1 Answers1

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:

Taras
  • 32,823
  • 4
  • 66
  • 137