1

I have a shapefile with thousands of polygons and a shapefile with 28 polygons that completely overlay the first shapefile. I'm trying to split the first shapefile features into 28 smaller shapefiles based on the location of polygons in the second shapefile. Here's an image of the subject.

enter image description here

Manually, I select one (blue) polygon and then I use the "Select Within" plugin which allows selecting features considering if the centroid of polygons falls into the layer of reference. Then I export the selection into a separate file. I'd like to do this process automatically generating X files for X features of the shapefile of reference.

Is there any way to do something like this?

I guess that something with python is possible, but I'm still not able to write a script.

2 Answers 2

1

In case the two layer do not exactly match, so that the polygons of the layer with the smaller polygons (lets call it p2) at the borders overlap with more than one of the larger polygons of the other layer (p1), you can use the centroid of the smaller polygons and get the $id of the larger polygon that it is within. Use field calculator to create an attribute field called within with this expression. Then proceed as in step 2 of the other solution:

array_get (
    overlay_nearest('p1', $id, limit:=-1),
    array_find( 
    array_foreach (
        overlay_nearest('p1', $id, limit:=-1),
        within (
            centroid ($geometry),
            geometry (
                get_feature_by_id (
                    'p1',
                    @element))))
        ,
        1))

As you can see (e.g. at the highlighted spot), small poygons that overlap with two of the larger polygons are assigned to the side where the centroid is within: enter image description here

Edit

Tested with the dataset you provided in the comment. To get proper results with this data, use this expression (apply it on the layer with the small polygons; the layer with the larger polygons should be named p1):

array_max(
    array_foreach (
        overlay_intersects('p1',$id),
        if (
            within (
                centroid ($geometry), 
                geometry (get_feature_by_id ('p1', @element))
            ),
            @element,
            ''
        )
    )
)

Then use Split vectort layer based on the field created in this way as explained in my other solution.

enter image description here

5
  • Thank you very much! It works, but there's something that's still off. This is the result of the expression as adapted for my case. i.imgur.com/EkMHbIr.png For some reason, the first record of the p2 layer (Tiles) is skipped from the expression, getting Null values. However, that's a minor issue, It's only to take a small extra step by selecting all those Null features and assigning them the proper value.
    – NorthSon
    Commented Dec 9, 2021 at 23:13
  • From the image, I can't tell very much. Can you somehow share the data?
    – Babel
    Commented Dec 10, 2021 at 6:37
  • I link the URL of these files on Google Drive: drive.google.com/file/d/1f5Kt_2hUbbjFt_qm141RdktpyhJZ_ZCC/… Let me know if you managed to download them. p.s. I've changed the ID order of the p2 layer (Tiles), so the incriminate polygon is the number 23.
    – NorthSon
    Commented Dec 10, 2021 at 20:44
  • See updated answer
    – Babel
    Commented Dec 10, 2021 at 22:37
  • It finally works! Thank you very much!
    – NorthSon
    Commented Dec 11, 2021 at 9:32
1
  1. On the first layer (let's call it p1), create a new attribute field called uid with field calculator, representing the id of the (larger) polygon from the second layer (called p2 here) that each of the small polygon is within. Use this expression:

    array_first (overlay_within('p1', $id))

  2. Use Menu Processing / Toolbox / Split vector layer and set the uid from step 1 as Unique ID field - and you're done.

Layer 1 (black lines), labeled with the uid from step 1; Layer 2 (red lines) and the resulting output in different colors: enter image description here

1
  • That's interesting, but there's a problem with my case. Many polygons on the p1 layer are between two polygons on the p2 layer. The result using that expression is this: i.imgur.com/EvUBZb7.png For this problem, I've resorted to that plugin which allows considering if the centroid of p1 polygons falls into p2 polygons. Maybe I could solve this by adding an extra step and generating a point shapefile with all centroids of p1 polygons, and then proceeding this way, but with millions of polygons on p1 would become much more time-consuming.
    – NorthSon
    Commented Dec 8, 2021 at 8:47

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.