Opened 20 years ago

Closed 20 years ago

Last modified 20 years ago

#653 closed enhancement (fixed)

GetLegendGraphic only shows last class without label

Reported by: bartvde@… Owned by: valik.solorzano.barboza@…
Priority: high Milestone: 4.4 release
Component: WMS Server Version: 4.3
Severity: minor Keywords:
Cc: mapserver@…, jdenisgiguere@…, valik.solorzano.barboza@…, pagurekd@…, godwinl@…, paul.den.dulk@…

Description

The current implementation of GetLegendGraphic only gives back a graphic for the
last CLASS in the LAYER when not specifying the Rule in the URL.

According to the spec the following should he done:

"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".

In Mapserver all classes are drawn on top of each other. Also the label is
missing from the legend graphic. 

I would suggest to follow Cubewerx implementation of the spec, an example can be
found here:

http://demo.cubewerx.com/demo/cubeserv/cubeserv.cgi?CONFIG=nrcan&SERVICE=WMS&VERSION=1.3.0&REQUEST=GetLegendGraphic&LAYER=ROUTE_L%3Anrcan&STYLE=Topographic&SCALE=125000&FORMAT=image%2Fpng&SLD=http%3A%2F%2Fdemo.cubewerx.com%2Fsld%2Fdemos%2Fntdb.xml

Change History (31)

comment:1 by dmorissette, 20 years ago

I guess we could go with this interpretation of the spec, but this means that
the WIDTH and HEIGHT parameter values have a different meaning depending on
whether a rule is specified or not:

- If a rule is specified then a single icon is produced with the width and
height specified (and no label is produced).  e.g.

http://demo.cubewerx.com/demo/cubeserv/cubeserv.cgi?CONFIG=nrcan&SERVICE=WMS&VERSION=1.3.0&REQUEST=GetLegendGraphic&LAYER=ROUTE_L%3Anrcan&STYLE=Topographic&SCALE=125000&FORMAT=image%2Fpng&SLD=http%3A%2F%2Fdemo.cubewerx.com%2Fsld%2Fdemos%2Fntdb.xml&WIDTH=10&HEIGHT=10&rule=Unclassified

- If no rule is specified, then we produce a legend image that includes all
classes and labels for each of them.  In this case the width and height
parameters are just "hints" for the size of the icons for each rule, which means
that it is impossible for the client to predict what the size of the complete
legend will be, e.g.
http://demo.cubewerx.com/demo/cubeserv/cubeserv.cgi?CONFIG=nrcan&SERVICE=WMS&VERSION=1.3.0&REQUEST=GetLegendGraphic&LAYER=ROUTE_L%3Anrcan&STYLE=Topographic&SCALE=125000&FORMAT=image%2Fpng&SLD=http%3A%2F%2Fdemo.cubewerx.com%2Fsld%2Fdemos%2Fntdb.xml&WIDTH=30&HEIGHT=30

comment:2 by bartvde@…, 20 years ago

Hi Daniel,

you're right about this one. But it is all in line with what the spec says. Even 
when asking for one Rule the width and height values are just hints, so a client 
cannot (always) depend on them.

WIDTH (Optional): 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. 
HEIGHT (Optional): This gives a hint for the height of the returned graphic in 
pixels.

But implementing the "GetLegendGraphic without any Rule specified" would be a 
powerful implementation for thin clients that don't want to build their legends 
using pieces.

Also, when using just one Rule, the client would have to perform a GetStyle 
request in order to get the label associated with the Rule which is quite a 
detour. So having a lightweight legend option would be great in my opinion.

comment:3 by jdenisgiguere@…, 20 years ago

Cc: jdenisgiguere@… added

comment:4 by bartvde@…, 20 years ago

Cc: morissette@… added
Daniel wrote:

About this specific bug, I think the fix would be to simply call the 
traditional GIF legend... no new development should be required... actually I 
would advise against creating a new set of legend generation functions specific 
to WMS.  Let's continue the discussion in the bug when you guys are ready to go 
ahead.

--

I had a look at the maplegend.c code. This probably involves adding a function 
to just draw the legend of one LAYER, instead of drawing the legend of the 
whole MAP, or not?

current interface function:
imageObj *msDrawLegend(mapObj *map)

