7

Basically, I have the layers above:

enter image description here

As shown in the image, I'm trying to join the layer lines with the layer points two times in a row so the labels of origin_id and extremity_id appear in the attribute table of the layer lines.

I tried with Joins in QGIS but unfortunately, I can only join the layer points once.

Is there a solution, please?

Here is an example:

enter image description here

And here is the expected output:

enter image description here

Taras
  • 32,823
  • 4
  • 66
  • 137
Timeless.
  • 644
  • 4
  • 13
  • 2
    Why would you want to join twice? Does not seem to make sense to me. What is your final goal you want to achieve? Joining once, you can add all attributes from one layer to the other, no neet to repete this for each attribute separately. – Babel Jan 01 '23 at 13:51
  • In the layer Lines there is only ids of origin and extremity. I need to get their labels from another layer that is Points. That's why I need to join twice.. – Timeless. Jan 01 '23 at 13:54
  • can you provide sample data? – Babel Jan 01 '23 at 13:54
  • Of course, I'll do that. One sec please! – Timeless. Jan 01 '23 at 13:54
  • Not clear what you join: you write about layers lines and points, but your screenshot shows a layer cables.. is this the same with the lines layer? – Babel Jan 01 '23 at 13:55
  • 1
    Duplicating the layer points is no option? – Babel Jan 01 '23 at 13:57
  • 1
    I think there is a design mistake if you think you have to join a table twice, maybe you want to rethink your problem. It's only a guess for the moment... – swiss_knight Jan 01 '23 at 13:57
  • 1
    I added an example to my question. I think that @Babel's solution (duplicating Points) will allow me to make appear two fields origin_label and extrem_label in the layer Lines. – Timeless. Jan 01 '23 at 14:03
  • I added the expected output as well. The goal is make a new field that concatenate the two labels. It's a very basic problem but looks like I failed to describe it very well. By the way, duplicating the layer Points worked for me. – Timeless. Jan 01 '23 at 14:12

3 Answers3

8

What you want to do is not joining layers, but creating two new attributes. You can achieve this with field calculator using this expression on the lines layer:

attribute (
    get_feature(
        'Points',  -- name of the points layer
        'id',  -- name of the attribute on the points layer
        extreme_id -- name of the attribute on the lines layer
    ),
    'label' -- name of the attribute on the points layer
)

enter image description here

Babel
  • 71,072
  • 14
  • 78
  • 208
3

Beside duplicating the point layer or fetching the desired attributes in the Field Calculator, you can also achieve this goal using a "Virtual layer"

Using this approach, you can also compute your new field.

Go to the menu Layer > Add Layer > Add/Edit Virtual Layer... and enter the following query. Adjust the layer and field names.

Remember that virtual layers are computed in memory, so feel free to export it to another format if needed.

SELECT l.*, 
      pt1.label as label_origin, pt2.label as label_extreme, 
      pt1.label || ' To ' || pt2.label
FROM myLineLayer l
JOIN myPointLayer pt1
 ON l.origin_id = pt1.id
JOIN myPointLayer pt2
 ON l.extreme_id = pt2.id;
Taras
  • 32,823
  • 4
  • 66
  • 137
JGH
  • 41,794
  • 3
  • 43
  • 89
2

Another solution is based on PyQGIS. It utilizes the QgsVectorLayerJoinInfo() class for joining purposes.

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

# imports
from qgis.core import QgsProject, QgsVectorLayerJoinInfo

original layer

layer = QgsProject.instance().mapLayersByName("union")[0] field = 'id'

target layer to join

target_layer = QgsProject.instance().mapLayersByName("points")[0] target_layer_id = target_layer.id()

params for the first join

target_field1 = 'from' prefix1 = 'from_'

params for the second join

target_field2 = 'to' prefix2 = 'to_'

First object to join

joinObject1 = QgsVectorLayerJoinInfo() joinObject1.setJoinFieldName(field) joinObject1.setTargetFieldName(target_field1) joinObject1.setJoinLayerId(target_layer_id) joinObject1.setJoinFieldNamesSubset(["date"]) joinObject1.setPrefix(prefix1) joinObject1.setUsingMemoryCache(True) joinObject1.setJoinLayer(target_layer) layer.addJoin(joinObject1)

Second object to join

joinObject2 = QgsVectorLayerJoinInfo() joinObject2.setJoinFieldName(field) joinObject2.setTargetFieldName(target_field2) joinObject2.setJoinLayerId(target_layer_id) joinObject2.setJoinFieldNamesSubset(["date"]) joinObject2.setPrefix(prefix2) joinObject2.setUsingMemoryCache(True) joinObject2.setJoinLayer(target_layer) layer.addJoin(joinObject2)

Input:

input

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

output


References:

Taras
  • 32,823
  • 4
  • 66
  • 137