-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add configurable extent buffer to symbols #59630
Add configurable extent buffer to symbols #59630
Conversation
🪟 Windows buildsDownload Windows builds of this PR for testing. 🪟 Windows Qt6 buildsDownload Windows Qt6 builds of this PR for testing. |
Tests failed for Qt 6One or more tests failed using the build from commit 371ee87 buffer_extent_zerobuffer_extent_zeroTest failed at testRenderWithExtentBuffer at tests/src/python/test_qgsvectorlayerrenderer.py:848 Rendered image did not match tests/testdata/control_images/vectorlayerrenderer/expected_buffer_extent_zero/expected_buffer_extent_zero.png (found 54 pixels different) The full test report (included comparison of rendered vs expected images) can be found here. Further documentation on the QGIS test infrastructure can be found in the Developer's Guide. |
@JuhoErvasti thanks for tackling this annoying problem! I have a few thoughts on the approach used here:
|
I agree that making it a symbol layer property does complicate things and the use cases for separate buffer levels are probably few and far between. The reason I did it this way was based on your comment from the issue's discussion:
I interpreted this to mean that it does need to be a symbol layer property, but reading the thread again you might've meant it as a symbol property (as opposed to layer/project property as suggested by others)? Either way if that isn't the requirement, I'm happy to change it to be on the symbol level.
Sounds good.
I figured it'd be good to be able to control the buffer with an expression (for example to make it scale-dependant as you mentioned) and since I was adding it as a symbol layer property it made sense to use a data-defined button since almost everything else has one. But if the location of the property is changed, this can of course be changed too. Could it be even just a normal expression widget, not a data-defined override button?
If it's done on the symbol level, how should this work? If you're using f.e. the graduated renderer you could set a different expression/value for each symbol, same with the geometry generator subsymbols. Wouldn't it have to be evaluated at least once per each symbol in the renderer? |
Sorry, must have been an accidental mis-phrasing at the time. I think I was referring to "should be at the symbol level" as opposed to "should be one setting at the project (or layer) level", but accidentally wrote "symbol layer".
Elsewhere we do use data-defined buttons for layer-level rendering properties. Eg for raster layer opacity you can data-define, even though it's only evaluated once just before the layer render. I'd say this could be similar -- we could evaluate once upfront at the start of the vector layer renderer, and then just use that to control the feature request extent. Nice and simple and we then avoid ALL handling when doing per-symbol-rendering.
For multi-symbol renderers I'd do it once per symbol upfront, and then take the max and that's the value used for the feature request. The worst case scenario there is that we end up rendering a few extra symbols which fall totally outside the map. |
If I could ask for one more clarification:
I might be missing something, but if the extent buffer should only be applied to the feature request and there shouldn't be any further handling what is the benefit of having separate values for different symbols? Doesn't that make it effectively a renderer-level property even if the values are set for the symbols? |
@JuhoErvasti good question! My thinking is that this property is innately associated with the shape and size of a particular symbol, so should be attached to that. That way, the property will be stored inside the symbol if you eg copy it to another layer or save to the style library and reuse the symbol in a different layer, and won't require re-configuring the renderer setting each time. |
5753e9c
to
53c25ac
Compare
I've reworked this so that the extent buffer is a symbol property now if you want to take a look. |
python/PyQt6/gui/auto_generated/symbology/qgsextentbufferdialog.sip.in
Outdated
Show resolved
Hide resolved
Thanks @JuhoErvasti ! One other consideration raised by @nirvn -- shouldn't we also add a unit selection for this setting? It would be more portable between different layers if the user could set the buffer size in eg millimeters instead of just map units (which may differ in size from layer to layer). QgsRenderContext.convertToMapUnits could be used to convert the size + unit to a map unit size when required. |
70ef57c
to
1a2fdd0
Compare
Thank you for the review! I've made the changes you suggested. I ended up dropping negative buffers since I didn't really have a clear use case for the in mind. I originally thought that I might as well allow it in case someone has an obscure use case for them but as you pointed out now that the extent buffer isn't in the symbol layer it wouldn't work that well. I also added the option to change the size unit. |
/** | ||
* Returns the units for the buffer size. | ||
* | ||
* \see setExtentBufferSizeUnit() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* \see setExtentBufferSizeUnit() | |
* \see extentBuffer() | |
* \see setExtentBufferSizeUnit() | |
* | |
* \since QGIS 3.42 |
/** | ||
* Sets the \a unit used for the extent buffer. | ||
* | ||
* \see extentBufferSizeUnit() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* \see extentBufferSizeUnit() | |
* \see setExtentBuffer() | |
* \see extentBufferSizeUnit() | |
* | |
* \since QGIS 3.42 |
Thanks @JuhoErvasti -- a few more minor comments here |
27fbdd6
to
7089713
Compare
Thanks, I've addressed the points. Hopefully everything's OK now. Also I realized that the data defined property still could've produced a negative buffer so that should be handled now, as well as the |
…rendering_out_of_extent
@JuhoErvasti there's one bit missed in 7089713 -- we still need the \since added to extentBufferSizeUnit / setExtentBufferSizeUnit |
Sorry, added now! |
Great, thanks for your hard work @JuhoErvasti ! |
@JuhoErvasti thanks for fixing that issue. Could you please update your top message to reflect the changes before we tag it for docs and changelog? |
I've updated the message now. |
@JuhoErvasti A documentation ticket will be opened at https://github.com/qgis/QGIS-Documentation when this PR is merged. Please update the description (not the comments) with helpful description and screenshot to help the work from documentors. Thank you! |
This pull request has been tagged for the changelog.
You can edit the description. Format available for credits
Thank you! |
@JuhoErvasti |
Fixes #38579.
Allows the user to set an extent buffer per symbol. Useful with for example geometry generator symbols:
2024-12-10.09-58-33.mp4
You can set the value in different units and it can also be controlled by an expression (for example you can set a different value based on the map scale).
When rendering
QgsRenderer
finds the biggest buffer value that has been set in all of its symbols. The extent for the feature request inQgsVectorLayerRenderer
is then modified according to that value.Backport to 3.40 requested (if possible).
Funded by the National Land Survey of Finland.