Cesium加载天地图二

标签: Cesium 分类: Gis 创建时间:2021-04-07 10:44:30 更新时间:2023-10-20 11:23:25

1.加载天地图影像

默认的Cesium加载的是bing地图的影像,我们通过在构造函数中指定imageryProvider,来将地图改为天地图。

1
2
3
4
5
6
7
8
9
10
var viewer = new Cesium.Viewer('cesiumContainer',{
/*前面的代码都忽略*/
imageryProvider : new Cesium.WebMapTileServiceImageryProvider({
url : "http://t0.tianditu.com/img_c/wmts?tk=你的密钥",
layer: "img",
format: "image/jpgpng",
style: "default",
tileMatrixSetID:"c"
})
});

通过WMTS服务即可加载天地图

但是我们知道,天地图的服务器不知一台,从t0、t1一直到t7,都可以访问,如果通过不指定服务的方式访问天地图呢?好在Cesium的WebMapTileServiceImageryProvider构造函数支持url中使用{s}代替域名,使用subdomains来指定子域名,但是不能这样写

1
2
3
4
5
6
7
8
imageryProvider : new Cesium.WebMapTileServiceImageryProvider({
url : "http://{s}.tianditu.com/img_c/wmts?tk=你的密钥",
layer: "img",
format: "image/jpgpng",
style: "default",
tileMatrixSetID:"c",
subdomains:["t0","t1","t2","t3","t4","t5","t6","t7"]
})

这样写虽然能正确的找打服务器,但是你会发现url后面的参数都不见了。

正确的做法是拼接url

1
2
3
4
5
6
7
8
9
10
var url="http://{s}.tianditu.com/img_c/wmts?tilematrix={TileMatrix}&layer=img&style=default&tilerow={TileRow}&tilecol={TileCol}&tilematrixset=c&format=image%2Fjpgpng&service=WMTS&version=1.0.0&request=GetTile&tk=你的密钥";
var viewer = new Cesium.Viewer('cesiumContainer',{
/*省略部分代码*/

//添加自定义图层
imageryProvider : new Cesium.WebMapTileServiceImageryProvider({
url : url,
subdomains:["t0","t1","t2","t3","t4","t5","t6","t7"]
})
});

这里需要注意的有三点,第一点就是{s};第二点是:tilematrix={TileMatrix},TileMatrix不能写错,否则加载不出来;第三点是:tilerow={TileRow}&tilecol={TileCol},这两项中的TileRow和TileCol也不能写错,大小写也要注意。还有就是tk是你在天地图上申请到的密钥。

参考文章:
1.Cesium应用篇:2影像服务(下) (加载天地图服务、Google Map影像服务以及同时加载多个Provider)
2.Cesium开发:关于加载CGCS2000切片 (这里有加载墨卡托投影,加载cgcs2000的坐标系会出现问题)

注意
今天重新查看Demo,发现了一个奇怪的现象,cesium加载的天地,只有一半,地图之覆盖了球形的上半部分,而地球的下半部分是空白的(这TM就尴尬了)。

通过参考文章 ,最终加载地图的正确代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 国家天地图
var url="http://{s}.tianditu.com/img_c/wmts?tilematrix={TileMatrix}&layer=img&style=default&tilerow={TileRow}&tilecol={TileCol}&tilematrixset=c&format=image%2Fjpgpng&service=WMTS&version=1.0.0&request=GetTile&tk=85b88ce10c15f390ee75bf571688b3b7";
var viewer = new Cesium.Viewer('cesiumContainer',{
geocoder:false,
homeButton:false,
sceneModePicker:false,
baseLayerPicker:false,
navigationHelpButton:false,
animation:false,
// creditContainer:"credit",
timeline:false,
fullscreenButton:false,
vrButton:false,

//添加自定义图层
imageryProvider : new Cesium.WebMapTileServiceImageryProvider({
url : url,
subdomains:["t0","t1","t2","t3","t4","t5","t6","t7"],
maximumLevel:16,
tilingScheme: new Cesium.GeographicTilingScheme(),
tileMatrixLabels:["1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17"]
}),
});

注意其中的tilingScheme和tileMatrixLabels就可以了。

随之而来的问题是,这个坐标系是WGS84(EPSG:4326)的坐标下,如何加载CGCS2000(EPSG:4490)坐标系呢?虽然两者相差不大,但是总归不是一个东西啊。

