[Qgis-developer] Symbology NG - rendering of selected symbols

Martin Dobias wonder.sk at gmail.com
Thu Apr 8 16:40:17 EDT 2010


Hi Chris

sorry for the lag, I'm too busy these days :-/

On Tue, Apr 6, 2010 at 12:13 AM, Chris Crook <ccrook at linz.govt.nz> wrote:
> I suppose I was thinking that the changes would need to be made in a minimal, non-breaking way, why I was thinking of adding renderSelectedFeature rather than adding a parameter to the renderFeature function, and by implementing this so it works continues to work with minimal changes for renderers which don't implement this function.  However maybe it isn't too late to make more dramatic changes - as this isn't the stable version!
>
> The other reason I can see for creating a separate function and implementation is that it ensures that if a new renderer doesn't provide an implementation for selected features, then they will still be visibly selected.

My idea is that the "V2" classes (which should replace the original
ones in qgis 2.0) shouldn't be regarded as a part of the stable 1.x
API. Such routines can be still a work in progress and not breaking
anything could limit the development. Of course, there should be
reasons for such breakage :)


> I think you are right in that it would be good for symbol layers to know how to render themselves when selected, and I guess just using setColor as a default implementation would work well, and give a better implementation than the current one.
>
> With the symbol layers potentially caching symbols in the start/stop functions I'm not sure how handling the selection flag at the symbol level would work.  I guess the ideal would be for the startRender function to be passed a flag to let the renderer/symbol/symbolLayer know that they may need a selected version.

Right, startRender() should take care of creating selected version of
the symbol. I was thinking that in order to keep things simple, the
symbol will always prepare itself to be able to draw also selected
version - the runtime and memory overhead will be probably very small
(one more cached image for markers) - but I have no strong opinion
about this.


> I'm not sure I follow your thinking about using the QgsSymbolV2RenderContext to pass a selected flag, as it looks to me as if this is only created within the QgsSymbolV2 startRender, stopRender, and renderFeature funtions, where the selected status isn't available.

Sorry I wasn't clear. I thought about creating instances of
QgsSymbolV2RenderContext already in the renderers and setting the
selected flag there (and QgsSymbolV2 would just add the output unit
and alpha). But that wouldn't be a nice approach either.


> I guess a boolean field in the QgsRenderContext could be used.  In the startRender function it would be used that the the renderer/symbol/symbolLayer needed to have a selected version available, and in the renderFeature function it would mean that the feature to be rendered is selected.

QgsRenderContext is currently immutable during the rendering of a
layer: all information is set before rendering, then there's only read
access. It would be good to keep this semantics, that would be broken
if a flag would be changed prior to each renderFeature call. And
considering addition of parallelism (on the level of splitting a layer
into chunks) in future, the QgsRenderContext would have to be cloned
etc.


> Alternatively the selected flag could be added as a parameter to the startRender and renderFeature functions for the renderer, symbol, and symbol layer.

I like this approach currently at most. Only with the modification
that the symbol layer could receive this flag in
QgsSymbolV2RenderContext. Renderer and symbol would get an additional
"selected" parameter (with false as an implicit value). Renderer's
startRender doesn't need the flag because it gets pointer to the layer
and can find out whether there are any selected features. Finally,
symbol's startRender can receive the "layer has selected features"
flag and pass it to the symbol layer - but as I've written above,
maybe this isn't necessary and all symbol layers could fall back to
always prepare themselves for selected features.


> Certainly adding the flag to the context would be less work than changing function signatures through the symbology stack.  I'm not sure which would be the "more correct" implementation?
>
> So I guess I'm leaning towards:
>
> 1) Adding a boolean selected flag to QgsRenderContext, which is only used by the V2 renderers, used in startRender to indicate a selected symbology will be required, and renderFeature to indicate that the current feature is selected.

I think I've covered this above...

> 2) Updating QgsSimpleMarkerSymbolLayerV2 to optionally cache and use a selected version of the image (using setColor to set the colour to the selected colour ... Should this change the border colour too?)

I guess the border color should be kept, only the fill color should be
changed... but then there are symbols like + or X that have no fill...

> 3) Update QgsFontMarkerSymbolLayerV2 to use the selected colour if it is selected
> 4) Update QgsSvgMarkerSymbolLayerV2 to cache and use a selected version of the image. Not sure how to do this?  This should include an option for defining a selected version of the symbol (but maybe not yet implemented in GUI), and also some sort of default handling - perhaps creating a picture by rendering a larger background circle in the selected colour under the SVG image.

This is a bit tough. I'd avoid using a completely different svg symbol
for selected version. When doing raster output (i.e. not to
pdf/printer/svg) then we could colorize the image by directly
modifying the pixel colors. But I have no idea how to do that for pure
vector output. So we should probably stick with a circle around the
svg image as you suggest.

> 5) Update QgsSimpleLineSymbolLayerV2 and QgsLineDecorationSymbolLayerV2 to create and optionally use a mSelectedPen, and QgsMarkerLineSymbolLayerV2 to pass the selected flag to its marker symbol
> 6) Update QgsMarkerLineSymbolLayerV2 to optionally use the selected colour, and QgsSVGFillSymbolLayer to optionally fill the polygon with the selected colour before applying the SVG fill.

Makes sense.

I hope the answers were worth the waiting :-)

Bye
Martin


More information about the Qgis-developer mailing list