三维场景 Map

4/3/2023

我们使用DIV渲染后看到的三维地球对象,我们统称为三维场景,在Mars3D中对应是mars3d.Map类 (opens new window),它是构建三维地球应用程序的入口,我们称其为视图容器,它承载了Mars3D应用的所有内容。这是一切的开始,所有相关控制的起点。掌握学习好了mars3d.Map类 基本也就掌握好了Mars3D。

# 1. 三维场景初始化

在使用mars3d时你可以根据需要对默认参数进行配置,如果你只是想得到默认的效果,你仅需要写下面一行代码即可:

var map = new mars3d.Map('mars3dContainer')
1

当你需要对地图进行配置的时候,mars3d提供了详细的参数配置方案(如下),你可以暂时不需要完全理解各个参数的意义,在接下来的后续教程中我们会详细解释相关参数。

// 创建三维地球场景
var 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
    }
  ]
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60

# 2. mars3d.Map类 参数说明

参数名 类型 参数解释
id String 或 Cesium.Viewer 地图容器的div的id或已经构造好的viewer对象
mapOptions Object 创建地球的参数

mapOptions 参数包括:

参数名 类型 参数API 说明
scene Object 参数清单 (opens new window) 场景参数
terrain Object 参数清单 (opens new window) 地形
basemaps Array 参数清单 (opens new window) 底图图层
layers Array 参数清单 (opens new window) 图层
control Object 参数清单 (opens new window) 控件
effect Object 参数清单 (opens new window) 特效
thing Object 参数清单 (opens new window) Thing对象(如分析、管理类等)
mouse Object 参数清单 (opens new window) 鼠标操作相关配置参数
method Object 参数清单 (opens new window) 通过参数方式来构造地图后就直接执行调用Map的相关属性、方法,便于序列化

更详细说明,参考 API文档 Map类 (opens new window)

# 2.1 使用json配置文件记录参数快速创建三维场景

我们在不同项目应用时,可能是同一套代码,仅仅只是地图的配置参数不一样, 那么我们可以把地图的参数保存在后端服务动态生成或存储在json文件,将三维场景参数化。 我们可以直接加载使用不同json数据来快速创建各种三维场景。

# (1)通过任意方式去读取json文件,下面只是一种演示的方式

let configUrl = 'http://mars3d.cn/config/config.json'
mars3d.Util.fetchJson({ url: configUrl }).then(function(json) {  
  initMap(json.map3d)//构建地图

}).otherwise(function(error) {
  console.log('加载JSON出错', error)
})
1
2
3
4
5
6
7

# (2)读取到的json对象传入new mars3d.Map方法创建地球

function initMap(mapOptions) { 
  //创建三维地球场景
  var map = new mars3d.Map('mars3dContainer', mapOptions)
}
1
2
3
4

config.json中的属性参数是与mapOptions参数相同。

# 2.2 运行效果

新窗口查看

# 3. scene 场景参数

scene场景是所有3D图形对象的容器(HTML canvas),在场景对象中我们可以控制:globe 椭圆体、camera相机 等。 在创建地图时,你可以通过参数中scene参数配置场景中的默认视角(类似二维地图的地图层级)、三维场景的各种参数控制、相机的各种控制等。 参数解释参考 API文档 (opens new window)

var 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, //是否允许 地形相机的碰撞检测
    },
  },
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

地球创建好之后,你可以通过参考下面代码示例来更新scene参数

// 更新地球参数
map.setSceneOptions({
 cameraController: {
   maximumZoomDistance: 500000000
 }
})
1
2
3
4
5
6

# 4. 默认视角参数

你如果想设置进入地图页面时,自定义默认视角和地图层级的话,你可以在创建地球时的scene参数中设置center参数 (opens new window) 值:

var map = new mars3d.Map('mars3dContainer', {
  scene: {
    center: { lat: 25.389914, lng: 119.084961, alt: 1179575, heading: 346, pitch: -60 }
  }
})
1
2
3
4
5

center参数不容易手动修改,建议通过map.getCameraView (opens new window) 方法获取当前的地图视角后拷贝设置到config.json中。或者在地图空白区域右键菜单中【查看当前视角】来快捷获取下参数值。

# 5. 控件

在创建地球的时候,你可以在配置项中通过control对控件中的功能组件进行相应的配置,支持的参数,参考 control参数说明 (opens new window)

var 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" },
  },
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

在地图初始化后,可以通过map.control.**的方式来获取所有地图上已有的控件对象。

# 6. 地形参数

