cesium按需下载天地图瓦片,进行离线加载

您所在的位置:网站首页 有什么离线地图 cesium按需下载天地图瓦片,进行离线加载

cesium按需下载天地图瓦片,进行离线加载

2024-07-05 04:13:20| 来源: 网络整理| 查看: 265

使用场景

在某些特定的需求中,需要对瓦片资源进行离线部署,这个时候在线的瓦片服务就满足不了这类需求,于是就需要将瓦片图加载下来,这种好处就是不需要后台部署瓦片服务也不需要依赖第三方瓦片服务器,还能实现指定的某块区域的瓦片进行加载。之前写了一篇关于arcGis的瓦片加载,由于它跟天地图的下载方式还不太一样,这里就详细写一篇关于天地图的瓦片下载案例

 

cesium版本要求

本案例是基于cesium 1.95版本实现

实现的思路

1.使用cesium加载在线天地图瓦片

2.重写cesium中ImageryProvider的loadImage函数,将加载到的瓦片通过image的方式生成并保存到集合中,集合上保存的是每张瓦片的http地址

3.写一个函数将集合中瓦片下载到本地,注意瓦片的命名

4.搭建nodejs服务来实现图片的级别设置和对应的瓦片图

5.影像地图和标注需要分别下载

具体实现 1.初始化cesium init(el) { Cesium.Ion.defaultAccessToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIyMGFhNTBjMi1kNGM4LTRjYWQtYWZhMC05ZTJhY2U2Y2U0ODkiLCJpZCI6MzE2MzYsImlhdCI6MTY2MDcxODA4NX0.jljbTXZPBaeSdsU7vuWg8V01oV1-fEA_qUa_08wXvq0" this.viewer = new Cesium.Viewer(el, { animation: false, //是否显示动画控件,左下角仪表 baseLayerPicker: false, //是否显示图层选择器 fullscreenButton: false, //是否显示全屏按钮 geocoder: false, //是否显示geocoder小器件,右上角查询按钮 homeButton: false, //是否显示Home按钮 infoBox: false, //是否显示信息框 sceneModePicker: false, //是否显示3D/2D选择器 scene3DOnly: true, //如果设置为true,则所有几何图形以3D模式绘制以节约GPU资源 selectionIndicator: false, //是否显示选取指示器组件 timeline: false, //是否显示时间轴 navigationHelpButton: false, //是否显示右上角的帮助按钮 baselLayerPicker: false, // 将图层选择的控件关掉,才能添加其他影像数据 shadows: true, //是否显示背影 shouldAnimate: true, skyBox: new Cesium.SkyBox({ sources: { positiveX: "../public/skybox/px.png", negativeX: "../public/skybox/nx.png", positiveY: "../public/skybox/pz.png", negativeY: "../public/skybox/nz.png", positiveZ: "../public/skybox/py.png", negativeZ: "../public/skybox/ny.png" } }), contextOptions: { webgl: { alpha: true } }, imageryProvider: new Cesium.TileMapServiceImageryProvider({ url: Cesium.buildModuleUrl("Assets/Textures/NaturalEarthII") }) // 加载地形,绘制路径的时候需要 // terrainProvider: new Cesium.CesiumTerrainProvider({ // url: "http://data.marsgis.cn/terrain" // }) }) //去除版权信息 this.viewer._cesiumWidget._creditContainer.style.display = "none" // 抗锯齿 this.viewer.scene.fxaa = true this.viewer.scene.postProcessStages.fxaa.enabled = true // 将地球放大 this.viewer.camera.zoomIn(7000000) //平面场景 // this.viewer.scene.mode = Cesium.SceneMode.COLUMBUS_VIEW // 限制鼠标缩放大小 // this.viewer.scene.screenSpaceCameraController.minimumZoomDistance = 2 // this.viewer.scene.screenSpaceCameraController.maximumZoomDistance = 6378137 * 2 // this.toChina() } 2.加载在线天地图瓦片 addOnlineTdtTile(type) { let TDU_Key = "e5b9de1f8a89a02fdc7bb3b1965cfe91" //天地图申请的密钥 //在线天地图影像服务地址(墨卡托投影) let TDT_IMG_W = "http://{s}.tianditu.gov.cn/img_w/wmts?service=wmts&request=GetTile&version=1.0.0" + "&LAYER=img&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}" + "&style=default&format=tiles&tk=" + TDU_Key const imgProvider = new Cesium.WebMapTileServiceImageryProvider({ url: TDT_IMG_W, layer: "img_w", //WMTS请求的层名称 style: "default", //WMTS请求的样式名称 format: "tiles", //MIME类型,用于从服务器检索图像 tileMatrixSetID: "GoogleMapsCompatible", // 用于WMTS请求的TileMatrixSet的标识符 subdomains: ["t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7"], //天地图8个服务器 minimumLevel: 0, //最小层级 maximumLevel: 18 //最大层级 }); this.viewer.imageryLayers.addImageryProvider(imgProvider) this.viewer.camera.setView({ destination : Cesium.Cartesian3.fromDegrees(112.35, 28.84, 500.0) }); }

这里就只实现影像瓦片的下载,标注的下载其实跟影像的下载思路是一模一样的

3.重写ImageryProvider.loadImage

// 将 loadImage 重载 ImageryProvider.loadImage = (imageryProvider, url)=> { // 其余情况,采用传统的加载图片的方式 return new Promise((resolve, reject) => { const imgUrl = url.url const img = new Image() img.src = imgUrl img.crossOrigin = "Anonymous" // 图片加载成功了,进行 reslove img.onload = () => { if (img.src.indexOf("Textures/NaturalEarthII") < 0) { this._tiles.push(img.src) } resolve(img) } // 图片未加载成功 img.onerror = (err) => { console.error("图片:【" + imgUrl + "】加载失败!") reject(err) } }) }

到这里就可以实现将已加载的瓦片添加到集合中了,

 这集合里的瓦片路径是可以在游览器里直接访问的,效果如下:

到这里我们有

就拥有了我们所需要的瓦片资源了,现在就是需要将瓦片下载到本地,下载使用nodejs来实现

使用downPartTile函数下载

在下载之前先解释为什么需要使用游览器端下载,而不是直接使用nodejs来下载带http地址的瓦片,因为nodejs 直接下载会报418拒绝访问的问题,在研究了一番后还是选择使用游览器来下载,在下载之前需要到天地图官网注册一个游览器key来实现下载

具体网址为:

 

 downPartTile函数如下

const downPartTile = ( tileArr:any )=> { let urls = tileArr; let indx = 0; let timer = setInterval(()=>{ if(indx==urls.length){ clearInterval(timer) } let url = urls[indx]; let keyValueArr = url.split("?")[1].split("&"); let obj:any = {} keyValueArr.forEach((item:any)=>{ let arr = item.split("="); obj[arr[0]] = arr[1]; }) let fileName = obj.TileMatrix+"-"+obj.TileCol+"-"+obj.TileRow+".png"; let x = new XMLHttpRequest(); x.open("GET",url,true); x.responseType = "blob"; x.onload = ()=>{ downloadImage(window.URL.createObjectURL(x.response),fileName) } x.send() ++indx; },300) }

这里需要主要的地方是:let fileName = obj.TileMatrix+"-"+obj.TileCol+"-"+obj.TileRow+".png"; 这里是图片文件命名是有顺序的,

天地图具体层级如下

这里只列出了1-10级对应的图片数量,x:代表第一层,y:代表第二层,z:代表具体位置上的某张瓦片图,根据这个规则我们也可以按层级来下载对应的瓦片哦,本案例不做实现

TileMatrix:代表的是上面的x,

TileCol:代表的是上面的y,

TileRow:代表的是上面的z,

在下载之前先关闭杀毒软件,防止杀毒软件对其扫描影响下载速度,然后在页面上添加一个按钮来触发这个函数进行下载

 

 最终下载到本地的瓦片图格式如下

这时下载下来的图片还不能直接使用,因为还不具备瓦片目录层级,此时需要使用nodejs来对图片进行瓦片的目标分层,实现效果如下

 此层为x层

 此处为y层

 此处为z层,也就是具体某个位置上的瓦片图了,

这样处理后的图片就可以使用cesium来加载使用了,具体加载方式如下

 这样就实现了离线天地图瓦片的加载了

nodejs对瓦片分层处理 const download = require('download'); var http = require('http'); var path = require('path'); var url = require("url"); var querystring = require("querystring"); const fs = require('fs'); // 收集所有的文件路径 const arr = []; let timer = null; const fileDisplay = (url, cb) => { const filePath = path.resolve(url); //根据文件路径读取文件,返回文件列表 fs.readdir(filePath, (err, files) => { if (err) return console.error('Error:(spec)', err) files.forEach((filename) => { //获取当前文件的绝对路径 const filedir = path.join(filePath, filename); // fs.stat(path)执行后,会将stats类的实例返回给其回调函数。 fs.stat(filedir, (eror, stats) => { if (eror) return console.error('Error:(spec)', err); // 是否是文件 const isFile = stats.isFile(); // 是否是文件夹 const isDir = stats.isDirectory(); if (isFile) { // 这块我自己处理了多余的绝对路径,第一个 replace 是替换掉那个路径,第二个是所有满足\\的直接替换掉 arr.push(filedir.replace(__dirname, '').replace(/\\/img, '/')) // 最后打印的就是完整的文件路径了 if (timer) clearTimeout(timer) timer = setTimeout(() => cb && cb(arr), 200) } // 如果是文件夹 if (isDir) fileDisplay(filedir, cb); }) }); }); } // 测试代码 fileDisplay('./tdt/image', (arr) => { let arrs = []; arr.forEach((url)=>{ arrs.push(url.replace(/\/tdt/,"http://192.168.125.2:7777")) }) arrs.forEach((fileUrl)=>{ let fileDir = fileUrl.split("image/")[1].split(".")[0].split("-"); (async () => { await download(fileUrl, './tdt/base/'+fileDir[0]+"/"+fileDir[1],{ filename:fileDir[2]+".png" }); })(); }); console.log("下载成功") })

 ./tdt/image:这里是放置下载后的天地图图片

./tdt/base/:这里是处理完保存的路径



【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