add:
imageObj *msDrawLegend(mapObj *map, layerObj *lp)

comment:5 by valik.solorzano.barboza@…, 20 years ago

Cc: valik.solorzano.barboza@… added

comment:6 by dmorissette, 20 years ago

Instead of splitting msDrawLegend() in two functions, you could also have the
GetLegendGraphic code in mapwms.c turn off all layer(s) but the selected one(s),
and then calling *msDrawLegend() would return a legend with only those layers.

BTW, do you still want to return an image with a label even when a single rule
is requested?  I understand why you feel that it is simpler for a client to
request legend images that include the label, but I think that the idea of the
GetLegendGraphic in the spec is to return an icon only (with no label) for use
in an HTML legend at the client end, even cubeserv works that way, see comment#1
above.  

If we want the possibility to return an icon+label when a single rule is
selected then I think that should be controlled via a vendor-specific parameter.

comment:7 by bartvde@…, 20 years ago

Hi Daniel,

Good tip turning the STATUS OFF for the other LAYERs.

When a user asks for a single Rule in the GetLegendGraphic request, no label
should be returned according to the spec (which is the current implementation in
Mapserver).

If a user does not specify the Rule in the GetLegendGraphic request, we can just
return the full legend for the requested layer including the labels.

That would be exactly like the Cubewerx server does it now.

I don't think we need the option for ONE Rule to include both graphic and label
as yet (which would have to be controlled by a vendor-specific parameter, I agree).

comment:8 by dmorissette, 20 years ago

Cool. No more comments/objections.  ;)

comment:9 by valik.solorzano.barboza@…, 20 years ago

Hi Daniel,

as previously mentioned by Bart I did make some changes in mapwms.c to 
implement the GetLegendGraphic in the case no 'rule' parameter has been 
specified in the request, which is to return the legend with all classes for 
the specified 'LAYER'. Indeed it was sufficient to set the status of all other 
layers to OFF and then to call msDrawLegend. What I realised now that we are 
not getting the name (WMS_TITLE) of the specified layer in the legend. I would 
imagine that users are expecting this information otherwise they will have to 
implemented still on the client side.

Another enhancement that I also can imagine would actually to be able to 
specify which 'LAYERS' we want to have in the legend, as in the GetMap 
request. But maybe this is a enhancement which should be discussed with the 
OGC-WMS guys.

comment:10 by mapserver@…, 20 years ago

Cc: mapserver@… added

comment:11 by pagurekd@…, 20 years ago

Cc: pagurekd@… added

comment:12 by dmorissette, 20 years ago

dependson: 732
I don't see an easy solution to the wms_title problem. Normally it's the layer's
"NAME" which is used for the labels. I'd hate to have to hack something in the
legend code for that.

I have created bug 732 to discuss a way to deal with this problem.

comment:13 by godwinl@…, 20 years ago

Cc: godwinl@… added

comment:14 by bartvde@…, 20 years ago

Should this functionality work with GROUP layers? 

Implementation will be difficult as users can group together any layer they
want, also layers with different classifications.

comment:15 by dmorissette, 20 years ago

Um... I guess the answer should be to react the same way to a GetLegendGraphic
call on a group layer than to a request to style such a layer via SLD.

Assefa: what happens at the moment if you try to apply a SLD rule to a WMS layer
that's at the 2nd level in the capabilities, i.e. the parent of a group of layers?

comment:16 by assefa, 20 years ago

SLD will only be applied when the layer name matches. As Bart mentionned in
earlier post, using the group could lead into other issues (for ex. when layers
are of diffrent types). If people feel that we should add it (with a big
warning) It could be done pretty easily.

comment:17 by dmorissette, 20 years ago

OK, so we cannot apply a rule or a SLD to a group layer (which is fine IMHO) so
the only case we need to worry about is GetLegendGraphic on a group layer where
there is no style or rule specified. 

In this case I think a legend image which all the individual layers in the group
should be returned.  Would that work for you Bart?

comment:18 by bartvde@…, 20 years ago

Cc: paul.den.dulk@… added
What needs to be done now is implement the optional SCALE parameter, otherwise
we run into trouble with creating legend images from scale-dependent layers.

Unlike other WMS requests, not the bbox and width and height are sent in the
request but the scale itself.

