【cesium知识梳理】2.cesium加载各类数据

7,214 阅读13分钟

之前零零碎碎学过、用过cesium,但也没做记录,现在重新整理一下,方便学习回顾。

cesium提供了非常全面且强大的接口用来加载不同来源、不同格式的数据,下面简单介绍:

1.加载影像数据

1.1.必应地图

cesium提供了BingMapslmageryProvider类来加载必应地图,但是当我们不做任何设置的时候(默认情况下),cesium加载的地图影像就是必应的。

当然,我们需要提前申请好cesium 的token。

Cesium.Ion.defaultAccessToken ="输入你申请的的cesium的token";
    var viewer = new Cesium.Viewer("cesiumContainer", {
            animation: false, //是否显示动画工具
            timeline: false, //是否显示时间轴工具
            fullscreenButton: false, //是否显示全屏按钮工具
});

1.2 天地图

天地图的地图服务采用0GC Web Map Tile Service ( WMTS)标准,使用之前需要先注册申请。

image.png

cesium提供了WebMapTileServicelmageryProvider类来调用天地图的地图服务。

代码如下:

var viewer = new Cesium.Viewer("cesiumContainer", {

//加载天地图影像图
imageryProvider: new Cesium.WebMapTileServiceImageryProvider({
        url: "天地图url",
        subdomains: ["0", "1", "2", "3", "4", "5", "6", "7"], //服务负载子域
        layer: "tdtImgLayer",
        style: "default",
        format: "image/jpeg",
        tileMatrixSetID: "GoogleMapsCompatible", //使用谷歌的瓦片切片方式
        show: true,
}),
});
viewer.imageryLayers.addImageryProvider(
        new Cesium.WebMapTileServiceImageryProvider({
                //天地图影像注记
                url: "http://t{s}.tianditu.com/cia_w/wmts",
                subdomains: ["0", "1", "2", "3", "4", "5", "6", "7"],
                layer: "tdtCiaLayer",
                style: "default",
                format: "image/jpeg",
                tileMatrixSetID: "GoogleMapsCompatible",
                show: true,
        })
);

效果如下:

image.png

1.3ArcGis地图

Cesium提供了ArcGisMapServerlmageryProvider类来加载地图

代码如下

var viewer = new Cesium.Viewer("cesiumContainer", {
    baseLayerPicker:false, //图层选择控件
    animation:false, //是否显示动画工具
    timeline:false,  //是否显示时间轴工具
    fullscreenButton:false,  //是否显示全屏按钮工具
    //加载ArcGIS在线影像图
    imageryProvider : new Cesium.ArcGisMapServerImageryProvider({
        url: "http://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer",
    })
});

1.4高德地图

Cesium提供了UrlTemplatelmageryProvider类来通过指定的URL模板请求地图。

var viewer = new Cesium.Viewer("cesiumContainer", {
        //加载高德地图,UrlTemplateImageryProvider接口是加载谷歌地图或者其他互联网地图的接口
        imageryProvider: new Cesium.UrlTemplateImageryProvider({
                url: "https://webst02.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}",
        }),
});

image.png

除了高德的影像,我们还可以添加高德其他的图层,路网,地名,地名+路网等等,但是需要重新创建imageryprovider来承接图层,并用addImageryProvider方法把图层添加到viewer.imageryLayers中去。

代码如下:

var viewer = new Cesium.Viewer("cesiumContainer", {
        //加载高德地图,UrlTemplateImageryProvider接口是加载谷歌地图或者其他互联网地图的接口
        imageryProvider: new Cesium.UrlTemplateImageryProvider({
                url: "https://webst02.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}",
        }),
});

// 地名 + 路网;
viewer.imageryLayers.addImageryProvider(
        new Cesium.UrlTemplateImageryProvider({
                url: "http://webst01.is.autonavi.com/appmaptile?style=8&x={x}&y={y}&z={z}",
        })
);

image.png

高德地图相关url如下(来源于网络)

//(1)卫星影像 
"http://webst01.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}"  

//(2)路网
"https://wprd01.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=1&style=8&ltype=11"    

//(3)地名
"https://wprd01.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=1&style=8&ltype=4" 

//(4)地名+路网 
"http://webst01.is.autonavi.com/appmaptile?style=8&x={x}&y={y}&z={z}", 

//矢量切片风格 
"http://webrd01.is.autonavi.com/appmaptile?&scale=1&lang=zh_cn&style=8&x={x}&y={y}&z={z}"

