当前位置:   article > 正文

Mars3D手把手开发教程(vue3)

mars3d

1. Mars3D是什么?

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

为企业提供敏捷高效的数字孪生可视化开发能力,助力企业加速数字化转型

2.Vue3项目中集成mars3D

(1)安装依赖

npm install vite-plugin-mars3d --save-dev

(2)修改 vite.config.ts 配置文件

(3)新建一个map.ts文件,底下代码直接复制

  1. import * as mars3d from "mars3d"
  2. import { Cesium } from "mars3d"
  3. import "mars3d/dist/mars3d.css";
  4. import "mars3d-cesium/Build/Cesium/Widgets/widgets.css";
  5. // 定义全局地图变量
  6. export let map: mars3d.Map | null = null;
  7. //必须有这两行css,否则地球出来了,样式还是乱的
  8. export function initMap() {
  9. // 创建三维地球场景
  10. map = new mars3d.Map("mars3dContainer", {
  11. scene: {
  12. center: { lat: 30.054604, lng: 108.885436, alt: 17036414, heading: 0, pitch: -90 },// 初始视角中心点和方向
  13. showSun: true, // 显示太阳
  14. showMoon: true, // 显示月亮
  15. showSkyBox: true, // 显示天空盒
  16. showSkyAtmosphere: false, // 关闭球周边的白色轮廓
  17. fog: true, // 开启雾效
  18. fxaa: true, // 开启FXAA抗锯齿
  19. globe: {
  20. showGroundAtmosphere: false, // 关闭球表面的大气效果
  21. depthTestAgainstTerrain: false,
  22. baseColor: "#546a53" // 球体基础颜色
  23. },
  24. cameraController: {
  25. zoomFactor: 3.0, // 缩放因子
  26. minimumZoomDistance: 1, // 最小缩放距离
  27. maximumZoomDistance: 50000000, // 最大缩放距离
  28. enableRotate: true, // 允许旋转
  29. enableZoom: true // 允许缩放
  30. },
  31. mapProjection: mars3d.CRS.EPSG3857, // 地图投影方式,这里是墨卡托投影
  32. mapMode2D: Cesium.MapMode2D.INFINITE_SCROLL // 2D模式下,地图可以无限滚动
  33. },
  34. control: {
  35. baseLayerPicker: true, // basemaps底图切换按钮
  36. homeButton: false, // 视角复位按钮
  37. sceneModePicker: false, // 二三维切换按钮
  38. navigationHelpButton: false, // 帮助按钮
  39. fullscreenButton: true, // 全屏按钮
  40. contextmenu: { hasDefault: false } // 右键菜单
  41. },
  42. terrain: {
  43. url: "//data.mars3d.cn/terrain", // 地形数据的URL
  44. show: true // 显示地形
  45. },
  46. basemaps: [
  47. {
  48. name: "暗色底图",
  49. type: "gaode",
  50. icon: "img/basemaps/blackMarble.png",
  51. layer: "vec",
  52. invertColor: true,
  53. filterColor: "#4e70a6",
  54. brightness: 0.6,
  55. contrast: 1.8,
  56. gamma: 0.3,
  57. hue: 1,
  58. saturation: 0
  59. show: true
  60. }
  61. ] as any,
  62. })
  63. return map
  64. }

(4)新建地图盒子,引入map.ts文件

  1. <template>
  2. <div>
  3. <div id="mars3dContainer" class="mars3d-container"></div>
  4. </div>
  5. </template>
  6. <script setup lang="ts">
  7. import { onMounted, ref } from 'vue';
  8. import * as mars3d from "mars3d"
  9. import { initMap,map } from "../map";
  10. //加载地图
  11. onMounted(() => {
  12. initMap();
  13. });
  14. <style scoped lang="scss">
  15. .mars3d-container {
  16. width: 100%;
  17. height: 100%;
  18. }
  19. </style>

自此,一个美丽的地图就出来了

 (5)如果要将视角移动到你设置的城市那里,改写map.ts文件中这个

