@sword916/vae-map-plus 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/build/index.mjs +113 -0
- package/examples/App.vue +18 -0
- package/examples/index.js +13 -0
- package/examples/router/index.js +35 -0
- package/examples/views/amap.vue +29 -0
- package/examples/views/amarker.vue +58 -0
- package/examples/views/buffer.vue +66 -0
- package/examples/views/cluster.vue +74 -0
- package/examples/views/cover.vue +85 -0
- package/examples/views/draw-line.vue +49 -0
- package/examples/views/draw.vue +54 -0
- package/examples/views/echarts.vue +142 -0
- package/examples/views/emarker.vue +39 -0
- package/examples/views/image.vue +182 -0
- package/examples/views/index.vue +61 -0
- package/examples/views/lrmap.vue +108 -0
- package/examples/views/map.vue +82 -0
- package/examples/views/measure.vue +86 -0
- package/examples/views/parts/popup.vue +39 -0
- package/examples/views/parts/tooltip.vue +39 -0
- package/examples/views/push-area.vue +52 -0
- package/examples/views/push-line.vue +84 -0
- package/examples/views/trace.vue +49 -0
- package/index.html +13 -0
- package/jsconfig.json +17 -0
- package/package.json +47 -0
- package/public/favicon.ico +0 -0
- package/public/images/game.png +0 -0
- package/public/images/grid.png +0 -0
- package/public/images/marker.png +0 -0
- package/public/index.html +30 -0
- package/src/components/resize-listener/component.jsx +30 -0
- package/src/components/resize-listener/index.js +3 -0
- package/src/composables/useAutoMessage.js +41 -0
- package/src/composables/useContextMenu.js +99 -0
- package/src/composables/useMapMeasure.js +191 -0
- package/src/composables/useResizeObserver.js +81 -0
- package/src/mixins/message.js +1 -0
- package/src/packages/index.js +16 -0
- package/src/packages/vae-amap/index.js +8 -0
- package/src/packages/vae-amap/style.less +9 -0
- package/src/packages/vae-amap/vae-amap.jsx +98 -0
- package/src/packages/vae-cloudmap/ctrl-context-menu/index.vue +74 -0
- package/src/packages/vae-cloudmap/ctrl-draw/index.vue +499 -0
- package/src/packages/vae-cloudmap/ctrl-draw-line/index.vue +161 -0
- package/src/packages/vae-cloudmap/index.js +57 -0
- package/src/packages/vae-cloudmap/scripts/L.MarkerCluster/index.js +2690 -0
- package/src/packages/vae-cloudmap/scripts/L.MarkerCluster/style.css +14 -0
- package/src/packages/vae-cloudmap/scripts/L.Vae.CRS/index.js +212 -0
- package/src/packages/vae-cloudmap/scripts/L.Vae.Client/index.js +780 -0
- package/src/packages/vae-cloudmap/scripts/Mixin.ContextMenu/index.js +101 -0
- package/src/packages/vae-cloudmap/style.less +163 -0
- package/src/packages/vae-cloudmap/vae-cloudmap.jsx +272 -0
- package/src/packages/vae-map/ctrl-context-menu/index.vue +74 -0
- package/src/packages/vae-map/ctrl-draw/index.vue +498 -0
- package/src/packages/vae-map/ctrl-draw-line/index.vue +128 -0
- package/src/packages/vae-map/index.js +59 -0
- package/src/packages/vae-map/scripts/L.MarkerCluster/index.js +2690 -0
- package/src/packages/vae-map/scripts/L.MarkerCluster/style.css +14 -0
- package/src/packages/vae-map/scripts/L.Vae.CRS/index.js +114 -0
- package/src/packages/vae-map/scripts/L.Vae.Client/index.js +548 -0
- package/src/packages/vae-map/scripts/Mixin.ContextMenu/index.js +1 -0
- package/src/packages/vae-map/style.less +161 -0
- package/src/packages/vae-map/vae-lrmap.jsx +237 -0
- package/src/packages/vae-map/vae-map.jsx +135 -0
- package/src/plugins/L.AnimatedMarker/index.js +158 -0
- package/src/plugins/L.EchartsLayer/index.js +339 -0
- package/src/plugins/L.ElasticMarker/index.js +162 -0
- package/src/plugins/L.FootageCalculator.Area/index.js +263 -0
- package/src/plugins/L.FootageCalculator.Line/index.js +273 -0
- package/src/plugins/L.GeoUtil/buffer.js +67 -0
- package/src/plugins/L.GeoUtil/index.js +284 -0
- package/src/plugins/L.Glyphicon/index.js +91 -0
- package/src/plugins/L.Glyphicon/style.less +37 -0
- package/src/plugins/L.MarkerClusterX/index.js +93 -0
- package/src/plugins/L.MarkerClusterX/style.less +162 -0
- package/src/plugins/L.SafeDivOverlay/index.js +55 -0
- package/src/plugins/L.TileLayer.ChinaProvider/index.js +108 -0
- package/src/plugins/L.VuePopup/index.js +67 -0
- package/src/plugins/L.VueTooltip/index.js +63 -0
- package/src/plugins/Mixin.Map.Measure/index.js +248 -0
- package/src/plugins/globals/index.js +7 -0
- package/src/utils/index.js +36 -0
- package/src/utils/resize-event.js +45 -0
- package/vite.config.mjs +25 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
.leaflet-cluster-anim .leaflet-marker-icon, .leaflet-cluster-anim .leaflet-marker-shadow {
|
|
2
|
+
-webkit-transition: -webkit-transform 0.3s ease-out, opacity 0.3s ease-in;
|
|
3
|
+
-moz-transition: -moz-transform 0.3s ease-out, opacity 0.3s ease-in;
|
|
4
|
+
-o-transition: -o-transform 0.3s ease-out, opacity 0.3s ease-in;
|
|
5
|
+
transition: transform 0.3s ease-out, opacity 0.3s ease-in;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.leaflet-cluster-spider-leg {
|
|
9
|
+
/* stroke-dashoffset (duration and function) should match with leaflet-marker-icon transform in order to track it exactly */
|
|
10
|
+
-webkit-transition: -webkit-stroke-dashoffset 0.3s ease-out, -webkit-stroke-opacity 0.3s ease-in;
|
|
11
|
+
-moz-transition: -moz-stroke-dashoffset 0.3s ease-out, -moz-stroke-opacity 0.3s ease-in;
|
|
12
|
+
-o-transition: -o-stroke-dashoffset 0.3s ease-out, -o-stroke-opacity 0.3s ease-in;
|
|
13
|
+
transition: stroke-dashoffset 0.3s ease-out, stroke-opacity 0.3s ease-in;
|
|
14
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
// 偏移墨卡托投影
|
|
2
|
+
const OffsetSphericalMercator = (offset = L.point(0, 0)) => {
|
|
3
|
+
|
|
4
|
+
const Mercator = L.Projection.SphericalMercator
|
|
5
|
+
const R = Mercator.R
|
|
6
|
+
const D = Math.PI / 180
|
|
7
|
+
|
|
8
|
+
return L.extend({}, Mercator, {
|
|
9
|
+
project(latlng) {
|
|
10
|
+
const max = Mercator.MAX_LATITUDE
|
|
11
|
+
const lat = Math.max(Math.min(max, latlng.lat), -max)
|
|
12
|
+
const sin = Math.sin(lat * D)
|
|
13
|
+
const point = L.point(R * latlng.lng * D, R * Math.log((1 + sin) / (1 - sin)) / 2)
|
|
14
|
+
|
|
15
|
+
return point.add(offset)
|
|
16
|
+
},
|
|
17
|
+
|
|
18
|
+
unproject(point) {
|
|
19
|
+
const [x, y] = point.subtract(offset)
|
|
20
|
+
|
|
21
|
+
return L.latLng((2 * Math.atan(Math.exp(y / R)) - (Math.PI / 2)) * D, x * D / R)
|
|
22
|
+
}
|
|
23
|
+
})
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// LRMAP常用CRS
|
|
27
|
+
const fns = {
|
|
28
|
+
|
|
29
|
+
SIMPLE(count = 2) {
|
|
30
|
+
const ratio = Math.pow(0.1, count)
|
|
31
|
+
|
|
32
|
+
return L.extend({}, L.CRS.Simple, {
|
|
33
|
+
scale: zoom => ratio * Math.pow(2, zoom),
|
|
34
|
+
zoom: scale => Math.log(scale / ratio) / Math.log(2)
|
|
35
|
+
})
|
|
36
|
+
},
|
|
37
|
+
|
|
38
|
+
OFFSET_EPSG3857(offset = L.point(0, 0)) {
|
|
39
|
+
|
|
40
|
+
return L.extend({}, L.CRS.EPSG3857, {
|
|
41
|
+
projection: OffsetSphericalMercator(offset)
|
|
42
|
+
})
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
BJ54(x,options={}) {
|
|
46
|
+
// console.log(options);
|
|
47
|
+
let resolutions = [307.2, 153.6, 76.8, 38.4, 19.2, 9.6, 4.8, 2.4, 1.2, 0.6, 0.3, 0.15, 0.075, 0.0375, 0.01875]
|
|
48
|
+
//为了解决矿政的1:500000的图纸新增了一个分辨率的参数,如果另外的项目需要改动,联系史新国
|
|
49
|
+
if(options.resolutions){
|
|
50
|
+
resolutions=options.resolutions
|
|
51
|
+
};
|
|
52
|
+
// 确定投影带和带号
|
|
53
|
+
let pType, pCode
|
|
54
|
+
if (x > 25000000 && x < 40000000) {
|
|
55
|
+
pType = 3
|
|
56
|
+
pCode = parseInt(x / 1000000)
|
|
57
|
+
} else if (x > 12000000 && x < 22000000) {
|
|
58
|
+
pType = 6
|
|
59
|
+
pCode = parseInt(x / 1000000)
|
|
60
|
+
}
|
|
61
|
+
// 确定proj4的各项参数:ESPG代码,中央经线,东伪偏移
|
|
62
|
+
let EPSGCode, lon_0, x_0
|
|
63
|
+
if (pCode >= 0) {
|
|
64
|
+
if (pType == 3) {
|
|
65
|
+
EPSGCode = 2376 + pCode
|
|
66
|
+
lon_0 = pCode * 3
|
|
67
|
+
x_0 = 1000000 * pCode + 500000
|
|
68
|
+
} else if (pType == 6) {
|
|
69
|
+
EPSGCode = 2325 + pCode
|
|
70
|
+
lon_0 = pCode * 6 - 3
|
|
71
|
+
x_0 = 1000000 * pCode + 500000
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// 返回3度带/6度带坐标系
|
|
75
|
+
if (EPSGCode) {
|
|
76
|
+
let proj = '+proj=tmerc +lat_0=0 +lon_0=' + lon_0 + ' +k=1 +x_0=' + x_0 + ' +y_0=0 +ellps=krass +units=m +no_defs no_defs'
|
|
77
|
+
return new L.Proj.CRS('EPSG:' + EPSGCode, proj, { resolutions:resolutions })
|
|
78
|
+
} else {
|
|
79
|
+
return this.SIMPLE()
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
|
|
83
|
+
XA80(x) {
|
|
84
|
+
let EPSGCode = 900099,
|
|
85
|
+
x_0 = 0,
|
|
86
|
+
lon_0 = 0,
|
|
87
|
+
pcode = parseInt(x / 1000000)
|
|
88
|
+
if (pcode > 0) {
|
|
89
|
+
lon_0 = pcode * 3
|
|
90
|
+
x_0 = 1000000 * pcode + 500000
|
|
91
|
+
EPSGCode = 2376 + pcode
|
|
92
|
+
}
|
|
93
|
+
let proj = '+proj=tmerc +lat_0=0 +lon_0=' + lon_0 + ' +k=1 +x_0=' + x_0 + ' +y_0=0 +a=6378140 +b=6356755.288157528 +units=m +no_defs no_defs'
|
|
94
|
+
let resolutions = [307.2, 153.6, 76.8, 38.4, 19.2, 9.6, 4.8, 2.4, 1.2, 0.6, 0.3, 0.15, 0.075, 0.0375, 0.01875]
|
|
95
|
+
return new L.Proj.CRS('EPSG:' + EPSGCode, proj, { resolutions, origin: [0, 0] })
|
|
96
|
+
},
|
|
97
|
+
CGCS2000(options={}){
|
|
98
|
+
let resolutions = [307.2, 153.6, 76.8, 38.4, 19.2, 9.6, 4.8, 2.4, 1.2, 0.6, 0.3, 0.15, 0.075, 0.0375, 0.01875]
|
|
99
|
+
if(options.resolutions){
|
|
100
|
+
resolutions=options.resolutions
|
|
101
|
+
};
|
|
102
|
+
let origin= [0, 0]
|
|
103
|
+
if(options.origin){
|
|
104
|
+
origin=options.origin
|
|
105
|
+
};
|
|
106
|
+
return new L.Proj.CRS("EPSG:4525","+proj=tmerc +lat_0=0 +lon_0=111 +k=1 +x_0=37500000 +y_0=0 +ellps=GRS80 +units=m +no_defs +type=crs",{
|
|
107
|
+
resolutions: resolutions,
|
|
108
|
+
origin: origin
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
L.Vae = L.Vae || {}
|
|
114
|
+
L.Vae.CRS = L.extend(L.Vae.CRS || {}, fns)
|
|
@@ -0,0 +1,548 @@
|
|
|
1
|
+
import axios from 'axios'
|
|
2
|
+
import { idGen, getTreeNode } from '@/utils'
|
|
3
|
+
|
|
4
|
+
L.Vae = L.Vae || {}
|
|
5
|
+
|
|
6
|
+
// LRMAP客户端
|
|
7
|
+
L.Vae.Client = L.Evented.extend({
|
|
8
|
+
|
|
9
|
+
options: {},
|
|
10
|
+
|
|
11
|
+
requestOptions: {},
|
|
12
|
+
|
|
13
|
+
leafletOptions: {},
|
|
14
|
+
|
|
15
|
+
extent: [],
|
|
16
|
+
|
|
17
|
+
treeLayers: [],
|
|
18
|
+
|
|
19
|
+
visibleKeys: [],
|
|
20
|
+
|
|
21
|
+
initialize(options) {
|
|
22
|
+
this.options = options
|
|
23
|
+
this.requestOptions = { url: null, uid: null, dsid: null, dsname: null }
|
|
24
|
+
this.leafletOptions = {}
|
|
25
|
+
},
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* 连接地图服务,构建地图参数
|
|
29
|
+
* @param {Boolean} alert 是否提示参数错误
|
|
30
|
+
*/
|
|
31
|
+
async start({ alert } = {}) {
|
|
32
|
+
return new Promise(async resolve => {
|
|
33
|
+
for (let v of ['url', 'dsname']) {
|
|
34
|
+
const value = this.options ? this.options[v] : null
|
|
35
|
+
const message = `参数 options.${v} 无效`
|
|
36
|
+
if (!_.isString(value) || value.trim().length == 0) {
|
|
37
|
+
if (alert) {
|
|
38
|
+
this.fire('message', { message, messageType: 'error' })
|
|
39
|
+
}
|
|
40
|
+
return
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
this.requestOptions.uid = this.options?.uid || `vae_client_${idGen()}`
|
|
44
|
+
|
|
45
|
+
try {
|
|
46
|
+
this.fire('openmask', { text: `正在 获取图元信息` })
|
|
47
|
+
const metaData = (await axios.get(this.options.url + 'map/getMeta', {
|
|
48
|
+
params: {
|
|
49
|
+
uid: this.requestOptions.uid,
|
|
50
|
+
dsname: this.options.dsname
|
|
51
|
+
}
|
|
52
|
+
})).data
|
|
53
|
+
this.fire('closemask')
|
|
54
|
+
if (metaData.status == 'success') {
|
|
55
|
+
this.buildMapOptions(metaData.result)
|
|
56
|
+
resolve(true)
|
|
57
|
+
} else {
|
|
58
|
+
console.error(metaData.errinfo)
|
|
59
|
+
this.fire('message', { message: "未获取到正确的图元信息", messageType: 'error' })
|
|
60
|
+
resolve(false)
|
|
61
|
+
}
|
|
62
|
+
} catch (error) {
|
|
63
|
+
console.error(error)
|
|
64
|
+
this.fire('message', { message: "获取图元失败,请检查地图服务和请求参数", messageType: 'error' })
|
|
65
|
+
this.fire('closemask')
|
|
66
|
+
resolve(false)
|
|
67
|
+
}
|
|
68
|
+
})
|
|
69
|
+
},
|
|
70
|
+
|
|
71
|
+
// 构建地图配置项
|
|
72
|
+
buildMapOptions({ dsid, extent }) {
|
|
73
|
+
try {
|
|
74
|
+
// 参数整理
|
|
75
|
+
if (dsid) {
|
|
76
|
+
this.requestOptions.url = this.options.url
|
|
77
|
+
this.requestOptions.dsid = dsid
|
|
78
|
+
this.requestOptions.dsname = this.options.dsname
|
|
79
|
+
} else {
|
|
80
|
+
throw new Error('数据源dsid错误')
|
|
81
|
+
}
|
|
82
|
+
// 构建配置
|
|
83
|
+
if (Array.isArray(extent) && extent.length == 4) {
|
|
84
|
+
// extent
|
|
85
|
+
this.extent = extent
|
|
86
|
+
let centerX = (extent[0] + extent[2]) * 0.5
|
|
87
|
+
let centerY = (extent[1] + extent[3]) * 0.5
|
|
88
|
+
// crs
|
|
89
|
+
let crs = this.options.crs || L.Vae.CRS.SIMPLE()
|
|
90
|
+
if (crs == 'bj54') {
|
|
91
|
+
crs = L.Vae.CRS.BJ54(centerX,this.options)
|
|
92
|
+
} else if (crs == 'xa80') {
|
|
93
|
+
crs = L.Vae.CRS.XA80(centerX)
|
|
94
|
+
} else if (crs == 'simple') {
|
|
95
|
+
crs = L.Vae.CRS.SIMPLE()
|
|
96
|
+
}else if (crs == 'CGCS2000' || crs == 'cgcs2000') {
|
|
97
|
+
crs = L.Vae.CRS.CGCS2000(this.options)
|
|
98
|
+
}
|
|
99
|
+
// wmscrs
|
|
100
|
+
let wmscrs = this.options.wmscrs || crs
|
|
101
|
+
if (wmscrs == 'bj54') {
|
|
102
|
+
wmscrs = L.Vae.CRS.BJ54(centerX)
|
|
103
|
+
} else if (wmscrs == 'xa80') {
|
|
104
|
+
wmscrs = L.Vae.CRS.XA80(centerX)
|
|
105
|
+
} else if (crs == 'simple') {
|
|
106
|
+
wmscrs = L.Vae.CRS.SIMPLE()
|
|
107
|
+
}else if (crs == 'CGCS2000' || crs == 'cgcs2000') {
|
|
108
|
+
wmscrs = L.Vae.CRS.CGCS2000(this.options)
|
|
109
|
+
}
|
|
110
|
+
// center
|
|
111
|
+
const center = this.options.center || wmscrs.unproject(L.point(centerX, centerY))
|
|
112
|
+
// maxzoom
|
|
113
|
+
const maxZoom = this.options.maxZoom ? this.options.maxZoom :
|
|
114
|
+
(crs.options && crs.options.resolutions) ? crs.options.resolutions.length - 1 : 25
|
|
115
|
+
// bounds
|
|
116
|
+
const corner1 = wmscrs.unproject(L.point(extent[0], extent[1]))
|
|
117
|
+
const corner2 = wmscrs.unproject(L.point(extent[2], extent[3]))
|
|
118
|
+
const bounds = L.latLngBounds(corner1, corner2)
|
|
119
|
+
this.leafletOptions = { crs, wmscrs, center, maxZoom, bounds }
|
|
120
|
+
} else {
|
|
121
|
+
throw new Error('地图属性extent错误')
|
|
122
|
+
}
|
|
123
|
+
} catch (e) {
|
|
124
|
+
console.error(e)
|
|
125
|
+
this.fire('message', { message: "地图参数构建错误", type: 'error' })
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* 请求地图服务
|
|
131
|
+
* @param {string} api 请求动作
|
|
132
|
+
* @param {string} message 提示消息
|
|
133
|
+
* @param {object} params 额外参数
|
|
134
|
+
* @param {boolean} forceResolve 请求结果无效时,强制resolve而不是reject
|
|
135
|
+
* @param {boolean} checkResult 是否校验结果
|
|
136
|
+
* @param {boolean} loadMask 是否添加遮罩层
|
|
137
|
+
*/
|
|
138
|
+
requestServer({ api, message = '加载数据', params = {}, forceResolve, checkResult = true, loadMask = true }) {
|
|
139
|
+
return new Promise((resolve, reject) => {
|
|
140
|
+
if (api) {
|
|
141
|
+
if (loadMask) { this.fire('openmask', { text: `正在 ${message}` }) }
|
|
142
|
+
axios.post(`${this.requestOptions.url}${api}`, L.extend({
|
|
143
|
+
uid: this.requestOptions.uid,
|
|
144
|
+
dsid: this.requestOptions.dsid
|
|
145
|
+
}, params)).then(result => {
|
|
146
|
+
if (checkResult) {
|
|
147
|
+
const data = result.data
|
|
148
|
+
if (data && data.status == 'success') {
|
|
149
|
+
resolve(data.result)
|
|
150
|
+
} else {
|
|
151
|
+
if (forceResolve) {
|
|
152
|
+
console.error(data.errinfo)
|
|
153
|
+
resolve('')
|
|
154
|
+
} else {
|
|
155
|
+
this.fire('message', { message: `${message}结果无效`, messageType: 'error' })
|
|
156
|
+
console.error(data.errinfo)
|
|
157
|
+
reject(data.errinfo)
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
} else { resolve(result.data) }
|
|
161
|
+
}).catch(e => {
|
|
162
|
+
this.fire('message', { message: `${message}失败,请检查地图服务和和请求参数`, messageType: 'error' })
|
|
163
|
+
console.error(e)
|
|
164
|
+
reject(e)
|
|
165
|
+
}).finally(() => {
|
|
166
|
+
if (loadMask) { this.fire('closemask') }
|
|
167
|
+
})
|
|
168
|
+
}
|
|
169
|
+
})
|
|
170
|
+
},
|
|
171
|
+
|
|
172
|
+
// 设置默认图层
|
|
173
|
+
async setDefaultLayers() {
|
|
174
|
+
this.fire('openmask', { text: `正在 加载默认图层` })
|
|
175
|
+
const { defaultLayers, defaultLayerSets, disabledLayerSets, layerTreeType } = this.options
|
|
176
|
+
await this.formatLayerGroup(layerTreeType, disabledLayerSets)
|
|
177
|
+
if (Array.isArray(defaultLayers)) {
|
|
178
|
+
this.visibleKeys = await this.showLayers(defaultLayers, { loadMask: false, refreshTiles: false })
|
|
179
|
+
} else if (Array.isArray(defaultLayerSets)) {
|
|
180
|
+
this.visibleKeys = await this.showLayerSets(defaultLayerSets, { loadMask: false, refreshTiles: false })
|
|
181
|
+
} else if (Array.isArray(disabledLayerSets)) {
|
|
182
|
+
await this.showLayers(this.visibleKeys, { loadMask: false, refreshTiles: false })
|
|
183
|
+
}
|
|
184
|
+
this.fire('closemask')
|
|
185
|
+
},
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* 初始化图层信息
|
|
189
|
+
* 有协同服务时,处理为树结构
|
|
190
|
+
* 无协同服务时,处理为列表结构
|
|
191
|
+
* @param {enum} type 类型,'leaf'(默认):叶子节点为实际图层,'branch':叶子节点为末级图集,图层置于layers属性
|
|
192
|
+
* @param {array<string>} disabledLayerSets 禁用的图集,支持'x>y>z'的选择方式
|
|
193
|
+
* @returns {treeLayers,visibleLayers}
|
|
194
|
+
* @property {array<object>} treeLayers 树结构:{id,label,children}
|
|
195
|
+
* @property {array<string>} visibleKeys 可见图层keys
|
|
196
|
+
*/
|
|
197
|
+
async formatLayerGroup(type = 'leaf', disabledLayerSets = []) {
|
|
198
|
+
// 处理结果:树结构和IDS
|
|
199
|
+
// 处理结果:树结构和IDS
|
|
200
|
+
let treeLayers = [], visibleKeys = []
|
|
201
|
+
let {treeLayersGroup} =this.options;
|
|
202
|
+
// 请求数据
|
|
203
|
+
const _layers = await this.requestServer({
|
|
204
|
+
api: 'layer/getlayers',
|
|
205
|
+
message: '获取图层',
|
|
206
|
+
loadMask: false
|
|
207
|
+
})
|
|
208
|
+
let _groups;
|
|
209
|
+
//如果不用协同服务,业务自定义接口,可以按时业务需求按照layer/showlayers接口格式传入数据
|
|
210
|
+
if(treeLayersGroup){
|
|
211
|
+
_groups=treeLayersGroup;
|
|
212
|
+
}else {
|
|
213
|
+
_groups = await this.requestServer({
|
|
214
|
+
api: 'layer/getlayergroups',
|
|
215
|
+
params: { type: 1 },
|
|
216
|
+
message: '获取图层分组',
|
|
217
|
+
forceResolve: true,
|
|
218
|
+
loadMask: false
|
|
219
|
+
})
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
// let treeLayers = [], visibleKeys = []
|
|
224
|
+
// // 请求数据
|
|
225
|
+
// const _layers = await this.requestServer({
|
|
226
|
+
// api: 'layer/getlayers',
|
|
227
|
+
// message: '获取图层',
|
|
228
|
+
// loadMask: false
|
|
229
|
+
// })
|
|
230
|
+
// const _groups = await this.requestServer({
|
|
231
|
+
// api: 'layer/getlayergroups',
|
|
232
|
+
// params: { type: 1 },
|
|
233
|
+
// message: '获取图层分组',
|
|
234
|
+
// forceResolve: true,
|
|
235
|
+
// loadMask: false
|
|
236
|
+
// })
|
|
237
|
+
// 组织数据
|
|
238
|
+
if (_layers && _layers.layers) {
|
|
239
|
+
// 有协同:树结构
|
|
240
|
+
if (_groups && _groups.layergroups) {
|
|
241
|
+
_groups.layergroups.forEach((g, i) => {
|
|
242
|
+
// 初始化分支
|
|
243
|
+
let branch = treeLayers
|
|
244
|
+
// 叶子节点,具体图层
|
|
245
|
+
let leafLayers = []
|
|
246
|
+
g.layers.forEach(v => {
|
|
247
|
+
const target = _.find(_layers.layers, { name: v })
|
|
248
|
+
if (target) {
|
|
249
|
+
const id = `LEAF_${i}_${target.guid}`
|
|
250
|
+
if (target.visible) {
|
|
251
|
+
visibleKeys.push(id)
|
|
252
|
+
}
|
|
253
|
+
leafLayers.push({ id, label: v })
|
|
254
|
+
}
|
|
255
|
+
})
|
|
256
|
+
// n1^n2^n3
|
|
257
|
+
const labels = _.split(g.name, '^')
|
|
258
|
+
labels.forEach((l, j) => {
|
|
259
|
+
// 当前层级
|
|
260
|
+
const level = j + 1
|
|
261
|
+
// 确认节点
|
|
262
|
+
let index = _.findIndex(branch, { label: l })
|
|
263
|
+
// 新增空节点
|
|
264
|
+
if (index < 0) {
|
|
265
|
+
index = branch.length
|
|
266
|
+
branch.push({ id: `NODE_${i}_${j}`, label: l, level, children: [] })
|
|
267
|
+
}
|
|
268
|
+
// 合并节点
|
|
269
|
+
if (j == labels.length - 1) {
|
|
270
|
+
// 添加层级
|
|
271
|
+
const leafLayersWithLevel = leafLayers.map(node => _.merge(node, { level: level + 1 }))
|
|
272
|
+
// 叶子
|
|
273
|
+
if (type == 'leaf') {
|
|
274
|
+
branch[index].children = _.concat(branch[index].children, leafLayersWithLevel)
|
|
275
|
+
}
|
|
276
|
+
// 枝干
|
|
277
|
+
else if (type == 'branch') {
|
|
278
|
+
branch[index].layers = _.concat(branch[index].children, leafLayersWithLevel)
|
|
279
|
+
if (g.visible) {
|
|
280
|
+
visibleKeys.push(branch[index].id)
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
} else {
|
|
284
|
+
// 下钻当前分支
|
|
285
|
+
branch = branch[index].children
|
|
286
|
+
}
|
|
287
|
+
})
|
|
288
|
+
})
|
|
289
|
+
}
|
|
290
|
+
// 无协同:列表结构
|
|
291
|
+
else {
|
|
292
|
+
_layers.layers.forEach(v => {
|
|
293
|
+
if (v.name && v.name !== "0") {
|
|
294
|
+
treeLayers.push({
|
|
295
|
+
id: v.guid,
|
|
296
|
+
label: v.name
|
|
297
|
+
})
|
|
298
|
+
if (v.visible) {
|
|
299
|
+
visibleKeys.push(v.guid)
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
})
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
// 处理禁用的图集
|
|
306
|
+
if (Array.isArray(disabledLayerSets) && disabledLayerSets.length > 0) {
|
|
307
|
+
let disabledKeys = []
|
|
308
|
+
let disabledAllKeys = []
|
|
309
|
+
disabledLayerSets.forEach(set => {
|
|
310
|
+
let node
|
|
311
|
+
set.split('>').forEach(v => {
|
|
312
|
+
if (v) {
|
|
313
|
+
node = getTreeNode(node ? [node] : treeLayers, { label: v })
|
|
314
|
+
}
|
|
315
|
+
})
|
|
316
|
+
if (node) {
|
|
317
|
+
disabledKeys.push(node.id)
|
|
318
|
+
}
|
|
319
|
+
})
|
|
320
|
+
if (disabledKeys.length > 0) {
|
|
321
|
+
// 获取节点下的图层
|
|
322
|
+
const collectLayers = node => {
|
|
323
|
+
let result = []
|
|
324
|
+
if (Array.isArray(node.children) && node.children.length > 0) {
|
|
325
|
+
node.children.forEach(v => {
|
|
326
|
+
result = _.concat(result, collectLayers(v))
|
|
327
|
+
})
|
|
328
|
+
} else {
|
|
329
|
+
result = _.concat(result, node.layers || node)
|
|
330
|
+
}
|
|
331
|
+
return result
|
|
332
|
+
}
|
|
333
|
+
// 去除禁用的节点集
|
|
334
|
+
const collectNodes = node => {
|
|
335
|
+
let result = node
|
|
336
|
+
if (_.includes(disabledKeys, node.id)) {
|
|
337
|
+
result = null
|
|
338
|
+
disabledAllKeys.push(node.id)
|
|
339
|
+
collectLayers(node).forEach(v => {
|
|
340
|
+
disabledAllKeys.push(v.id)
|
|
341
|
+
})
|
|
342
|
+
} else {
|
|
343
|
+
let children = result.children
|
|
344
|
+
if (children && children.length > 0) {
|
|
345
|
+
result.children = _.compact(children.map(v => collectNodes(v)))
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
return result
|
|
349
|
+
}
|
|
350
|
+
// 更新图层树和全量keys
|
|
351
|
+
treeLayers = _.compact(treeLayers.map(v => collectNodes(v)))
|
|
352
|
+
visibleKeys = _.pull(visibleKeys, ..._.uniq(disabledAllKeys))
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
this.treeLayers = treeLayers
|
|
357
|
+
this.visibleKeys = visibleKeys
|
|
358
|
+
}
|
|
359
|
+
},
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* 显示指定图层
|
|
363
|
+
* @param {array} nodes 图层节点集,兼容keys/leaf节点/branch节点
|
|
364
|
+
* @param {boolean} args.loadMask 是否添加遮罩层
|
|
365
|
+
* @param {boolean} args.refreshTiles 是否刷新瓦片
|
|
366
|
+
* @returns {array} 对应的图层keys
|
|
367
|
+
*/
|
|
368
|
+
async showLayers(nodes = [], args = { loadMask: true, refreshTiles: true }) {
|
|
369
|
+
// 参数对象转义
|
|
370
|
+
const loadMask = _.isUndefined(args.loadMask) ? true : !!args.loadMask
|
|
371
|
+
const refreshTiles = _.isUndefined(args.refreshTiles) ? true : !!args.refreshTiles
|
|
372
|
+
// 关闭全部图层
|
|
373
|
+
await this.requestServer({
|
|
374
|
+
api: 'layer/hidelayers',
|
|
375
|
+
params: { type: 'all' },
|
|
376
|
+
message: '关闭全部图层',
|
|
377
|
+
loadMask
|
|
378
|
+
})
|
|
379
|
+
const nodesToLabels = ns => {
|
|
380
|
+
let ls = [], ks = []
|
|
381
|
+
if (Array.isArray(ns)) {
|
|
382
|
+
const getLabelByKey = (tree, key) => {
|
|
383
|
+
let labels = []
|
|
384
|
+
function doRecursion(array) {
|
|
385
|
+
for (let node of array) {
|
|
386
|
+
if (node.id == key) {
|
|
387
|
+
if (Array.isArray(node.layers)) {
|
|
388
|
+
labels = node.layers.map(v => v.label)
|
|
389
|
+
} else {
|
|
390
|
+
labels = [node.label]
|
|
391
|
+
}
|
|
392
|
+
break
|
|
393
|
+
} else if (Array.isArray(node.children) && node.children.length > 0) {
|
|
394
|
+
doRecursion(node.children)
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
doRecursion(tree)
|
|
399
|
+
return labels
|
|
400
|
+
}
|
|
401
|
+
ns.forEach(n => {
|
|
402
|
+
if (typeof (n) == 'string') {
|
|
403
|
+
ls = _.concat(ls, getLabelByKey(this.treeLayers, n))
|
|
404
|
+
ks.push(n)
|
|
405
|
+
} else if (typeof (n) == 'object') {
|
|
406
|
+
if (Array.isArray(n.layers)) {
|
|
407
|
+
ls = _.concat(ls, n.layers.map(v => v.label))
|
|
408
|
+
ks = _.concat(ls, n.layers.map(v => v.id))
|
|
409
|
+
} else {
|
|
410
|
+
ls.push(n.label)
|
|
411
|
+
ks.push(n.id)
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
})
|
|
415
|
+
}
|
|
416
|
+
return [ls, ks]
|
|
417
|
+
}
|
|
418
|
+
const [labels, keys] = nodesToLabels(nodes)
|
|
419
|
+
await this.requestServer({
|
|
420
|
+
api: 'layer/showlayers',
|
|
421
|
+
params: { layers: _.join(labels) },
|
|
422
|
+
message: '打开指定图层',
|
|
423
|
+
loadMask
|
|
424
|
+
})
|
|
425
|
+
if (refreshTiles) {
|
|
426
|
+
this.fire('refreshtilelayer')
|
|
427
|
+
}
|
|
428
|
+
this.visibleKeys = keys
|
|
429
|
+
|
|
430
|
+
return this.visibleKeys
|
|
431
|
+
},
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* 显示指定图组,支持'xx>yy>zz'形式的精确选择
|
|
435
|
+
* @param {array} sets 图组名称
|
|
436
|
+
* @param {boolean} args.loadMask 是否添加遮罩层
|
|
437
|
+
* @param {boolean} args.refreshTiles 是否刷新瓦片
|
|
438
|
+
* @returns {array} 对应的图层keys
|
|
439
|
+
*/
|
|
440
|
+
async showLayerSets(sets = [], args = { loadMask: true, refreshTiles: true }) {
|
|
441
|
+
// 参数对象转义
|
|
442
|
+
const loadMask = _.isUndefined(args.loadMask) ? true : !!args.loadMask
|
|
443
|
+
const refreshTiles = _.isUndefined(args.refreshTiles) ? true : !!args.refreshTiles
|
|
444
|
+
if (_.isString(sets) && sets.length > 0) {
|
|
445
|
+
sets = [sets]
|
|
446
|
+
}
|
|
447
|
+
if (this.treeLayers.length > 0) {
|
|
448
|
+
// 获取目标节点的图层集
|
|
449
|
+
const collectLayers = node => {
|
|
450
|
+
let result = []
|
|
451
|
+
if (Array.isArray(node.children) && node.children.length > 0) {
|
|
452
|
+
node.children.forEach(v => {
|
|
453
|
+
result = _.concat(result, collectLayers(v))
|
|
454
|
+
})
|
|
455
|
+
} else {
|
|
456
|
+
result = _.concat(result, node.layers || node)
|
|
457
|
+
}
|
|
458
|
+
return result
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
// 组织并定位图集
|
|
462
|
+
let keys = []
|
|
463
|
+
sets.forEach(set => {
|
|
464
|
+
let node
|
|
465
|
+
set.split('>').forEach(v => {
|
|
466
|
+
if (v) {
|
|
467
|
+
node = getTreeNode(node ? [node] : this.treeLayers, { label: v })
|
|
468
|
+
}
|
|
469
|
+
})
|
|
470
|
+
if (node) {
|
|
471
|
+
keys.push(node.id)
|
|
472
|
+
collectLayers(node).forEach(v => {
|
|
473
|
+
keys.push(v.id)
|
|
474
|
+
})
|
|
475
|
+
}
|
|
476
|
+
})
|
|
477
|
+
await this.showLayers(keys, { loadMask, refreshTiles })
|
|
478
|
+
return keys
|
|
479
|
+
}
|
|
480
|
+
},
|
|
481
|
+
|
|
482
|
+
/**
|
|
483
|
+
* 查询实体信息
|
|
484
|
+
* @param {object} params 查询参数
|
|
485
|
+
* @param {boolean} loadMask 是否添加遮罩层
|
|
486
|
+
*/
|
|
487
|
+
queryEntity(params = {}, loadMask) {
|
|
488
|
+
return this.requestServer({
|
|
489
|
+
api: 'query/entity',
|
|
490
|
+
params,
|
|
491
|
+
message: '查询实体',
|
|
492
|
+
loadMask
|
|
493
|
+
})
|
|
494
|
+
},
|
|
495
|
+
|
|
496
|
+
// 获取缩略图
|
|
497
|
+
getThumbnail() {
|
|
498
|
+
return new Promise(resolve => {
|
|
499
|
+
if (this.extent.length == 4) {
|
|
500
|
+
const { url, dsid, uid } = this.requestOptions
|
|
501
|
+
axios.get(`${url}wmsmap/getmap`, {
|
|
502
|
+
params: {
|
|
503
|
+
dsid,
|
|
504
|
+
uid,
|
|
505
|
+
request: 'GetMap',
|
|
506
|
+
service: 'WMS',
|
|
507
|
+
width: 256,
|
|
508
|
+
height: 256,
|
|
509
|
+
format: 'image/png',
|
|
510
|
+
transparent: true,
|
|
511
|
+
version: '1.1.1',
|
|
512
|
+
bbox: _.join(this.extent, ','),
|
|
513
|
+
},
|
|
514
|
+
responseType: 'arraybuffer'
|
|
515
|
+
}).then(result => {
|
|
516
|
+
const base64Data = btoa(new Uint8Array(result.data).reduce((data, byte) => data + String.fromCharCode(byte), ''))
|
|
517
|
+
resolve(`data:image/png;base64,${base64Data}`)
|
|
518
|
+
})
|
|
519
|
+
}
|
|
520
|
+
})
|
|
521
|
+
},
|
|
522
|
+
|
|
523
|
+
|
|
524
|
+
// 获取切片图层对象
|
|
525
|
+
// 适用于requestOptions、leafletOptions以及图层状态已经准备的场景
|
|
526
|
+
currentTileLayer() {
|
|
527
|
+
const { url, dsid, uid } = this.requestOptions
|
|
528
|
+
const { wmscrs, maxZoom } = this.leafletOptions
|
|
529
|
+
const wmsUrl = `${url}wmsmap/getmap?dsid=${dsid}&uid=${uid}&tid=${idGen()}`
|
|
530
|
+
return L.tileLayer.wms(wmsUrl, {
|
|
531
|
+
format: 'image/png',
|
|
532
|
+
transparent: true,
|
|
533
|
+
crs: wmscrs,
|
|
534
|
+
maxZoom: maxZoom
|
|
535
|
+
})
|
|
536
|
+
},
|
|
537
|
+
|
|
538
|
+
// 生成切片图层对象
|
|
539
|
+
async createTileLayer({ beforeCreate } = {}) {
|
|
540
|
+
await this.start()
|
|
541
|
+
if (_.isFunction(beforeCreate)) {
|
|
542
|
+
await beforeCreate(this)
|
|
543
|
+
}
|
|
544
|
+
await this.setDefaultLayers()
|
|
545
|
+
return this.currentTileLayer()
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
})
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { useContextMenu as default } from '@/composables/useContextMenu'
|