If I look at the source of maplegend.c, the scale is calculated with the
following statement:

status = msCalculateScale(map->extent, map->units, map->width, map->height,
map->resolution, &map->scale); 

This determines which layers are drawn in the legend.

In the case of GetLegendGraphic, this should be overruled, or the
GetLegendGraphic code should create a dummy map extent which matches the scale
given in the request (and use default values for width and height).

Or maybe I am even missing an option? Any ideas?

comment:19 by dmorissette, 20 years ago

I think this bug is getting too long already, we should not keep adding more
items to it otherwise it becomes extremely long and messy and impossible to deal
with. We should try to close this one ASAP and create new bugs for new stuff
instead, 

I have created bug 809 about the scale issue. 

comment:20 by valik.solorzano.barboza@…, 20 years ago

The fix has been commited in the 4.2 branch. I already sent an email to Steve
asking whether it is possible to have the fix in to the new release 4.2.3.

I also noticed that this fix does not work in the 4.3 development. We will
figure out what is going on and commit our changes in the 4.3 version.

Who is resposible for closing this bug?

comment:21 by dmorissette, 20 years ago

Cc: mapserver-bugs@… added; dmorissette@… removed
Owner: changed from mapserverbugs to valik.solorzano.barboza@…
If you fixed the issue then you are responsible for marking the bug fixed. Also
please indicate how you fixed it... this bug is so long that just saying "fixed"
isn't enough. We need to know what you did exactly. Also, will any documentation
need to be updated?

BTW, you wrote that the fix didn't work in 4.3, so I guess the bug needs to stay
open until 4.3 works too.

comment:22 by assefa, 20 years ago

I just checked the implemenation for this bug (in 4.2.3) when using the RULE 
parameter : right now when the user specifies a RULE, an icon is returned for 
the last class of the layer (all classes are drawn on top of each other). The 
RULE value does not have any effect. I was expecting to see the RULE value 
being used to extract the class (using the class name) and only draw that 
class. Am I missing a point ?

comment:23 by bartvde@…, 20 years ago

Hi Assefa,

nothing was changed in the way the Rule parameter is interpreted. I checked with
mapserv 4.2.2 and when specifying a Rule in the request I also get back the
legend icon of the last class. I will file an enhancement request for this.

Bart

comment:24 by dmorissette, 20 years ago

For the record, the bug that Bart filed for the RULE parameter is bug 843

comment:25 by dmorissette, 20 years ago

Milestone: 4.4 release
Valik, in comment #15 above you wrote that the fix didn't work in 4.3 and worked
only in 4.2. We are trying to release 4.4 now, so it would be great if you could
give us an update on this.

comment:26 by valik.solorzano.barboza@…, 20 years ago

Daniel, I'll be working on this problem today and I expect it to work by the end
of the day. The I'll commit my changes

comment:27 by valik.solorzano.barboza@…, 20 years ago

blocked: 809

comment:28 by valik.solorzano.barboza@…, 20 years ago

Resolution: fixed
Status: newclosed
This bug was already fixed in 4.2.3 but now it is also ported to 4.3 and tested.
Everything works as it should. Changes are in mapwms.c. Brief description what
has been implemented:

If a GetLegendgraphic request does not provide a RULE parameter then all the
layers are set to status MS_OFF except the layer specified in the LAYER request
parameter. Then msDrawLegend is called. When the SCALE parameter is provided
some extra calculations have to be performed before calling msDrawLegend. See
bug 809.

Documentation will be provided very soon.

comment:29 by valik.solorzano.barboza@…, 20 years ago

op_sys: Windows 2000All

comment:30 by tomkralidis, 20 years ago

Nice.  Two issues:

1./ Text is truncated:

http://devgeo.cciw.ca/cgi-bin/mapserv/ecows?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetLegendGraphic&LAYER=naps&FORMAT=image%2Fgif&width=300&height=300

2./ The text labels are showing up below the graphic, i.e.

rule1graphic
rule1text
rule2graphic
rule2text

Isn't this format (CubeSERV style) more intuitive?  i.e.:

rule1graphic rule1text
rule1graphic rule1text

comment:31 by valik.solorzano.barboza@…, 20 years ago

The problem Tom has is been further discussed in bug 966
Note: See TracTickets for help on using tickets.