(6)想要更换地图,更改map.ts文件中的basemaps更换底图,什么天地图,高德图,百度图,蓝色黑色地图等等

 

3.地图点位标注

创建图层-将图层添加到地图-创建点位对象-将点对象添加到图层 

  1. <template>
  2. <div>
  3. <div id="mars3dContainer" class="mars3d-container"></div>
  4. </div>
  5. </template>
  6. <script setup lang="ts">
  7. import { onMounted, ref } from 'vue';
  8. import * as mars3d from "mars3d"
  9. import { initMap, map } from "../map";
  10. import tb from '@/assets/image/hyfw.png'
  11. const arr = [
  12. { grid: '{"type":"Point","coordinates":[109.006887,34.232718]}', name: '测试', remark: 'xx区' },
  13. //其他数据...
  14. ];
  15. onMounted(() => {
  16. initMap();
  17. mapKindergarten()
  18. console.log(map, 'map');
  19. });
  20. let pointLayer: any;
  21. /**
  22. * Date:2024/3/21
  23. * Author:zx
  24. * Function:【地图点分布】
  25. * @param 无
  26. */
  27. const mapKindergarten = () => {
  28. // 初始化地图
  29. // 创建一个用于存放所有点位的图层
  30. pointLayer = new mars3d.layer.GraphicLayer({
  31. name: 'PointLayer',
  32. hasEdit: false,
  33. isAutoEditing: false
  34. });
  35. // 将图层添加到地图
  36. map.addLayer(pointLayer);
  37. // 遍历数组,为每个点位数据创建图形点
  38. arr.forEach((pointData: any) => {
  39. // 解析点位的坐标
  40. const coordinates = JSON.parse(pointData.grid).coordinates;
  41. // 创建 Mars3D 中的点对象(默认点位样式)
  42. // const pointGraphic = new mars3d.graphic.PointEntity({
  43. // position: coordinates,
  44. // attr: pointData,
  45. // style: {
  46. // color: mars3d.Cesium.Color.RED,
  47. // pixelSize: 10,
  48. // scale: 1,
  49. // image: undefined,
  50. // }
  51. // });
  52. // 创建自定义图标点
  53. // 创建 Mars3D 中的点对象(默认点位样式)
  54. const pointGraphic = new mars3d.graphic.BillboardEntity({
  55. position: coordinates,
  56. attr: pointData,
  57. style: {
  58. pixelSize: 10,
  59. scale: 0.5,
  60. image: tb,
  61. }
  62. });
  63. // 添加点位点击事件
  64. pointGraphic.on(mars3d.EventType.click, function (event: any) {
  65. console.log('点击了点位', event);
  66. });
  67. // 将点对象添加到图层
  68. pointLayer.addGraphic(pointGraphic);
  69. });
  70. };
  71. </script>
  72. <style scoped lang="scss">
  73. .mars3d-container {
  74. width: 100%;
  75. height: 100%;
  76. }
  77. </style>

效果图

4.热力图

(1)安装热力图库

   npm install mars3d-heatmap

 (2)引入库

    import "mars3d-heatmap"

(3)写函数

        注:  创建热力图层,添加图层,再调用函数

                  arr就是前面点位标注函数的arr数据

  1. /**
  2. * Date:2024/3/21
  3. * Author:zx
  4. * Function:【热力图】
  5. * @param 无
  6. */
  7. let heatLayer: any = null
  8. const mapKindergartenHeatmap = () => {
  9. let arrPoints: any = []
  10. arr.forEach((item: any) => {
  11. if (item.point || item.grid) {
  12. let pointData = item.point ? JSON.parse(item.point).coordinates : JSON.parse(item.grid).coordinates
  13. arrPoints.push({ lng: pointData[0], lat: pointData[1], value: 1 })
  14. }
  15. })
  16. if (heatLayer) {
  17. map.removeLayer(heatLayer)
  18. heatLayer = null
  19. }
  20. // 热力图 图层
  21. heatLayer = new mars3d.layer.HeatLayer({
  22. name: "Point",
  23. positions: arrPoints,
  24. heatStyle: {
  25. radius: 40,
  26. blur: 0.85,
  27. gradient: { 0.4: 'blue', 0.6: 'green',0.9: 'yellow',1: 'red' }
  28. },
  29. // 以下为矩形矢量对象的样式参数
  30. style: {
  31. arc: false, // 是否为曲面
  32. height: 10
  33. },
  34. // flyTo: true,
  35. })
  36. map.addLayer(heatLayer)
  37. };

