当前位置:   article > 正文

vue3 mars3d 天地图_mars3d绘制结束经纬度

mars3d绘制结束经纬度

准备工作:

        安装mars3d依赖:

                npm i mars3d 

                npm i mars3d-heatmap (热力图,需要的话安装)

                npm i -D copy-webpack-plugin

                增加mars3d目录配置,修改vue.config.js中configureWebpack里的内容如下:

  1. const CopyWebpackPlugin = require("copy-webpack-plugin");
  2. const cesiumSourcePath = "node_modules/mars3d-cesium/Build/Cesium/"; // cesium库安装目录
  3. const cesiumRunPath = "./mars3d-cesium/"; // cesium运行时路径
  4. const timeStamp = Date.now()
  5. module.exports = {
  6. configureWebpack: (config) => {
  7. const plugins = [
  8. // 标识cesium资源所在的主目录,cesium内部资源加载、多线程等处理时需要用到
  9. new webpack.DefinePlugin({
  10. CESIUM_BASE_URL: JSON.stringify(path.join(config.output.publicPath, cesiumRunPath))
  11. }),
  12. // Cesium相关资源目录需要拷贝到系统目录下面(部分CopyWebpackPlugin版本的语法可能没有patterns)
  13. new CopyWebpackPlugin([
  14. { from: path.join(cesiumSourcePath, 'Workers'), to: path.join(config.output.path, cesiumRunPath, 'Workers') },
  15. { from: path.join(cesiumSourcePath, 'Assets'), to: path.join(config.output.path, cesiumRunPath, 'Assets') },
  16. { from: path.join(cesiumSourcePath, 'ThirdParty'), to: path.join(config.output.path, cesiumRunPath, 'ThirdParty') },
  17. { from: path.join(cesiumSourcePath, 'Widgets'), to: path.join(config.output.path, cesiumRunPath, 'Widgets') }
  18. ])
  19. ]
  20. if (process.env.NODE_ENV === "production") {
  21. plugins.push(
  22. new UglifyJSPlugin({
  23. uglifyOptions: {
  24. //删除注释
  25. output: {comments: false},
  26. warnings: false,
  27. //删除console 和 debugger 删除警告
  28. compress: {
  29. drop_debugger: true,
  30. drop_console: true
  31. }
  32. },
  33. cache: true, // 启用文件缓存
  34. sourceMap: false,//不生成调试文件
  35. parallel: true // 使用多进程并行运行来提高构建速度
  36. })
  37. );
  38. }
  39. config.plugins = [...config.plugins, ...plugins]
  40. //给打包的文件名加上时间戳,防止浏览器缓存
  41. config.output.filename = `js/[name].${timeStamp}.js`
  42. config.output.chunkFilename = `js/[name].${timeStamp}.js`
  43. return {
  44. module: { unknownContextCritical: false }, // 配置加载的模块类型,cesium时必须配置
  45. plugins: plugins
  46. }
  47. },
  48. //...其它配置
  49. }

组件页:

  1. <template>
  2. <div class="r-map-3d">
  3. <div class="map-box" :id="mapId"></div>
  4. </div>
  5. </template>
  6. <script setup>
  7. import {defineEmits, defineProps, onMounted, reactive, ref} from 'vue'
  8. import mars3D from '@/plugins/mars3d/mapController'
  9. const props = defineProps({
  10. //中心点
  11. center: {
  12. type: Array,
  13. default: () => [0, 0]
  14. }
  15. })
  16. const emit = defineEmits(['onLoad']);
  17. const mapId = ref(`map_${Date.now()}`)
  18. const data = reactive({
  19. map: null,
  20. })
  21. onMounted(() => {
  22. data.map = new mars3D(mapId.value, props.center)
  23. emit('onLoad', data.map)
  24. })
  25. </script>
  26. <style scoped lang="scss">
  27. .r-map-3d {
  28. width: 100%;
  29. height: 100%;
  30. .map-box {
  31. height: 100%;
  32. width: 100%;
  33. }
  34. }
  35. </style>

