Hi,
our current implementation of GetFeatureInfo is basically a proximity query that
tries to find all geometries in the database which are close enough to the location
being clicked, while taking into account the size of the largest symbol in the layer
(when static) and the filters being applied while running GetMap (CQL_FILTER,
rule filters, scale dependencies, and the like).
This is fine, but fails miserably in a number of cases:
symbols having wildly large differences in size, to account for the largest one
we end up picking also small symbols even if we clicked far away from them
dynamic sizes, in which we cannot know what the symbol size will be until we
actually paint the data
oddly shaped or translated point symbols, point in case, the Google pushpin
(http://www.mcwetboy.net/maproom/images/omwo_pushpin.jpg), the
geometry should be at the tip, but the user will tipically click the large top area
of the pin instead
How to improve this? Well… actually paint the data and find which features
actually colors the pixel in question or any pixel in the search buffer around it
(5x5 pixels), with some smarts:
if possible, reduce the paint area to cover only the features that can actually
intercept, based on a static analysis of the style and active rules (which will
only work if the symbolizers are static enough)
otherwise, perform a two pass process, first load the data captured by the GetMap
to evaluate the expressions and find the largest value, then go back and run
as if we knew statically. This will reduce the amount of paint operations and avoid
allocating a paint area as large as the GetMap itself
Once we start painting, the code will paint one feature on the test RGBA surface,
check if the alpha channel has been set to anything above 0 for any pixel, if so
select the feature, wipe out the alpha band, move to the next feature, and so on,
until we reach the max number of features we’re supposed to return, once that happens,
stop the rendering.
I plan to implement this algorithm in its own class, and have GetFeatureInfo
call onto it based on some system variable: on trunk, run by default with the new
code, unless otherwise specified, on the stable series, the opposite, default to
what we have now, but allow the admin to experiment if they like to
Hi,
our current implementation of GetFeatureInfo is basically a proximity query that
tries to find all geometries in the database which are close enough to the location
being clicked, while taking into account the size of the largest symbol in the layer
(when static) and the filters being applied while running GetMap (CQL_FILTER,
rule filters, scale dependencies, and the like).
This is fine, but fails miserably in a number of cases:
symbols having wildly large differences in size, to account for the largest one
we end up picking also small symbols even if we clicked far away from them
dynamic sizes, in which we cannot know what the symbol size will be until we
actually paint the data
oddly shaped or translated point symbols, point in case, the Google pushpin
(http://www.mcwetboy.net/maproom/images/omwo_pushpin.jpg), the
geometry should be at the tip, but the user will tipically click the large top area
of the pin instead
How to improve this? Well… actually paint the data and find which features
actually colors the pixel in question or any pixel in the search buffer around it
(5x5 pixels), with some smarts:
if possible, reduce the paint area to cover only the features that can actually
intercept, based on a static analysis of the style and active rules (which will
only work if the symbolizers are static enough)
otherwise, perform a two pass process, first load the data captured by the GetMap
to evaluate the expressions and find the largest value, then go back and run
as if we knew statically. This will reduce the amount of paint operations and avoid
allocating a paint area as large as the GetMap itself
Once we start painting, the code will paint one feature on the test RGBA surface,
check if the alpha channel has been set to anything above 0 for any pixel, if so
select the feature, wipe out the alpha band, move to the next feature, and so on,
until we reach the max number of features we’re supposed to return, once that happens,
stop the rendering.
I plan to implement this algorithm in its own class, and have GetFeatureInfo
call onto it based on some system variable: on trunk, run by default with the new
code, unless otherwise specified, on the stable series, the opposite, default to
what we have now, but allow the admin to experiment if they like to
On Wed, Nov 20, 2013 at 6:43 PM, Jody Garnett <jody.garnett@anonymised.com>wrote:
One point to note is you should repress text symbolisers for your approach.
Right, forgot to say it, but it was in the plans already. Thanks for the
reminder anyways,
having everything written down helps when starting to code :-p