[mapserver-users] Filtering Layer Legend Icons

Seth G sethg at geographika.co.uk
Thu Aug 9 16:40:24 PDT 2018


Hi list,

Just some brief(ish) notes on attempts to how to limit what is displayed in layer legends in MapServer that may be of use to someone else - and any simpler alternatives welcome!

I wanted to display only certain icons in a WMS legend, to match parameters passed to the WMS service which filtered the data in the layer using run time substitution. E.g. &RATING=1,3,5 only displays records with values 1,3,5 by filtering in the DATA clause. 
See https://mapserver.org/cgi/runsub.html

Content Dependent Legend Responses https://www.mapserver.org/development/rfc/ms-rfc-101.html almost does what I want, but I wanted to display the legend based on what was filtered by the user rather than what remained to be displayed in the map. 

I then looked at the CGI approach to creating legends and altering Mapfiles from a URL - https://www.mapserver.org/cgi/controls.html

I knew that setting a CLASS NAME to an empty string, or removing it would remove the icon from the legend, but you can't remove items from a Mapfile via a URL. It also became apparent you can't change a CLASS NAME - a list of all keywords that can be changed can be found in https://github.com/mapserver/mapserver/blob/branch-7-2/maplexer.l
If the keyword is prefixed with URL_STRING then it can be modified e.g. <INITIAL,URL_STRING>expression   

A CLASS STATUS can be changed. However STATUS+OFF does not affect if a CLASS is displayed in a legend. There is a mention of this in this ticket - https://github.com/mapserver/mapserver/issues/2431, and I'm of the opinion 
this should probably be logged as an issue/bug. Thoughts on this welcome. 

Finally I found that the CLASS GROUP is available for changing, which led to my current solution. All classes selected by a user would have their CLASS GROUP set to a "visible" string in the URL and I could then generate the layer legend using the CLASSGROUP "visible". 

http://localhost/mapserver/?MODE=legend&LAYER=MyLayer&map.layer[MyLayer].class[MyClass1]=GROUP filtered+CLASSGROUP=filtered

A few notes on the above:

- The CLASSGROUP sent via the URL needed to be lowercase, yet any case could be used for the GROUP name in the Mapfile snippet e.g. GROUP+vISible
 - CLASSGROUP had to be added to the end of the URL after the Mapfile snippets. 
-  "group" "^filtered$" needed to be added to the LAYER's VALIDATION block or you get the following error: "loadClass(): General error message. URL-based GROUP configuration failed pattern validation."

Then "all" that remains was to generate the querystring in JavaScript based on the user selected filters, and load the filtered legend into the browser. 

Hope the above helps someone in the future,

Seth


--
web:http://geographika.co.uk
twitter: @geographika


More information about the mapserver-users mailing list