openlayer通过SLD改变图层Feature的样式


GeoServer能够提供WMS服务,采用SLD来渲染地图样式。如何动态地改变地图的样式,来完成一些特殊的功能呢?可以参照demo中的wms-sld_body示例,做法如下:(下列代码是在OpenLayers中的js代码)


    var sld = "<StyledLayerDescriptor version="1.0.0" xmlns="http://www.opengis.net/sld" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/sld [url]http://schemas.opengeospatial.net/sld/1.0.0/StyledLayerDescriptor.xsd[/url]"><NamedLayer><Name>AAA207</Name><UserStyle><FeatureTypeStyle><Rule><Filter><PropertyIsEqualTo><PropertyName>DIENSTNAAM</PropertyName><Literal>%literal%</Literal></PropertyIsEqualTo></Filter><PolygonSymbolizer><Fill><CssParameter name="fill">#000099</CssParameter></Fill></PolygonSymbolizer></Rule><Rule><ElseFilter/><PolygonSymbolizer><Fill><CssParameter name="fill">#bfcaea</CssParameter></Fill><Stroke><CssParameter name="stroke">#a6c6ff</CssParameter><CssParameter name="stroke-width">1.0</CssParameter></Stroke></PolygonSymbolizer></Rule></FeatureTypeStyle></UserStyle></NamedLayer></StyledLayerDescriptor>";

        layer = new OpenLayers.Layer.WMS.Untiled( "Beheersgebieden", "http://www.rijkswaterstaat.nl/services/geoservices/basispakket/grenzen?", {layers: "AAA207", "format":"image/gif", "transparent":"true"}, {"numZoomLevels": 1, "ratio":1, isBaseLayer: true} );    


       newsld = sld.replace("%literal%",  【某个属性值】);

      layer.mergeNewParams({"sld_body":newsld });

layer.mergeNewParams({"sld_body":newsld });

这里有一个致命的缺陷就是SLD作为URL参数传递到服务器,很容易超过URL长度限制。

 

 

 

 

在geoserver中动态改变SLD的过程:
1.获得原始的SLD文件,这个SLD文件可以是geoserver里的demo,也可以使自己构造的,只要符合ogc规范可以在geoserver里应用到layer上,openlayers有OpenLayers.loadURL这个函数可以用,java里面可以使用filereader读取文件;

2.根据自己的需要修改SLD文件里的参数,这个可以在js或JAVA里进行,就是将文件内容读取为字符串,对字符串进行操作;
3.将修改好的SLD文件(后缀可以是sld或xml,geoserver都可以加载的)加载到相关的layer上,openlayers里可以使用OpenLayers.Layer.WMS这个函数(也可以使用layer.mergeNewParams这个函数,不过sld的长度会受到限制)。

在使用OpenLayers.Layer.WMS这个函数时,其参数的设置很重要.

mapa = new OpenLayers.Map(‘map’, options);

// setup tiled layer SLD: “http://deltha:8080/SLD/mapa.sld”,

faro= new OpenLayers.Layer.WMS(
“topp:mapacuba – Tiled”, “http://deltha:8080/geoserver/wms”,
{
layers: ‘topp:faro‘,
styles: ”,
height: ‘300’,
width: ‘800’,
srs: ‘EPSG:4267’,
format: ‘image/png’,
tiled: ‘true’,
tilesOrigin : “-85.49711392680179,19.65266328193469”
},
{buffer: 0}
);

map.addLayers([faro]);

mapa.mergeNewParams({sld:’http://localhost:8080/SLD/faros.sld’});
mapa.redraw();

这样设置是不会成功的,地图可以显示,但是通过mapa.mergeNewParams({sld:’http://localhost:8080/SLD/faros.sld’})和mapa.redraw()却无法更改地图的sld。

因为wms请求要么就需要layers和styles两个参数,要么就只需要sld或sld_body中的一个参数。

上面的例子可以这样设置:

faro= new OpenLayers.Layer.WMS(
“topp:mapacuba – Tiled”, “http://deltha:8080/geoserver/wms”,
{
//layers: ‘topp:faro,
//styles: ”,
sld_body:
‘<StyledLayerDescriptor   version=1.0.0”><UserLayer><Name>topp:faro</Name><UserStyle><Name>UserSelection</Name><FeatureTypeStyle><Rule><Filter 
xmlns:gml=“http://www.opengis.net/gml”><PropertyIsEqualTo><PropertyName>STATE_NAME</PropertyName><Literal>Illinois</Literal></PropertyIsEqualTo></Filter><PolygonSymbolizer><Fill><CssParameter 
name=“fill”>#FF0000</CssParameter></Fill></PolygonSymbolizer></Rule><Rule><LineSymbolizer><Stroke/></LineSymbolizer></Rule></FeatureTypeStyle></UserStyle></UserLayer></StyledLayerDescriptor>’,            //这里的SLD_BODY为XML里的原格式,不能变
height: ‘300’,
width: ‘800’,
srs: ‘EPSG:4267’,
format: ‘image/png’,
tiled: ‘true’,
tilesOrigin : “-85.49711392680179,19.65266328193469”
},
{buffer: 0}
);

map.addLayers([faro]);

这样只需要提前修改sld_body中的内容就可以修改地图的sld。如果有一个sld文件,可以用sld:’http://localhost:8080/SLD/faros.sld’替换sld_body这个参数就行了。

转载自:https://blog.csdn.net/xiaoyaoyunzi/article/details/8279558

You may also like...