[Geoserver-devel] Getting the right size for WMS LegendURL widht/height

Hi,
here we have a report http://jira.codehaus.org/browse/GEOS-6245 about
legend graphic url not reporting the real width and height of the legend
images.

In fact we are reporting a static 20x20 size, but the spec says:

element in LegendURL indicates the MIME type of the logo image, and the attributes
width and height state the size of the image in pixels.”

Now, the code that builds legend graphic is rather complex, and I’m sure it will
get worse over time (think support for label font preview, categorize/interpolate,
better handling of multiple feature type styles), so I have doubts about the maintainability
of an approach that would compute the output size without actually painting
the legend.

Painting the legend, getting the image and grabbing its size is easy enough,
but doing so for each and every style/layer in the caps document might take a toll.

I’ve considered an approach in which the BufferedImage/Graphics used in
the code are mocks, just to speed up things, but it will not really work,
partly because the code works by building several internal bufferd images
and asembling them later, and partly because we need to measure font
metrics, and that requires a real graphics (and we could not just share
a singleton one, these operations are not thread safe).

So… short of that, I was wondering about maintaining a cache of the
style legend sizes in the StyleInfo metadata. Which could work,
but we’d need to make a few changes around to know when the style
changed, namely:

  • store in the metadata map the width/height and date when they were last computed
  • have the catalog store in the metadata map an information about when the
    styleinfo was last changed (which should be easy, and sort of useful for
    other purposes too)

