Cesium加载Supermap的wmts和wmts100服务

文章讲述了作者在使用Cesium加载SuperMapWMTS服务时遇到的加载异常和白屏问题,通过查阅文档和调整关键参数如layer、tileMatrixSetID、format以及设置tilingScheme来解决,并介绍了如何使用xml-js自动解析XML获取参数的过程,最后解决了wmts100服务加载400问题。
摘要由CSDN通过智能技术生成

最近使用cesium 加载supermap的wmts 服务,多次遇到加载异常与白页面问题,纠结好久最后才搞定[特此记录]

1、首先找到方法加载wmts 的api 文档

官方提示使用WebMapTileServiceImageryProvider加载wmts
官方加载方法

2、然后编辑加载代码

			//1.新建ImageryProvider
				let wmtsImageryProvider = new Cesium.WebMapTileServiceImageryProvider({
					url: 'http://localhost:8080/iserver/services/agscachev-Layers/wmts', //服务地址,如:'http://localhost:8080/geoserver/gwc/service/wmts'
					layer: 'Layers', //图层名称,如:'tasmania'
					style: 'default',
					format: 'image/png',
					tileMatrixSetID: 'ChinaPublicServices_Layers',
					 tileMatrixLabels: ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23"],
					tilingScheme: new Cesium.GeographicTilingScheme({ 
						numberOfLevelZeroTilesX: 2,
						numberOfLevelZeroTilesY: 1
					}),
				});

				viewer.imageryLayers.addImageryProvider(wmtsImageryProvider);

【重点】其中查找layer 、tileMatrixSetID、format相当关键,当初就是因为这个参数没对一直400

还有一个是tilingScheme一定要给,否则加载后一直白页面

手动查找方法:网页打开http://localhost:8080/iserver/services/agscachev-Layers/wmts如下分别找到layer 、tileMatrixSetID、format值填入以上方法中
查找layer

3、测试加载结果

测试加载结果
测试wmts 已经加载成功,但是手动查找wmts 参数的确不利于生产,那有没有自动获取参数的方法呢?答案时有的,我们可以使用大佬的 xml-js吧xml 解析为json 获取想要的参数即可

4、自动解析xml

我们参考这个博客将xml解析为json建一个util.js

const xmlContent = require("xml-js");
/**
 * 将xml转换为json
 */
const TransferXmlToJson = {
  // 把_text属性直接改为值,见xml-js issue
  RemoveJsonTextAttribute(value, parentElement) {
    try {
      var keyNo = Object.keys(parentElement._parent).length;
      var keyName = Object.keys(parentElement._parent)[keyNo - 1];
      parentElement._parent[keyName] = value;
    } catch (e) {}
  },
  // 以文本方式获取xml文件
  getWMTSParamsFromUrl(xmlUrl) {
    var option = {
      ignoreDeclaration: true,
      compact: true,
      trim: true,
      ignoreInstruction: true,
      ignoreComment: true,
      ignoreCdata: true,
      ignoreDoctype: true,
    };
    return new Promise((resolve, reject) => {
      fetch(xmlUrl)
        .then((res) => res.text())
        .then((res) => {
          try {
            // 解析xml为JS对象
            var xmlObj = xmlContent.xml2js(res, { ...option, textFn: this.RemoveJsonTextAttribute });
            var info = this.getWMTSInfo(xmlObj);
            resolve(info);
          } catch (e) {
            console.error(e);
            resolve(null);
          }
        })
        .catch((e) => {
          console.error(e);
          resolve(null);
        });
    });
  },
  // 获取服务需要的参数
  getWMTSInfo(obj) {
    const WMTSXML = "http://www.opengis.net/wmts/1.0";
    const wmstList = [];
    if (obj.Capabilities) {
      const { _attributes, Contents } = obj.Capabilities;
      if (_attributes?.xmlns !== WMTSXML) {
        return;
      }
      const { Layer, TileMatrixSet } = Contents;
      if (!Layer || !TileMatrixSet) {
        return;
      }
      const info = {
        url: null,
        layer: null,
        style: null,
        tileMatrixSetID: null,
        format: null,
        tileMatrixLabels: null,
        crs: null,
        center: null,
      };

      const tileSet = TileMatrixSet[0] || TileMatrixSet;
      info.tileMatrixSetID = tileSet["ows:Identifier"];
      info.crs = tileSet["ows:SupportedCRS"];
      info.tileMatrixLabels = tileSet.TileMatrix.map((s) => s["ows:Identifier"]);

      let LayerInfo = Layer;

      if (!Array.isArray(LayerInfo)) {
        LayerInfo = [LayerInfo];
      }

      LayerInfo.forEach((layer) => {
        let resourceURL = layer?.ResourceURL;
        if (!Array.isArray(resourceURL)) {
          resourceURL = [resourceURL];
        }
        info.format = "image/png" || layer?.Format;
        const resourceURLItem = resourceURL.filter((s) => s._attributes.resourceType === "tile");
        let pngResource = resourceURLItem.find((s) => s._attributes.format.endsWith("png")) || resourceURLItem[0];
        if (pngResource) {
          info.url = pngResource?._attributes?.template;
          info.format = pngResource?._attributes?.format;
        }
        info.layer = layer["ows:Identifier"];
        info.style = layer.Style["ows:Identifier"];

        const wgsBox = layer["ows:WGS84BoundingBox"];
        const lower = wgsBox["ows:LowerCorner"].split(" ").map((s) => Number(s));
        const upper = wgsBox["ows:UpperCorner"].split(" ").map((s) => Number(s));
        const center = [lower[0] + (upper[0] - lower[0]) / 2, lower[1] + (upper[1] - lower[1]) / 2];
        info.center = center;
        wmstList.push({ ...info });
      });

      return wmstList;
    }
  },
};

