外观
三维场景
4137字约14分钟
2024-12-27
我们使用DIV渲染后看到的三维地球对象,我们统称为三维场景。mars3d.Map类是构建Mars3D应用程序的入口,我们称其为视图容器,它承载了Mars3D应用的所有内容。
mars3d.Map这是一切的开始,所有相关控制的起点,掌握好了mars3d.Map类 基本也就掌握好了Mars3D。 本文将详细介绍如何使用该类创建和管理三维地图场景。
1. 三维场景初始化
在使用mars3d时你可以根据需要对默认参数进行配置,如果你只是想得到默认的效果,你仅需要写下面一行代码即可:
const map = new mars3d.Map("mars3dContainer")
正常我们需要在初始化时,显示对应的影像地图,加载一些业务数据、三维模型、场景特效等,所以我们需要对其进行一些配置,mars3d提供了详细的参数配置方案(如下),你可以暂时不需要完全理解各个参数的意义,在接下来的后续教程中我们会详细解释相关参数。
// 创建三维地球场景
const map = new mars3d.Map("mars3dContainer", {
scene: {
// 默认视角参数
center: { lat: 30.054604, lng: 108.885436, alt: 17036414, heading: 0, pitch: -90 },
shadows: false, // 是否启用日照阴影
removeDblClick: true, // 是否移除Cesium默认的双击事件
// 以下是Cesium.Viewer所支持的options【控件相关的写在另外的control属性中】
sceneMode: 3, // 3等价于Cesium.SceneMode.SCENE3D,
// 以下是Cesium.Scene对象相关参数
showSun: true, // 是否显示太阳
showMoon: true, // 是否显示月亮
showSkyBox: true, // 是否显示天空盒
showSkyAtmosphere: true, // 是否显示地球大气层外光圈
fog: true, // 是否启用雾化效果
fxaa: true, // 是否启用抗锯齿
// 以下是Cesium.Globe对象相关参数
globe: {
depthTestAgainstTerrain: false, // 是否启用深度监测
baseColor: "#546a53", // 地球默认背景色
showGroundAtmosphere: true, // 是否在地球上绘制的地面大气
enableLighting: false // 是否显示昼夜区域
},
// 以下是Cesium.ScreenSpaceCameraController对象相关参数
cameraController: {
zoomFactor: 3.0, // 鼠标滚轮放大的步长参数
minimumZoomDistance: 1, // 地球放大的最小值(以米为单位)
maximumZoomDistance: 50000000, // 地球缩小的最大值(以米为单位)
enableRotate: true, // 2D和3D视图下,是否允许用户旋转相机
enableTranslate: true, // 2D和哥伦布视图下,是否允许用户平移地图
enableTilt: true, // 3D和哥伦布视图下,是否允许用户倾斜相机
enableZoom: true, // 是否允许 用户放大和缩小视图
enableCollisionDetection: true // 是否允许 地形相机的碰撞检测
}
},
control: {
baseLayerPicker: true, // basemaps底图切换按钮
homeButton: true, // 视角复位按钮
sceneModePicker: true, // 二三维切换按钮
navigationHelpButton: true, // 帮助按钮
fullscreenButton: true // 全屏按钮
},
terrain: {
url: "http://data.mars3d.cn/terrain",
show: true
},
basemaps: [
{
name: "天地图卫星",
icon: "img/basemaps/tdt_img.jpg",
type: "tdt",
layer: "img_d",
key: ["9ae78c51a0a28f06444d541148496e36"],
show: true
}
]
})
运行效果
新窗口查看
2. 构造参数说明
Map类的构造参数比较多,我们已经分类放在方法的第2个参数mapOptions参数中
参数名 | 类型 | 参数解释 |
---|---|---|
id | String 或 Cesium.Viewer | 地图容器的div的id或已经构造好的viewer对象 |
mapOptions | Object | 创建地球的参数 |
2.1 使用json配置文件记录参数快速创建三维场景
我们在不同项目应用时,可能是同一套代码,仅仅只是地图的配置参数不一样, 那么我们可以把地图的参数保存在后端服务动态生成或存储在json文件,将三维场景参数化。 我们可以直接加载使用不同json数据来快速创建各种三维场景。
(1)通过任意方式去读取json文件,下面只是一种演示的方式
const configUrl = "http://mars3d.cn/config/config.json"
mars3d.Util.fetchJson({ url: configUrl }).then((json) => {
initMap(json) // 构建地图
})
(2)读取到的json对象传入new mars3d.Map
方法创建地球
function initMap(mapOptions) {
// 创建三维地球场景
const map = new mars3d.Map("mars3dContainer", mapOptions)
}
config.json
中的属性参数是与mapOptions参数相同。
(3)地球创建好之后可以通过map.setOptions
方法更新所有参数
// 更新地球参数
map.setOptions({
scene: {
cameraController: {
maximumZoomDistance: 500000000
}
}
})
2.2 工具配置参数导出
可访问Map参数配置工具进行UI界面的方式进行配置所有Map参数后导出配置JSON直接加载JSON即可。
2.3 scene 场景参数
scene场景是所有3D图形对象的容器(HTML canvas),在场景对象中我们可以控制:globe 椭圆体、camera相机 等。 在创建地图时,你可以通过参数中scene
参数配置场景中的默认视角(类似二维地图的地图层级)、三维场景的各种参数控制、相机的各种控制等。 参数解释参考 API文档
const map = new mars3d.Map("mars3dContainer", {
scene: {
// 默认视角参数
center: { lat: 30.715648, lng: 116.300527, alt: 10727, heading: 3, pitch: -25 },
shadows: false, // 是否启用日照阴影
removeDblClick: true, // 是否移除Cesium默认的双击事件
// 以下是Cesium.Viewer所支持的options【控件相关的写在另外的control属性中】
sceneMode: 3, // 3等价于Cesium.SceneMode.SCENE3D,
// 以下是Cesium.Scene对象相关参数
showSun: true, // 是否显示太阳
showMoon: true, // 是否显示月亮
showSkyBox: true, // 是否显示天空盒
showSkyAtmosphere: true, // 是否显示地球大气层外光圈
fog: true, // 是否启用雾化效果
fxaa: true, // 是否启用抗锯齿
// 以下是Cesium.Globe对象相关参数
globe: {
depthTestAgainstTerrain: false, // 是否启用深度监测
baseColor: "#546a53", // 地球默认背景色
showGroundAtmosphere: true, // 是否在地球上绘制的地面大气
enableLighting: false // 是否显示昼夜区域
},
// 以下是Cesium.ScreenSpaceCameraController对象相关参数
cameraController: {
zoomFactor: 3.0, // 鼠标滚轮放大的步长参数
minimumZoomDistance: 1, // 地球放大的最小值(以米为单位)
maximumZoomDistance: 50000000, // 地球缩小的最大值(以米为单位)
enableRotate: true, // 2D和3D视图下,是否允许用户旋转相机
enableTranslate: true, // 2D和哥伦布视图下,是否允许用户平移地图
enableTilt: true, // 3D和哥伦布视图下,是否允许用户倾斜相机
enableZoom: true, // 是否允许 用户放大和缩小视图
enableCollisionDetection: true // 是否允许 地形相机的碰撞检测
}
}
})
scene.center默认视角参数
相机是三维场景渲染中非常重要的一个概念,用于控制场景的视角。相机用于代表人的眼睛,即从哪儿看,看向哪儿,哪些对象看得见,那些对象看不见。你如果想设置进入地图页面时,自定义默认视角和地图层级的话,你可以在创建地球时的scene参数中设置center参数来设置相机中的默认视角值:
const map = new mars3d.Map("mars3dContainer", {
scene: {
center: { lat: 25.389914, lng: 119.084961, alt: 1179575, heading: 346, pitch: -60 }
}
})
center参数不容易手动修改,建议通过map.getCameraView 方法获取当前的地图视角后拷贝设置到config.json中。或者在地图空白区域右键菜单中【查看当前视角】来快捷获取下参数值。
2.4 terrain地形参数
地形是三维场景中的重要三维效果,能看到山峰的高低起伏效果。在创建地球的时候,你可以在配置项中通过terrain
参数来设置和是否开启地形。支持的参数,参考 地形的terrain参数说明
const map = new mars3d.Map("mars3dContainer", {
terrain: {
// type:'xyz',//默认未传入时代表 'xyz'
url: "http://data.mars3d.cn/terrain",
show: true
}
})
更新地形
如果不想在创建时设置地形,也可以创建完map后, 通过 mars3d.LayerUtil.createTerrainProvider 创建地形服务对象,并赋值给 map.terrainProvider ,目前1个球只支持1个地形服务
map.terrainProvider = mars3d.LayerUtil.createTerrainProvider({
type: "arcgis",
url: "https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer"
})
2.5 basemaps栅格瓦片底图
地形是三维的"骨骼",栅格底图就是我们浏览三维能感知的"皮肤"了,在创建地球的时候,你可以通过basemapOptions 添加栅格瓦片底图(允许添加多个,添加多个图层后可在底图控制器中切换),一般我们可以设置basemaps数组中默认显示的底图的show参数为true
const map = new mars3d.Map("mars3dContainer", {
basemaps: [
{
name: "天地图卫星",
icon: "img/basemaps/tdt_img.jpg",
type: "tdt",
layer: "img_d",
key: ["9ae78c51a0a28f06444d541148496e36"],
show: true
},
{
name: "离线地图",
icon: "img/basemaps/mapboxSatellite.jpg",
type: "xyz",
url: "http://data.mars3d.cn/tile/googleImg/{z}/{x}/{y}.jpg",
maximumLevel: 12
},
{
name: "单张图片",
icon: "img/basemaps/offline.jpg",
type: "image",
url: "img/tietu/world.jpg"
}
]
})
2.5.1 底图的图层参数
栅格底图所支持的图层类型,只能是瓦片图层,均是继承自 BaseTileLayer类 的图层类型。basemaps参数为一个数组,其中各图层的参数支持:
basemaps参数说明
参数名 | 类型 | 参数解释 |
---|---|---|
type | string | 图层类型 |
icon | string | 图层缩略图,用于图层切换控件的显示 |
通用参数 | BaseTileLayer类构造参数 | |
其他参数 | 每个type都有一些个性化的不同参数,参考各type对应的图层类构造参数 |
2.5.2 底图的type图层类型
basemaps所支持的type目前包括:
类型名 | 说明 | 对应的图层类 | 备注 |
---|---|---|---|
image | 单张图片 | mars3d.layer.ImageLayer | |
xyz | 标准金字塔地图 | mars3d.layer.XyzLayer | |
wms | OGC WMS标准服务 | mars3d.layer.WmsLayer | |
wmts | OGC WMTS标准服务 | mars3d.layer.WmtsLayer | |
arcgis | ArcGIS标准服务 | mars3d.layer.ArcGisLayer | |
arcgis_cache | ArcGIS切片 | mars3d.layer.ArcGisCacheLayer | |
tdt | 天地图 | mars3d.layer.TdtLayer | 在线地图 |
gaode | 高德 | mars3d.layer.GaodeLayer | 在线地图 |
baidu | 百度 | mars3d.layer.BaiduLayer | 在线地图 |
tencent | 腾讯 | mars3d.layer.TencentLayer | 在线地图 |
osm | OpenStreetMap(OSM) | mars3d.layer.OsmLayer | 国外在线地图 |
bing | 微软 BingMaps | mars3d.layer.ArcGisCacheLayer | 国外在线地图 |
mapbox | Mapbox地图 | mars3d.layer.MapboxLayer | 国外在线地图 |
ion | Cesium Ion服务 | mars3d.layer.IonLayer | 国外在线地图 |
谷歌地图 | mars3d.layer.GoogleLayer | 目前已被封 | |
gee | 谷歌地球企业服务 | mars3d.layer.GeeLayer | 需部署私服 |
2.5.3 更新底图
创建完成底图后,需要切换底图或获取当前的底图,可以根据config配置的id或name属性,显示指定的底图,如:
// 获取或设置当前显示的底图,设置时可以传入图层id或name
map.basemap = "离线地图"
// 获取配置的底图数组
const arr = map.getBasemaps()
2.6 layers叠加图层参数
在三维地图中,你可以在地图上添加多个图层来叠加显示。 在创建地球时,可以传layers参数 来将当前项目内常用的图层一次性配置好,代码中去按需使用。
const map = new mars3d.Map("mars3dContainer", {
layers: [
{
type: "tdt", // 必须的参数
name: "天地图注记",
layer: "img_z",
key: ["天地图token值"],
show: true
},
{
id: 1987,
type: "tileset",
name: "县城社区",
url: "http://data.mars3d.cn/3dtiles/qx-shequ/tileset.json",
show: false
}
]
})
2.6.1 可以叠加的类型
layers 配置支持的 basemaps所有支持的瓦片图层,还支持所有矢量覆盖物数据的加载,支持的type类型,请参考 图层类型 ,每个type都有一些个性化的不同参数,参考各type对应的图层类构造参数。
2.6.2 对图层的控制
可以通过 let layer = map.getLayer(1987,'id')来获取config.json中配置的对应id为1987的图层对象。
为了方便理解getLayer获取到的对象,layers配置的图层与下面的创建方式是等价的,
// 用工厂方法创建图层
const layer = mars3d.LayerUtil.create({
type: "tileset",
name: "县城社区",
url: "http://data.mars3d.cn/3dtiles/qx-shequ/tileset.json"
})
map.addLayer(layer)
在Map创建后可以通过addLayer和removeLayer方法来控制图层的加载和删除。
更多方法可以在图层类型 找到对应的 图层类 后,查阅对应类的属性或方法进行进一步控制及管理图层。
2.7 control、effect、thing参数
在创建地球的时候,你可以在配置项中: 通过control
对控件中的功能组件进行相应的配置、 通过effect
对特效进行配置、 通过thing
对场景中常用的管理及分析类进行配置。 这3类的参数初始化方式、取值方式、添加方式都比较类型。
control参数
const map = new mars3d.Map("mars3dContainer", {
control: {
// 以下是Cesium.Viewer所支持的控件相关的options
baseLayerPicker: true, // basemaps底图切换按钮,图层选择器,选择要显示的地图服务和地形服务
homeButton: true, // 视角复位按钮
sceneModePicker: true, // 二三维切换按钮, 选择投影模式,有三种:3D,2D,哥伦布视图
navigationHelpButton: true, // 帮助按钮,显示默认的地图控制帮助
infoBox: true, // 信息框
selectionIndicator: true, // 选择框
vrButton: true, // vr模式按钮
fullscreenButton: true, // 全屏按钮
animation: false, // 动画部件按钮(左下角),控制视图动画的播放速度
timeline: false, // 时间线(下侧),指示当前时间,并允许用户跳到特定的时间
geocoder: true, // POI查询按钮
geocoderConfig: { key: ["ae29a37307840c7ae4a785ac905927e0"] }, // POI查询按钮参数配置
// 以下是mars3d.control定义的控件
contextmenu: { hasDefault: true },
mouseDownView: true,
zoom: { insertIndex: 1 },
compass: { bottom: "toolbar", left: "5px" },
distanceLegend: { left: "100px", bottom: "2px" }
}
})
effect参数
const map = new mars3d.Map("mars3dContainer", {
effect: {
rain: {
speed: 10,
size: 20,
direction: 10
}
}
})
thing参数
const map = new mars3d.Map("mars3dContainer", {
thing: {
terrainClip: {
diffHeight: 50,
image: "//data.mars3d.cn/img/textures/poly-stone.jpg",
imageBottom: "//data.mars3d.cn/img/textures/poly-soil.jpg",
splitNum: 100,
area: [
{
exact: true,
diffHeight: 900,
positions: [
[116.334222, 30.899171, 645.5],
[116.370874, 30.899171, 645.5],
[116.370874, 30.944509, 645.5],
[116.334222, 30.944509, 645.5]
]
},
{
exact: true,
diffHeight: 200,
positions: [
[116.416497, 30.934256, 775.9],
[116.427392, 30.962941, 1084.9],
[116.434838, 30.932608, 900.4],
[116.462994, 30.923081, 771.4],
[116.437571, 30.916044, 906.4],
[116.44977, 30.894487, 776.1],
[116.424183, 30.908752, 727],
[116.402218, 30.898406, 593.1],
[116.414309, 30.918806, 588.8],
[116.387022, 30.933539, 700.6]
]
}
]
}
}
})
在地图初始化后,可以通过map.control.*
、map.effect.*
、map.thing.*
的方式来获取所有地图上已有的对应对象。 如果需要初始化不构造,后续可以通过阅读对应章节内容理解功能后new构造对应类,add到map地图中。
2.8 method参数
method参数对应map的一些属性和方法的参数化调用,通过参数方式来构造地图后就直接执行调用Map的相关属性、方法,便于序列化。 目前主要方便Studio低代码平台中实现零代码加载地图。
3 Map的属性
属性是指实例化地图后,可以通过map.*的方式来设置或获取地图的属性值。
3.1 主要属性
map.camera:是相机是三维场景渲染中非常重要的一个概念,用于控制场景的视角。相机用于代表人的眼睛,即从哪儿看,看向哪儿,哪些对象看得见,那些对象看不见。相机的类型为Cesium.Camera ,此类提供了大量的方法和属性用于操作视角,我们在后面的“相机”一节进行详细介绍。
map.canvas :是canvas元素,Mars3D是基于WebGL的,而WebGL绘图就是将canvas元素当做一个画布。
map.scene :场景是Mars3D依赖的Cesium底层程序中一个非常重要的对象,它是所有3D图形对象的容器,用于管理所有的3D图形对象和状态,上面的相机对象也是在场中对象内创建的,其类型为 Cesium.Scene
map.control.:Map初始化和
map.addControl(obj)
方法添加的控件对象都可以通过map.control.*来获取对象。map.effect.:Map初始化和
map.addEffect(obj)
方法添加的控件对象都可以通过map.effect.*来获取对象。map.thing.:Map初始化和
map.addThing(obj)
方法添加的控件对象都可以通过map.thing.*来获取对象。
4 Map的方法
map实例化后的对象提供了很多方法用于对地图进行操作。
4.1 主要方法
map.addLayer、map.removeLayer:控制图层的加载和删除
map.addControl、map.removeControl:控制控件的加载和删除
map.addEffect、map.removeEffect:来控制特效的加载和删除
map.addThing、map.removeThing:来控制Thing管理分析等其他类的加载和删除
map.bindContextMenu、map.unbindContextMenu、map.openContextMenu、map.closeContextMenu、map.getContextMenu:来控制右键菜单
map.centerAt、map.flyToExtent、map.flyToGraphic等flyTo开头的方法:来进行视角定位
还有更多方法,再此就不一一列举了,具体参考API文档及后续的教程中进行详细说明。