The primary source of data for a map that I'm making in QGIS 3.14 QGIS 3.20 is OSM.
There is a layer which contains natural peaks, obtained with a natural=peak
query.
In order to reduce clutter, I'd like to only display a particular peak if it's the highest peak in a 5km radius. Is there a plugin that can help me achieve this, or some OSM query magic that would yield the same result?
(EDIT) What I've tried so far:
After suggestions from @Babel, I tried a couple of things.
I updated to QGIS 3.20.0-Odense and this is the version I'll be using from now on. This is the latest version available and contains functions such as overlay_nearest
and array_max
.
Since OSM data has the elevation data stored in the ele
field as a string, I used the Field Calculator to create a new field called ele_int
based on to_int(to_real(ele))
expression.
I had to first clean up and fix data fields that contained elevations such as 123m
and 1`234
manually, as well as delete entries which didn't contain any elevation information in the ele
field.
Then I tried using select by expression using the following:
array_max (
overlay_nearest(
@layer,
ele_int,
limit:=100,
max_distance:=1000
)
) > ele_int
But this results in 4122 peaks selected out of 4152 in total.
Interestingly, if I change max_distance
to 10 or 50000, I still get 4122 selected rows, so max_distance
doesn't affect the result.
(Hindsight: because there was a mismatch between the feature layer CRS and the project CRS, I had to use max_distance
value of 0.08 in order to get the needed result)
One thing that does impact results is changing the limit
in the expression, so if the limit is set to 1000, then 4149 peaks are selected, and if the limit is set to 10, then 3890 peaks are selected, but this doesn't give me the results that I need.
In the image below, you see the selection results. This tight group of 6 peaks is at least 14km away from the nearest peak outside of the group, so I'm using it to verify my results. The distance between the top left two peaks is approximately 2400 meters. It doesn't matter whether max_distance is set to 10, 1000, or 50000, I always see all 6 of these peaks selected. I've also verified that map unit is set to meters.
It feels like I'm very close to the goal but can't quite figure out the last bit. One thing I found interesting is that if I set the max_distance
to 100000
(100 km), and the limit
to 1
, only one feature gets selected, and I would expect to see more. It feels almost like the expression is not performed for each feature, but only for one?
(EDIT 2) Additional findings about overlay_nearest
When I add a label to each peak for debugging so that every peak is labeled as to_string("ele_int") + ' - ' + array_to_string(overlay_nearest(@layer, "ele_int", limit:=5, max_distance:=100))
This is the result: Note that overlay_nearest returns values while completely disregarding the distance to nearest point (the distance between each of these points is >2km). Also note that the first member of the array is the point itself, and the second point in the array is the closest one.
Either I'm using overlay_nearest
wrong (more likely), or this could be a bug in QGIS (less likely).
(EDIT 3)
I start seeing the effects of max_distance when it's set to a very low value. In practice, I get results that I'd like to see when it's set to 0.07 (corresponds to around 5-10 km). Could it be the CRS I'm using (EPSG:32634)? The distance measurement tool gets the distance correctly though...
Final thoughts
The accepted answer works well. The problem I am seeing seems to be due to CRS mismatch between the feature layer and the project. It's possible even in this case to make things work by choosing a very small value for max_distance
, something like 0.08.