7

I have a bunch of GPS points that need to be a minimum set distance (100m) apart from each other. I have buffered these points, however this results in long chains of overlapping polygons that I need to manually go through to delete every other polygon.

I am trying to preserve as many polygons as possible, so when I automatically select all overlapping polygons and delete, there is a huge loss in total polygons (hence the manual deletion process).

Is there any way for QGIS to automatically select every other polygon for deletion (like as seen below)?

enter image description here

4
  • 2
    Is it a shapefile? Selecting using % (mod) of the row number docs.qgis.org/2.8/en/docs/user_manual/working_with_vector/… and groups.google.com/g/australian-qgis-user-group/c/FEYhD7aJ5Ds (select every 2nd row) might help as the polygons look to be consecutive. Jan 24 at 2:03
  • Unfortunately, a modulus solution is likely to fail with the case where the features do not overlap, so a simplistic solution is going to remove features that a more sophisticated solution would not..
    – Vince
    Jan 24 at 2:26
  • 1
    Do you have a time or order reference and other attributes in your point data ? Do you need the original points themselves or would a 100m resampling of the trajectory work ?
    – Kasper
    Jan 24 at 8:23
  • As we don't have some details that are crucial to find a solution (see below, comment by @Kadir Şahbaz), plese provide a sample data set for testing. Otherwise, we speculate about possible solutions that might not match your exact use case.
    – Babel
    Jan 24 at 13:02

1 Answer 1

8

Create an array of all id's, than generate a series of every second element of this array. Apply this only for features that intersect other features.

To do so, use this expression with select by expression:

case 
when overlay_intersects(@layer)
then
array_contains( 
    with_variable (
        'array',
        array_agg( $id),
        generate_series (1, array_length(@array),2)
    ), 
    $id
)
end

enter image description here


There might be the case that you don't have an id that follows the spatial order of your polygons. In this case, create a new field that you can use in the expression above instead of $id. For this, first create a line layer and draw a line along the polygons in the correct order. Then on the polygon layer, create this order field using the following expression:

with_variable(
    'line',  
    overlay_nearest ('lineorder', $geometry)[0],
    array_find (
        array_sort(
            array_agg (
                line_locate_point (
                    @line,
                    centroid ($geometry)
                )
            )
        ),
        line_locate_point (
            @line,
            centroid ($geometry)
        )
    )
)

Or, without creating a separate field, use this expression directly in select by expression:

with_variable (
    'order',
    with_variable(
    'line',  
    overlay_nearest ('lineorder', $geometry)[0],
    array_find (
        array_sort(
            array_agg (
                line_locate_point (
                    @line,
                    centroid ($geometry)
                )
            )
        ),
        line_locate_point (
            @line,
            centroid ($geometry)
        )
    )
),


case 
when overlay_intersects(@layer)
then
array_contains( 
    with_variable (
        'array',
        array_agg(@order),
        generate_series (1, array_length(@array),2)
    ), 
    @order
)
end
)

Correctly selecting every second polygon even though id (see labeled values) are in random order. The order of the polygon is createad as distance along the red line of the polygon's centroid: enter image description here

4
  • 1
    OK, to really solve OP's problem than I think we would need a dataset to exactly see the details of how it looks and what is neede in detail. Otherwise we speculate about solutions that work in one case, but not in the other. Thnaks for your input!
    – Babel
    Jan 24 at 13:00
  • I think there is no way but to create some soft of sorting id if it doesn't already exist, e.g. by drawing a line and than create a new field with line_locate_point() function.
    – Babel
    Jan 24 at 13:09
  • Tried to adapt to solution for this case.
    – Babel
    Jan 24 at 13:39
  • Thank you so much, this works perfectly!
    – John Tom
    Jan 25 at 3:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.