Geoserver反转单波段GeoTIFF的SLD标签后渲染失败问题求助
问题:GeoServer单波段GeoTIFF反转ColorMap排序后无法渲染及图例需求解决
问题背景
在GeoServer中发布单波段GeoTIFF图层,配置SLD样式可正常渲染,但将ColorMapEntry按quantity降序排列(反转高低标签)后图层无法渲染,同时需要图例呈现“high在上,low在下”的渐变样式。使用GeoServer版本2.22.0和2.18.3均存在该问题。
正常渲染的SLD代码
<?xml version="1.0" encoding="UTF-8"?> <StyledLayerDescriptor xmlns="http://www.opengis.net/sld" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" version="1.0.0" xmlns:sld="http://www.opengis.net/sld"> <UserLayer> <sld:LayerFeatureConstraints> <sld:FeatureTypeConstraint/> </sld:LayerFeatureConstraints> <sld:UserStyle> <sld:Name>one_band</sld:Name> <sld:FeatureTypeStyle> <sld:Rule> <sld:RasterSymbolizer> <sld:ChannelSelection> <sld:GrayChannel> <sld:SourceChannelName>1</sld:SourceChannelName> </sld:GrayChannel> </sld:ChannelSelection> <sld:ColorMap type="ramp"> <sld:ColorMapEntry quantity="777.09796142578125" label="low" color="#d7191c"/> <sld:ColorMapEntry quantity="1605.9965057373047" label="" color="#fdae61"/> <sld:ColorMapEntry quantity="2434.8950500488281" label="" color="#ffffbf"/> <sld:ColorMapEntry quantity="3263.7935943603516" label="" color="#abdda4"/> <sld:ColorMapEntry quantity="4092.692138671875" label="high" color="#2b83ba"/> </sld:ColorMap> </sld:RasterSymbolizer> </sld:Rule> </sld:FeatureTypeStyle> </sld:UserStyle> </UserLayer> </StyledLayerDescriptor>
反转后出错的ColorMap片段
<sld:ColorMapEntry quantity="4092.692138671875" label="high" color="#2b83ba"/> <sld:ColorMapEntry quantity="3263.7935943603516" label="" color="#abdda4"/> <sld:ColorMapEntry quantity="2434.8950500488281" label="" color="#ffffbf"/> <sld:ColorMapEntry quantity="1605.9965057373047" label="" color="#fdae61"/> <sld:ColorMapEntry quantity="777.09796142578125" label="low" color="#d7191c"/>
错误日志信息
java.lang.IllegalArgumentException: Provided ranges are overlapping:-Infinity : 4092.692138671875 / 777.0979614257812 : 4092.692138671875 at it.geosolutions.jaiext.piecewise.PiecewiseUtilities.domainElementsOverlap(PiecewiseUtilities.java:62) at it.geosolutions.jaiext.piecewise.DefaultDomain1D.init(DefaultDomain1D.java:181) at it.geosolutions.jaiext.piecewise.DefaultDomain1D.<init>(DefaultDomain1D.java:132) at it.geosolutions.jaiext.piecewise.DefaultPiecewiseTransform1D.<init>(DefaultPiecewiseTransform1D.java:42) at it.geosolutions.jaiext.classifier.LinearColorMap.initColorModel(LinearColorMap.java:398) at it.geosolutions.jaiext.classifier.LinearColorMap.hasGaps(LinearColorMap.java:519) at org.geotools.image.ImageWorker.classify(ImageWorker.java:5018) at org.geotools.renderer.lite.gridcoverage2d.ColorMapNode.execute(ColorMapNode.java:288) at org.geotools.renderer.lite.gridcoverage2d.ColorMapNode.execute(ColorMapNode.java:65) at org.geotools.renderer.lite.gridcoverage2d.StyleVisitorCoverageProcessingNodeAdapter$1.execute(StyleVisitorCoverageProcessingNodeAdapter.java:94) at org.geotools.renderer.lite.gridcoverage2d.BaseCoverageProcessingNode.checkExecuted(BaseCoverageProcessingNode.java:229) at org.geotools.renderer.lite.gridcoverage2d.BaseCoverageProcessingNode.getOutput(BaseCoverageProcessingNode.java:329) at org.geotools.renderer.lite.gridcoverage2d.BaseCoverageProcessingNode.getOutput(BaseCoverageProcessingNode.java:51) at org.geotools.renderer.lite.gridcoverage2d.StyleVisitorCoverageProcessingNodeAdapter.getOutput(StyleVisitorCoverageProcessingNodeAdapter.java:130) at org.geotools.renderer.lite.gridcoverage2d.ContrastEnhancementNode.execute(ContrastEnhancementNode.java:232) Caused by: org.geoserver.platform.ServiceException: org.geotools.coverage.processing.CoverageProcessingException: org.geotools.coverage.processing.CoverageProcessingException: org.geotools.coverage.processing.CoverageProcessingException: java.lang.IllegalArgumentException: Provided ranges are overlapping:-Infinity : 4092.692138671875 / 777.0979614257812 : 4092.692138671875
图层预览显示渲染错误,图例需求为顶部显示"high"、底部显示"low"的渐变样式。
问题原因及解决方案
原因分析
GeoServer的SLD解析器处理type="ramp"的ColorMap时,强制要求ColorMapEntry必须按quantity值升序排列。降序排列时,解析器默认第一个条目覆盖从负无穷到对应quantity的范围,后续条目的数值范围会与前面的范围重叠,触发报错中的“范围重叠”问题。
解决方案
要实现图例“high在上、low在下”的需求,无需反转ColorMapEntry的顺序,可通过以下方式调整:
方案1:自定义SLD图例顺序(推荐)
使用SLD 1.1.0及以上版本的Legend节点自定义图例展示顺序,保持图层渲染逻辑不变:
<?xml version="1.0" encoding="UTF-8"?> <StyledLayerDescriptor xmlns="http://www.opengis.net/sld" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" version="1.1.0"> <UserLayer> <LayerFeatureConstraints> <FeatureTypeConstraint/> </LayerFeatureConstraints> <UserStyle> <Name>one_band</Name> <FeatureTypeStyle> <Rule> <RasterSymbolizer> <ChannelSelection> <GrayChannel> <SourceChannelName>1</SourceChannelName> </GrayChannel> </ChannelSelection> <ColorMap type="ramp"> <ColorMapEntry quantity="777.09796142578125" label="low" color="#d7191c"/> <ColorMapEntry quantity="1605.9965057373047" label="" color="#fdae61"/> <ColorMapEntry quantity="2434.8950500488281" label="" color="#ffffbf"/> <ColorMapEntry quantity="3263.7935943603516" label="" color="#abdda4"/> <ColorMapEntry quantity="4092.692138671875" label="high" color="#2b83ba"/> </ColorMap> </RasterSymbolizer> </Rule> </FeatureTypeStyle> <!-- 自定义图例展示顺序 --> <Legend> <LegendSymbol> <Graphic> <Mark> <WellKnownName>rectangle</WellKnownName> <Fill> <CssParameter name="fill">#2b83ba</CssParameter> </Fill> </Mark> <Size>20</Size> </Graphic> <Label>high</Label> </LegendSymbol> <LegendSymbol> <Graphic> <Mark> <WellKnownName>rectangle</WellKnownName> <Fill> <CssParameter name="fill">#abdda4</CssParameter> </Fill> </Mark> <Size>20</Size> </Graphic> </LegendSymbol> <LegendSymbol> <Graphic> <Mark> <WellKnownName>rectangle</WellKnownName> <Fill> <CssParameter name="fill">#ffffbf</CssParameter> </Fill> </Mark> <Size>20</Size> </Graphic> </LegendSymbol> <LegendSymbol> <Graphic> <Mark> <WellKnownName>rectangle</WellKnownName> <Fill> <CssParameter name="fill">#fdae61</CssParameter> </Fill> </Mark> <Size>20</Size> </Graphic> </LegendSymbol> <LegendSymbol> <Graphic> <Mark> <WellKnownName>rectangle</WellKnownName> <Fill> <CssParameter name="fill">#d7191c</CssParameter> </Fill> </Mark> <Size>20</Size> </Graphic> <Label>low</Label> </LegendSymbol> </Legend> </UserStyle> </UserLayer> </StyledLayerDescriptor>
方案2:交换颜色值实现反向渐变(若需同步反转图层颜色)
如果需要同时让高值显示原低值的颜色、低值显示原高值的颜色,可保持ColorMapEntry升序,交换颜色参数:
<sld:ColorMap type="ramp"> <sld:ColorMapEntry quantity="777.09796142578125" label="low" color="#2b83ba"/> <sld:ColorMapEntry quantity="1605.9965057373047" label="" color="#abdda4"/> <sld:ColorMapEntry quantity="2434.8950500488281" label="" color="#ffffbf"/> <sld:ColorMapEntry quantity="3263.7935943603516" label="" color="#fdae61"/> <sld:ColorMapEntry quantity="4092.692138671875" label="high" color="#d7191c"/> </sld:ColorMap>
内容的提问来源于stack exchange,提问作者George
相关产品推荐
相关产品推荐

