[Geoserver-devel] Improving GetFeatureInfo for vector data

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

Opinions?

Cheers
Andrea

==
Our support, Your Success! Visit http://opensdi.geo-solutions.it for more information.

Ing. Andrea Aime

@geowolf
Technical Lead

GeoSolutions S.A.S.
Via Poggio alle Viti 1187
55054 Massarosa (LU)
Italy
phone: +39 0584 962313
fax: +39 0584 1660272
mob: +39 339 8844549

http://www.geo-solutions.it
http://twitter.com/geosolutions_it


One point to note is you should repress text symbolisers for your approach.

But yes the implementation idea is sound, I remember a similar trick with OpenGL “selection”.

Jody Garnett

On 21 November 2013 at 4:05:35 am, Andrea Aime (andrea.aime@anonymised.com) wrote:

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

Opinions?

Cheers
Andrea

==
Our support, Your Success! Visit http://opensdi.geo-solutions.it for more information.

Ing. Andrea Aime

@geowolf
Technical Lead

GeoSolutions S.A.S.
Via Poggio alle Viti 1187
55054 Massarosa (LU)
Italy
phone: +39 0584 962313
fax: +39 0584 1660272
mob: +39 339 8844549

http://www.geo-solutions.it
http://twitter.com/geosolutions_it



Shape the Mobile Experience: Free Subscription
Software experts and developers: Be at the forefront of tech innovation.
Intel(R) Software Adrenaline delivers strategic insight and game-changing
conversations that shape the rapidly evolving mobile landscape. Sign up now.
http://pubads.g.doubleclick.net/gampad/clk?id=63431311&iu=/4140/ostg.clktrk_______________________________________________
Geoserver-devel mailing list
Geoserver-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/geoserver-devel

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

Cheers
Andrea

--

Our support, Your Success! Visit http://opensdi.geo-solutions.it for more
information.

Ing. Andrea Aime
@geowolf
Technical Lead

GeoSolutions S.A.S.
Via Poggio alle Viti 1187
55054 Massarosa (LU)
Italy
phone: +39 0584 962313
fax: +39 0584 1660272
mob: +39 339 8844549

http://www.geo-solutions.it
http://twitter.com/geosolutions_it

-------------------------------------------------------