补充

               //高德纯路网
	// viewer.imageryLayers.addImageryProvider(
                // new Cesium.UrlTemplateImageryProvider({
                // url: "https://wprd01.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=2&style=8&ltype=11",
	// 		maximumLevel: 18,
	// 	})
	// );
	// 高德地名 + 路网;
	// viewer.imageryLayers.addImageryProvider(
	// 	new Cesium.UrlTemplateImageryProvider({
	// 		url: "http://webst01.is.autonavi.com/appmaptile?style=8&x={x}&y={y}&z={z}",
	// 	})
	// );
	//高德纯矢量,白色电子地图
	// viewer.imageryLayers.addImageryProvider(
	// 	new Cesium.UrlTemplateImageryProvider({
	// 		url: "http://wprd04.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&x={x}&y={y}&z={z}",
	// 		maximumLevel: 18,
	// 	})
	// );
	//谷歌路网+地名+行政边界
	// viewer.imageryLayers.addImageryProvider(
	// 	new Cesium.UrlTemplateImageryProvider({
	// 		url: "https://mt1.google.com/vt/lyrs=h&x={x}&y={y}&z={z}",
	// 		// maximumLevel: 18,
	// 	})
	// );

	//谷歌电子地图
	// viewer.imageryLayers.addImageryProvider(
	// 	new Cesium.UrlTemplateImageryProvider({
	// 		url: "https://tile.openstreetmap.org/{z}/{x}/{y}.png",
	// 		// maximumLevel: 18,
	// 	})
	// );

1.5OSM

Cesium提供了OpenStreetMaplmageryProvider类来加载OSM数据,只需直接指定OSM数据URL即可

当然,也可以用UrlTemplateImageryProvider,以XYZ的形式请求影像瓦片。

var viewer = new Cesium.Viewer("cesiumContainer", {
        // 加载OSM影像
        imageryProvider: new Cesium.OpenStreetMapImageryProvider({
                url: "https://a.tile.openstreetmap.org/",
        }),

        // XYZ形式
        // imageryProvider: new Cesium.UrlTemplateImageryProvider({
        // 	url: "http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
        // 	subdomains: ["a", "b", "c"],
        // }),
});

1.6MapBox影像

使用mapbox需要提前注册一下(魔法网络环境),注册教程可以看这个: mapbox如何注册

用cesiun加载mapbox,首先可以用new Cesium.UrlTemplateImageryProvider

var viewer = new Cesium.Viewer("cesiumContainer", {
    baseLayerPicker: false, //图层选择控件
    animation: false, //是否显示动画工具
    timeline: false, //是否显示时间轴工具
    fullscreenButton: false, //是否显示全屏按钮工具
    //加载MapBox影像
    imageryProvider: new Cesium.UrlTemplateImageryProvider({
            url: "https://a.tiles.mapbox.com/v4/mapbox.satellite/{z}/{x}/{y}.png?access_token=g",
    }),
});

很明显,mapbox的影像要更加鲜亮,这是默认的mapbox影像。

image.png

如果要加载自定义风格的mapbox,需要先在mapbox设置好风格,

点击查看如何设置mapbox风格,加载

然后用 new Cesium.MapboxStyleImageryProvider进行加载,代码和效果如下:

// 加载自定义MapBox地图
imageryProvider: new Cesium.MapboxStyleImageryProvider({
        url: "https://api.mapbox.com/styles/v1",
        username: "qiaaun",
        styleId: "clkwaxdd600290q6f8d",
        accessToken:
                "pk.eyJ1IjoicWlhbmRhdW4iLCJhIEWYO1jGrZD4awg",
        scaleFactor: true,
}),

image.png

image.png

2.OGC地图服务

0GC全称为0pen Geospatial Consortium,开放地理空间信息联盟,这个组织制定了GIS数据的规范、标准。

2.1WMS

WMS,即网络地图服务(Web Map Service),用户向接口请求,即可返回地图。这里我们采用Geoserver软件来发布地图服务。关于geoserver的下载、安装、使用,这里不过多赘述。

首先要在geoserver里面发布服务,这里我选用了武汉某地的tiff影像,进行服务发布。 然后在cesium里,进行调用。

在调用的时候,注意一下geoserver的跨域问题,网上也有很多解决方案,这里不赘述。

