3

I have just started using QGIS (2.12.3) and I need your help.

Overall, I have two polyline shapefiles with the same geometry (the one layer overlaps the other), but the information is stored in a different way. Furthermore, each layer has different attributes. My purpose is to copy specific data from the one layer to other one.

In particular, let's say that I have a layer called F and a layer called M. The layer F is consisted of sets of many lines, whereas the layer M is consisted of sets of a few lines. See what happens when I select the line1 on layer M and what happens when I select the same line on layer F (Image 1).Image 1

This occurs because, the corresponding line1 of layer M in layer F, is part of many polylines (Image 2). Therefore, for one entity in layer M, I have many entities in layer F.

The lines in layer F have a field (integer) and my target is to copy each time (e.g. overlapped lines for line1) only the row that contains the minimum value of this field, into the corresponding line in layer M. Image2

For example, if the field of interest in layer F for the line 1 has values 1987 (a), 1802 (b), 167 (c), 2989(d), I would like to join to the line1 of layer M the row of layer F that contains the number 167.

I have tried the spatial join, but this tool takes "the attributes of the first located feature". If there was any possibility to take "the attributes of the min value of a specific field" then it would be the solution, I think. Also, I cannot remove the redundant values because with this way I will lose the correct information for other lines.

Any ideas??

6
  • Hi! Welcome to GIS.Se. Is there a specific reason you want to continue having multipart geometries in Layer F? You couldn't just make Layer F go multi-part to single?
    – raphael
    Commented Mar 3, 2016 at 17:00
  • As raphael suggests explode multi-part features of layer F to single part. But then it may be possible, that the single part lines do not have the same geometry as lines in layer M. This reminds me to this problem gis.stackexchange.com/questions/167648. To test the approach you need to adapt the layer configuration and attributes_dict. Search for line segments[key][the_attrib] = ... and replace it with segments[key][the_attrib] = min(segments[key][the_attrib], line.attribute(the_attrib)). If you find this a solution worth to consider, I will elaborate and post as an answer.
    – Detlev
    Commented Mar 3, 2016 at 17:59
  • Thank you for your quick responses! I would like to clarify that polylines of layerF illustrated with red on the first image are not 1 record. They exist as four different records according to what you see in the second image. The purpose of these images was to explain that for one line I have many records. In particular: for the line 1 in layerM (1record), I have one record from the polyline a, one from b, one from c and one from d in layerF. Therefore, multi to single-part is not needed.
    – cine_mary
    Commented Mar 4, 2016 at 15:46
  • @Detlev I have tried the method you mentioned. I changed the layers, the attributes_dict, the reference system and replaced the line with the min. Master layer, which is layerM in my case, has 11 fields and layer F,8. In the “result” layer there are only 3 fields: FID, length and the field that I wrote last in the attributes_dict, although it’s empty. The only advantage is that in the result I have as many entities as in the master layer. If that was working as I would like to,in which part of the code I have to specify the field that I want its min value from each set of overlapping lines?
    – cine_mary
    Commented Mar 4, 2016 at 15:46
  • @cine_mary I have uploaded the most recent code to github. I did many fixes, user feedback, and performance issues when processing huge datasets. Please have a look at gist.github.com/detlevn/d663261499c5b05a9a51 . Unfortunately it is missing a GUI yet. You have to change lines 69, 70 (layers), 79 (fields), and 84 (the field to compare with), and optionally 448 (EPSG). Since from layer1 (the network) only geometry and feature id is used, you can join layer1 with the result on field fid to get the full set of attributes.
    – Detlev
    Commented Mar 5, 2016 at 11:20

1 Answer 1

1

To select feature (c) on LayerF among those intersect with the line on LayerM:

[Option 1] Sort Layer F features to bring the (c) to the top row and do Join.

[Option 2] Create a Virtual Layer

To test them, I created layers outlined in your question.

enter image description here


Option 1 would be easier if we use MMQGIS plugin;

  1. Create a dummy field to control the order. Edit the attribute table and add an integer field my_order and give 1 to feature ( c ). You can leave other cells blank.
  2. Start MMQGIS | Modify | Sort and sort LayerF by my_order field (Ascending).

    enter image description here

That's all. Perform JOIN as you have been doing, and it will pick ( c ) up.


Option 2 is also simple, go to Layer | Add Layer | Add/Edit Virtual Layer.

enter image description here

  1. [Import] LayerF and LayerM
  2. Type query (as below). and OK.

Query is:

SELECT LayerF.* FROM LayerM
INNER JOIN LayerF
ON st_intersects(LayerM.geometry, LayerF.geometry)=1
WHERE LayerF.value= 167

I do not know which option is easier, but you may consider doing this task repeatedly.

Next time if you want to select (d) 2989, then

[Option 1] Edit my_order field of (d) to 1 (also clear the one for (c)) and re-do sorting, or

[Option 2] Open Virtual Layer and change the last line of query from 167 to 2989.

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.