参考文章:
1.cesium调用天地图服务
2.cesium加载坐标系为4490的arcgis瓦片图 (这个没有源码,我估计是修改了Cesium的源码来实现的切片加载,没有具体研究)

2.加载天地图浙江

国家天地图只提供了1-17级的影像,天地图浙江提供了17-20级的影像,原先的代码加载天地图是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//加载天地图浙江影像
// var zjUrl="http://www.zjditu.cn/_proxy_/tile_zhejiang/ZJDOM_2D/wmts";
var zjUrl="http://srv1.zjditu.cn/ZJDOM_2D/wmts";

var zjImgProvider=new Cesium.WebMapTileServiceImageryProvider({
url : zjUrl,
layer: "imgmap",
format: "image/jpgpng",
style: "default",
tileMatrixSetID:"default028mm",
// tilingScheme: new Cesium.GeographicTilingScheme()
});
var zjImglayer=new Cesium.ImageryLayer(zjImgProvider,{
minimumTerrainLevel:17,
maximumTerrainLevel:19
})
viewer.imageryLayers.add(zjImglayer);

出现的问题是,无法加载17到19级的影像,虽然请求了影像,但是无法正确的计算瓦片的行列号和地图的级别(通过在谷歌浏览器的开发者工具中右键打开请求的瓦片链接,发现请求的瓦片是空白)。经过多次反复的尝试,正确的加载天地图浙江的影像地图的方式是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
 var zjUrl="http://{s}.zjditu.cn/ZJDOM_2D/wmts?tilematrix={TileMatrix}&layer=imgmap&style=default&tilematrixset=default028mm&Service=WMTS&Request=GetTile&Version=1.0.0&Format=image%2Fjpgpng&tilecol={TileCol}&tilerow={TileRow}";
var zjImgProvider=new Cesium.WebMapTileServiceImageryProvider({
url : zjUrl,
subdomains:["srv0","srv1","srv2","srv3"], //定义域名
maximumLevel:19, //定义最大级别,好像不管用,于是就有了下面的ImageryLayer,可以去掉了
tilingScheme: new Cesium.GeographicTilingScheme(), //定义切片的方式为地理坐标系
tileMatrixLabels:["1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19"] //定义瓦片的级别
});

var zjImglayer=new Cesium.ImageryLayer(zjImgProvider,{
minimumTerrainLevel:13, //定义最小级别
maximumTerrainLevel:18 //定义最大级别,虽然是18,但是可以加载到19级,不知道这是什么原理,如果写17,就可以加载到18级
})
viewer.imageryLayers.add(zjImglayer); //加载到地图上

这里有一点需要说明的是,经过测试,tileMatrixLabels要从1开始写,否则,url中就计算不出来正确的级别,出现url中的tilematrix={TileMatrix}情况;tilingScheme这个参数也不能缺少,否则也是计算不出来缩放级别。

3.图层无法定义最小分辨率(设置图层最大最小分辨率)

假如图层不是从0级开始的,就需要定义最小分辨率,但是我尝试从第六级开始显示,刷新浏览器,会出现,浏览器疯狂的请求最小分辨率的图层,甚至将页面卡死了。

1
2
3
4
5
6
imageryProvider : new Cesium.WebMapTileServiceImageryProvider({
url : url,
subdomains:["t0","t1","t2","t3","t4","t5","t6","t7"],
minimumLevel:6,
maximumLevel:18
})

这里针对imageryProvider无法定义最小级别,暂时无法知道什么原因,但是我们可以针对一个图层进行定义最大最小值,比如加载浙江地图,从13到19级影像地图。就不会出现疯狂加载影像的问题了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
 //加载天地图浙江影像
var zjUrl="http://www.zjditu.cn/_proxy_/tile_zhejiang/ZJDOM_2D/wmts";
var zjImgProvider=new Cesium.WebMapTileServiceImageryProvider({
url : zjUrl,
layer: "imgmap",
format: "image/jpgpng",
style: "default",
tileMatrixSetID:"default028mm",
});
var zjImglayer=new Cesium.ImageryLayer(zjImgProvider,{
minimumTerrainLevel:13,
maximumTerrainLevel:19
})
viewer.imageryLayers.add(zjImglayer);

这个provider和layer的关系有点像openlayers中的layer和source的关系,一个图层对应一个数据源,通过定义图层的最大最小级别来约束什么时候需要加载图层,什么时候不需要加载图层。