var viewer = new Cesium.Viewer("cesiumContainer", {
        baseLayerPicker: false, //图层选择控件
        animation: false, //是否显示动画工具
        timeline: false, //是否显示时间轴工具
        fullscreenButton: false, //是否显示全屏按钮工具
});
//加载WMS
var wmsImageryProvider = new Cesium.WebMapServiceImageryProvider({
        url: "http://localhost:8086/geoserver/cesium/wms", // 服务地址
        layers: "cesium:dida", // 图层名称
        parameters: {
                transparent: true, // 是否透明
                format: "image/png", // 返回格式
                srs: "EPSG:4326", // 坐标系
        },
});
viewer.imageryLayers.addImageryProvider(wmsImageryProvider);

加载效果如下:

image.png

2.2WMTS

Web地图瓦片服务(Web Map Tile Server,WMTS)提供了一种采用预定义图块方法发 布数字地图服务的标准化解决方案,并且弥补了WMS不能提供分块地图的不足。

简单来说,就是把一整张地图切成小块,用金字塔的形式组织起来,地图越放大,展示的块数就越多。

image.png

image.png

具体操作:

在geoserver创建切片图层,并对数据进行切片,设置相关参数如下

image.png

代码加载,Cesium提供了WebMapTileServiceImageryProvider类来加载

GeoServer发布的WMTS切片影像

var wmtsImageryProvider = new Cesium.WebMapTileServiceImageryProvider({
    url:'http://localhost:8088/geoserver/gwc/service/wmts/rest/Cesium:dida/{style}/{TileMatrixSet}/{TileMatrixSet}:{TileMatrix}/{TileRow}/{TileCol}?format=image/png',
    layer: 'Cesium:dida',
    style: '',
    format: 'image/png',  //不能用jpeg格式,因为jpeg格式不能设置透明背景,设置透明背景会变成白色
    tileMatrixSetID: 'EPSG:900913',      //一般使用EPSG:3857坐标系
});
viewer.imageryLayers.addImageryProvider(wmtsImageryProvider);

2.3TMS

Cesium提供了UrlTemplateImageryProvider类,用于通过指定的

URL来加载TMS。

var urlTemplateImageryProvider =

new Cesium.UrlTemplateImageryProvider({
    url : "http://localhost:8088/geoserver/gwc/service/tms/1.0.0/Cesium%3Adida@EPSG%3A900913@png/{z}/{x}/{reverseY}.png"
    layers: "cesium:dida",
    parameters: {
        srs: "EPSG:4326",
        format: "application/openlayers",
        format: "png", //指定文件拓展名为png
        transparent: true,  
    },
});

3.加载GeoJSON数据

GeoJSON 是一种使用 JSON 来编码各种地理数据结构的格式,是一种轻量级的数据交换格式,可以用来表示几何对象、属性数据、空间参考系统等信息。

关于GeoJSON更加详细的解释,可以看这两篇文章

1.GeoJSON介绍

2.GeoJSON介绍

geojson.io/ 这个网站还可以在线预览GeoJSON数据

image.png

言归正传,cesium加载GeoJSON,要用到GeoJsonDataSource类,可以通过load方法加载GeoJSON 对象,并设置相应的填充颜色、边框颜色、边框宽度、是否贴地等属性。

var GeoJsonData = viewer.dataSources.add(
        Cesium.GeoJsonDataSource.load("./矢量文件/json/merge.json", {
                fill: Cesium.Color.PINK, //填充色
                stroke: Cesium.Color.HOTPINK, //轮廓颜色
                strokeWidth: 5, //轮廓宽度
        })
);
GeoJsonData.then(viewer.zoomTo(GeoJsonData));

效果如下:

image.png

4.加载KML数据

Cesium提供了KmlDataSource类来处理KML数据,可以通过load方法加载KML数据

var viewer = new Cesium.Viewer("cesiumContainer", {
    animation: false, //是否显示动画工具
    timeline: false,  //是否显示时间轴工具
    fullscreenButton: false,  //是否显示全屏按钮工具
});

var kmlData = viewer.dataSources.add(Cesium.KmlDataSource.load(
    './矢量文件/kml/road.kml',
    {
        camera: viewer.scene.camera,
        canvas: viewer.scene.canvas,
    })
);

kmlData.then(viewer.zoomTo(kmlData))

image.png

5.TIFF数据

