2

I have been trawling for a solution for a while now, and either I cant find the correct solution or I'm not quite getting my search right.

I have some GPS points from a ship track that are collected every 10 seconds or so with the time they were collected. At one point the GPS goes down. I want to recreate estimated points during this down time. Is there a way to create a list of points with GPS coordinates between the last GPS fix and the next fix every 10 seconds?

1
  • 4
    Welcome to Geographic Information Systems! Welcome to GIS SE! We're a little different from other sites; this isn't a discussion forum but a Q&A site. Your questions should as much as possible describe not just what you want to do, but precisely what you have tried and where you are stuck trying that. Please check out our short tour for more about how the site works
    – Ian Turton
    Feb 7 at 12:13
2

You can use QGIS for that. There are at least three possibilities to interpolate points:

  1. In the middle between two neighboring points
  2. A constant number of interpolated dots between each two neighboring points (constant percentage of the whole distance between two points)
  3. At a regular interval (constant distance between two points)

Each solution works in the geometry generator as you can see on the screenshots. This is for visualization only. If you want to create actual geometries, use Menu Processing / Toolbox / Geometry by expression. Both versions require the same expression for each solution.

What you need: a unique identifier in the sequence along the path. This can be a timestamp - I used the field id. Change it accordingly if you use another field.

Solution 1

You can interpolate points simply be adding the coordiantes (x and y separately) of each feautre with each next feature and dividing it by 2 (to get a point in the middle). Use the following expression:

make_point (
    (
        x + attribute (
            get_feature_by_id (
                @layer, 
                $id + 1
            ), 
            'x'
        )
    ) / 2 ,
    (
        y + attribute (
            get_feature_by_id (
                @layer, 
                $id + 1
            ),
            'y'
        )
    )/2
)

See screenshot: the white dots are interpolated from the original red ones: enter image description here

Solution 2

If you want more than just one interpolated point between each point you have, you can use the following expression. It creates a series (in this case here: from 1 to 10) and for each value, you get an interpolated point on the line from one point to the next point, in the distance of 0.1, 0.2, 0.3 etc. You can change the expression accordingly. If you want points at 1/4, 2/4 and 3/4 of the line, change the third line to: generate_series (0.25, 0.75, 0.25), and line 16 to * @element, simply:

collect_geometries (
    array_foreach ( 
        generate_series (1,10),
        project (
            $geometry, 
            length (
                make_line (
                    $geometry, 
                    geometry (
                        get_feature_by_id (
                            @layer, 
                            $id+1
                        )
                    )
                )
            ) *to_real ('0.' || @element), 
            azimuth (
                $geometry, 
                geometry (
                    get_feature_by_id (
                        @layer, 
                        $id+1
                    )
                )
            )
        )
    )
)

Screenshot: interpolated dots at 1/10, 2/10, 3/10 etc. between two points: enter image description here

Solution 3

And there is a third option: you can create interpolated points at regular distances, thus depending on how close the original points are to each other, the number of interpolated points will vary. The solution is similar, using this expression. In this example, I used a distance of 4 for the points to be interpolated: change this accordingly in line 13 and 16:

collect_geometries (
    array_foreach ( 
        generate_series (
            1,
            length (
                make_line (
                    $geometry, 
                    geometry (
                        get_feature_by_id (
                            @layer, 
                            $id+1
                        )
                    )
                )
            ) /4),
        project (
            $geometry, 
            4 * @element, 
            azimuth (
                $geometry, 
                geometry (
                    get_feature_by_id (
                        @layer, 
                        $id+1
                    )
                )
            )
        )
    )
)

Screenshot: interpolated points at regular intervals: enter image description here

0

In the simplest scenario when points are ordered by timestamps, in 10 seconds interval, but some missing, you can do it even in spreadsheet with simple math, or way more easily with simple Python script if you can code a bit.

  1. Between each pair calculate the time difference in seconds, devided by ten, minus one - this will give you number of points you need to interpolate between previous and next point, 0 means no calculation necessary:

points_count = round((time_next - time_previous / 10) - 1

  1. For each point [i] in points_count calculate coordinates by using coordinates of previous point and difference between coordinates of next point:

point_x[i] = p_prev_x + ((p_next_x - p_prev_x)/(points_count + 1)*i)

Same equation for y. If you want to get also time for each interpolated point it is as easy as:

time[i] = time_previous + i*10

If you have huge number of tracks, with huge number of missing points, you will have to use coding, or software like open source QGIS to automate these steps.

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.