地形是三维场景中的重要三维效果,能看到山峰的高低起伏效果。在创建地球的时候,你可以在配置项中通过terrain参数来设置和是否开启地形。支持的参数,参考 地形的terrain参数说明 (opens new window)

var map = new mars3d.Map('mars3dContainer', {
  terrain: {
    //type:'xyz',//默认未传入时代表 'xyz'
    url: 'http://data.mars3d.cn/terrain',
    show: true
  },
})
1
2
3
4
5
6
7

# 6.1 地形的type类型

地形的 type (opens new window) 支持以下类型

类名 说明
xyz 标准xyz服务(未配置时的默认值)
arcgis ArcGIS地形服务
ion cesium官方ion在线服务
gee 谷歌地球企业版服务
vr vr地形服务
none 无地形,标准椭球体

# 6.2 更新地形

如果不想在创建时设置地形,也可以创建完map后, 通过 mars3d.LayerUtil.createTerrainProvider (opens new window) 创建地形服务对象,并赋值给 map.terrainProvider (opens new window) ,目前1个球只支持1个地形服务

map.terrainProvider = mars3d.LayerUtil.createTerrainProvider({
  type: 'arcgis',
  url: 'https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer',
})
1
2
3
4

# 7. 栅格瓦片底图

地形是三维的"骨骼",栅格底图就是我们浏览三维能感知的"皮肤"了,在创建地球的时候,你可以通过basemapse (opens new window) 添加栅格瓦片底图(允许添加多个,添加多个图层后可在底图控制器中切换),一般我们可以设置basemaps数组中默认显示的底图的show参数为true

var 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',
      },
  ]
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# 7.1 底图的图层参数

栅格底图所支持的图层类型,只能是瓦片图层,均是继承自 BaseTileLayer类 (opens new window) 的图层类型。basemaps参数为一个数组,其中各图层的参数支持:

basemaps参数说明

参数名 类型 参数解释
type string 图层类型
icon string 图层缩略图,用于图层切换控件的显示
通用参数 BaseTileLayer类构造参数 (opens new window)
其他参数 每个type都有一些个性化的不同参数,参考各type对应的图层类构造参数

# 7.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 国外在线地图
google 谷歌地图 mars3d.layer.GoogleLayer 目前已被封
gee 谷歌地球企业服务 mars3d.layer.GeeLayer 需部署私服

# 7.3 更新底图

创建完成底图后,需要切换底图或获取当前的底图,可以根据config配置的id或name属性,显示指定的底图,如:

//获取或设置当前显示的底图,设置时可以传入图层id或name
map.basemap = '离线地图' 

//获取配置的底图数组
let arr = map.getBasemaps()

1
2
3
4
5
6

# 8. 可以叠加的图层

在三维地图中,你可以在地图上添加多个图层来叠加显示。 在创建地球时,可以传layers参数 (opens new window) 来将当前项目内常用的图层一次性配置好,代码中去按需使用。

var map = new mars3d.Map('mars3dContainer', {
  layers: [
    {
      "type": "tdt", //必须的参数
      "name": "天地图注记",
      "layer": "img_z",
      "key": ["天地图token值"],
      "show": true
    },
    {
      "id":1987,
      "type": "3dtiles",
      "name": "县城社区",
      "url": "http://data.mars3d.cn/3dtiles/qx-shequ/tileset.json",
      "show": false
    },
  ]
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 8.1 可以叠加的图层

layers 配置支持的 basemaps所有支持的瓦片图层,还支持所有矢量覆盖物数据的加载,支持的type类型,请参考 图层类型 (opens new window) ,每个type都有一些个性化的不同参数,参考各type对应的图层类构造参数。

# 8.2 对图层的控制

可以通过 let layer = map.getLayer(1987,'id') (opens new window)来获取config.json中配置的对应id为1987的图层对象。

为了方便理解getLayer获取到的对象,layers配置的图层与下面的创建方式是等价的,

//用工厂方法创建图层
var layer = mars3d.LayerUtil.create({
  "type": "3dtiles",
  "name": "县城社区",
  "url": "http://data.mars3d.cn/3dtiles/qx-shequ/tileset.json",
}) 
map.addLayer(layer)
1
2
3
4
5
6
7

在Map创建后可以通过addLayer (opens new window)removeLayer (opens new window)方法来控制图层的加载和删除。

更多方法可以在图层类型 (opens new window) 找到对应的 图层类 后,查阅对应类的属性或方法进行进一步控制及管理图层。

最后更新: 11/14/2024, 12:03:09 PM