Cesium并不能直接加载本地TIFF格式的影像数据,而是需要对其进行切片处理后才能加载,我们可以采用【北京西部世界】公司研发的cesiumLab软件,来进行数据切片操作。

关于cesium的下载、使用这里不赘述,我们直接使用影像切片功能,导入tiff文件,设置 “储存类型”为“散列文件”,并设置好输出路径,即可开始运行。

image.png

image.png

输出结果长这样

image.png

image.png

关键点,使用UrlTemplateImageryProvider类指定瓦片文件路径并通

过xyz方式加载瓦片数据(瓦片文件路径后加/{z}/{x}/{y}.png)

 var localImage = viewer.scene.imageryLayers.addImageryProvider(
      new Cesium.UrlTemplateImageryProvider({
        url: './RasterImage/切片文件路径/{z}/{x}/{y}.png',
        fileExtension: "png"
      })
    )

6.加载点云数据

点云数据(Point Cloud Data)是指在一个三维坐标系统中的一组向量的集合。扫描资料 以点的形式被记录,每一个点都包含三维坐标,有些可能包含颜色信息(RGB)或反射强度 信息(Intensity)。

上述这段话是借鉴来的一段比较科学的定义,我们可以先粗浅地理解为,点云就是一堆点,组合在一起,有一个形状,点云相关的知识我了解不多,就不赘述了

这里以LAS格式的点云数据为例介绍Cesium加载点云数据的过程。

我们还是要借助cesiumlab这个数据处理软件:

使用点云切片功能,加载las数据,进行切片

image.png

代码加载:

首先创建一个Cesium3D切片集,并指定点云切片数据的 JSON文件路径URL,然后将其添加至场景primitives中。

var tileset = viewer.scene.primitives.add(
        new Cesium.Cesium3DTileset({
                url: "./RasterImage/点云切片数据/tileset.json", //文件的路径
        })
);

viewer.zoomTo(tileset); //定位过去

效果如下:

image.png

放大了看,点云,名副其实,就是一堆点(粗浅理解)

image.png

7.加载地形数据

7.1 加载在线的地形数据

使用 terrainProvider: Cesium.createWorldTerrain(),

var viewer = new Cesium.Viewer("cesiumContainer", {
        terrainProvider: Cesium.createWorldTerrain(),//加载在线地形数据
        animation: false, //是否显示动画工具
        timeline: false, //是否显示时间轴工具
        fullscreenButton: false, //是否显示全屏按钮工具
});

viewer.zoomTo(kmlData);

7.2 加载本地的地形数据

大部分地形原始数据都是TIFF格式的,而Cesium支持的是TERRAIN,可以用cesiumlab。格 式的数据,因此需要先处理数据。

获取地形数据可以到地理空间数据云网站下载 www.gscloud.cn

在高级检索中找到DEM,选择一块下载即可

image.png

处理数据,tiff转为TERRAIN,可以用cesiumlab,不赘述。然后需要把数据放在服务环境中,并且要注意设置好跨域,我用了http-server,在数据所在位置,直接

//在数据所在位置,打开终端,开启服务,并设置好跨域
http-server --cors -p 8082

在cesium中加载数据

var viewer = new Cesium.Viewer("cesiumContainer", {
    //加载本地地形切片
    terrainProvider: new Cesium.CesiumTerrainProvider({
            url: "http://localhost:8082", 
    }),
    animation: false, //是否显示动画工具
    timeline: false, //是否显示时间轴工具
    fullscreenButton: false, //是否显示全屏按钮工具
});

image.png

image.png

8.加载倾斜摄影模型数据

目前,常见的倾斜摄影三维模型一般是OSGB格式,二进制存储,并且配备一个metadata.xml文件(类似于配置文件),cesium无法直接加载OSGB,需要先将数据转换为3Dtiles格式,这种数据格式是cesium团队打造的,可以被cesium很好地加载。

点击详细了解3Dtiles

拿到3Dtiles数据后,如何用cesium加载?

var tileset = viewer.scene.primitives.add(
    new Cesium.Cesium3DTileset({
        url: './倾斜摄影/大雁塔3DTiles/tileset.json',//文件的路径
        maximumScreenSpaceError:1
    })
);
//定位过去
viewer.zoomTo(tileset);

image.png

3Dtiles已被加载,不过模型没在地上,在空中,如果要移动模型的位置、体态,就得学习cesium其他的API,这里暂且不论,后续慢慢聊。

9.加载glTF数据

