3

As it is seen in the picture, I have the attributes table which shows the random extracted routes from Istanbul highway map and points on it. Points were uniformly distributed through 2000 random extracted routes, once in 20 meters. After adding the points on the random routes layer, I joined them by osm_id field value (one to many join) and got the table shown below. enter image description here In the table, there are distance and angle values of the points. Additionally, I added timestamp to each point, representing the imaginary cars' movement. For example, the car is in 0th meter of the route at 20:00:00, in 20th meter at 20:00:01 and so on. If the angle difference between 2 points is so much (100 or more), it means the car had turn on the route, which should make the car go slower. That's why I need to increase the time it takes to move between those 2 points. Question: how can I apply that condition to update the timestamp field when there is so much difference between 2 following angles?

P.S. I use QGIS 3.22.2, and the layer is in GeoPackage format.

P.S. It is not seen in the table, but between some 2 following angles, there is a reasonable difference, it's just by chance that the angle values in the screenshot are same.

I also added the screenshot to show a sample route with turn. Between the points right before and after the turn, the angle difference is more than 100. There, for example, I need to apply delay to respective timestamp values. enter image description here

2
  • 3
    You use PyQGIS. What have you tried so far? Jan 17, 2022 at 13:25
  • By using PyQGIS, I can find the angle difference and tell the user in which interval there is the turn. But I could not update the timestamp in the attribute table. That is where I need the help. I add the link of the screenshot of the output and source code for you to check it out: screenshot: ibb.co/dtkHHwW source code: drive.google.com/file/d/1Lr6pfnvRXs8lAdNU4Lr6aNBrdprQZM45/… Jan 17, 2022 at 16:08

1 Answer 1

6

Building on this answer, you can first find the relative angle between the current point and the previous point then use that angle as a condition for your speed in the distance/speed calculation for your Date & Time type field.

I used 50 m distance between points and a 30 degree threshold just to demonstrate.

I set the fast and slow speeds to 14 m/s and 8 m/s arbitrarily. You might want to make the slower speed a function of the relative angle for 'realism'.

with_variable('rangle', abs("angle" - attribute(get_feature_by_id(@layer, $id - 1), 'angle')),
    with_variable('threshold', 30,   -- set a threshold variable
        with_variable('dist', 50,    -- set this to the distance between your points
            with_variable('start_time', make_datetime(2022, 1, 15, 20, 0 ,0),   -- set a start time variable
                    CASE 
                        WHEN "distance" = 0                        
                        THEN @start_time          -- input the start time at zero distance
                        
                        ELSE 
                        
                            CASE WHEN @rangle < @threshold 
                                THEN attribute(get_feature_by_id(@layer, $id-1), 'timestamp') + to_interval(to_string(@dist / 14) || ' seconds')  -- get the time from the previous row and add the elapsed interval (distance/speed)
                                
                            ELSE                        
                                attribute(get_feature_by_id(@layer, $id-1), 'timestamp') + to_interval(to_string(@dist / 8) || ' seconds')  -- when the angle is above threshold, use a slower speed.
                            END
                            
                    END
            )
        )
    )
)

The image shows the points labelled with the interval in seconds between the current point and the previous point. (Ignore the -243 label, I didn't do any grouping when I wrote the quick label expression, so it is taking the time difference from a different line)

enter image description here

Just a word of warning: you may lose some fidelity with your original line when interpolating points along it.

Here in blue is the original line I used, the red line represents the angles between the interpolated points.

enter image description here

8
  • Update: I added the timestamp same as you suggested in the previous question I asked. Then, I wanted to update it by the code you answered but it fixes the timestamps to the beginning value. I add the attributes table here: ibb.co/mCMMtCq In the preview, when I check step by step, it shows correctly. But, when I try to submit it, since the data is big (18k rows), it gives runtime error for 20-30 seconds then adds the time same as I showed in the link above Jan 20, 2022 at 15:00
  • since it is has a massive attributes table, maybe there are some "endpoints" to consider. I could not find sadly, if anyone considers to help, I add the project below: drive.google.com/file/d/1-sBH58DeIwt6XsZjm7iz14-MMM-ioR0P/… Jan 20, 2022 at 17:55
  • The expression I gave works with a single line feature. It likely needs some modification to work with multiple lines.
    – Matt
    Jan 20, 2022 at 18:01
  • Is there any suggestion for me to apply modifications for multiple lines? Jan 20, 2022 at 18:07
  • I have updated the expression in my answer. You no longer need to calculate the relative angle first. That is handled all in the same expression. You can use this expression on the Time field. It works on a test dataset I made with 3 lines.
    – Matt
    Jan 20, 2022 at 18:16

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.