4.使用DataServer服务

2021年10月13日,最新的加载方式,可以使用DataServer服务,加载不同的图层了。

1
2
3
4
5
6
7
8
9
10
11
12
var imageryProvider=new Cesium.WebMapTileServiceImageryProvider({
//影像底图
// url: "http://t{s}.tianditu.com/vec_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=vec&tileMatrixSet=c&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default&format=tiles&tk="+this.tk,
url:"http://t{s}.tianditu.com/DataServer?T=vec_w&x={TileCol}&y={TileRow}&l={TileMatrix}&tk="+this.tk,
subdomains: this.subdomains,
maximumLevel:17, // 定义最大缩放级别
layer: "tdtImgLayer",
style: "default",
format: "image/jpeg",
tileMatrixSetID: "GoogleMapsCompatible",//使用谷歌的瓦片切片方式
show: true
});
参考文章:
1.cesium调用天地图服务 全球矢量地图服务、全球影像地图服务、全球影像中文注记服务、全球矢量中文注记服务,这里的域名都是.com结尾的,最新的应该使用.gov.cn结尾的
2.影像加载篇:WebMapTileServiceImageryProvider
3.uart_write_bytes(UART1_PORT_NUM, PubData.data, PubData.size); Blocked loading mixed active content,这个错误的原因就是:由于安全原因,它给出了错误。为此,请在网站 url 中使用“https”而不是“http”。
4.天地图服务在https协议下请求正常加载显示地图 1.添加代理,解决跨域问题。2.在地图服务的http后面加上s,即是https即可,如果是加载天地图的矢量地图服务需要加载完整的路径
5.Cesium多源数据加载之影像图层(一)
6.Cesium加载天地图及注记,并且去除自带控件

5.加载影像地图

下面的代码包括创建地球,加载地图。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 构造地球(可以使用原生Cesium或第3方SDK方式去构造Viewer)
var tiandituTk='xxx';
// 服务负载子域
var subdomains=['0','1','2','3','4','5','6','7'];
const viewer = new Cesium.Viewer(withKeyId.value, {
animation: false,
timeline: false,
baseLayerPicker: false, // 是否显示图层选择控件
imageryProvider: new Cesium.WebMapTileServiceImageryProvider({
//影像底图
url: "http://t{s}.tianditu.com/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="+tiandituTk,
subdomains: subdomains,
layer: "tdtImgLayer",
style: "default",
format: "image/jpeg",
tileMatrixSetID: "GoogleMapsCompatible",//使用谷歌的瓦片切片方式
})
})
小额赞助
本人提供免费与付费咨询服务,感谢您的支持!赞助请发邮件通知,方便公布您的善意!
**光 3.01 元
Sun 3.00 元
bibichuan 3.00 元
微信公众号
广告位
诚心邀请广大金主爸爸洽谈合作
每日一省
isNaN 和 Number.isNaN 函数的区别?

1.函数 isNaN 接收参数后,会尝试将这个参数转换为数值,任何不能被转换为数值的的值都会返回 true,因此非数字值传入也会返回 true ,会影响 NaN 的判断。

2.函数 Number.isNaN 会首先判断传入参数是否为数字,如果是数字再继续判断是否为 NaN ,不会进行数据类型的转换,这种方法对于 NaN 的判断更为准确。

每日二省
为什么0.1+0.2 ! == 0.3,如何让其相等?

一个直接的解决方法就是设置一个误差范围,通常称为“机器精度”。对JavaScript来说,这个值通常为2-52,在ES6中,提供了Number.EPSILON属性,而它的值就是2-52,只要判断0.1+0.2-0.3是否小于Number.EPSILON,如果小于,就可以判断为0.1+0.2 ===0.3。

每日三省
== 操作符的强制类型转换规则?

1.首先会判断两者类型是否**相同,**相同的话就比较两者的大小。

2.类型不相同的话,就会进行类型转换。

3.会先判断是否在对比 null 和 undefined,是的话就会返回 true。

4.判断两者类型是否为 string 和 number,是的话就会将字符串转换为 number。

5.判断其中一方是否为 boolean,是的话就会把 boolean 转为 number 再进行判断。

6.判断其中一方是否为 object 且另一方为 string、number 或者 symbol,是的话就会把 object 转为原始类型再进行判断。

每日英语
Happiness is time precipitation, smile is the lonely sad.
幸福是年华的沉淀,微笑是寂寞的悲伤。