效果对比
加载我们自定义图层时候,我们的面数据在地图上只显示部分位置,但是使用WMTS加载满屏瓦片会导致很多无效的瓦片请求,
具体报错为“ XX is out of range, min: XX max:XX”,简单的意思就是
WMTS服务通常只提供有限的瓦片范围,请求超出该范围的瓦片会导致此错误。
文档内容对应参数是extent,该参数不是必填项.
平铺网格的范围:XYZ平铺格线的原点是范围的左上角。如果未提供maxResolution,则网格的零级别由一个瓦片适合所提供范围的分辨率定义。
经过分析是WMTS没有设置参数extent,导致报错,虽然该请求不会导致使用,但是会发起很多无效请求和增加服务器负担。
依照上节文章导入openlayers(三)操作geoserver。
代码使用vue3+若依后台
首先新建一个工作空间’qg’,然后导入湖南省、广东省市级shp数据,
数据来源可以使用这篇文章中省市数据
https://blog.csdn.net/qq_46877697/article/details/121432672
加载效果,参数仅请求有效图层
比如我请求图层包括湖南、广东两个图层等。
我们不需要到Geoserver中查询每个extent参数,我们可以使用fetch()请求获取XML数据,把图层边框参数放到前端Map中保存。
相应参数是XML数据,请求参数是工作空间,可获取该工作空间下所有图层extent参数,代码如下
此时需要注意前端fetch()获取XML和WMTS获取图层的先后顺序,不然会导致extent参数
// 图层边框范围map,key图层命名Native Name,value图层边框4个点位数组
const layersExtentMap= new Map()
// 接口请求获取XXX作空间下,所有图层边框范围 最大最小xy
function postAllExtent(){
// 定义WMTS GetCapabilities请求URL
let url = 'http://'+ postUrl+'/geoserver/'+workPace+'/gwc/service/wmts?request=GetCapabilities';
// 发送WMTS GetCapabilities请求并解析响应
fetch(url).then(function(response) {
return response.text();
}).then(function(text) {
// 解析WMTS GetCapabilities响应
let parser = new WMTSCapabilities();
let result = parser.read(text);
// 获取指定图层的Native Bounding Box信息
let layers = result.Contents.Layer;
for (let i = 0, ii = layers.length; i < ii; ++i) {
let layer = layers[i];
// key图层命名Native Name,value图层边框4个点位数组
layersExtentMap.set(layer.Identifier,layer.WGS84BoundingBox)
}
});
}
此时可以优化WTMS请求方式
let tileGrid = new WMTSTileGrid({
//设置 边框范围 //TODO
// extent: [109.650790017,20.21417992,117.31371173,25.5196163260001],
extent:layersExtentMap.get(layerData.layerName),
origin: getTopLeft(projectionExtent),
matrixIds: ['EPSG:4326:0', 'EPSG:4326:1', 'EPSG:4326:2', 'EPSG:4326:3',
'EPSG:4326:4', 'EPSG:4326:5', 'EPSG:4326:6', 'EPSG:4326:7', 'EPSG:4326:8',
'EPSG:4326:9', 'EPSG:4326:10', 'EPSG:4326:11', 'EPSG:4326:12', 'EPSG:4326:13',
'EPSG:4326:14', 'EPSG:4326:15', 'EPSG:4326:16', 'EPSG:4326:17', 'EPSG:4326:18',
'EPSG:4326:19', 'EPSG:4326:20', 'EPSG:4326:21'
],
resolutions: [0.703125, 0.3515625, 0.17578125, 0.087890625, 0.0439453125, 0.02197265625, 0.010986328125, 0.0054931640625, 0.00274658203125, 0.001373291015625, 6.866455078125E-4, 3.4332275390625E-4, 1.71661376953125E-4, 8.58306884765625E-5, 4.291534423828125E-5, 2.1457672119140625E-5, 1.0728836059570312E-5, 5.364418029785156E-6, 2.682209014892578E-6, 1.341104507446289E-6, 6.705522537231445E-7, 3.3527612686157227E-7],
wrapX: true
})
这里需要使用openlayers中的Raster对象中的operation方法,该方法可以在使用wmts请求获取到瓦片图片后修改图片RGB颜色。
import { Raster as RasterSource } from 'ol/source';
即
let postLayerData = [{
layerName : 'hn',
colour :[186,148,209]
},{
layerName : 'gd',
colour :[244,234,43]
}]
layerData.colour = [XXX,XXX,XXX]
const raster = new RasterSource({
sources: [
//传入图层,这里是天地图矢量图或者天地图矢量注记
temSource,
],
//这里设置为image类型,与官方示例不同,优化速度
operationType: 'image',
operation: function (pixels, data) {
//执行颜色转换方法,注意,这里的方法需要使用lib引入进来才可以使用
for (let i = 0; i < pixels[0].data.length; i += 4) {
//将rgb的值
pixels[0].data[i] = data.layerRgb[0]; //R
pixels[0].data[i + 1] = data.layerRgb[1];//G
pixels[0].data[i + 2] = data.layerRgb[2];//B
}
return pixels[0];
},
//线程数量
threads: 10,
//允许operation使用外部方法
});
raster.on('beforeoperations', function (event) {
const data = event.data;
data['layerRgb'] = layerData.colour
})
geoserver中有一个样式功能,我们可以看到一个默认的polygon(面样式)灰白色
我们新建一个样式,命名和相应图层保持一致
填写XML文件,其中
面-填充颜色
#FFF89A
边框线-颜色和粗细
#12a2ee
0.2
<?xml version="1.0" encoding="ISO-8859-1"?>
<StyledLayerDescriptor version="1.0.0"
xsi:schemaLocation="http://www.opengis.net/sld StyledLayerDescriptor.xsd"
xmlns="http://www.opengis.net/sld"
xmlns:ogc="http://www.opengis.net/ogc"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<!-- a named layer is the basic building block of an sld document -->
<NamedLayer>
<Name>Default Polygon</Name>
<UserStyle>
<!-- they have names, titles and abstracts -->
<Title>Grey Polygon</Title>
<Abstract>A sample style that just prints out a grey interior with a black outline</Abstract>
<!-- FeatureTypeStyles describe how to render different features -->
<!-- a feature type for polygons -->
<FeatureTypeStyle>
<!--FeatureTypeName>Feature</FeatureTypeName-->
<Rule>
<Name>Rule 1</Name>
<Title>Grey Fill and Black Outline</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">#FFF89A</CssParameter>
</Fill>
<Stroke>
<CssParameter name="stroke">#12a2ee</CssParameter>
<CssParameter name="stroke-width">0.2</CssParameter>
</Stroke>
</PolygonSymbolizer>
</Rule>
</FeatureTypeStyle>
</UserStyle>
</NamedLayer>
</StyledLayerDescriptor>
此时在geoserver中预览图层效果