The other annoying bit is that running the get caps would end up modifying
the styles that do not have the cached infos (an OGC operation that modifies
the catalog contents woud be a first, and it would need to grab the
configuration lock to work (hum… maybe just when a styleinfo write is needed…)

An alternative could be to keep the info about width/height/last compute
in a separate in memory cache, or store them on disk as sidecar files,
but the nice thing about the styleinfo storage is that we basically have it
already there when we build the style, and it would help scale up to large
catalogs.

Thoughts?

Cheers
Andrea

==
Meet us at GEO Business 2014! in London! Visit http://goo.gl/fES3aK
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


Can I have a small rant in response to this.

The legend URL does not have to call get legend graphics, and the goal for each image is not quite the same.

In a GetCapabilities doc we just want the image, as we already have the title sitting in parsed form in the get capabilities data structure.

Solve this problem by throwing a no titles option into your get legend graphic URL, return a consistent 20x20 image and let’s move on with life.

Got a group layer? Return a 20x20 group icon.

Jody

On Saturday, May 31, 2014, Andrea Aime <andrea.aime@anonymised.com> wrote:

Hi,
here we have a report http://jira.codehaus.org/browse/GEOS-6245 about
legend graphic url not reporting the real width and height of the legend
images.

In fact we are reporting a static 20x20 size, but the spec says:

element in LegendURL indicates the MIME type of the logo image, and the attributes
width and height state the size of the image in pixels.”

Now, the code that builds legend graphic is rather complex, and I’m sure it will
get worse over time (think support for label font preview, categorize/interpolate,
better handling of multiple feature type styles), so I have doubts about the maintainability
of an approach that would compute the output size without actually painting
the legend.

Painting the legend, getting the image and grabbing its size is easy enough,
but doing so for each and every style/layer in the caps document might take a toll.

I’ve considered an approach in which the BufferedImage/Graphics used in
the code are mocks, just to speed up things, but it will not really work,
partly because the code works by building several internal bufferd images
and asembling them later, and partly because we need to measure font
metrics, and that requires a real graphics (and we could not just share
a singleton one, these operations are not thread safe).

So… short of that, I was wondering about maintaining a cache of the
style legend sizes in the StyleInfo metadata. Which could work,
but we’d need to make a few changes around to know when the style
changed, namely:

  • store in the metadata map the width/height and date when they were last computed
  • have the catalog store in the metadata map an information about when the
    styleinfo was last changed (which should be easy, and sort of useful for
    other purposes too)

The other annoying bit is that running the get caps would end up modifying
the styles that do not have the cached infos (an OGC operation that modifies
the catalog contents woud be a first, and it would need to grab the
configuration lock to work (hum… maybe just when a styleinfo write is needed…)

An alternative could be to keep the info about width/height/last compute
in a separate in memory cache, or store them on disk as sidecar files,
but the nice thing about the styleinfo storage is that we basically have it
already there when we build the style, and it would help scale up to large
catalogs.

Thoughts?

Cheers
Andrea

==
Meet us at GEO Business 2014! in London! Visit http://goo.gl/fES3aK
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


Jody Garnett

On Fri, May 30, 2014 at 10:24 PM, Jody Garnett <jody.garnett@anonymised.com>
wrote:

Can I have a small rant in response to this.

The legend URL does not have to call get legend graphics, and the goal for
each image is not quite the same.

In a GetCapabilities doc we just want the image, as we already have the
title sitting in parsed form in the get capabilities data structure.

Solve this problem by throwing a no titles option into your get legend
graphic URL, return a consistent 20x20 image and let's move on with life.

This is clearly impossible. Have a style with 5 rules? You need 5 20x20
icons with titles on their sides to make the five icons readable.
Have a color map? Its representation is way larger.

In general (beyond the limits of our GLG implementation) the idea that you
can return a single 20x20 icon works in some specific cases,
like targeting a single rule that has a simple style (e.g., no categorize
usage, no color map), but in the capabilities document
we have to refer to a legend for the layer.
Leave the title out sure, that's not a problem (but it does not make sense
for layer groups of course), but you simply cannot cram a
full layer style in a 20x20 icon

Cheers
Andrea

--

Meet us at GEO Business 2014! in London! Visit http://goo.gl/fES3aK
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

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

As I indicated it was a rant. The point being that the legend URL does not have quite the same expectations as GetLegendGrapics.

You may just end up with a 20x20 copy of our group layer icon for example.

I spend a fair bit of effort on the client side trying to request 20x20 icons often I get back something else (which I then crop) Sounds like that is a sepereate bug report.

Jody

···

On Fri, May 30, 2014 at 10:24 PM, Jody Garnett jody.garnett@anonymised.com wrote:

Can I have a small rant in response to this.

The legend URL does not have to call get legend graphics, and the goal for each image is not quite the same.

In a GetCapabilities doc we just want the image, as we already have the title sitting in parsed form in the get capabilities data structure.

Solve this problem by throwing a no titles option into your get legend graphic URL, return a consistent 20x20 image and let’s move on with life.

This is clearly impossible. Have a style with 5 rules? You need 5 20x20 icons with titles on their sides to make the five icons readable.
Have a color map? Its representation is way larger.

In general (beyond the limits of our GLG implementation) the idea that you can return a single 20x20 icon works in some specific cases,
like targeting a single rule that has a simple style (e.g., no categorize usage, no color map), but in the capabilities document
we have to refer to a legend for the layer.
Leave the title out sure, that’s not a problem (but it does not make sense for layer groups of course), but you simply cannot cram a
full layer style in a 20x20 icon

Cheers
Andrea

==
Meet us at GEO Business 2014! in London! Visit http://goo.gl/fES3aK
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


I like storing the style infos, and the approach works well when setting up with an image (rather than get legend graphics call).

Can I suggest a scary alternative, what about generating and storing the image on disk. The image has a width and height after all, and you could refer to it farther that get legend graphics?

Since you have to paint the thing anyways is it worth keeping the image?

On Saturday, May 31, 2014, Andrea Aime <andrea.aime@anonymised.com> wrote:

Hi,
here we have a report http://jira.codehaus.org/browse/GEOS-6245 about
legend graphic url not reporting the real width and height of the legend
images.

In fact we are reporting a static 20x20 size, but the spec says:

element in LegendURL indicates the MIME type of the logo image, and the attributes
width and height state the size of the image in pixels.”

Now, the code that builds legend graphic is rather complex, and I’m sure it will
get worse over time (think support for label font preview, categorize/interpolate,
better handling of multiple feature type styles), so I have doubts about the maintainability
of an approach that would compute the output size without actually painting
the legend.

Painting the legend, getting the image and grabbing its size is easy enough,
but doing so for each and every style/layer in the caps document might take a toll.

I’ve considered an approach in which the BufferedImage/Graphics used in
the code are mocks, just to speed up things, but it will not really work,
partly because the code works by building several internal bufferd images
and asembling them later, and partly because we need to measure font
metrics, and that requires a real graphics (and we could not just share
a singleton one, these operations are not thread safe).

So… short of that, I was wondering about maintaining a cache of the
style legend sizes in the StyleInfo metadata. Which could work,
but we’d need to make a few changes around to know when the style
changed, namely:

  • store in the metadata map the width/height and date when they were last computed
  • have the catalog store in the metadata map an information about when the
    styleinfo was last changed (which should be easy, and sort of useful for
    other purposes too)

The other annoying bit is that running the get caps would end up modifying
the styles that do not have the cached infos (an OGC operation that modifies
the catalog contents woud be a first, and it would need to grab the
configuration lock to work (hum… maybe just when a styleinfo write is needed…)

An alternative could be to keep the info about width/height/last compute
in a separate in memory cache, or store them on disk as sidecar files,
but the nice thing about the styleinfo storage is that we basically have it
already there when we build the style, and it would help scale up to large
catalogs.

Thoughts?

Cheers
Andrea

==
Meet us at GEO Business 2014! in London! Visit http://goo.gl/fES3aK
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


Jody Garnett

On Fri, May 30, 2014 at 11:21 PM, Jody Garnett <jody.garnett@anonymised.com>
wrote:

As I indicated it was a rant. The point being that the legend URL does not
have quite the same expectations as GetLegendGrapics.

Not really. GetLegendGraphics has a single rule operation mode where the
small icon can be generated, but that assumes
you know the rules, which you can do only by fetching the styles via
GetStyles... but at that point you have the SLD client
side, so you can generate the icons you need by yourself...

From the spec, table entry describing the "rule" parameter:

"Rule of style to produce legend graphic for, if applicable. *In the*
*case that a style has multiple rules but no specific rule is selected,*
*then the map server is obligated to produce a graphic that is*
*representative of all of the rules of the style.*"

Also about width and height:

"This gives a *hint* for the width of the returned graphic in pixels.
Vector-graphics can use this value as a hint for the level of detail
to include."

I spend a fair bit of effort on the client side trying to request 20x20
icons often I get back something else (which I then crop) Sounds like that
is a sepereate bug report.

See above, you cannot expect a 20x20 symbol even if you ask for a single
rule,
writing code with that expectations is bound to fail because it's not
agreeing with the spec.

Cheers
Andrea

--

Meet us at GEO Business 2014! in London! Visit http://goo.gl/fES3aK
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

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

On Fri, May 30, 2014 at 11:26 PM, Jody Garnett <jody.garnett@anonymised.com>
wrote:

I like storing the style infos, and the approach works well when setting
up with an image (rather than get legend graphics call).

Can I suggest a scary alternative, what about generating and storing the
image on disk. The image has a width and height after all, and you could
refer to it farther that get legend graphics?

Since you have to paint the thing anyways is it worth keeping the image?

Hum... I was about to say "but reading a PNG is expensive", however... we
have PNGJ now in the classpath,
and with that, I can just read the header without having to decompress the
entire image as I'd have to do
with ImageIO. It would still be a file open for each style/layer
combination in the capabilities document though.

Given that clients might also want to follow the link and get the legend
graphics, this could
be coupled with a dispatcher callback that intercepts the legend graphic
request and if it
matches the one used to generate the PNG file, we could just shortcut and
return the file on disk,
getting some caching benefit

We'd still need the "last updated" information in the style files, which
could become something
standard, or maybe could be done by attaching a style specific listener to
the catalog

Cheers
Andrea

--

Meet us at GEO Business 2014! in London! Visit http://goo.gl/fES3aK
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

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

Given that clients might also want to follow the link and get the legend
graphics, this could
be coupled with a dispatcher callback that intercepts the legend graphic
request and if it
matches the one used to generate the PNG file, we could just shortcut and
return the file on disk, getting some caching benefit

I was more thinking the GetCapabilities document could provide a URL
straight to those generated images. The GetCapabilities document is
supposed to link to a URL, nothing says that URL has to be a
GetLegendGraphic request (especially since GetLegendGraphics is an
optional operation).

We'd still need the "last updated" information in the style files, which

could become something standard, or maybe could be done by attaching a
style specific listener to the catalog

You could also check resource modification time on the style file, and
compare against your generated image.
--
Jody

On Sat, May 31, 2014 at 3:38 PM, Jody Garnett <jody.garnett@anonymised.com>
wrote:

Given that clients might also want to follow the link and get the legend

graphics, this could
be coupled with a dispatcher callback that intercepts the legend graphic
request and if it
matches the one used to generate the PNG file, we could just shortcut and
return the file on disk, getting some caching benefit

I was more thinking the GetCapabilities document could provide a URL
straight to those generated images. The GetCapabilities document is
supposed to link to a URL, nothing says that URL has to be a
GetLegendGraphic request (especially since GetLegendGraphics is an
optional operation).

That would work as well, but we don't have a way to publish specific files
out of the data dir, only full folders, so we'd have to somehow
pimp up the FilePublisher, making it filter-able.
Plus the current way gives a valid example of how to use GetLegendGraphics,
why remove it?

We'd still need the "last updated" information in the style files, which

could become something standard, or maybe could be done by attaching a
style specific listener to the catalog

You could also check resource modification time on the style file, and
compare against your generated image.

Right... that would double the number of file system accesses though

Cheers
Andrea

--

Meet us at GEO Business 2014! in London! Visit http://goo.gl/fES3aK
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

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