然后直接调用即可

import { TransferXmlToJson } from '@/utils/index'


const serviceUrl ='http://localhost:8080/iserver/services/agscachev-Layers/wmts';

  TransferXmlToJson.getWMTSParamsFromUrl(serviceUrl).then((rxml) => {
            if (rxml) {
             console.log("获取解析结果:",rxml);
            }
          });

🆗现在任何wmts服务都可以自动读取参数加载服务了

5、修复wmts100加载时400问题

  • fix:wmts100服务加载400问题,

今日(2024/01/25)发现通过

info.tileMatrixSetID = tileSet["ows:Identifier"];

来获取tileMatrixSetID 加载wmts100老是提示400
看这是我的wmts100服务的xml文件
xml
通过tileSet[“ows:Identifier”]获取到的 tileMatrixSetID 值为Custom_Layers

加载代码大概如下

      let wmtsImageryProvider = new Cesium.WebMapTileServiceImageryProvider({
        url: 'http://localhost:8080/iserver/services/map-agscache-Layers/wmts100',
        layer: 'Layers', 
        style: 'default',
        format: 'image/png',
        minimumLevel: 0,
        maximumLevel: 20,
        tileMatrixSetID: 'Custom_Layers',
        tileMatrixLabels: ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20"],
        tilingScheme: new Cesium.GeographicTilingScheme({
          numberOfLevelZeroTilesX: 2,
          numberOfLevelZeroTilesY: 1
        }),
      });
      viewer.imageryLayers.addImageryProvider(wmtsImageryProvider);

最后运行都是400
400
400
为了排查错误于是手动去找TileMatrixSet,却 发现了wmts100中存在多个TileMatrixSet节点
多个TileMatrixSet
而我们通过"ows:Identifier"获取的却是第一个TileMatrixSet节点的值,没办法就一个个手动获取测试
最后发现只有ChinaPublicServicesCGCS2000_Layers 可以加载


于是我们就把 上面第自动解析xml中的

      const tileSet = TileMatrixSet[0] || TileMatrixSet;
      info.tileMatrixSetID = tileSet["ows:Identifier"];

改成

      const tileSet = Array.isArray(TileMatrixSet) ? TileMatrixSet[TileMatrixSet.length - 1] : TileMatrixSet;
      info.tileMatrixSetID = tileSet["ows:Identifier"];

就可以了


预览

why?为啥换个TileMatrixSet就可以了呢?这里回顾下刚开始遇到问题的时候,是否忘记了查看提示,如下

问题
这个提示是不是表明了矩阵有问题他,就是TileMatrixSet 错误了呢?但是目前任然不明白为什么wmts100会有那么多个其他类型的矩阵,是为了兼容其他的服务加载?或许时我配置参数不正确加载都没成功罢了,有知道的朋友请告知。

好了到此为止暂时解决了wmts100加载400问题

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奔跑的痕迹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值