效果如下

 

 5.地图面分布

创建面图层-将面图层添加到地图-创建多边形对象-将面对象添加到图层

下面是根据数据生成面的函数, polygonData是后台数据 ,我模拟了个别

  1. /**
  2. * Date:2024/3/21
  3. * Author:zx
  4. * Function:【地图面分布】
  5. * @param 无
  6. */
  7. let polygonData = ref( [
  8. {
  9. grid: {
  10. type: "Polygon",
  11. coordinates: [
  12. [
  13. [108.901467, 34.22501],
  14. [108.90235, 34.224611],
  15. [108.902374, 34.223664],
  16. [108.90208, 34.223183],
  17. [108.901581, 34.222639],
  18. [108.901447, 34.222412],
  19. [108.901445, 34.222413],
  20. [108.901417, 34.222425],
  21. [108.901366, 34.222449],
  22. [108.90134, 34.22246],
  23. [108.901334, 34.222463],
  24. [108.901295, 34.22248],
  25. [108.901291, 34.222482],
  26. [108.901232, 34.222509],
  27. [108.901189, 34.222527],
  28. [108.901173, 34.222534],
  29. [108.901103, 34.222568],
  30. [108.901033, 34.222601],
  31. [108.900963, 34.222635],
  32. [108.900906, 34.22266],
  33. [108.900899, 34.222663],
  34. [108.900827, 34.222695],
  35. [108.900821, 34.222697],
  36. [108.900732, 34.222737],
  37. [108.900636, 34.222778],
  38. [108.900541, 34.22282],
  39. [108.900446, 34.222862],
  40. [108.90035, 34.222904],
  41. [108.900292, 34.22293],
  42. [108.900234, 34.222956],
  43. [108.900171, 34.222983],
  44. [108.900783, 34.223906],
  45. [108.901467, 34.22501]
  46. ]
  47. ]
  48. },
  49. num: 1,
  50. name: "中天花园"
  51. }, {
  52. grid: {
  53. type: "Polygon",
  54. coordinates: [
  55. [
  56. [108.903272,34.19876],
  57. [108.902163,34.198774],
  58. [108.902107,34.198582],
  59. [108.901865,34.197436],
  60. [108.90172,34.197456],
  61. [108.900913,34.197557],
  62. [108.900863,34.197241],[108.900343,34.197292],
  63. [108.900339,34.199717],[108.90037,34.199792],
  64. [108.900392,34.199849],[108.903211,34.19984],
  65. [108.903251,34.199807],[108.903278,34.199785],
  66. [108.903273,34.199352],[108.903272,34.19876]
  67. ]
  68. ]
  69. },
  70. num: 1,
  71. name: "xx花园"
  72. },
  73. {
  74. grid: {
  75. type: "Polygon",
  76. coordinates: [
  77. [
  78. [108.911196,34.22649],
  79. [108.910652,34.22675],[108.911124,34.22748],
  80. [108.911472,34.227295],[108.911621,34.227229],
  81. [108.911196,34.22649]
  82. ]
  83. ]
  84. },
  85. num: 1,
  86. name: "xx花园"
  87. },
  88. {
  89. grid: {
  90. type: "Polygon",
  91. coordinates: [
  92. [
  93. [108.901062,34.232978],[108.901054,34.233017],
  94. [108.900955,34.233057],[108.900473,34.233278],
  95. [108.900505,34.233331],[108.900542,34.233393],
  96. [108.90058,34.233455],[108.900625,34.233524],
  97. [108.900669,34.233593],[108.900717,34.233666],
  98. [108.900765,34.23374],[108.900813,34.233813],
  99. [108.900856,34.233877],[108.900898,34.23394],
  100. [108.900941,34.234004],[108.900983,34.234067],
  101. [108.901015,34.234114],[108.901023,34.234127],
  102. [108.901068,34.234196],[108.901112,34.234264],
  103. [108.901156,34.234333],[108.9012,34.234401],
  104. [108.901245,34.23447],[108.901289,34.234538],
  105. [108.901333,34.234607],[108.90138,34.23468],[
  106. 108.901427,34.234752],[108.901473,34.234825],
  107. [108.90152,34.234897],[108.901567,34.23497],
  108. [108.901583,34.234995],[108.901618,34.235048],
  109. [108.901653,34.235102],[108.901688,34.235156],
  110. [108.90169,34.235161],[108.901703,34.235183],
  111. [108.901987,34.235047],[108.901305,34.233942],
  112. [108.901418,34.233891],[108.901066,34.233256],
  113. [108.901635,34.232992],[108.901228,34.23234],
  114. [108.901179,34.232363],[108.901094,34.232402],
  115. [108.901009,34.232441],[108.900923,34.232479],
  116. [108.900838,34.232518],[108.900798,34.232537],
  117. [108.90079,34.23254],[108.901062,34.232978]
  118. ]
  119. ]
  120. },
  121. num: 1,
  122. name: "xx花园"
  123. },
  124. {
  125. grid: {
  126. type: "Polygon",
  127. coordinates: [
  128. [
  129. [108.903119,34.228991],
  130. [108.902817,34.228477],
  131. [108.90172,34.228988],
  132. [108.901765,34.229057],
  133. [108.90181,34.229128],
  134. [108.901856,34.229198],
  135. [108.901901,34.229269],
  136. [108.901947,34.229339],
  137. [108.901993,34.22941],
  138. [108.902031,34.229469],
  139. [108.902034,34.229474],
  140. [108.902621,34.229205],
  141. [108.903119,34.228991]
  142. ]
  143. ]
  144. },
  145. num: 1,
  146. name: "xx花园"
  147. }
  148. ,
  149. {
  150. grid: {
  151. type: "Polygon",
  152. coordinates: [
  153. [
  154. [108.903443,34.230496],
  155. [108.903075,34.229939],
  156. [108.902621,34.229205],
  157. [108.902034,34.229474],
  158. [108.902081,34.229546],
  159. [108.902131,34.229624],
  160. [108.90218,34.229701],
  161. [108.90223,34.229778],
  162. [108.90228,34.229856],
  163. [108.90233,34.229933],
  164. [108.90238,34.23001],
  165. [108.90243,34.230088],
  166. [108.90248,34.230165],
  167. [108.90253,34.230243],
  168. [108.90258,34.23032],
  169. [108.90263,34.230397],
  170. [108.902677,34.23047],
  171. [108.902724,34.230542],
  172. [108.902772,34.230614],
  173. [108.902819,34.230687],
  174. [108.902865,34.230758],
  175. [108.903443,34.230496]
  176. ]
  177. ]
  178. },
  179. num: 1,
  180. name: "xx花园"
  181. },
  182. {
  183. grid: {
  184. type: "Polygon",
  185. coordinates: [
  186. [
  187. [108.904156,34.230607],
  188. [108.903706,34.229914],
  189. [108.903119,34.228991],
  190. [108.902621,34.229205],
  191. [108.903075,34.229939],
  192. [108.903443,34.230496],
  193. [108.903656,34.230842],
  194. [108.904156,34.230607]
  195. ]
  196. ]
  197. },
  198. num: 1,
  199. name: "xx花园"
  200. }
  201. ])
  202. const mapKindergartenFace = () => {
  203. // 创建一个用于存放所有面的图层
  204. const polygonLayer = new mars3d.layer.GraphicLayer({
  205. name: 'PolygonLayer',
  206. hasEdit: false,
  207. isAutoEditing: false
  208. });
  209. // 将图层添加到地图
  210. map.addLayer(polygonLayer);
  211. // 遍历数组,为每个面数据创建多边形
  212. polygonData.value.forEach((polygonCoords: any) => {
  213. // 解析多边形的坐标
  214. const coordinates = JSON.parse(polygonCoords.grid).coordinates; // 这里假设polygonCoords是一个JSON格式的坐标数组
  215. // 创建 Mars3D 中的多边形对象
  216. const polygonEntity = new mars3d.graphic.PolygonEntity({
  217. positions: coordinates, // 设置多边形的位置坐标数组
  218. style: {
  219. color: "#e8b99d"
  220. // fillColor: mars3d.Cesium.Color.RED.withAlpha(1), // 设置面的填充颜色和透明度
  221. // outlineColor: mars3d.Cesium.Color.BLACK, // 设置面的边框颜色
  222. // outlineWidth: 10 // 设置面的边框宽度
  223. }
  224. });
  225. // 将多边形对象添加到图层
  226. polygonLayer.addGraphic(polygonEntity);
  227. });
  228. };

