11

I'm using QGIS 2.14.4-Essen. I have two layers:

  • points.shp that contains points with a YEAR column
  • lines.shp that contains lines that exactly connect the points from points.shp

I would like to get the YEAR attribute from points.shp back to lines.shp. Each line is a single segment with one point at each end (see picture below). What I would like to get is YEAR from first point and YEAR from second point back into each line attributes.

For instance: line 1 is touching a first point with YEAR=2010 and a second point with YEAR=2011. I would like to get back something like '2010-2011' into line 1 attributes. The result should look like this:

id  | points
----+-----------------
1   | 2010-2011
2   | 2011-2012
3   | 2012-2016

enter image description here

Is there a way to achieve this using QGIS?

9
+50

Although @radouxju answer is valid, I will explain it a little more detailed.

  1. You need to make sure that the polyline feature is split exactly above the point locations.
  2. Use Join attribute by location. Choose the split line feature at point locations as target layer - in my case I name it "exploded".
  3. In the summary section, select "Take summary of intersecting feature". Here, instead of running the tool two times; one for Min and another time for Max, you can run it one time and choose both Min and Max.

enter image description here

  1. The out file will have the following attribute:

enter image description here

  1. Add new field of type string with a name "Year" to the new shapefile from step 4.
  2. Use Field calculator, and go to update existing field. Select "Year" and write the following expression:

    to_string( "MINYEAR2" ) + '-' + to_string( "MAXYEAR2" )

  3. The final output attribute will look like this:

enter image description here

  1. The final output will be like this:

enter image description here


Here is the output after testing your data:

enter image description here

The table on the left is the point data after creating a new field of type integer, and the table on the right is after joining the line with point data using step 2 mentioned above. Then I used steps 5-6 to create the final data.

Update

I tried to convert the field YEAR from string to integer using expression to_int() and it worked. So you don't need to do it manually. However, The field type should be of type Integer not Integer64. Make sure that the field length is up to 9. If you chose a field length of 10, it will be converted to Interger64, and it will not work with Interger64. Then you can follow the process from step 2-6

Here is the final output after using the expression to_int():

enter image description here

In the above attribute table on the left, the YEAR is of type string and the YEAR2 is of type integer converted using expression to_int(). You can see in the attribute table on the right after following steps 2-6, I got MINYEAR2 and MAXYEAR2, then converted to string back again to concatenate everything together in the field YEAR.

  • Thanks a lot! That is exactly what I did several times. I guess that the polyline features are split exactly above the points locations because I created the lines from points layers using Points2One plugin. Can you try with this data subset: drive.google.com/file/d/0B7ZWEFkkfYgheG92Q29sa0I3LW8/view? Thanks again! – wiltomap Sep 2 '16 at 8:49
  • The field YEAR in the attribute table is of type string. You need to add a new field of type integer and input the years manually. After creating the integer type field and save the edits, remove the old string field. Then, follow the above detailed process. – ahmadhanb Sep 2 '16 at 10:02
  • I tried to convert the field YEAR from string to integer using expression to_int(), but also didn't work. When I entered the years manually, it worked as expected. – ahmadhanb Sep 2 '16 at 10:04
  • Clear explanation @ahmadhanb – Shiko Sep 2 '16 at 10:40
  • Thanks @ahmadhanb! The fact is that the data I shared above is a subset. I have several thousands of lines and points so entering years manually will be quite a lot of work! Is this a bug? – wiltomap Sep 2 '16 at 11:08
5

When join join points to line you will have multiple relationship. With "join attribute by location", you will be able to ask for a given summary method. In your case, do this twice : once with minimum and once with maximum. After that you can concatenate the two fields in a new field and you end up with what you need.

enter image description here

In field calculator :

tostring(minYEAR) + '-' + tostring(maxYEAR)
  • This method returns an additional column named COUNT and containing value 2 for each line. Either Min and Max options return these informations. I have selected the lines layer as target layer and the points layer as join layer, am I right? – wiltomap Aug 31 '16 at 6:51
  • is you year field numeric or text ? – radouxju Sep 1 '16 at 7:42
  • The YEAR field is integer. I tried to create a new column with to_string("YEAR") but the result is exactly the same... – wiltomap Sep 1 '16 at 11:13
  • I made a quick test to make sure (QGIS 2.8.3) and it worked. If your count is 2, it means that you do have 2 points for each segment, which is correct. But with me I have the attribute values MINYEAR MAXYEAR in the new line vector created by the spatial join. I do not understand why it doesn't work in your case. Could you try with another file ? – radouxju Sep 2 '16 at 8:30
4

Assuming the topology is perfect, creating a field 'WKT' with the the expression

geom_to_wkt( $geometry) 

in your point layer, you could use the expression:

min( attribute( get_feature('points','WKT', geom_to_wkt(start_point($geometry)  )),'year'),attribute( get_feature('points','WKT', geom_to_wkt(end_point($geometry)  )),'year'))||'-'|| max( attribute( get_feature('points','WKT', geom_to_wkt(start_point($geometry)  )),'year'),attribute( get_feature('points','WKT', geom_to_wkt(end_point($geometry)  )),'year'))

in the field calculator of the pipe layer, creating a text string.

  • attribute(feature, attribute_name) Returns the value of a specified attribute from a feature, here, the year of the point feature
    obtained.
  • get_feature(layer, attribute, value) returns the first feature of a layer matching a given attribute value. Here we check if we can find a point with the same coordinates (in WKT format) as the
    ones of your line's start and end vertices.
  • start_point(geometry) returns the first node from a geometry. Here the first vertex of your line.
  • end_point(geometry) returns the last node from a geometry. Here the last vertex of your line.
  • geom_to_wkt(geometry) returns the Well-Known Text (WKT) representation of the geometry. enter image description here

You could even update it to:

CASE
WHEN attribute( get_feature('points','WKT', geom_to_wkt(start_point($geometry)  )),'year') = attribute( get_feature('points','WKT', geom_to_wkt(end_point($geometry)  )),'year')
THEN attribute( get_feature('points','WKT', geom_to_wkt(end_point($geometry)  )),'year')
ELSE min( attribute( get_feature('points','WKT', geom_to_wkt(start_point($geometry)  )),'year'),attribute( get_feature('points','WKT', geom_to_wkt(end_point($geometry)  )),'year'))||'-'|| max( attribute( get_feature('points','WKT', geom_to_wkt(start_point($geometry)  )),'year'),attribute( get_feature('points','WKT', geom_to_wkt(end_point($geometry)  )),'year'))
END

in order to show just one year if two points with the same year are connected (getting 200X instead of 200X-200X).

The main advantage of this method is that if your data changes in your points, you can update it very fast with just one field calculator.
You could even add this rule as an Autofield for when you create new lines.
Cheers,

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.