2

Solution below worked for a small subset with a filesize <<1 gb, for larger file sizes another solution would be needed

I'm trying to formulate an expression which extracts specific parts/geometries from a dataset.

The background is my work on quick clay zones; I have produced discharge areas (U) based on previously mapped release areas (L). Followed by cutting off areas over a certain threshold (average height of the release area). Now I am stuck with several split discharge areas, where I want to extract only the discharge areas directly connected to their respective release area.

I have many overlapping areas, so extracting by location doesn't yield a good result, since it also extracts discharge areas which overlap with other release areas.

Basically, I want to filter areas which overlap and have the same "ID", I can't really iterate over the layer since I have more than 10'000 features, and don't want to end up with the same amount of shapefiles.

For easier understanding (process from top to bottom):

enter image description here

2 Answers 2

4

Not entirely sure if thats what you want. But this expressions returns the areas which overlap and have the same ID as MultiPolygon. Its for use in geometry by expression:

collect_geometries( -- turn geometries into multipolygon (expressionwise you cannot handle it differently
 array_foreach(
  array_filter(
   overlay_intersects('over',$currentfeature), -- get all intersecting features of the layer called 'over'
   attribute(@element,'id')="id" -- filter them by attribute 'id' (from layer 'over') equals "id" (from current layer)
   and  -- add a second filter
   overlaps(geometry(@element),$geometry) -- check if the geometries of these features overlap (you need to go this way because there is no overlay_overlaps() expression...
  ),
 geometry(@element) -- belongs to array_foreach, iterates over all matching features and extracts their geometry
 )
)

Make sure both layers are in the same CRS. Explanations added as comments. You need to change fieldnames and layernames. In case you do not actually look for overlaps predicate you can remove or replace it or e.g. add another one like ... and (overlaps(geometry(@element),$geometry) or within(geometry(@element),$geometry)), consider that in some cases its easier to simply use another overlay expression then.

The expression for extract by expression is slightly different:

array_contains(
 array_foreach(
  array_filter(
   overlay_intersects('over',$currentfeature),
   attribute(@element,'id')="id"
   and
   overlaps(geometry(@element),$geometry)
  ),
 attribute(@element,'id')),
"id")
2
  • hmm, it seems to not work as intended - I've checked my geometry, and ran the expression (modified to suit my files), but it seems to have ended up in a loop; I let it run overnight, and it still hasn't yielded any results (neither finished nor threw an error). I assume the problem may be to stick everything in an array, which overloads the system (both files contain many features, and are several gb in size). Is there a way to maybe break it down to subsets of points of L, check if any of those have the same ID as U, and then move to the next subset? Jun 2 at 6:57
  • 1
    @JonathanRyan sounds like you have a very large dataset then? Maybe a threaded PyQGIS solution would be better? This way one could improve performance and have control over progress. For now maybe just try the expression on a small subset of your data, to see if it really does what you want.
    – MrXsquared
    Jun 2 at 7:00
0

After cutting U the result is Multypoligon, then Vector -> Geometry tools -> Multipart to Single part. If you mean U "directly connected" to L : TOUCH then You can use Vector-> research tools-> select by location. Select from U where Touch from L, then invert feature selection.

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.