Openlayers(四)WMTS请求优化和图层颜色更改

Openlayers(四)WMTS请求优化和图层颜色更改

目标

  • 优化WMTS请求
  • WMTS前端修改图层颜色

效果对比

优化后
Openlayers(四)WMTS请求优化和图层颜色更改_第1张图片
原图
Openlayers(四)WMTS请求优化和图层颜色更改_第2张图片

加载我们自定义图层时候,我们的面数据在地图上只显示部分位置,但是使用WMTS加载满屏瓦片会导致很多无效的瓦片请求,

具体报错为“ XX is out of range, min: XX max:XX”,简单的意思就是

WMTS服务通常只提供有限的瓦片范围,请求超出该范围的瓦片会导致此错误。

Openlayers(四)WMTS请求优化和图层颜色更改_第3张图片

Openlayers(四)WMTS请求优化和图层颜色更改_第4张图片

文档内容对应参数是extent,该参数不是必填项.
平铺网格的范围:XYZ平铺格线的原点是范围的左上角。如果未提供maxResolution,则网格的零级别由一个瓦片适合所提供范围的分辨率定义。
经过分析是WMTS没有设置参数extent,导致报错,虽然该请求不会导致使用,但是会发起很多无效请求和增加服务器负担。
Openlayers(四)WMTS请求优化和图层颜色更改_第5张图片

这里的数据其实是对应Geoserver图层中边框的XY参数
Openlayers(四)WMTS请求优化和图层颜色更改_第6张图片

1.前期准备

依照上节文章导入openlayers(三)操作geoserver。
代码使用vue3+若依后台

首先新建一个工作空间’qg’,然后导入湖南省、广东省市级shp数据,
数据来源可以使用这篇文章中省市数据

https://blog.csdn.net/qq_46877697/article/details/121432672

Openlayers(四)WMTS请求优化和图层颜色更改_第7张图片

2.代码分析

前端代码使用正确的extent参数
Openlayers(四)WMTS请求优化和图层颜色更改_第8张图片

加载效果,参数仅请求有效图层

Openlayers(四)WMTS请求优化和图层颜色更改_第9张图片

3.多图层请求

比如我请求图层包括湖南、广东两个图层等。

我们不需要到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
    })

4.图层颜色更改之前端修改

这里需要使用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
    })

Openlayers(四)WMTS请求优化和图层颜色更改_第10张图片

5.图层颜色更改之Geoserver修改

geoserver中有一个样式功能,我们可以看到一个默认的polygon(面样式)灰白色
Openlayers(四)WMTS请求优化和图层颜色更改_第11张图片

打开一个图层预览,他默认也是这个样式
Openlayers(四)WMTS请求优化和图层颜色更改_第12张图片

我们新建一个样式,命名和相应图层保持一致

Openlayers(四)WMTS请求优化和图层颜色更改_第13张图片

填写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中预览图层效果

Openlayers(四)WMTS请求优化和图层颜色更改_第14张图片
前端使用时候,如wmts请求图层时候可以添加STYLE参数。

你可能感兴趣的:(前端,javascript,java)