3

I have two point datasets; Person (in red) and Connections (in blue). They have matching columns Person_UID. I'm trying to connect the red points to all the blue points that have matching Person_UIDs. So far I am only able to make one connection for each UID in'Connections' the point that was first digitized.

Code: make_line( $geometry, geometry(get_feature('Connections', 'Person_UID', "Person_UID")) )

I'm using QGIS 3.12.0

Screen grab attached.

enter image description here

0

2 Answers 2

4

Your expression is correct but you are using the wrong layer.

To create a group of lines that connects all the Person points with the Connections points you need to change the order of the layers.

Instead using Person Layer, create a line with Geometry generator in the Connections layer with the expression

make_line( $geometry, geometry(get_feature('Person', 'Person_UID', "Person_UID")) )

It will create the line that you want.

enter image description here

2

Just wanted to add another answer in case anyone has a similar situation but wants to use the Person layer for some reason or wants a many-to-many join.

You need to use aggregate() - which returns multiple matches from one point returned as a multigeometry (one to many join), instead of get_feature() which will only ever return one feature each time (one to one or many to one join).

However, the expression that I got to work was a lot more complex than I thought. You can't use make_line() to join a single point (from the Persons layer) to multipoints (matching points in Connections layer). So you have to convert the Connections multipoints to an array of single points and then make a line from each Person point to it. I did this using generate_series() to create an array of number of points and looped through the multipoints using that and array_foreach().

collect_geometries(array_foreach( generate_series(1,num_geometries( aggregate('connections','collect',$geometry, "Person_UID"=attribute(@parent,'Person_UID')))), make_line($geometry,geometry_n( aggregate('connections','collect',$geometry, "Person_UID"=attribute(@parent,'Person_UID')) ,@element))))

enter image description here

The bonus is that this works for many-to-many joins as well, where get_feature() won't work no matter which layer you use it on.

enter image description here

EDIT: The above works if your Persons layer is a Point geometry (not Multipoint). Your Connections layer can be a Point or Multipoint geometry.

If your Persons layer is a Multipoint geometry then make_line() using $geometry won't work - you need to convert your Persons layer to single point either by creating a new layer, or using this even lengthier expression to loop through the multipoint geometries in each Person feature.

Would be nice to have a "promote to single parts" expression in the QGIS expression builder...

collect_geometries(array_foreach(generate_series(1,num_geometries(aggregate('connections','collect',$geometry,"Person_UID"=attribute(@parent,'Person_UID')))),make_line(array_foreach(generate_series(1,num_geometries($geometry)),geometry_n($geometry,@element)),geometry_n(aggregate('connections','collect',$geometry,"Person_UID"=attribute(@parent,'Person_UID')),@element))))

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.