效果如下

6. 地图放大展示点位名称

(1)编写一个相机移动视角的函数(三维地图,不再是地图的缩放,而是视角,)

         函数中创建了标签图层,并添加

      sceneData.value.alt为相机的高度,也就是地图放大缩小率

  1. /**
  2. * Date:2024/3/21
  3. * Author:zx
  4. * Function:【相机移动或视角变化】
  5. * @param 无
  6. */
  7. let labelLayer: any = null; // 添加标签的图层
  8. let sceneData = ref()
  9. const map_cameraChangedHandler = () => {
  10. sceneData.value = map.getCameraView();
  11. // console.log(sceneData.value, '视角');
  12. // 检查相机高度是否小于 3000
  13. if (sceneData.value.alt > 10000) {
  14. // 删除 labelLayer 图层中的标签
  15. map.getLayers().forEach((item: any) => {
  16. if (item.options.name === "LabelLayer") {
  17. map.removeLayer(item);
  18. }
  19. })
  20. } else {
  21. // 显示标签
  22. labelLayer = new mars3d.layer.GraphicLayer({
  23. name: 'LabelLayer',
  24. hasEdit: false,
  25. isAutoEditing: false
  26. });
  27. map.addLayer(labelLayer);
  28. // 遍历标签图层中的标签,并添加到图层中
  29. arr.forEach((pointData: any) => {
  30. const coordinates = JSON.parse(pointData.grid).coordinates;
  31. // 创建标签图形
  32. const labelGraphic = new mars3d.graphic.LabelEntity({
  33. position: coordinates,
  34. style: {
  35. text: pointData.name, // 幼儿园名称
  36. font: '16px sans-serif', // 字体大小和样式
  37. fillColor: mars3d.Cesium.Color.YELLOW, // 字体颜色
  38. // outlineColor: mars3d.Cesium.Color.BLACK, // 字体描边颜色
  39. outlineWidth: 1, // 字体描边宽度
  40. horizontalOrigin: mars3d.Cesium.HorizontalOrigin.CENTER, // 文本水平对齐方式
  41. verticalOrigin: mars3d.Cesium.VerticalOrigin.BOTTOM, // 文本垂直对齐方式
  42. pixelOffset: new mars3d.Cesium.Cartesian2(0, -40), // 文本偏移量,使其显示在点的上方
  43. disableDepthTestDistance: Number.POSITIVE_INFINITY // 防止标签被遮挡
  44. }
  45. });
  46. // 将标签图形添加到标签图层中
  47. labelLayer.addGraphic(labelGraphic);
  48. });
  49. }
  50. };

(2)在点位标注函数那 绑定相机视角事件

 

效果如下,可自由设置相机视角高度,实现放大展示点位信息,缩小隐藏点位信息

通过本文,开发者将获得对Mars3D简单的一些操作,更高级的功能小编还在学习中,期待一起进步。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/617996
推荐阅读
相关标签
  

闽ICP备14008679号