ArcGIS在VUE框架中的构建思想
- 手机
- 2025-08-16 16:06:02

项目快要上线了,出乎意料的有些空闲时间。想着就把其他公司开发的一期代码里面,把关于地图方面的代码给优化一下。试运行的时候,客户说控制台有很多飘红的报错,他们很在意,虽然很不情愿,但能改的就给改了吧。
代码框架使用的是VUE框架, vue 2.x 版本的,使用vue-cli脚手架进行搭建的。在package.json中,arcgis的版本为"@arcgis/core": "^4.23.1"
使用到的第三方库 "dependencies": { "@arcgis/core": "^4.23.1", "axios": "0.18.1", "core-js": "3.6.5", "echarts": "^4.5.0", "echarts-gl": "1.0.0-beta.6", "echarts-liquidfill": "^2.0.6", "element-ui": "2.15.7", "events": "^3.3.0", "js-cookie": "2.2.0", "lodash": "^4.17.21", "moment": "^2.29.1", "normalize.css": "7.0.0", "nprogress": "0.2.0", "path-to-regexp": "2.4.0", "qrcodejs2": "^0.0.2", "screenfull": "^4.2.1", "vue": "2.6.10", "vue-i18n": "^8.18.2", "vue-router": "3.0.6", "vuex": "3.1.0" }, "devDependencies": { "@vue/cli-plugin-babel": "4.4.4", "@vue/cli-plugin-eslint": "4.4.4", "@vue/cli-service": "4.4.4", "autoprefixer": "9.5.1", "babel-eslint": "10.1.0", "babel-plugin-dynamic-import-node": "2.3.3", "chalk": "2.4.2", "connect": "3.6.6", "eslint": "6.7.2", "eslint-plugin-vue": "6.2.2", "html-webpack-plugin": "3.2.0", "mockjs": "1.0.1-beta3", "runjs": "4.3.2", "sass": "1.26.8", "sass-loader": "8.0.2", "script-ext-html-webpack-plugin": "2.1.3", "serve-static": "1.13.2", "svg-sprite-loader": "4.1.3", "svgo": "1.2.2", "vue-template-compiler": "2.6.10" } 地图封装将ArcGIS封装成一个组件,专门用来加载地图,一些事件分发处理。
DOM <template> <div style="width:100%;height:100%"> <div id="map" :style="sty"> </div> </div> </template> Style #map { height: calc(100vh); } 事件注册在main.js中需要进行一个事件总线的注册
Vue.prototype.$mapEventBus = new Vue()然后在utils文件夹中创建一个文件,专门放置一些用得到的事件。比如这个文件名称为mapEvent.js
export default { cleanOverlay: 'cleanOverlay', hideDike: 'hideDike', showDikes: 'showDikes', showBillboard: 'showBillboard', /** 改变图层可见性 */ changeLayerVisible: 'changeLayerVisible' }这里面就是一些事件类型,比如清除,隐藏堤坝,显示堤坝,显示广告牌,改变图层可见性等等。
然后在封装的时候引入这个文件。
import mapEvent from '@/utils/mapEvent'当后续想添加事件,统一名称就行,不用来回在用到的地方去改字符串了。最好能从名称看出用途。随后就是对事件总线进行事件注册和监听。
this.$mapEventBus.$on(mapEvent.cleanOverlay, (data) => { // 执行某些方法 }) this.$mapEventBus.$on(mapEvent.hideDike, (data) => { // 执行某些方法 }) this.$mapEventBus.$on(mapEvent.showDikes, (data) => { // 执行某些方法 }) this.$mapEventBus.$on(mapEvent.showBillboard, (data) => { // 执行某些方法 })当这些注册好之后,只要有其他页面,使用emit进行事件发送,那么就能拿到传递的data参数,再去执行对应的代码逻辑。某个页面触发hideDike和showBillboard为例。
this.$mapEventBus.$emit(mapEvent.hideDike) this.$mapEventBus.$emit(mapEvent.showBillboard, ['layer', 78, 'rain']) 场景View地图该有的事件总线注册完毕之后,就可以开始创建地图了,首先引入Map对象,创建一个地图对象。再根据需要的场景,创建对应的视图View,平面2D和立体3D是有不同的View对象的。
import Map from '@arcgis/core/Map' import SceneView from "@arcgis/core/views/SceneView"; import MapView from "@arcgis/core/views/MapView"; const m = new Map({ ground: "world-elevation", basemap: "topo-vector" }) // 3D场景的话,使用SceneView scene= new SceneView({ container: 'map', map: m, zoom: 9, center: [中心坐标值, 中心坐标值], }) // 普通地图场景的话使用MapView view= new MapView({ container: 'map', map: m, zoom: 10, center: [中心坐标值, 中心坐标值], }) 图层加载地图map创建好之后,开始为地图设置对应显示的layer。这里以天地图为例,图层类型有很多种,很多配置都是相同唯独一些type值不同,因此封装成一个方法function。下面的示例是加载WebTileLayer的一些简易封装配置,将其写在tdt.js中。wkid为参考坐标系,ArcGIS的官网有对这个值的解释,有特殊坐标系的场景,或者百度坐标系高德坐标系,这些值可能都需要更改。
切片信息可以单独写在一个js文件中tdtconfig.js,与tdt.js同级目录
export default { tileInfo: { rows: 256, cols: 256, origin: { x: -20037508.342787, y: 20037508.342787, }, compressionQuality: 0, spatialReference: { wkid: 102113 }, lods: [ { endTileCol: 31, endTileRow: 31, level: 5, resolution: 4891.96981024998, scale: 18489297.737236, startTileCol: 0, startTileRow: 0, }, { endTileCol: 63, endTileRow: 63, level: 6, resolution: 2445.98490512499, scale: 9244648.868618, startTileCol: 0, startTileRow: 0, }, { endTileCol: 127, endTileRow: 127, level: 7, resolution: 1222.992452562495, scale: 4622324.434309, startTileCol: 0, startTileRow: 0, }, { endTileCol: 255, endTileRow: 255, level: 8, resolution: 611.4962262812475, scale: 2311162.2171545, startTileCol: 0, startTileRow: 0, }, { endTileCol: 511, endTileRow: 511, level: 9, resolution: 305.74811314062373, scale: 1155581.10857725, startTileCol: 0, startTileRow: 0, }, { endTileCol: 1023, endTileRow: 1023, level: 10, resolution: 152.87405657031186, scale: 577790.554288625, startTileCol: 0, startTileRow: 0, }, { endTileCol: 2047, endTileRow: 2047, level: 11, resolution: 76.43702828515593, scale: 288895.2771443125, startTileCol: 0, startTileRow: 0, }, { endTileCol: 4095, endTileRow: 4095, level: 12, resolution: 38.218514142577966, scale: 144447.63857215625, startTileCol: 0, startTileRow: 0, }, { endTileCol: 8191, endTileRow: 8191, level: 13, resolution: 19.109257071288983, scale: 72223.81928607813, startTileCol: 0, startTileRow: 0, }, { endTileCol: 16383, endTileRow: 16383, level: 14, resolution: 9.554628535644492, scale: 36111.909643039064, startTileCol: 0, startTileRow: 0, }, { endTileCol: 32767, endTileRow: 32767, level: 15, resolution: 4.777314267822246, scale: 18055.954821519532, startTileCol: 0, startTileRow: 0, }, { endTileCol: 65534, endTileRow: 65534, level: 16, resolution: 2.388657133911123, scale: 9027.977410759766, startTileCol: 0, startTileRow: 0, }, { endTileCol: 131069, endTileRow: 131069, level: 17, resolution: 1.1943285669555614, scale: 4513.988705379883, startTileCol: 0, startTileRow: 0, }, { endTileCol: 262138, endTileRow: 262138, level: 18, resolution: 0.5971642834777807, scale: 2256.9943526899415, startTileCol: 0, startTileRow: 0, } ] }, }然后在tdt.js中引入这个切片信息配置。
import WebTileLayer from "@arcgis/core/layers/WebTileLayer"; import SpatialReference from "@arcgis/core/geometry/SpatialReference"; import Extent from "@arcgis/core/geometry/Extent"; import tileInfo from './tdtconfig'; function tdtLayer(type,visible){ const url = `http://t0.tianditu.gov /${type}_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=${type}&STYLE=default&TILEMATRIXSET=w&TILEMATRIX={level}&TileRow={row}&TileCol={col}&format=tiles&tk=${天地图的token}`; const tiledLayer = new WebTileLayer({ urlTemplate: url, subDomains: ["t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7"], spatialReference: new SpatialReference({ wkid: 102113, }), fullExtent: new Extent({ xmax: 20038088.3427892, xmin: -20038088.3427892, ymax: 20038088.3427892, ymin: -20038088.3427892, spatialReference: {wkid: 102113} }), initialExtent: new Extent({ xmax: 13211664.142019678, xmin: 13077211.409266088, ymax: 2843822.418908416, ymin: 2810801.622689228, spatialReference: {wkid: 102113} }), tileInfo: tileInfo.tileInfo, visible }); return tiledLayer; } export { tdtLayer, }在正式使用的时候,引入这个tdt.js文件,使用其中的tdtLayer方法。可以通过传递不同的字符串,去加载不同类型的图层。比如vec,cva,img,cia,ter,cta。通过visible的布尔类型值,控制加载时的显示与隐藏。还可以考虑增加一个参数,来控制是否需要设置透明度opacity。
在原先他们一期的项目中,是没有多加visible的,他们在创建完成之后,手动设置layer.visible的值为false。其实这个可以在创建layer的时候就指定好。他们甚至还主动设置对应的layer.id值,我看了一下ArcGIS的官网,其实应该可以通过title来设置id值的,我还没主动尝试过。
这些图层通过tdtLayer创建完成后,便可以通过之前的地图对象m来进行批量添加了。
const layer1 = tdtLayer('vec'); const layer2 = tdtLayer('cva'); const layer3 = tdtLayer('img'); const layer4 = tdtLayer('cia'); const layer5 = tdtLayer('ter'); const layer6 = tdtLayer('cta'); m.layers.addMany([layer3, layer4]) m.layers.addMany([layer1, layer2, layer5, layer6])ArcGIS在VUE框架中的构建思想由讯客互联手机栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“ArcGIS在VUE框架中的构建思想”