mapController.js:(地图操作类)

  1. import {mapUrl, mapAk} from "@/config/baseURL";
  2. //引入cesium基础库
  3. import "mars3d-cesium/Build/Cesium/Widgets/widgets.css";
  4. import * as Cesium from "mars3d-cesium";
  5. //导入mars3d主库
  6. import "mars3d/dist/mars3d.css";
  7. import * as mars3d from "mars3d";
  8. import "mars3d-heatmap"
  9. export default class MapController {
  10. constructor(mapId) {
  11. this.ak = mapAk
  12. this.mapId = mapId
  13. /** 地图实例 */
  14. this.instance = null
  15. this.initMap()
  16. }
  17. /**
  18. * 创建天地图层
  19. * @param name 描述
  20. * @auth Roffer
  21. * @date 2022/9/29 15:50
  22. *
  23. */
  24. initMap() {
  25. // 需要覆盖config.json中地图属性参数(当前示例框架中自动处理合并)
  26. //option相关设置:http://mars3d.cn/apidoc.html#Map
  27. const mapOptions = {
  28. //scene相关设置:http://mars3d.cn/api/Map.html#.sceneOptions
  29. scene: {
  30. center: {lat: 29.068075, lng: 103.966252, alt: 82849.5, heading: 358.9, pitch: -28.4},
  31. showSkyAtmosphere: false,
  32. backgroundColor: '#000',
  33. contextOptions: {
  34. webgl: {
  35. //通过canvas.toDataURL()实现截图需要将该项设置为true
  36. preserveDrawingBuffer: true
  37. }
  38. },
  39. cameraController: {
  40. //相机最近视距,变焦时相机位置的最小量级(以米为单位),默认为1。该值是相机与地表(含地形)的相对距离。默认1.0
  41. minimumZoomDistance: 1,
  42. //相机最远视距,变焦时相机位置的最大值(以米为单位)。该值是相机与地表(含地形)的相对距离。默认50000000.0
  43. maximumZoomDistance: 200000
  44. },
  45. globe: {
  46. show: true,//是否显示地球
  47. }
  48. },
  49. // control: {
  50. // locationBar: {
  51. // fps: true,//是否显示实时FPS帧率
  52. // navigationHelpButton: true
  53. // }
  54. // },
  55. }
  56. this.instance = new mars3d.Map(this.mapId, mapOptions); //支持的参数请看API文档:http://mars3d.cn/api/Map.html
  57. this.instance.basemap = 2017 // 蓝色底图
  58. const mapLayer = mars3d.LayerUtil.create({
  59. type: "wmts",
  60. url: mapUrl,
  61. //wmts服务元数据中指定的layer值
  62. format: "image/png",
  63. layer: "defaultLayer",
  64. style: "default",
  65. //跨域支持,在使用html2canvas截屏的时候,如果不设置该属性,会截不到地图内容
  66. crossOrigin: 'Anonymous',
  67. tileMatrixSetID: "GetTileMatrix",
  68. minimumLevel: 3,
  69. maximumLevel: 17,
  70. minimumTerrainLevel: 1,
  71. maximumTerrainLevel: 25,
  72. zIndex: 2,
  73. crs: "EPSG4490",
  74. chinaCRS: "WGS84",
  75. tileWidth: 256,
  76. tileHeight: 256,
  77. name: "影像",
  78. extent: {
  79. xmin: 96.8064823,
  80. ymin: 25.68096106,
  81. xmax: 109.1252279,
  82. ymax: 34.75215408
  83. }
  84. })
  85. this.instance.addLayer(mapLayer)
  86. //获取右键菜单绘制完成数据
  87. this.instance.on(mars3d.EventType.drawCreated, (e) => {
  88. console.log(JSON.stringify(e.graphic));
  89. })
  90. }
  91. /**
  92. * 区域标记
  93. * @param areaCode 区域编码
  94. * @param filter 透明度,默认不透明,值范围:0~1
  95. * @param popupState 点击地图popup显隐
  96. * @auth Roffer
  97. * @date 2022/11/10 19:03
  98. *
  99. */
  100. addAreaLayer(areaCode = '510100000000', filter = 1, styleCback,popupState=true) {
  101. const geoJsonLayer = new mars3d.layer.GeoJsonLayer({
  102. name: "成都市",
  103. url: `/json/5101/${areaCode}.json`,
  104. allowDrillPick: true,
  105. symbol: {
  106. type: "polygon",
  107. styleOptions: {
  108. materialType: mars3d.MaterialType.PolyGradient, // 重要参数,指定材质
  109. // materialType: mars3d.MaterialType.Stripe, // 重要参数,指定材质
  110. materialOptions: {
  111. color: "#3388cc",
  112. opacity: 0.7,
  113. alphaPower: 1.3
  114. },
  115. // 面中心点,显示文字的配置
  116. label: {
  117. text: "{name}", // 对应的属性名称
  118. opacity: 1,
  119. font_size: 18,
  120. color: "#fff",
  121. font_family: "宋体",
  122. outline: false,
  123. scaleByDistance: true,
  124. scaleByDistance_far: 20000000,
  125. scaleByDistance_farValue: 0.1,
  126. scaleByDistance_near: 1000,
  127. scaleByDistance_nearValue: 1
  128. }
  129. },
  130. callback: styleCback ? styleCback : function (attr, styleOpt) {
  131. const randomHeight = (attr.childrenNum || 1) * 600 // 测试的高度
  132. return {
  133. materialOptions: {
  134. color: attr.fill,
  135. alphaPower: filter
  136. // color: getColor()
  137. },
  138. height: 20,
  139. diffHeight: randomHeight
  140. }
  141. }
  142. },
  143. popup:popupState ? "{name}" : false
  144. })
  145. this.instance.addLayer(geoJsonLayer)
  146. const arrColor = ["rgb(15,176,255)", "rgb(18,76,154)", "#40C4E4", "#42B2BE", "rgb(51,176,204)", "#8CB7E5", "rgb(0,244,188)", "#139FF0"]
  147. let index = 0
  148. function getColor() {
  149. return arrColor[++index % arrColor.length]
  150. }
  151. return geoJsonLayer
  152. }
  153. /**
  154. * 添加自定义多边形
  155. * @param geoJson geoJson数据
  156. * @param color 多边形颜色
  157. * @auth Roffer
  158. * @date 2022/12/8 11:01
  159. *
  160. */
  161. addCustomLayer({pointList, color, text, popup, popupOptions, tooltip, tooltipOptions}) {
  162. const graphicLayer = this.genGraphicLayer()
  163. const graphic = new mars3d.graphic.PolygonEntity({
  164. positions: pointList,
  165. style: {
  166. color,
  167. opacity: 0.5,
  168. outline: false,
  169. outlineWidth: 3,
  170. outlineColor: "#ffffff",
  171. highlight: {
  172. opacity: 0.8
  173. },
  174. label: {
  175. show: false,
  176. text,
  177. font_size: 12,
  178. color: "#ffffff",
  179. distanceDisplayCondition: true,
  180. distanceDisplayCondition_far: 500000,
  181. distanceDisplayCondition_near: 0
  182. }
  183. },
  184. popup,
  185. popupOptions,
  186. tooltip,
  187. tooltipOptions
  188. })
  189. graphicLayer.addGraphic(graphic)
  190. this.instance.addLayer(graphicLayer)
  191. return graphicLayer
  192. }
  193. /**
  194. * 添加一个自定义标注层
  195. * @auth Roffer
  196. * @date 2022/11/11 14:19
  197. *
  198. */
  199. genGraphicLayer() {
  200. let graphicLayer = new mars3d.layer.GraphicLayer()
  201. this.instance.addLayer(graphicLayer)
  202. return graphicLayer
  203. }
  204. /**
  205. * 添加自定义html标记点,适用于小于100条数据
  206. * @param point 经纬度,示例:[123.1,22.444]
  207. * @param html 要显示的html内容
  208. * @param popup 自定义详细信息(String,Array,function)
  209. * @param popupOptions 自定义详细信息参数设置(Object)详情:http://mars3d.cn/api/Popup.html#.StyleOptions
  210. * @param tooltip 自定义鼠标悬浮提示信息(String,Array,function)
  211. * @param tooltipOptions 自定义鼠标悬浮提示信息参数设置(Object)详情:http://mars3d.cn/api/Tooltip.html#.StyleOptions
  212. * @param attr 附加自定义属性(可在点击时,通过e.target.attr获取)
  213. * @param click 点击回调函数(返回点击的对象)
  214. * @param style Object,覆盖style对象中的属性值
  215. * @auth Roffer
  216. * @date 2022/10/22 14:55
  217. *
  218. */
  219. addDivLayer({point, html, popup, popupOptions, tooltip, tooltipOptions, attr, click, style}, graphicLayer) {
  220. const graphic = new mars3d.graphic.DivGraphic({
  221. position: new mars3d.LngLatPoint(point[0], point[1], 915),
  222. style: {
  223. html,
  224. horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
  225. verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
  226. clampToGround: true,
  227. offsetX: -20,
  228. offsetY: -30,
  229. ...style
  230. },
  231. attr,
  232. popup,
  233. popupOptions,
  234. tooltip,
  235. tooltipOptions,
  236. eventParent: false,//不冒泡事件
  237. })
  238. graphicLayer.addGraphic(graphic)
  239. click && graphic.on(mars3d.EventType.click, click)
  240. return graphicLayer
  241. }
  242. /**
  243. * 批量添加html标标注
  244. * @param list 数据,
  245. * 格式为:
  246. * [{
  247. * point:[103.111,30.123],html:'<div>xxx</div>',attr:{},click:()=>{}
  248. * },...]
  249. * @auth Roffer
  250. * @date 2022/11/11 14:00
  251. *
  252. */
  253. batchAddDivLayer(list = []) {
  254. // 创建矢量数据图层
  255. let graphicLayer = this.genGraphicLayer()
  256. list.forEach(item => {
  257. this.addDivLayer(item, graphicLayer)
  258. })
  259. return graphicLayer
  260. }
  261. /**
  262. * 获取当前屏幕边界坐标
  263. * @auth Roffer
  264. * @date 2022/11/21 15:37
  265. *
  266. */
  267. getScreenXY() {
  268. //屏幕边界坐标
  269. let info = this.instance.viewer.camera.computeViewRectangle()
  270. info.east = Cesium.Math.toDegrees(info.east)
  271. info.north = Cesium.Math.toDegrees(info.north)
  272. info.south = Cesium.Math.toDegrees(info.south)
  273. info.west = Cesium.Math.toDegrees(info.west)
  274. // east 104.58916517174933
  275. // north 30.8081617249502
  276. // south 30.48271217718593
  277. // west 103.95342383654778
  278. return info
  279. }
  280. /**
  281. * 添加自定义标记点
  282. * @param data 参数对象,包含以下:
  283. * url 请求数据的接口地址(url、data二选一)
  284. * dataColumn data字段key(url时指定)
  285. * data 请求数据的接口地址(url、data二选一)
  286. * lngColumn 经纬字段key
  287. * latColumn 纬纬字段key
  288. * altColumn 高度字段key
  289. * positionIconImg 显示的图标图片
  290. * showGroup 是否显示聚合分组数据,默认true显示
  291. * text 显示的名称字段key
  292. * @param popup 详细信息对象
  293. * key:对象中的key值
  294. * item[key]:显示的名称 eg:{name:'名称'}
  295. * @auth Roffer
  296. * @date 2022/10/22 14:55
  297. *
  298. */
  299. addBusineDataLayer(data, popup) {
  300. let option = {
  301. showGroup: true,
  302. ...data
  303. }
  304. // 创建矢量数据图层(业务数据图层)
  305. let busineDataLayer = new mars3d.layer.BusineDataLayer({
  306. ...option,
  307. symbol: {
  308. type: "billboard", // 对应是 mars3d.graphic.BillboardEntity
  309. styleOptions: {
  310. image: option.positionIconImg,
  311. horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
  312. verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
  313. scaleByDistance: new Cesium.NearFarScalar(1000, 0.7, 5000000, 0.3),
  314. visibleDepth: false,
  315. // label: {
  316. // text: `{${data.text || 'text'}}`,
  317. // font_size: 13,
  318. // color: Cesium.Color.AZURE,
  319. // outline: true,
  320. // outlineColor: Cesium.Color.BLACK,
  321. // outlineWidth: 2,
  322. // horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
  323. // verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
  324. // pixelOffset: new Cesium.Cartesian2(10, 0), // 偏移量
  325. // distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0.0, 80000)
  326. // }
  327. }
  328. },
  329. // 点的聚合配置
  330. clustering: {
  331. enabled: option.showGroup,
  332. pixelRange: 20,
  333. clampToGround: false,
  334. opacity: 1,
  335. // getImage: function (count) { //getImage是完全自定义方式
  336. // let colorIn
  337. // if (count < 10) {
  338. // colorIn = 'rgba(110, 204, 57, 0.6)'
  339. // } else if (count < 100) {
  340. // colorIn = 'rgba(240, 194, 12, 0.6)'
  341. // } else {
  342. // colorIn = 'rgba(241, 128, 23, 0.6)'
  343. // }
  344. // return mars3d.Util.getCircleImage(count, {
  345. // color: colorIn,
  346. // radius: 30,
  347. // })
  348. // },
  349. }
  350. })
  351. this.instance.addLayer(busineDataLayer)
  352. //包含详情
  353. if (popup) {
  354. //详细信息弹窗
  355. busineDataLayer.bindPopup(function (event) {
  356. const item = event.graphic?.attr
  357. if (!item) {
  358. return false
  359. }
  360. const tabData = [
  361. `<table style="width: auto;">
  362. <tr><th scope="col" colspan="2" style="text-align:center;font-size:15px;">${item[option.text]}</th></tr>`
  363. ]
  364. for (let key in popup) {
  365. tabData.push(`<tr>`)
  366. tabData.push(`<td>${popup[key]}</td><td>${item[key]}</td>`)
  367. tabData.push(`</tr>`)
  368. }
  369. tabData.push('</table>')
  370. return tabData.join('')
  371. })
  372. busineDataLayer.bindTooltip(function (event) {
  373. const item = event.graphic?.attr
  374. if (!item) {
  375. return false
  376. }
  377. const tabData = [
  378. `<table style="width: auto;">
  379. <tr><th scope="col" colspan="2" style="text-align:center;font-size:15px;">${item[option.text]}</th></tr>`
  380. ]
  381. for (let key in popup) {
  382. tabData.push(`<tr>`)
  383. tabData.push(`<td>${popup[key]}</td><td>${item[key]}</td>`)
  384. tabData.push(`</tr>`)
  385. }
  386. tabData.push('</table>')
  387. return tabData.join('')
  388. })
  389. }
  390. // 单击事件
  391. busineDataLayer.on(mars3d.EventType.click, (event) => {
  392. if (this.instance.camera.positionCartographic.height > 1000) {
  393. const graphic = event.graphic
  394. if (graphic) {
  395. // 单击了具体的点对象
  396. // graphic.closePopup()
  397. const position = graphic.positionShow
  398. this.instance.flyToPoint(position, {
  399. radius: 1000, // 距离目标点的距离
  400. duration: 3,
  401. complete: function (e) {
  402. // 飞行完成回调方法
  403. // graphic.openPopup()
  404. }
  405. })
  406. } else {
  407. // 单击了聚合的点
  408. const arrEntity = event.pickedObject.id
  409. this.instance.flyTo(arrEntity)
  410. }
  411. }
  412. })
  413. return busineDataLayer
  414. }
  415. /**
  416. * 两点连线(弧线)
  417. * @param startPoint 起始经纬度
  418. * @param endPoint 结束经纬度
  419. * @param attr 显示的信息对象(object,key、value格式)
  420. * @param popup 点击时显示的信息
  421. * @param popupOptions 点击时显示的信息参数设置对象,如可以设置偏移量{offsetX:-10,offsetY:-10},更多参数:http://mars3d.cn/api/Popup.html#.StyleOptions
  422. * @param tooltip hover时显示的信息
  423. * @param tooltipOptions hover时显示的信息参数设置对象,如可以设置偏移量{offsetX:-10,offsetY:-10},更多参数:http://mars3d.cn/api/Tooltip.html#.StyleOptions
  424. * @param lineColor 线条的颜色(默认:#1a9850)
  425. * @auth Roffer
  426. * @date 2022/12/3 11:04
  427. *
  428. */
  429. addArc({startPoint, endPoint, attr, popup, popupOptions, tooltip, tooltipOptions, lineColor}, graphicLayer) {
  430. graphicLayer = graphicLayer || this.genGraphicLayer()
  431. const start = Cesium.Cartesian3.fromDegrees(...startPoint, 42.31)
  432. const end = Cesium.Cartesian3.fromDegrees(...endPoint, 37.53)
  433. const positions = mars3d.PolyUtil.getLinkedPointList(start, end, 20000, 50) // 计算曲线点
  434. const graphic = new mars3d.graphic.PolylineEntity({
  435. positions: positions,
  436. style: {
  437. width: 10,
  438. // 动画线材质
  439. materialType: mars3d.MaterialType.LineFlow,
  440. materialOptions: {
  441. image: require('@/assets/img/map_icon/line-arrow-blue.png'),
  442. color: lineColor || '#1a9850',
  443. mixt: false,
  444. speed: 20,
  445. repeat: new Cesium.Cartesian2(5, 1)
  446. }
  447. },
  448. attr,
  449. popup,
  450. popupOptions,
  451. tooltip,
  452. tooltipOptions
  453. })
  454. graphicLayer.addGraphic(graphic)
  455. return graphicLayer
  456. }
  457. /**
  458. * 热力图
  459. * @param pointData 经纬度数组 [{lng:123,lat:456},...]
  460. * @auth Roffer
  461. * @date 2022/11/11 14:58
  462. *
  463. */
  464. addHeatLayer(pointData) {
  465. // 热力图 图层
  466. let heatLayer = new mars3d.layer.HeatLayer({
  467. positions: pointData,
  468. // rectangle: rectangle,
  469. // 以下为热力图本身的样式参数,可参阅api:https://www.patrick-wied.at/static/heatmapjs/docs.html
  470. heatStyle: {
  471. radius: 40,
  472. blur: 0.85
  473. },
  474. // 以下为矩形矢量对象的样式参数
  475. style: {
  476. arc: true, // 是否为曲面
  477. height: 100.0,
  478. opacity: 0.6,
  479. // classificationType: Cesium.ClassificationType.CESIUM_3D_TILE,
  480. // clampToGround: true
  481. }
  482. })
  483. this.instance.addLayer(heatLayer)
  484. return heatLayer
  485. }
  486. /**
  487. * 删除layer
  488. * @param layer layer对象
  489. * @auth Roffer
  490. * @date 2022/11/11 14:26
  491. *
  492. */
  493. removeLayer(layer) {
  494. this.instance.removeLayer(layer)
  495. }
  496. }

 使用:

<r-map-3d @onLoad="mapLoad"/>

  1. <script setup>
  2. let map = null//地图实例
  3. let areaLayer = null//图层的操作最好不要定义在vue3的响应式对象中,否则会引起页面卡顿
  4. /** 地图加载完成 */
  5. const mapLoad = (instance) => {
  6. map = instance
  7. areaLayer = map.addAreaLayer('510100000000')
  8. }
  9. </script>

最后附上天地图mapUrl地址:

  1. export const mapAk = 'xxxx'//请自行去官方申请
  2. //浅色底图
  3. // export const mapUrl = `http://www.scgis.net/services/newtianditudlg/WMTS?ak=${mapAk}`
  4. //暗色底图
  5. export const mapUrl = `http://www.scgis.net/services/tdtdarkmap/WMTS?ak=${mapAk}`

 省市区地图json数据,请移步到https://geojson.cn/ 根据业务需求下载对应的json数据

mars3d官网 

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

闽ICP备14008679号