需求背景

最近开发的系统需要能够加载用户手动填写的WMTS服务,希望用户输入一个URL地址后自动加载对应的WMTS服务,不用填写额外的参数,并且很用用户也可能不知道例如layertileMatrixSetID 这些参数怎么填,而且很有可能填错,因此,需要解析一下WMTS服务的xml文件。

cesium需要的参数

cesiumWebMapTileServiceImageryProvider构造函数至少需要urllayertileMatrixSetID 这些参数,其他的styletileMatrixLabelstilingScheme则可以省略,通过研究WMTS服务,发现还可以解析出服务的投影方式以及中心wgs84坐标,这些也可以顺便获取。

解析xml

wmts服务的定义是一个xml文件,例如 arcgis的https://localhost:6443/arcgis/rest/services/honglianhu/ezhou_land/MapServer/WMTS/1.0.0/WMTSCapabilities.xml 以及 geoserver的 http://localhost:8080/geoserver/gwc/service/wmts?REQUEST=GetCapabilities地址,目前只针对这2种服务地址进行解析。

至于wmts的描述文件格式大家可以自行了解,这里只贴一下解析的代码

选择了xml-js 这个库进行解析,首先通过wmts服务描述文件xml地址,获取文本进行解析,去掉多余的部分

var option = {ignoreDeclaration: true,compact: true,trim: true,ignoreInstruction: true,ignoreComment: true,ignoreCdata: true,ignoreDoctype: true
}
// 把_text属性直接改为值,见xml-js issue
function 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文件
function getWMTSParamsFromUrl(xmlUrl) {return new Promise((resolve, reject) => {fetch(xmlUrl).then(res => res.text()).then(res => {try {// 解析xml为JS对象var xmlObj = xml2js(res, { ...option, textFn: RemoveJsonTextAttribute })var info = getWMTSInfo(xmlObj)resolve(info)} catch (e) {console.log(e);resolve()}}).catch(() => {resolve()})})
}

然后获取xml中所需的属性:

// 获取服务需要的参数
function getWMTSInfo(obj) {const WMTSXML = 'http://www.opengis.net/wmts/1.0'const wmstList = []if (obj.Capabilities) {const { _attributes, Contents } = obj.Capabilitiesif (_attributes?.xmlns !== WMTSXML) {return}const { Layer, TileMatrixSet } = Contentsif (!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]info.tileMatrixSetID = tileSet['ows:Identifier']info.crs = tileSet['ows:SupportedCRS']info.tileMatrixLabels = tileSet.TileMatrix.map(s => s['ows:Identifier'])let LayerInfo = Layerif (!Array.isArray(LayerInfo)) {LayerInfo = [LayerInfo]}LayerInfo.forEach(layer => {let resourceURL = layer?.ResourceURLif (!Array.isArray(resourceURL)) {resourceURL = [resourceURL]}info.format = 'image/png' || layer?.Formatconst 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?.templateinfo.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 = centerwmstList.push({ ...info })})return wmstList}
}

需要注意的是arcgis的wmts服务是一个服务一个xml地址,而geoserver的wmts是所有服务都在一个xml地址,因此解析的时候需要判断是否是一个数组,返回的结果也将是一个数组,

解析出来的结果示例如下:

[{url: "https://localhost:6443/arcgis/rest/services/honglianhu/ezhou_land/MapServer/WMTS/tile/1.0.0/honglianhu_ezhou_land/{Style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.png",layer: "honglianhu_ezhou_land",style: "default",tileMatrixSetID: "default028mm",format: "image/png",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"],crs: "urn:ogc:def:crs:EPSG::3857",center: [114.59548160858947, 30.448104919756297]}
]

在cesium中直接使用:

const viewer = new Cesium.Viewer('app')var xmlUrl = 'https://localhost:6443/arcgis/rest/services/honglianhu/ezhou_land/MapServer/WMTS/1.0.0/WMTSCapabilities.xml'
getWMTSParamsFromUrl(xmlUrl).then(info => {if (info) {info.forEach(item => {const { url, center, crs, ...other } = itemif (url) {const provider = new Cesium.WebMapTileServiceImageryProvider({url,...other,tilingScheme: crs.endsWith('4326') ? new Cesium.GeographicTilingScheme() : new Cesium.WebMercatorTilingScheme()})var wmts = new Cesium.ImageryLayer(provider)viewer.imageryLayers.add(wmts)viewer.camera.flyTo({destination: new Cesium.Cartesian3.fromDegrees(center[0], center[1], 1000)})}})}
})

再也不用自己找参数了,完美解决问题!

以上几个部分的代码可以直接拷贝在一起使用,亲测有效。

WMTS服务参数解析以及Cesium加载WMTS服务相关推荐

  1. Cesium:加载GeoServer-WMS服务

    Cesium:加载GeoServer-WMS服务 WMS服务与GeoServer发布 Cesium:加载WMS服务 Cesium接口:WebMapServiceImageryProvider Cesi ...

  2. cesium加载wmts服务

    cesium加载wmts服务 进入切片图层,选择一个图层点击Seed/Truncate,这里我选择的是topp:states 根据自己需求选择缩放层级然后点击提交 进入任务列表的页面,点击刷新列表查看 ...

  3. cesium加载wsm服务

    cesium加载wsm服务 点击openLayers并打开调试窗口 vue中 const viewer = new Cesium.Viewer("cesiumContainer", ...

  4. Cesium加载地图服务

    一.加载矢量地图 1.加载geoserver发布的矢量数据 api:viewer.imageryLayers.addImageryProvider viewer.imageryLayers.addIm ...

  5. cesium加载OGC服务

    WMTS服务 let url ='http://localhost:16080/geoserver/gwc/service/wmts/rest/homework:Town/{style}/{TileM ...

  6. Geoserver 发布wmts服务,以及cesium加载发布的wmts服务

    WMTS提供了一种采用预定义图块方法发布数字地图服务的标准化解决方案.WMTS弥补了WMS不能提供分块地图的不足.WMS针对提供可定制地图的服务,是一个动态数据或用户定制地图(需结合SLD标准)的理想 ...

  7. cesium加载wms、wmts、tms、wfs服务

    目录 cesium加载wms服务 cesium加载wmts服务 cesium加载tms服务 cesium加载wfs服务 首先引入cesium.js,参考:https://blog.csdn.net/q ...

  8. React框架+cesium加载GeoWebCache发布4326WMTS服务的ArcGIS切片图层请求400问题

    前言 由于业务的要求,需要在前端展示个性化美化的地图底图,尝试使用mapbox的配置和其它方案去搞Geojson格式的,但是个性化比较麻烦,而且门槛较高,不好配置,于是本菜鸟使用arcMap来美化底图 ...

  9. (二十)ArcGIS JS 加载WMTS服务(超图示例)

    前言 在前一篇中说到我们可以通过加载WMS服务解决用ArcGIS API加载超图发布的服务,但是WMS服务在加载效率上是低于切片服务的,加上超图的IServer,无力吐槽,所以,在加载速度的要求下,切 ...

最新文章

  1. 用循环队列模拟银行窗口排队_银行告诉你什么是无锁队列
  2. 下一代CAN通信技术CAN XL简介
  3. SpringMVC注解驱动开发
  4. PDF免费转word方法
  5. linux定时任务_linux定时任务cron HelloWorld
  6. mvc路由原理 php_PHP实战002:CodeIgniter安装和入门使用
  7. Project Euler 3 Largest prime factor
  8. web框架--MVC、MTV
  9. 元气骑士没有手柄怎么解锁机器人_元气骑士机器人怎么解锁?机器人获取方式和技能介绍...
  10. 键盘快捷键锁定计算机,用于锁定键盘的键盘快捷键
  11. 双网卡同时上内外网的解决方法
  12. docker 两行命令启动 qq音乐api服务器 和 网易云音乐api服务器
  13. 微信小程序---wxss模板样式
  14. android nfc 启动流程,android-NFC-如何使用NDEF_DISCOVERED启动应用程序
  15. 3、移植UBOOT之新建单板-时钟-SDRAM-串口
  16. 京东接口对接流程(以下举例物流接口):
  17. 2021/03/27 K8S集群日志与监控
  18. spring中tx:advice/tx:advice是什么意思?作用是什么?谁能简单说下
  19. Doris Weekly FAQ】2021.07.19~2021.08.01
  20. Ajax异步请求的步骤

热门文章

  1. MySql中报错:java.sql.SQLException: Incorrect string value: '\xF0\x9F\x90\xBB' for column
  2. Android App常规测试内容
  3. 教育OA如何选型?教育OA系统选型必看技巧
  4. 从零开始机器学习-03
  5. Android HVGA,QVGA等的英文全拼简介
  6. jdbc连接oracle_JDBC连接拒绝连接,建立连接失败
  7. spring cloud 建一个服务消费者client-ribbon
  8. 菲律宾计算机读研含金量,告诉学妹学哥菲律宾留学选择哪个学校含金量高
  9. 携手2019CCF大数据与计算智能大赛,蓄力视频版权检测新突破
  10. Revit二次开发实现BIM盈利(以橄榄山快模为例解说) 视频讲座下载