I tried to get a legend image from my GeoServer Instance filtered by extent (render only symbologies that are currently displayed on screen).
For this purpose I used the getLegendUrl
function from OpenLayers 6 (docs here : https://openlayers.org/en/latest/apidoc/module-ol_source_TileWMS-TileWMS.html#getLegendUrl)
So far I tried this example : https://openlayers.org/en/latest/examples/wms-getlegendgraphic.html
But it does not work (even in this above example, any zoom to the map won't re-render the legend).
Now I tried this :
var url = mylayer.getSource().getLegendUrl(mymap.getView().getResolution())
which gave me the good url with a SCALE
parameter (which change every time I zoom in/out, because I had the listener on the 'change:resolution'
event).
The URL looks like this :
http://localhost:8080/geoserver/MyStore/wms?&LAYERS=MyStore%3Ajunctions&SERVICE=WMS&VERSION=1.3.0&REQUEST=GetLegendGraphic&FORMAT=image%2Fpng&LAYER=MyStore%3Ajunctions&SCALE=1789.2350833905004
URL-decoded :
base url : http://localhost:8080/geoserver/MyStore/wms
**Params**
LAYERS=MyStore:junctions
SERVICE=WMS&VERSION=1.3.0
REQUEST=GetLegendGraphic
FORMAT=image/png
LAYER=MyStore:junctions
SCALE=1789.2350833905004 <=== THIS CHANGE ON ZOOM IN/OUT BUT HAS NO EFFECT : THE SAME LEGEND WILL BE RETURNED
Any ideas on how can I make the SCALE
parameter (or anything else) modify the legend by extent?
Extra:
I found this old question : GetLegendGraphic with bbox or filter.
But it should be closed now because the link provided lead me to a 404 page…I did not found any questions on this specific issue anywhere else…
By the way here is my SLD (if it could somehow helps but I don't think that it has any effect here):
<?xml version="1.0" encoding="UTF-8"?>
<NamedLayer>
<Name>Junctions Polygon</Name>
<UserStyle>
<Title>Junctions</Title>
<Abstract>A sample style for junctions</Abstract>
<FeatureTypeStyle>
<Rule>
<Name>710</Name>
<ogc:Filter>
<ogc:PropertyIsEqualTo>
<ogc:PropertyName>junctions</ogc:PropertyName>
<ogc:Literal>710</ogc:Literal>
</ogc:PropertyIsEqualTo>
</ogc:Filter>
<Title>710</Title>
<Abstract>junctions 710</Abstract>
<!-- like a linesymbolizer but with a fill too -->
<PolygonSymbolizer>
<Fill>
<CssParameter name="fill">#FFFF33</CssParameter>
<CssParameter name="fill-opacity">1</CssParameter>
</Fill>
<Stroke>
<CssParameter name="stroke">#000000</CssParameter>
<CssParameter name="stroke-width">1</CssParameter>
</Stroke>
</PolygonSymbolizer>
</Rule>
<Rule>
<Name>7730</Name>
<ogc:Filter>
<ogc:PropertyIsEqualTo>
<ogc:PropertyName>junctions</ogc:PropertyName>
<ogc:Literal>7730</ogc:Literal>
</ogc:PropertyIsEqualTo>
</ogc:Filter>
<Title>7730</Title>
<Abstract>junctions730</Abstract>
<!-- like a linesymbolizer but with a fill too -->
<PolygonSymbolizer>
<Fill>
<CssParameter name="fill">#78D232</CssParameter>
<CssParameter name="fill-opacity">1</CssParameter>
</Fill>
<Stroke>
<CssParameter name="stroke">#000000</CssParameter>
<CssParameter name="stroke-width">1</CssParameter>
</Stroke>
</PolygonSymbolizer>
</Rule>
<Rule>
<Name>Rule 1</Name>
<Title>GreyFill BlackOutline</Title>
<Abstract>Grey fill with a black outline 1 pixel in width</Abstract>
<!-- like a linesymbolizer but with a fill too -->
<PolygonSymbolizer>
<Fill>
<CssParameter name="fill">#AAAAAA</CssParameter>
</Fill>
<Stroke>
<CssParameter name="stroke">#000000</CssParameter>
<CssParameter name="stroke-width">1</CssParameter>
</Stroke>
</PolygonSymbolizer>
</Rule>
</FeatureTypeStyle>
</UserStyle>
</NamedLayer>
Update:
Okay I found this question : How to get the legends from geoserver
It somehow gives me a way to do this but it's a very hard way I think: It supposed to first request features by extent on my own and reduce those features by the symbology field name, and send back a request of getLegendUrl
with a RULE parameter to get only the specific rules…
I would like to know why the SCALE
params does not work…
Best Answer
As specified in the docs of GeoServer :
https://docs.geoserver.org/stable/en/user/services/wms/get_legend_graphic/index.html#content-dependent-legends
Now the thingis that it also needs more params in the URL :
Let's do this with the given exemple here
https://openlayers.org/en/latest/examples/wms-getlegendgraphic.html
It has this function :
Now in order to make it works as a "Content dependent" legend I added those steps :
First create two useful functions :
Create a the CRS parameter :
Create the BBOX parameter :
Create the SRCWIDTH and SRCHEIGHT parameters :
Create the LEGEND_OPTIONS params :
Finally build the url :
Job done : it works.
Final code :
Of course : this is only the part of the code (in order to make it works it needs the map object, Geoserver instance with a WMS or WFS to query. Also, each service must be bound to an SLD with specified rules.
Now a last improvment of this function, just for less coupling purpose, is to remove the resolution params and get it directly from the map object, like so :
now the signature of the
updateLegend
function is empty, and will work independently:Some screenshots :