glTF(GL Transmission Format),图形语言交换格式,是一种3D内容的格式标准, 其本质是一个JSON文件。简单来说就是一种3D模型的文件格式(粗浅理解)

1.详细了解glTF

2.详细了解glTF

如何Cesium通过加载glTF?

Model.fromGltf 接口指定glTF数据URL来进行glTF数据加载,并可以设置相关的配置项,例如

modelMatrix调整glTF数据的加载位置,

scale可以调整缩放比例等。

var origin = Cesium.Cartesian3.fromDegrees(114.39278, 30.52357, 0.0);
//
var modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(origin);

var model = viewer.scene.primitives.add(Cesium.Model.fromGltf({

    url: './3D格式数据/glTF/CesiumMilkTruck.gltf',

    modelMatrix : modelMatrix,  //Gltf数据加载位置

    scale : 5     //放大倍数

}));

//移动相机

viewer.camera.flyTo({  

  destination : Cesium.Cartesian3.fromDegrees(114.39278, 30.52357, 60.0)     //相机飞入点

});

image.png

cesium中还有其他关于3Dtiles的类,可以看一下

10.加载CZML数据

czml数据时cesium团队打造的,本质上还是JSON数据,但是其功能更加强大,除了可以绘制图形、加载模型,还加入了时间属性,从而能让物体跟随时间变化,动起来

话不多说,先上代码:

//初始化,要记得开启时间线 和 动画
var viewer = new Cesium.Viewer("cesiumContainer", {
        timeline: true,  //开启时间线
        animation: true, //开启动画
        vrButton: false,
        sceneModePicker: false,
        infoBox: true,
        scene3DOnly: false,
});

var czml = [
{
        id: "document",
        name: "CZML Model",
        version: "1.0",
},
{
        id: "aircraft model",
        name: "Cesium Air",

        // 物体在什么时间范围可用
        availability: "2012-08-04T16:00:00Z/2012-08-04T16:05:00Z",
        position: {
                // 设置物体的起始时间
                epoch: "2012-08-04T16:00:00Z",
                // 坐标数据,4个为一组,1时间,2经度,3纬度,4高度
                cartographicDegrees: [
                        0, -70, 20, 150000, 100, -80, 44, 150000, 200, -90,
                        18, 150000, 300, -98, 52, 150000,
                ],
        },
        model: {
                gltf: "./3D格式数据/glb/Cesium_Air.glb", //模型路径URL
                scale: 20000.0, //缩放比例
        },
},
];

在初始化地图的时候,要打开时间线和动画的配置,因为后续要用到。

image.png

CZML至少要包含两个对象,每一个对象都是一个CZML的数据包。

第一个对象,

id一般都写document,

name属性值可以自定义,

version可以CZML版本号,暂时只有1.0。

第二个对象是关于场景内的几何模型数据。

id是每一个几何模型对象都有的,id属性用于标识,如果id没有指定,cesium会自动生成一个,但是在后续开发中我们无法对其进行引用,如添加数据等,所以id我们要提前设定好,且在CZML中是唯一的。

name属性可以自定义名称。

availability设定了数据的时间范围,

position用来设置模型的位置,epoch设置了起始时间,cartographicDegrees设置了4个不同时间点的位置,从起始时间开始,第0秒的时候模型在第一个位置,第100秒的时候模型在第二个位置,以此类推。

image.png

点击左下角的播放,飞机就会按照设定的时间、位置开始运动,随着时间的推移,飞机的位置已经变化,进度条也在变化。

image.png

11.加载单张图片


//左下角坐标,右上角坐标
var rectangle=Cesium.Rectangle.fromDegrees(114.38004,30.51667,114.40471,30.53045);
viewer.imageryLayers.addImageryProvider(new Cesium.SingleTileImageryProvider({
        url:"./RasterImage/图片/single.jpg",
        rectangle: rectangle
}))
viewer.camera.setView({
        destination: Cesium.Rectangle.fromDegrees(114.38304,30.51667,114.40471,30.52345)
});

首先创建了一个矩形范围(rectangle)对象,用于指定图像或地理实体在地球上的显示范围。通过  Cesium.Rectangle.fromDegrees()  方法,提供了四个经度和纬度值,分别表示矩形的西、南、东、北边界。

通过new Cesium.SingleTileImageryProvider 加载单张图片,并且设定好显示范围,

最后设置相机的初始显示范围