Mars3D开发基础:三维场景 Map

2,198 阅读11分钟

Mars3D 是什么?

Mars3D三维可视化平台 是火星科技 研发的一款基于 WebGL 技术实现的三维客户端开发平台,基于Cesium 优化提升与B/S架构设计,支持多行业扩展的轻量级高效能GIS开发平台,能够免安装、无插件地在浏览器中高效运行,并可快速接入与使用多种GIS数据和三维模型,呈现三维空间的可视化,完成平台在不同行业的灵活应用。

Mars3D平台可用于构建无插件、跨操作系统、 跨浏览器的三维 GIS 应用程序。平台使用 WebGL 来进行硬件加速图形化,跨平台、跨浏览器来实现真正的动态大数据三维可视化。通过 Mars3D产品可快速实现浏览器和移动端上美观、流畅的三维地图呈现与空间分析。

功能体验: 👉 Mars3D官网

开发资料: 👉 API文档  👉 开发教程 

开源代码: 👉 Github开源代码  👉 Gitee开源代码(国内)

Mars3D开发基础系列文档导航

  1. 三维场景 Map
  2. 地图控件
  3. 地图图层 Layer
  4. 加载DEM地形
  5. 栅格瓦片图层
  6. 坐标系及坐标变换
  7. 相机Camera及视角控制
  8. 时钟Clock及时序控制
  9. 事件机制
  10. 矢量图层Layer
  11. 矢量数据Graphic
  12. Property属性机制
  13. Material材质
  14. glTF小模型
  15. 3DTiles三维模型
  16. 场景特效
  17. 管理及分析功能

我们使用DIV渲染后看到的三维地球对象,我们统称为三维场景,在Mars3D中对应是mars3d.Map类,这是一切的开始,所有相关控制的起点。掌握学习好了mars3d.Map类 基本也就掌握好了Mars3D。

image.png

1. 三维场景初始化

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

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

当你需要对地图进行配置的时候,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
    }
  ]
})

2. mars3d.Map类 参数说明

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

mapOptions 参数包括:

参数名类型参数API说明
sceneObject参数清单场景
controlObject参数清单控件
terrainObject参数清单地形
basemapsArray参数清单底图图层
layersArray参数清单图层

更详细说明,参考 API文档 Map类

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

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

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

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

}).otherwise(function(error) {
  console.log('加载JSON出错', error)
})

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

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

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

2.2 运行效果

image.png

3. scene 场景参数

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

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, //是否允许 地形相机的碰撞检测
    },
  },
})

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

// 更新地球参数
map.setSceneOptions({
 cameraController: {
   maximumZoomDistance: 500000000
 }
})

4. 默认视角参数

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

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

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

5. 控件

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

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定义的控件
    defaultContextMenu: true, //右键菜单
    mouseDownView: true,
    compass: { top: '10px', right: '5px' },
    distanceLegend: { left: '100px', bottom: '2px' },
  },
})

6. 地形参数

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

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

6.1 地形的type类型

地形的 type 支持以下类型

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

6.2 更新地形

如果不想在创建时设置地形,也可以创建完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',
})

7. 栅格瓦片底图

地形是三维的"骨骼",栅格底图就是我们浏览三维能感知的"皮肤"了,在创建地球的时候,你可以通过basemapse 添加栅格瓦片底图(允许添加多个,添加多个图层后可在底图控制器中切换),一般我们可以设置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',
      },
  ]
})

7.1 底图的图层参数

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

basemaps参数说明

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

7.2 底图的type图层类型

basemaps所支持的type目前包括:

类型名说明对应的图层类备注
image单张图片mars3d.layer.ImageLayer
xyz标准金字塔地图mars3d.layer.XyzLayer
wmsOGC WMS标准服务mars3d.layer.WmsLayer
wmtsOGC WMTS标准服务mars3d.layer.WmtsLayer
arcgisArcGIS标准服务mars3d.layer.ArcGisLayer
arcgis_cacheArcGIS切片mars3d.layer.ArcGisCacheLayer
tdt天地图mars3d.layer.TdtLayer在线地图
gaode高德mars3d.layer.GaodeLayer在线地图
baidu百度mars3d.layer.BaiduLayer在线地图
tencent腾讯mars3d.layer.TencentLayer在线地图
osmOpenStreetMap(OSM)mars3d.layer.OsmLayer国外在线地图
bing微软 BingMapsmars3d.layer.ArcGisCacheLayer国外在线地图
mapboxMapbox地图mars3d.layer.MapboxLayer 国外在线地图
ionCesium 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()

8. 可以叠加的图层

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

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
    },
  ]
})

8.1 可以叠加的图层

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

8.2 对图层的控制

可以通过 let layer = map.getLayer(1987,'id')来获取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)

在Map创建后可以通过addLayerremoveLayer方法来控制图层的加载和删除。

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

image.png