diff --git a/doc/en/user/source/styling/sld/extensions/index.rst b/doc/en/user/source/styling/sld/extensions/index.rst
index 43913e4e4a0..20c453bc541 100644
--- a/doc/en/user/source/styling/sld/extensions/index.rst
+++ b/doc/en/user/source/styling/sld/extensions/index.rst
@@ -19,3 +19,4 @@ Although not portable to other applications, these extensions make styling more
randomized
composite-blend/index
z-order/index
+ rendering-selection
diff --git a/doc/en/user/source/styling/sld/extensions/rendering-selection.rst b/doc/en/user/source/styling/sld/extensions/rendering-selection.rst
new file mode 100644
index 00000000000..cfa542d590b
--- /dev/null
+++ b/doc/en/user/source/styling/sld/extensions/rendering-selection.rst
@@ -0,0 +1,311 @@
+.. _rendering_selection:
+
+Rendering Selection
+====================
+
+GeoServer provides a ``VendorOption`` to define whether a particular element ``Rule``, ``FeatureTypeStyle`` or ``Symbolizer`` should be applied to a ``getLegendGraphic`` output or to a ``getMap`` output.
+
+This allows to generate legends from the SLD that can be better looking and more expressive, without the underlying complexity of the actual rendered style. Other systems have a dedicated language to build legends instead. The advantage of using the same language is that dynamic behaviors, like rule removal based on the area being rendered, can be easily retained.
+
+The vendor option is named ``inclusion``, e.g.:
+
+* legendOnly
+
+* mapOnly
+
+Valid values are:
+
+* ``legendOnly`` the element will be skipped when applying the style to the data to render map.
+* ``mapOnly`` the element will be skipped when applying the style to the data to render legend.
+* ``normal`` will have the same effect then omitting the VendorOption: the SLD element will be used for both map and legend (same effect as not specifying the vendor option).
+
+
+Take as an example the following style: for each Rule two symbolizers are defined one that will be skipped when rendering the legend and one that will be skipped when rendering the map and loads the legend icon from an external svg file.
+
+.. code-block:: xml
+
+
+
+
+ Style example
+
+
+
+
+
+ numericValue
+ 90
+
+
+
+
+
+ circle
+
+ 0xFF0000
+
+
+ 32
+
+ mapOnly
+
+
+
+
+
+ image/svg+xml
+
+ 20
+
+ legendOnly
+
+
+
+
+
+
+ numericValue
+ 90
+
+
+ numericValue
+ 180
+
+
+
+
+
+
+ circle
+
+ #6495ED
+
+
+ 32
+
+ mapOnly
+
+
+
+
+
+ image/svg+xml
+
+ 20
+
+ legendOnly
+
+
+
+
+
+
+
+
+The same result could have been obtained by defining each rule two time each one with a single symbolizer, and defining the vendor options at the rule level.
+
+.. code-block:: xml
+
+
+
+
+ Style example
+
+
+
+
+
+ numericValue
+ 90
+
+
+
+
+
+ circle
+
+ 0xFF0000
+
+
+ 32
+
+
+ mapOnly
+
+
+
+
+
+ numericValue
+ 90
+
+
+ numericValue
+ 180
+
+
+
+
+
+
+ circle
+
+ #6495ED
+
+
+ 32
+
+ mapOnly
+
+
+
+
+
+ numericValue
+ 90
+
+
+
+
+
+
+ image/svg+xml
+
+ 20
+
+ legendOnly
+
+
+
+
+
+
+ numericValue
+ 90
+
+
+ numericValue
+ 180
+
+
+
+
+
+
+
+ image/svg+xml
+
+ 20
+
+ legendOnly
+
+
+
+
+
+
+
+
+
+A third way to obtain the same result could be to define vendor options at the FeatureTypeStyle level.
+
+.. code-block:: xml
+
+
+
+
+ Style example
+
+
+
+
+
+ numericValue
+ 90
+
+
+
+
+
+ circle
+
+ 0xFF0000
+
+
+ 32
+
+
+
+
+
+
+
+ numericValue
+ 90
+
+
+ numericValue
+ 180
+
+
+
+
+
+
+ circle
+
+ #6495ED
+
+
+ 32
+
+
+
+ mapOnly
+
+
+
+
+
+ numericValue
+ 90
+
+
+
+
+
+
+ image/svg+xml
+
+ 20
+
+
+
+
+
+
+
+ numericValue
+ 90
+
+
+ numericValue
+ 180
+
+
+
+
+
+
+
+ image/svg+xml
+
+ 20
+
+
+
+ legendOnly
+
+
+
+
diff --git a/src/wms/src/main/java/org/geoserver/wms/legendgraphic/BufferedImageLegendGraphicBuilder.java b/src/wms/src/main/java/org/geoserver/wms/legendgraphic/BufferedImageLegendGraphicBuilder.java
index eef95a47c34..e53e80ec8b3 100644
--- a/src/wms/src/main/java/org/geoserver/wms/legendgraphic/BufferedImageLegendGraphicBuilder.java
+++ b/src/wms/src/main/java/org/geoserver/wms/legendgraphic/BufferedImageLegendGraphicBuilder.java
@@ -135,6 +135,7 @@ public BufferedImage buildLegendGraphic(GetLegendGraphicRequest request)
throw new NullPointerException("request.getStyle()");
}
+ gt2Style = applyRenderingSelection(gt2Style);
// get rule corresponding to the layer index
// normalize to null for NO RULE
String ruleName = legend.getRule(); // was null
diff --git a/src/wms/src/main/java/org/geoserver/wms/legendgraphic/JSONLegendGraphicBuilder.java b/src/wms/src/main/java/org/geoserver/wms/legendgraphic/JSONLegendGraphicBuilder.java
index f2ca598d020..d7628277547 100644
--- a/src/wms/src/main/java/org/geoserver/wms/legendgraphic/JSONLegendGraphicBuilder.java
+++ b/src/wms/src/main/java/org/geoserver/wms/legendgraphic/JSONLegendGraphicBuilder.java
@@ -269,6 +269,7 @@ public JSONObject buildLegendGraphic(GetLegendGraphicRequest request) {
FeatureType layer = legend.getFeatureType();
Style gt2Style = legend.getStyle();
+ gt2Style = applyRenderingSelection(gt2Style);
if (gt2Style == null) {
throw new NullPointerException("request.getStyle()");
}
diff --git a/src/wms/src/main/java/org/geoserver/wms/legendgraphic/LegendGraphicBuilder.java b/src/wms/src/main/java/org/geoserver/wms/legendgraphic/LegendGraphicBuilder.java
index acad8ec2e6d..42ecebf85c9 100644
--- a/src/wms/src/main/java/org/geoserver/wms/legendgraphic/LegendGraphicBuilder.java
+++ b/src/wms/src/main/java/org/geoserver/wms/legendgraphic/LegendGraphicBuilder.java
@@ -35,6 +35,8 @@
import org.geotools.styling.Symbolizer;
import org.geotools.styling.TextSymbolizer;
import org.geotools.styling.visitor.DpiRescaleStyleVisitor;
+import org.geotools.styling.visitor.LegendRenderingSelectorStyleVisitor;
+import org.geotools.styling.visitor.RenderingSelectorStyleVisitor;
import org.geotools.styling.visitor.RescaleStyleVisitor;
import org.geotools.styling.visitor.UomRescaleStyleVisitor;
import org.locationtech.jts.geom.Coordinate;
@@ -509,4 +511,18 @@ protected void checkForRenderingTransformations(Style gt2Style) {
}
}
}
+
+ /**
+ * Checks if any false is present in the
+ * style removing style's elements not meant to be applied to the legend.
+ *
+ * @param style the style being used to build the legend
+ * @return the style without the element not meant to be applied to obtain the legend output
+ */
+ protected Style applyRenderingSelection(Style style) {
+ RenderingSelectorStyleVisitor renderingSelectorStyleVisitor =
+ new LegendRenderingSelectorStyleVisitor();
+ style.accept(renderingSelectorStyleVisitor);
+ return (Style) renderingSelectorStyleVisitor.getCopy();
+ }
}
diff --git a/src/wms/src/test/java/org/geoserver/wms/WMSTestSupport.java b/src/wms/src/test/java/org/geoserver/wms/WMSTestSupport.java
index 745be2d1ecf..1a599fef3be 100644
--- a/src/wms/src/test/java/org/geoserver/wms/WMSTestSupport.java
+++ b/src/wms/src/test/java/org/geoserver/wms/WMSTestSupport.java
@@ -46,6 +46,7 @@
import org.geoserver.catalog.LayerGroupInfo.Mode;
import org.geoserver.catalog.LayerInfo;
import org.geoserver.catalog.ResourceInfo;
+import org.geoserver.catalog.StyleInfo;
import org.geoserver.data.test.MockData;
import org.geoserver.data.test.SystemTestData;
import org.geoserver.data.test.TestData;
@@ -460,12 +461,22 @@ protected void setupTemplate(QName featureTypeName, String template, String body
protected LayerGroupInfo createLakesPlacesLayerGroup(
Catalog catalog, LayerGroupInfo.Mode mode, LayerInfo rootLayer) throws Exception {
- return createLakesPlacesLayerGroup(catalog, "lakes_and_places", mode, rootLayer);
+ return createLakesPlacesLayerGroup(catalog, "lakes_and_places", mode, rootLayer, null);
}
protected LayerGroupInfo createLakesPlacesLayerGroup(
Catalog catalog, String name, LayerGroupInfo.Mode mode, LayerInfo rootLayer)
throws Exception {
+ return createLakesPlacesLayerGroup(catalog, name, mode, rootLayer, null);
+ }
+
+ protected LayerGroupInfo createLakesPlacesLayerGroup(
+ Catalog catalog,
+ String name,
+ LayerGroupInfo.Mode mode,
+ LayerInfo rootLayer,
+ List styleInfos)
+ throws Exception {
LayerInfo lakes = catalog.getLayerByName(getLayerId(MockData.LAKES));
LayerInfo places = catalog.getLayerByName(getLayerId(MockData.NAMED_PLACES));
@@ -480,9 +491,12 @@ protected LayerGroupInfo createLakesPlacesLayerGroup(
group.getLayers().add(lakes);
group.getLayers().add(places);
- group.getStyles().add(null);
- group.getStyles().add(null);
-
+ if (styleInfos == null) {
+ group.getStyles().add(null);
+ group.getStyles().add(null);
+ } else {
+ group.getStyles().addAll(styleInfos);
+ }
CatalogBuilder cb = new CatalogBuilder(catalog);
cb.calculateLayerGroupBounds(group);
diff --git a/src/wms/src/test/java/org/geoserver/wms/legendgraphic/BaseLegendTest.java b/src/wms/src/test/java/org/geoserver/wms/legendgraphic/BaseLegendTest.java
index 3b5436c8aba..73d50fd495d 100644
--- a/src/wms/src/test/java/org/geoserver/wms/legendgraphic/BaseLegendTest.java
+++ b/src/wms/src/test/java/org/geoserver/wms/legendgraphic/BaseLegendTest.java
@@ -47,6 +47,8 @@ protected void onSetUp(SystemTestData testData) throws Exception {
testData.addStyle("rainfall_ramp", MockData.class, catalog);
testData.addStyle("rainfall_classes", MockData.class, catalog);
testData.addStyle("rainfall_classes_nolabels", MockData.class, catalog);
+ testData.addStyle("styleWithLegendSelection", this.getClass(), catalog);
+ testData.addStyle("styleWithLegendSelectionOnSymbolizer", this.getClass(), catalog);
// add raster layer for rendering transform test
testData.addRasterLayer(
new QName("http://www.opengis.net/wcs/1.1.1", "DEM", "wcs"),
diff --git a/src/wms/src/test/java/org/geoserver/wms/legendgraphic/BufferedImageLegendGraphicOutputFormatTest.java b/src/wms/src/test/java/org/geoserver/wms/legendgraphic/BufferedImageLegendGraphicOutputFormatTest.java
index 9e6ce3b656c..bc9e2ffb1d4 100644
--- a/src/wms/src/test/java/org/geoserver/wms/legendgraphic/BufferedImageLegendGraphicOutputFormatTest.java
+++ b/src/wms/src/test/java/org/geoserver/wms/legendgraphic/BufferedImageLegendGraphicOutputFormatTest.java
@@ -14,7 +14,9 @@
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
+import java.io.File;
import java.io.IOException;
+import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -43,6 +45,7 @@
import org.geotools.feature.type.AttributeTypeImpl;
import org.geotools.feature.type.GeometryDescriptorImpl;
import org.geotools.feature.type.GeometryTypeImpl;
+import org.geotools.image.test.ImageAssert;
import org.geotools.image.util.ImageUtilities;
import org.geotools.referencing.CRS;
import org.geotools.renderer.lite.RendererUtilities;
@@ -1454,6 +1457,52 @@ public void testScaleDPI() throws Exception {
assertEquals(66, this.legendProducer.h);
}
+ @org.junit.Test
+ public void testLegendRenderingSelectionInRule() throws Exception {
+ // test false set for rule
+ // works for a getLegendGraphicRequest
+ // only the yellow square should be displayed
+ GetLegendGraphicRequest req = new GetLegendGraphicRequest(null);
+ req.setWidth(20);
+ req.setHeight(20);
+
+ FeatureTypeInfo ftInfo =
+ getCatalog()
+ .getFeatureTypeByName(
+ MockData.MPOLYGONS.getNamespaceURI(),
+ MockData.MPOLYGONS.getLocalPart());
+
+ req.setLayer(ftInfo.getFeatureType());
+ req.setStyle(getCatalog().getStyleByName("styleWithLegendSelection").getStyle());
+
+ BufferedImage image = this.legendProducer.buildLegendGraphic(req);
+ URL result = getClass().getResource("./results/renderingSelectionOnRule.png");
+ ImageAssert.assertEquals(new File(result.toURI()), image, 50);
+ }
+
+ @org.junit.Test
+ public void testLegendRenderingSelectionInSymbolizer() throws Exception {
+ // test the false in a Symbolizer
+ // only the a blue square should be rendered
+ GetLegendGraphicRequest req = new GetLegendGraphicRequest(null);
+ req.setWidth(20);
+ req.setHeight(20);
+
+ FeatureTypeInfo ftInfo =
+ getCatalog()
+ .getFeatureTypeByName(
+ MockData.MPOLYGONS.getNamespaceURI(),
+ MockData.MPOLYGONS.getLocalPart());
+
+ req.setLayer(ftInfo.getFeatureType());
+ req.setStyle(
+ getCatalog().getStyleByName("styleWithLegendSelectionOnSymbolizer").getStyle());
+
+ BufferedImage image = this.legendProducer.buildLegendGraphic(req);
+ URL result = getClass().getResource("./results/renderingSelectionOnSymbolizer.png");
+ ImageAssert.assertEquals(new File(result.toURI()), image, 50);
+ }
+
/** */
private Style readSLD(String sldName) throws IOException {
StyleFactory styleFactory = CommonFactoryFinder.getStyleFactory(null);
diff --git a/src/wms/src/test/java/org/geoserver/wms/legendgraphic/JSONLegendGraphicOutputFormatTest.java b/src/wms/src/test/java/org/geoserver/wms/legendgraphic/JSONLegendGraphicOutputFormatTest.java
index 783a913b5f4..a5a7719954a 100644
--- a/src/wms/src/test/java/org/geoserver/wms/legendgraphic/JSONLegendGraphicOutputFormatTest.java
+++ b/src/wms/src/test/java/org/geoserver/wms/legendgraphic/JSONLegendGraphicOutputFormatTest.java
@@ -1662,6 +1662,66 @@ public void testDescreteRaster() throws Exception {
assertEquals("intervals", colormap.get(JSONLegendGraphicBuilder.COLORMAP_TYPE));
}
+
+ @org.junit.Test
+ public void testLegendSelectionInRule() throws Exception {
+ // test that the false works with the Json
+ // output
+ GetLegendGraphicRequest req = getRequest();
+ req.setWidth(20);
+ req.setHeight(20);
+
+ FeatureTypeInfo ftInfo =
+ getCatalog()
+ .getFeatureTypeByName(
+ MockData.MPOLYGONS.getNamespaceURI(),
+ MockData.MPOLYGONS.getLocalPart());
+
+ req.setLayer(ftInfo.getFeatureType());
+ req.setStyle(getCatalog().getStyleByName("styleWithLegendSelection").getStyle());
+ req.setFormat(JSONFormat);
+ JSONObject jsonLegend = this.legendProducer.buildLegendGraphic(req);
+ JSONArray legend = jsonLegend.getJSONArray(JSONLegendGraphicBuilder.LEGEND);
+ JSONArray rules = legend.getJSONObject(0).getJSONArray("rules");
+ // only one rule should be included in the output the other one has the renderingLegend
+ // option set to false.
+ assertEquals(1, rules.size());
+ String ruleName = rules.getJSONObject(0).getString("name");
+ assertEquals("nationalpark", ruleName);
+ }
+
+ @org.junit.Test
+ public void testLegendSelectionInSymbolizer() throws Exception {
+ // test that the false option set in
+ // symbolizer works
+ // avoiding the inclusion in the final output of one of the two symbolizers
+ GetLegendGraphicRequest req = getRequest();
+ req.setWidth(20);
+ req.setHeight(20);
+
+ FeatureTypeInfo ftInfo =
+ getCatalog()
+ .getFeatureTypeByName(
+ MockData.MPOLYGONS.getNamespaceURI(),
+ MockData.MPOLYGONS.getLocalPart());
+
+ req.setLayer(ftInfo.getFeatureType());
+ req.setStyle(
+ getCatalog().getStyleByName("styleWithLegendSelectionOnSymbolizer").getStyle());
+ req.setFormat(JSONFormat);
+ JSONObject jsonLegend = this.legendProducer.buildLegendGraphic(req);
+ JSONArray rules =
+ jsonLegend
+ .getJSONArray(JSONLegendGraphicBuilder.LEGEND)
+ .getJSONObject(0)
+ .getJSONArray("rules");
+ assertEquals(1, rules.size());
+ JSONArray symbolizers = rules.getJSONObject(0).getJSONArray("symbolizers");
+ // only one symbolizer of the two defined should be present in the final output
+ // the other one has the renderingLabel option set to false
+ assertEquals(1, symbolizers.size());
+ }
+
/** @param result */
private void assertNotEmpty(JSONObject result) {
assertNotNull(result);
diff --git a/src/wms/src/test/java/org/geoserver/wms/wms_1_1_1/GetMapIntegrationTest.java b/src/wms/src/test/java/org/geoserver/wms/wms_1_1_1/GetMapIntegrationTest.java
index 9b3a722598e..56711150c2f 100644
--- a/src/wms/src/test/java/org/geoserver/wms/wms_1_1_1/GetMapIntegrationTest.java
+++ b/src/wms/src/test/java/org/geoserver/wms/wms_1_1_1/GetMapIntegrationTest.java
@@ -230,6 +230,15 @@ protected void onSetUp(SystemTestData testData) throws Exception {
testData.addStyle(
"transparencyFillWidth", "transparencyFillStyleWidth.sld", getClass(), catalog);
+ testData.addStyle(
+ "namedPlacesRenderingSelection",
+ "NamedPlacesRenderingSelection.sld",
+ getClass(),
+ catalog);
+
+ testData.addStyle(
+ "lakesRenderingSelection", "LakesRenderingSelection.sld", getClass(), catalog);
+
Map properties = new HashMap<>();
properties.put(LayerProperty.STYLE, "raster");
testData.addRasterLayer(
@@ -2292,4 +2301,70 @@ public void testTransparencyFillMosaicWithWidth() throws Exception {
assertPixel(imageFill, i, 639, Color.RED);
}
}
+
+ @Test
+ public void testNamedPlacesRenderingSelection() throws Exception {
+ // We have two set of rules in the style one for the map having
+ // test false
+ // and one for the legend having test
+ // false
+ // the final result obtained with a legend decorator should show
+ // polygons and legend icons with same colors but icons without black border
+ Catalog catalog = getCatalog();
+ File layouts = getDataDirectory().findOrCreateDir("layouts");
+ URL layout = GetMapIntegrationTest.class.getResource("../test-layout-legend-image.xml");
+ FileUtils.copyURLToFile(layout, new File(layouts, "test-layout-legend-image.xml"));
+ LayerInfo places = catalog.getLayerByName(getLayerId(MockData.NAMED_PLACES));
+ StyleInfo placesStyle = catalog.getStyleByName("namedPlacesRenderingSelection");
+ LegendInfoImpl legend = new LegendInfoImpl();
+ legend.setFormat("image/png;charset=utf-8");
+ legend.setHeight(32);
+ legend.setWidth(32);
+ placesStyle.setLegend(legend);
+ catalog.save(placesStyle);
+ places.getStyles().add(placesStyle);
+ catalog.save(places);
+ String url =
+ "wms?LAYERS="
+ + places.getName()
+ + "&STYLES=namedPlacesRenderingSelection&FORMAT=image%2Fpng"
+ + "&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&SRS=EPSG%3A4326&WIDTH=256"
+ + "&HEIGHT=256&BBOX=0.0000,-0.0020,0.0035,0.0010&format_options=layout:test-layout-legend-image";
+ BufferedImage image = getAsImage(url, "image/png");
+ URL urlPng = getClass().getResource("renderingSelectionNamedPlaces.png");
+ ImageAssert.assertEquals(new File(urlPng.toURI()), image, 1300);
+ }
+
+ @Test
+ public void testLakesWithRenderingSelection() throws Exception {
+ // We have two featureTypeStyle in the style one for the map having
+ // test false
+ // and one for the legend having test
+ // false
+ // the final result obtained with a legend decorator should show
+ // polygon and legend icon with same color but icon without black border
+ Catalog catalog = getCatalog();
+ File layouts = getDataDirectory().findOrCreateDir("layouts");
+ URL layout = GetMapIntegrationTest.class.getResource("../test-layout-legend-image.xml");
+ FileUtils.copyURLToFile(layout, new File(layouts, "test-layout-legend-image.xml"));
+ LayerInfo lakes = catalog.getLayerByName(getLayerId(MockData.LAKES));
+ StyleInfo lakesStyle = catalog.getStyleByName("lakesRenderingSelection");
+ LegendInfoImpl legend = new LegendInfoImpl();
+ legend.setFormat("image/png;charset=utf-8");
+ legend.setHeight(32);
+ legend.setWidth(32);
+ lakesStyle.setLegend(legend);
+ catalog.save(lakesStyle);
+ lakes.getStyles().add(lakesStyle);
+ catalog.save(lakes);
+ String url =
+ "wms?LAYERS="
+ + lakes.getName()
+ + "&STYLES=lakesRenderingSelection&FORMAT=image%2Fpng"
+ + "&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&SRS=EPSG%3A4326&WIDTH=256"
+ + "&HEIGHT=256&BBOX=0.0000,-0.0020,0.0035,0.0010&format_options=layout:test-layout-legend-image";
+ BufferedImage image = getAsImage(url, "image/png");
+ URL urlPng = getClass().getResource("renderingSelectionLakes.png");
+ ImageAssert.assertEquals(new File(urlPng.toURI()), image, 1300);
+ }
}
diff --git a/src/wms/src/test/resources/org/geoserver/wms/legendgraphic/results/renderingSelectionOnRule.png b/src/wms/src/test/resources/org/geoserver/wms/legendgraphic/results/renderingSelectionOnRule.png
new file mode 100644
index 00000000000..b4f25eb3ad2
Binary files /dev/null and b/src/wms/src/test/resources/org/geoserver/wms/legendgraphic/results/renderingSelectionOnRule.png differ
diff --git a/src/wms/src/test/resources/org/geoserver/wms/legendgraphic/results/renderingSelectionOnSymbolizer.png b/src/wms/src/test/resources/org/geoserver/wms/legendgraphic/results/renderingSelectionOnSymbolizer.png
new file mode 100644
index 00000000000..3a74dadcc8f
Binary files /dev/null and b/src/wms/src/test/resources/org/geoserver/wms/legendgraphic/results/renderingSelectionOnSymbolizer.png differ
diff --git a/src/wms/src/test/resources/org/geoserver/wms/legendgraphic/styleWithLegendSelection.sld b/src/wms/src/test/resources/org/geoserver/wms/legendgraphic/styleWithLegendSelection.sld
new file mode 100644
index 00000000000..9677abef8d7
--- /dev/null
+++ b/src/wms/src/test/resources/org/geoserver/wms/legendgraphic/styleWithLegendSelection.sld
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+
+
+ tl 2010 08013 arealm
+
+
+ group 0
+ Feature
+ generic:geometry
+ simple
+
+
+ park
+
+
+ MTFCC
+ K2180
+
+
+ 500000.0
+
+
+
+
+
+
+ image/png
+
+
+
+
+
+ mapOnly
+
+
+
+ nationalpark
+
+
+ MTFCC
+ K2181
+
+
+ 500000.0
+
+
+
+
+
+ square
+
+ #ffff00
+
+
+ 6
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/wms/src/test/resources/org/geoserver/wms/legendgraphic/styleWithLegendSelectionOnSymbolizer.sld b/src/wms/src/test/resources/org/geoserver/wms/legendgraphic/styleWithLegendSelectionOnSymbolizer.sld
new file mode 100644
index 00000000000..5ce1a9ae286
--- /dev/null
+++ b/src/wms/src/test/resources/org/geoserver/wms/legendgraphic/styleWithLegendSelectionOnSymbolizer.sld
@@ -0,0 +1,86 @@
+
+
+
+
+
+
+
+
+ tl 2010 08013 arealm
+
+
+ group 0
+ Feature
+ generic:geometry
+ simple
+
+ nationalpark
+
+
+ MTFCC
+ K2181
+
+
+
+
+ #0099cc
+
+
+ #000000
+ 0.5
+
+
+
+
+
+
+
+ circle
+
+ #ffffff
+
+
+ 4
+
+
+ rotation
+ -1
+
+
+ 0.4
+
+
+
+
+
+
+
+ square
+
+ #ffff00
+
+
+ 6
+
+
+ rotation
+ -1
+
+
+ 0.4
+
+
+
+ mapOnly
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/wms/src/test/resources/org/geoserver/wms/wms_1_1_1/LakesRenderingSelection.sld b/src/wms/src/test/resources/org/geoserver/wms/wms_1_1_1/LakesRenderingSelection.sld
new file mode 100644
index 00000000000..6b00f8e6e60
--- /dev/null
+++ b/src/wms/src/test/resources/org/geoserver/wms/wms_1_1_1/LakesRenderingSelection.sld
@@ -0,0 +1,70 @@
+
+
+
+ Default Styler
+ Default Styler
+
+
+ Feature
+
+ name
+ Abstract
+ title
+
+
+
+ #4040C0
+
+
+ 1.0
+
+
+
+
+ #000000
+
+
+ butt
+
+
+ miter
+
+
+ 1
+
+
+ 1
+
+
+ 0
+
+
+
+
+ mapOnly
+
+
+ Feature
+
+ name
+ Abstract
+ title
+
+
+
+ #4040C0
+
+
+ 1.0
+
+
+
+
+ legendOnly
+
+
+
diff --git a/src/wms/src/test/resources/org/geoserver/wms/wms_1_1_1/NamedPlacesRenderingSelection.sld b/src/wms/src/test/resources/org/geoserver/wms/wms_1_1_1/NamedPlacesRenderingSelection.sld
new file mode 100644
index 00000000000..4e1526fcd5c
--- /dev/null
+++ b/src/wms/src/test/resources/org/geoserver/wms/wms_1_1_1/NamedPlacesRenderingSelection.sld
@@ -0,0 +1,98 @@
+
+
+
+ Default Styler
+ Default Styler
+
+
+ Feature
+
+ ashton
+ Ashton
+
+
+ NAME
+ Ashton
+
+
+
+
+
+ #AAAAAA
+
+
+
+
+ #000000
+
+
+
+ mapOnly
+
+
+ goose_island
+ Goose Island
+
+
+ NAME
+ Goose Island
+
+
+
+
+
+ #FF5733
+
+
+
+
+ #000000
+
+
+
+ mapOnly
+
+
+
+ ashton
+ Ashton
+
+
+ NAME
+ Ashton
+
+
+
+
+
+ #AAAAAA
+
+
+
+ legendOnly
+
+
+ goose_island
+ Goose Island
+
+
+ NAME
+ Goose Island
+
+
+
+
+
+ #FF5733
+
+
+
+ legendOnly
+
+
+
+
diff --git a/src/wms/src/test/resources/org/geoserver/wms/wms_1_1_1/renderingSelectionLakes.png b/src/wms/src/test/resources/org/geoserver/wms/wms_1_1_1/renderingSelectionLakes.png
new file mode 100644
index 00000000000..67f2f4c917a
Binary files /dev/null and b/src/wms/src/test/resources/org/geoserver/wms/wms_1_1_1/renderingSelectionLakes.png differ
diff --git a/src/wms/src/test/resources/org/geoserver/wms/wms_1_1_1/renderingSelectionNamedPlaces.png b/src/wms/src/test/resources/org/geoserver/wms/wms_1_1_1/renderingSelectionNamedPlaces.png
new file mode 100644
index 00000000000..bbb53bb080f
Binary files /dev/null and b/src/wms/src/test/resources/org/geoserver/wms/wms_1_1_1/renderingSelectionNamedPlaces.png differ