af-mobile-client-vue3 1.0.98 → 1.1.2
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/mock/modules/demo.mock.ts +20 -0
- package/package.json +1 -1
- package/src/components/data/XOlMap/README.md +220 -0
- package/src/components/data/XOlMap/demo.vue +179 -58
- package/src/components/data/XOlMap/index.vue +414 -140
- package/src/components/data/XOlMap/utils/wgs84ToGcj02.js +154 -0
- package/src/router/routes.ts +6 -0
- package/src/services/api/common.ts +1 -1
- package/src/services/api/search.ts +16 -0
- package/src/services/restTools.ts +13 -9
- package/src/utils/http/index.ts +5 -4
- package/src/views/component/XRequestView/index.vue +185 -0
- package/src/views/component/index.vue +13 -1
- package/src/views/user/login/LoginForm.vue +22 -5
- package/vite.config.ts +130 -123
|
@@ -12,12 +12,14 @@ import { defaults as defaultControls, ScaleLine } from 'ol/control'
|
|
|
12
12
|
import Feature from 'ol/Feature'
|
|
13
13
|
import Point from 'ol/geom/Point'
|
|
14
14
|
import { defaults as defaultInteractions } from 'ol/interaction'
|
|
15
|
-
import { Tile as TileLayer, Vector as VectorLayer } from 'ol/layer'
|
|
15
|
+
import { Image as ImageLayer, Tile as TileLayer, Vector as VectorLayer } from 'ol/layer'
|
|
16
16
|
import { fromLonLat } from 'ol/proj'
|
|
17
|
-
import { Vector as VectorSource, XYZ } from 'ol/source'
|
|
18
|
-
import {
|
|
17
|
+
import { ImageWMS, Vector as VectorSource, XYZ } from 'ol/source'
|
|
18
|
+
import { Fill, Icon, Stroke, Style, Text } from 'ol/style'
|
|
19
|
+
import { Button } from 'vant'
|
|
19
20
|
import { onUnmounted, ref } from 'vue'
|
|
20
|
-
import
|
|
21
|
+
import { wgs84ToGcj02Projection } from './utils/wgs84ToGcj02'
|
|
22
|
+
import 'vant/lib/index.css'
|
|
21
23
|
|
|
22
24
|
/** 初始化参数接口 */
|
|
23
25
|
interface InitParams {
|
|
@@ -46,21 +48,27 @@ interface PointData {
|
|
|
46
48
|
}
|
|
47
49
|
|
|
48
50
|
/** 点位图层配置接口 */
|
|
49
|
-
interface
|
|
50
|
-
/**
|
|
51
|
+
interface PointLayerConfig {
|
|
52
|
+
/** 图层ID */
|
|
53
|
+
id: number
|
|
54
|
+
/** 图层名称 */
|
|
55
|
+
value: string
|
|
56
|
+
/** 是否显示 */
|
|
57
|
+
show: boolean
|
|
58
|
+
/** 图标URL */
|
|
51
59
|
icon: string
|
|
52
|
-
/**
|
|
53
|
-
iconSize?: [number, number]
|
|
54
|
-
/** 图标锚点位置 [x, y],范围 0-1 */
|
|
60
|
+
/** 图标锚点 */
|
|
55
61
|
iconAnchor?: [number, number]
|
|
56
|
-
/**
|
|
57
|
-
data: PointData[]
|
|
58
|
-
/** 点击事件回调 */
|
|
62
|
+
/** 点击回调函数 */
|
|
59
63
|
onClick?: (point: PointData, event: any) => void
|
|
64
|
+
/** 点位数据 */
|
|
65
|
+
data?: PointData[]
|
|
60
66
|
}
|
|
61
67
|
|
|
62
68
|
/** WebGL渲染配置接口 */
|
|
63
|
-
interface WebGLPointOptions extends
|
|
69
|
+
interface WebGLPointOptions extends PointLayerConfig {
|
|
70
|
+
/** 图标大小 */
|
|
71
|
+
iconSize?: [number, number]
|
|
64
72
|
/** 是否开启聚合 */
|
|
65
73
|
enableCluster?: boolean
|
|
66
74
|
/** 聚合距离,单位像素 */
|
|
@@ -87,12 +95,48 @@ interface WebGLPointOptions extends PointLayerOptions {
|
|
|
87
95
|
}
|
|
88
96
|
}
|
|
89
97
|
|
|
98
|
+
/** WMS 图层配置接口 */
|
|
99
|
+
interface WMSLayerConfig {
|
|
100
|
+
/** 图层名称 */
|
|
101
|
+
layerName: string
|
|
102
|
+
/** 图层显示名称 */
|
|
103
|
+
value: string
|
|
104
|
+
/** 是否显示 */
|
|
105
|
+
show: boolean
|
|
106
|
+
/** 手机端是否显示 */
|
|
107
|
+
phoneShow: boolean
|
|
108
|
+
/** 图层 ID */
|
|
109
|
+
id: number
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/** WMS 服务配置接口 */
|
|
113
|
+
interface WMSConfig {
|
|
114
|
+
/** 工作空间 */
|
|
115
|
+
workspace: string
|
|
116
|
+
/** 坐标系 */
|
|
117
|
+
srs: string
|
|
118
|
+
/** 图片格式 */
|
|
119
|
+
format: string
|
|
120
|
+
/** WMS 版本 */
|
|
121
|
+
version: string
|
|
122
|
+
/** WMS 服务地址 */
|
|
123
|
+
url: string
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/** WMS 完整配置接口 */
|
|
127
|
+
interface WMSOptions {
|
|
128
|
+
/** WMS 图层列表 */
|
|
129
|
+
layers: WMSLayerConfig[]
|
|
130
|
+
/** WMS 服务配置 */
|
|
131
|
+
wms: WMSConfig
|
|
132
|
+
}
|
|
133
|
+
|
|
90
134
|
/** 地图容器引用 */
|
|
91
135
|
const mapRef = ref<HTMLDivElement>()
|
|
92
136
|
/** 地图实例 */
|
|
93
137
|
let map: Map | null = null
|
|
94
138
|
/** 当前底图类型 */
|
|
95
|
-
const currentMapType = ref<string>('
|
|
139
|
+
const currentMapType = ref<string>('gaode')
|
|
96
140
|
|
|
97
141
|
/** 图层选项配置 */
|
|
98
142
|
const layerOptions = [
|
|
@@ -105,6 +149,16 @@ const layerOptions = [
|
|
|
105
149
|
/** 存储所有底图图层 */
|
|
106
150
|
const baseMaps: Record<string, TileLayer<XYZ>> = {}
|
|
107
151
|
|
|
152
|
+
/** 存储 WMS 图层 */
|
|
153
|
+
const wmsLayers: Record<string, ImageLayer<ImageWMS>> = {}
|
|
154
|
+
|
|
155
|
+
/** WMS 图层状态 */
|
|
156
|
+
const wmsLayerStatus = ref<WMSLayerConfig[]>([])
|
|
157
|
+
|
|
158
|
+
/** 存储点位图层 */
|
|
159
|
+
const vectorLayers: Record<number, VectorLayer<VectorSource>> = {}
|
|
160
|
+
const pointLayerStatus = ref<PointLayerConfig[]>([])
|
|
161
|
+
|
|
108
162
|
/**
|
|
109
163
|
* 切换地图图层
|
|
110
164
|
* @param type - 图层类型
|
|
@@ -175,7 +229,7 @@ function initializeLayers(tianDiTuKey = ''): void {
|
|
|
175
229
|
url: 'http://t0.tianditu.gov.cn/vec_w/wmts?'
|
|
176
230
|
+ 'SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=vec&STYLE=default&TILEMATRIXSET=w&'
|
|
177
231
|
+ `FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=${tianDiTuKey}`,
|
|
178
|
-
projection:
|
|
232
|
+
projection: wgs84ToGcj02Projection,
|
|
179
233
|
}),
|
|
180
234
|
visible: false,
|
|
181
235
|
})
|
|
@@ -186,7 +240,7 @@ function initializeLayers(tianDiTuKey = ''): void {
|
|
|
186
240
|
url: 'http://t0.tianditu.gov.cn/cva_w/wmts?'
|
|
187
241
|
+ 'SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cva&STYLE=default&TILEMATRIXSET=w&'
|
|
188
242
|
+ `FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=${tianDiTuKey}`,
|
|
189
|
-
projection:
|
|
243
|
+
projection: wgs84ToGcj02Projection,
|
|
190
244
|
}),
|
|
191
245
|
visible: false,
|
|
192
246
|
})
|
|
@@ -197,7 +251,7 @@ function initializeLayers(tianDiTuKey = ''): void {
|
|
|
197
251
|
url: 'http://t0.tianditu.gov.cn/img_w/wmts?'
|
|
198
252
|
+ 'SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&'
|
|
199
253
|
+ `FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=${tianDiTuKey}`,
|
|
200
|
-
projection:
|
|
254
|
+
projection: wgs84ToGcj02Projection,
|
|
201
255
|
}),
|
|
202
256
|
visible: false,
|
|
203
257
|
})
|
|
@@ -208,7 +262,7 @@ function initializeLayers(tianDiTuKey = ''): void {
|
|
|
208
262
|
url: 'http://t0.tianditu.gov.cn/cia_w/wmts?'
|
|
209
263
|
+ 'SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cia&STYLE=default&TILEMATRIXSET=w&'
|
|
210
264
|
+ `FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=${tianDiTuKey}`,
|
|
211
|
-
projection:
|
|
265
|
+
projection: wgs84ToGcj02Projection,
|
|
212
266
|
}),
|
|
213
267
|
visible: false,
|
|
214
268
|
})
|
|
@@ -371,62 +425,76 @@ function setCenterAndZoom(center: [number, number], zoom: number, animate = true
|
|
|
371
425
|
}
|
|
372
426
|
|
|
373
427
|
/**
|
|
374
|
-
*
|
|
375
|
-
* @param
|
|
376
|
-
* @
|
|
428
|
+
* 创建点位要素
|
|
429
|
+
* @param point - 点位数据
|
|
430
|
+
* @param icon - 图标URL
|
|
431
|
+
* @param iconAnchor - 图标锚点
|
|
432
|
+
* @returns 返回要素实例
|
|
377
433
|
*/
|
|
378
|
-
function
|
|
379
|
-
|
|
380
|
-
|
|
434
|
+
function createPointFeature(point: PointData, icon: string, iconAnchor: [number, number] = [0.5, 1]): Feature {
|
|
435
|
+
const feature = new Feature({
|
|
436
|
+
geometry: new Point(fromLonLat([point.longitude, point.latitude])),
|
|
437
|
+
properties: point,
|
|
438
|
+
})
|
|
381
439
|
|
|
382
|
-
const {
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
440
|
+
const style = new Style({
|
|
441
|
+
image: new Icon({
|
|
442
|
+
src: icon,
|
|
443
|
+
scale: 0.5,
|
|
444
|
+
anchor: iconAnchor,
|
|
445
|
+
anchorXUnits: 'fraction',
|
|
446
|
+
anchorYUnits: 'fraction',
|
|
447
|
+
crossOrigin: 'anonymous',
|
|
448
|
+
}),
|
|
449
|
+
text: new Text({
|
|
450
|
+
text: point.title || '',
|
|
451
|
+
offsetY: -35,
|
|
452
|
+
font: '12px sans-serif',
|
|
453
|
+
fill: new Fill({
|
|
454
|
+
color: '#333',
|
|
455
|
+
}),
|
|
456
|
+
stroke: new Stroke({
|
|
457
|
+
color: '#fff',
|
|
458
|
+
width: 2,
|
|
459
|
+
}),
|
|
460
|
+
}),
|
|
461
|
+
})
|
|
462
|
+
|
|
463
|
+
feature.setStyle(style)
|
|
464
|
+
return feature
|
|
465
|
+
}
|
|
388
466
|
|
|
467
|
+
/**
|
|
468
|
+
* 创建点位图层
|
|
469
|
+
* @param config - 图层配置
|
|
470
|
+
* @param points - 点位数据
|
|
471
|
+
* @returns 返回图层实例
|
|
472
|
+
*/
|
|
473
|
+
function createPointLayer(config: PointLayerConfig, points: PointData[]): VectorLayer<VectorSource> {
|
|
389
474
|
const vectorSource = new VectorSource()
|
|
390
475
|
const vectorLayer = new VectorLayer({
|
|
391
476
|
source: vectorSource,
|
|
392
|
-
|
|
477
|
+
visible: config.show,
|
|
478
|
+
zIndex: config.id === undefined ? 1 : 3, // 根据是否有ID决定层级
|
|
393
479
|
})
|
|
394
480
|
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
properties: {
|
|
399
|
-
...point,
|
|
400
|
-
},
|
|
401
|
-
})
|
|
402
|
-
|
|
403
|
-
const style = new Style({
|
|
404
|
-
image: new Icon({
|
|
405
|
-
src: icon,
|
|
406
|
-
scale: 0.5,
|
|
407
|
-
anchor: iconAnchor,
|
|
408
|
-
anchorXUnits: 'fraction',
|
|
409
|
-
anchorYUnits: 'fraction',
|
|
410
|
-
crossOrigin: 'anonymous',
|
|
411
|
-
}),
|
|
412
|
-
})
|
|
413
|
-
|
|
414
|
-
feature.setStyle(style)
|
|
481
|
+
// 添加点位要素
|
|
482
|
+
points.forEach((point) => {
|
|
483
|
+
const feature = createPointFeature(point, config.icon, config.iconAnchor)
|
|
415
484
|
vectorSource.addFeature(feature)
|
|
416
485
|
})
|
|
417
486
|
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
if (feature) {
|
|
424
|
-
const properties = feature.getProperties()
|
|
425
|
-
onClick(properties as PointData, event)
|
|
426
|
-
return true
|
|
427
|
-
}
|
|
428
|
-
return false
|
|
487
|
+
// 添加点击事件处理
|
|
488
|
+
if (config.onClick) {
|
|
489
|
+
map?.on('click', (event) => {
|
|
490
|
+
const feature = map.forEachFeatureAtPixel(event.pixel, feature => feature, {
|
|
491
|
+
layerFilter: layer => layer === vectorLayer,
|
|
429
492
|
})
|
|
493
|
+
if (feature) {
|
|
494
|
+
const properties = feature.getProperties()
|
|
495
|
+
const { geometry, ...pointData } = properties
|
|
496
|
+
config.onClick(pointData as PointData, event)
|
|
497
|
+
}
|
|
430
498
|
})
|
|
431
499
|
}
|
|
432
500
|
|
|
@@ -434,82 +502,140 @@ function addVectorPoints(options: PointLayerOptions): VectorLayer<VectorSource>
|
|
|
434
502
|
}
|
|
435
503
|
|
|
436
504
|
/**
|
|
437
|
-
*
|
|
438
|
-
* @param
|
|
505
|
+
* 渲染点位
|
|
506
|
+
* @param config - 点位图层配置
|
|
439
507
|
* @returns 返回图层实例
|
|
440
508
|
*/
|
|
441
|
-
function
|
|
442
|
-
if (!map)
|
|
509
|
+
function addVectorPoints(config: PointLayerConfig): VectorLayer<VectorSource> | null {
|
|
510
|
+
if (!map || !config.data)
|
|
443
511
|
return null
|
|
444
512
|
|
|
445
|
-
const
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
const
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
}),
|
|
470
|
-
}),
|
|
471
|
-
}),
|
|
472
|
-
updateWhileAnimating: false, // 动画时不更新以提高性能
|
|
473
|
-
updateWhileInteracting: false, // 交互时不更新以提高性能
|
|
474
|
-
zIndex: 1,
|
|
513
|
+
const vectorLayer = createPointLayer(config, config.data)
|
|
514
|
+
map.addLayer(vectorLayer)
|
|
515
|
+
return vectorLayer
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
/**
|
|
519
|
+
* 添加 WMS 图层
|
|
520
|
+
* @param options - WMS 配置
|
|
521
|
+
*/
|
|
522
|
+
function addWMSLayers(options: WMSOptions): void {
|
|
523
|
+
if (!map)
|
|
524
|
+
return
|
|
525
|
+
|
|
526
|
+
const { layers, wms } = options
|
|
527
|
+
|
|
528
|
+
// 更新图层状态
|
|
529
|
+
wmsLayerStatus.value = layers.map(layer => ({
|
|
530
|
+
...layer,
|
|
531
|
+
show: layer.show,
|
|
532
|
+
}))
|
|
533
|
+
|
|
534
|
+
// 移除已存在的 WMS 图层
|
|
535
|
+
Object.values(wmsLayers).forEach((layer) => {
|
|
536
|
+
map?.removeLayer(layer)
|
|
475
537
|
})
|
|
476
538
|
|
|
477
|
-
//
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
}
|
|
539
|
+
// 清空图层记录
|
|
540
|
+
Object.keys(wmsLayers).forEach((key) => {
|
|
541
|
+
delete wmsLayers[key]
|
|
542
|
+
})
|
|
543
|
+
|
|
544
|
+
// 添加新的 WMS 图层
|
|
545
|
+
layers.forEach((layerConfig) => {
|
|
546
|
+
const wmsSource = new ImageWMS({
|
|
547
|
+
url: wms.url,
|
|
548
|
+
params: {
|
|
549
|
+
LAYERS: layerConfig.layerName,
|
|
550
|
+
FORMAT: wms.format,
|
|
551
|
+
VERSION: wms.version,
|
|
552
|
+
SRS: wms.srs,
|
|
553
|
+
},
|
|
554
|
+
ratio: 1,
|
|
555
|
+
serverType: 'geoserver',
|
|
556
|
+
})
|
|
557
|
+
|
|
558
|
+
const wmsLayer = new ImageLayer({
|
|
559
|
+
source: wmsSource,
|
|
560
|
+
visible: layerConfig.show,
|
|
561
|
+
zIndex: 2,
|
|
562
|
+
})
|
|
563
|
+
|
|
564
|
+
wmsLayers[layerConfig.layerName] = wmsLayer
|
|
565
|
+
map.addLayer(wmsLayer)
|
|
566
|
+
})
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
/**
|
|
570
|
+
* 控制 WMS 图层显示/隐藏
|
|
571
|
+
* @param layerName - 图层名称
|
|
572
|
+
* @param visible - 是否显示
|
|
573
|
+
*/
|
|
574
|
+
function setWMSLayerVisible(layerName: string, visible: boolean): void {
|
|
575
|
+
const layer = wmsLayers[layerName]
|
|
576
|
+
if (layer) {
|
|
577
|
+
layer.setVisible(visible)
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
/**
|
|
582
|
+
* 切换 WMS 图层显示状态
|
|
583
|
+
* @param layer - 图层配置
|
|
584
|
+
*/
|
|
585
|
+
function handleToggleWMSLayer(layer: WMSLayerConfig): void {
|
|
586
|
+
layer.show = !layer.show
|
|
587
|
+
setWMSLayerVisible(layer.layerName, layer.show)
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
/**
|
|
591
|
+
* 添加点位图层
|
|
592
|
+
* @param config - 图层配置
|
|
593
|
+
* @param points - 点位数据
|
|
594
|
+
* @returns 返回图层ID
|
|
595
|
+
*/
|
|
596
|
+
function addPointLayer(config: PointLayerConfig, points: PointData[]): number {
|
|
597
|
+
if (!map)
|
|
598
|
+
return -1
|
|
599
|
+
|
|
600
|
+
const vectorLayer = createPointLayer(config, points)
|
|
601
|
+
map.addLayer(vectorLayer)
|
|
602
|
+
vectorLayers[config.id] = vectorLayer
|
|
603
|
+
|
|
604
|
+
// 更新图层状态
|
|
605
|
+
const existingIndex = pointLayerStatus.value.findIndex(layer => layer.id === config.id)
|
|
606
|
+
if (existingIndex === -1) {
|
|
607
|
+
pointLayerStatus.value.push(config)
|
|
495
608
|
}
|
|
496
609
|
else {
|
|
497
|
-
|
|
498
|
-
new Feature({
|
|
499
|
-
geometry: new Point(fromLonLat([point.longitude, point.latitude])),
|
|
500
|
-
properties: {
|
|
501
|
-
title: point.title,
|
|
502
|
-
...point.extData,
|
|
503
|
-
},
|
|
504
|
-
}),
|
|
505
|
-
)
|
|
506
|
-
vectorSource.addFeatures(features)
|
|
610
|
+
pointLayerStatus.value[existingIndex] = config
|
|
507
611
|
}
|
|
508
612
|
|
|
509
|
-
|
|
510
|
-
|
|
613
|
+
return config.id
|
|
614
|
+
}
|
|
511
615
|
|
|
512
|
-
|
|
616
|
+
/**
|
|
617
|
+
* 控制点位图层显示/隐藏
|
|
618
|
+
* @param layerId - 图层ID
|
|
619
|
+
* @param visible - 是否显示
|
|
620
|
+
*/
|
|
621
|
+
function setPointLayerVisible(layerId: number, visible: boolean): void {
|
|
622
|
+
const layer = vectorLayers[layerId]
|
|
623
|
+
if (layer) {
|
|
624
|
+
layer.setVisible(visible)
|
|
625
|
+
// 更新图层状态
|
|
626
|
+
const layerIndex = pointLayerStatus.value.findIndex(layer => layer.id === layerId)
|
|
627
|
+
if (layerIndex !== -1) {
|
|
628
|
+
pointLayerStatus.value[layerIndex].show = visible
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
/**
|
|
634
|
+
* 切换点位图层显示状态
|
|
635
|
+
*/
|
|
636
|
+
function handleTogglePointLayer(layer: PointLayerConfig): void {
|
|
637
|
+
layer.show = !layer.show
|
|
638
|
+
setPointLayerVisible(layer.id, layer.show)
|
|
513
639
|
}
|
|
514
640
|
|
|
515
641
|
// 暴露方法给父组件
|
|
@@ -521,7 +647,11 @@ defineExpose({
|
|
|
521
647
|
getZoom,
|
|
522
648
|
setCenterAndZoom,
|
|
523
649
|
addVectorPoints,
|
|
524
|
-
|
|
650
|
+
addWMSLayers,
|
|
651
|
+
setWMSLayerVisible,
|
|
652
|
+
handleToggleWMSLayer,
|
|
653
|
+
addPointLayer,
|
|
654
|
+
setPointLayerVisible,
|
|
525
655
|
})
|
|
526
656
|
|
|
527
657
|
// 组件卸载时清理地图实例
|
|
@@ -537,13 +667,55 @@ onUnmounted(() => {
|
|
|
537
667
|
<div class="map-wrapper">
|
|
538
668
|
<div ref="mapRef" class="ol-map" />
|
|
539
669
|
|
|
540
|
-
<!--
|
|
541
|
-
<div class="
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
670
|
+
<!-- 图层控制面板 -->
|
|
671
|
+
<div class="map-controls">
|
|
672
|
+
<!-- 底图切换 -->
|
|
673
|
+
<div class="control-panel base-layer-control">
|
|
674
|
+
<div class="control-title">
|
|
675
|
+
底图切换
|
|
676
|
+
</div>
|
|
677
|
+
<select v-model="currentMapType" @change="handleMapChange(currentMapType)">
|
|
678
|
+
<option v-for="layer in layerOptions" :key="layer.value" :value="layer.value">
|
|
679
|
+
{{ layer.text }}
|
|
680
|
+
</option>
|
|
681
|
+
</select>
|
|
682
|
+
</div>
|
|
683
|
+
|
|
684
|
+
<!-- WMS 图层控制 -->
|
|
685
|
+
<div v-if="wmsLayerStatus.length > 0" class="control-panel wms-layer-control">
|
|
686
|
+
<div class="control-title">
|
|
687
|
+
图层控制
|
|
688
|
+
</div>
|
|
689
|
+
<div class="control-buttons">
|
|
690
|
+
<Button
|
|
691
|
+
v-for="layer in wmsLayerStatus"
|
|
692
|
+
:key="layer.id"
|
|
693
|
+
:type="layer.show ? 'primary' : 'default'"
|
|
694
|
+
size="small"
|
|
695
|
+
@click="handleToggleWMSLayer(layer)"
|
|
696
|
+
>
|
|
697
|
+
{{ layer.value }}
|
|
698
|
+
</Button>
|
|
699
|
+
</div>
|
|
700
|
+
</div>
|
|
701
|
+
|
|
702
|
+
<!-- 点位图层控制 -->
|
|
703
|
+
<div v-if="pointLayerStatus.length > 0" class="control-panel point-layer-control">
|
|
704
|
+
<div class="control-title">
|
|
705
|
+
点位图层
|
|
706
|
+
</div>
|
|
707
|
+
<div class="control-buttons">
|
|
708
|
+
<Button
|
|
709
|
+
v-for="layer in pointLayerStatus"
|
|
710
|
+
:key="layer.id"
|
|
711
|
+
:type="layer.show ? 'primary' : 'default'"
|
|
712
|
+
size="small"
|
|
713
|
+
@click="handleTogglePointLayer(layer)"
|
|
714
|
+
>
|
|
715
|
+
{{ layer.value }}
|
|
716
|
+
</Button>
|
|
717
|
+
</div>
|
|
718
|
+
</div>
|
|
547
719
|
</div>
|
|
548
720
|
</div>
|
|
549
721
|
</template>
|
|
@@ -566,20 +738,39 @@ onUnmounted(() => {
|
|
|
566
738
|
}
|
|
567
739
|
}
|
|
568
740
|
|
|
569
|
-
.
|
|
741
|
+
.map-controls {
|
|
570
742
|
position: absolute;
|
|
571
743
|
right: 10px;
|
|
572
744
|
top: 10px;
|
|
573
745
|
z-index: 1000;
|
|
746
|
+
display: flex;
|
|
747
|
+
flex-direction: column;
|
|
748
|
+
gap: 10px;
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
.control-panel {
|
|
574
752
|
background: white;
|
|
575
753
|
border-radius: 4px;
|
|
576
754
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
|
577
|
-
padding:
|
|
755
|
+
padding: 10px;
|
|
756
|
+
min-width: 140px;
|
|
578
757
|
|
|
758
|
+
.control-title {
|
|
759
|
+
font-size: 14px;
|
|
760
|
+
font-weight: 500;
|
|
761
|
+
color: #333;
|
|
762
|
+
margin-bottom: 8px;
|
|
763
|
+
padding-left: 4px;
|
|
764
|
+
border-left: 3px solid #1989fa;
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
.base-layer-control {
|
|
579
769
|
select {
|
|
770
|
+
width: 100%;
|
|
580
771
|
padding: 6px 24px 6px 12px;
|
|
581
772
|
font-size: 14px;
|
|
582
|
-
border:
|
|
773
|
+
border: 1px solid #dcdee0;
|
|
583
774
|
border-radius: 4px;
|
|
584
775
|
background-color: white;
|
|
585
776
|
cursor: pointer;
|
|
@@ -593,7 +784,7 @@ onUnmounted(() => {
|
|
|
593
784
|
background-size: 12px;
|
|
594
785
|
|
|
595
786
|
&:hover {
|
|
596
|
-
|
|
787
|
+
border-color: #1989fa;
|
|
597
788
|
}
|
|
598
789
|
|
|
599
790
|
option {
|
|
@@ -602,6 +793,54 @@ onUnmounted(() => {
|
|
|
602
793
|
}
|
|
603
794
|
}
|
|
604
795
|
|
|
796
|
+
.wms-layer-control {
|
|
797
|
+
.control-buttons {
|
|
798
|
+
display: flex;
|
|
799
|
+
flex-direction: column;
|
|
800
|
+
gap: 8px;
|
|
801
|
+
|
|
802
|
+
:deep(.van-button) {
|
|
803
|
+
width: 100%;
|
|
804
|
+
justify-content: flex-start;
|
|
805
|
+
padding-left: 12px;
|
|
806
|
+
border-radius: 4px;
|
|
807
|
+
|
|
808
|
+
&--default {
|
|
809
|
+
border: 1px solid #dcdee0;
|
|
810
|
+
|
|
811
|
+
&:hover {
|
|
812
|
+
border-color: #1989fa;
|
|
813
|
+
color: #1989fa;
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
.point-layer-control {
|
|
821
|
+
.control-buttons {
|
|
822
|
+
display: flex;
|
|
823
|
+
flex-direction: column;
|
|
824
|
+
gap: 8px;
|
|
825
|
+
|
|
826
|
+
:deep(.van-button) {
|
|
827
|
+
width: 100%;
|
|
828
|
+
justify-content: flex-start;
|
|
829
|
+
padding-left: 12px;
|
|
830
|
+
border-radius: 4px;
|
|
831
|
+
|
|
832
|
+
&--default {
|
|
833
|
+
border: 1px solid #dcdee0;
|
|
834
|
+
|
|
835
|
+
&:hover {
|
|
836
|
+
border-color: #1989fa;
|
|
837
|
+
color: #1989fa;
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
|
|
605
844
|
// 比例尺样式
|
|
606
845
|
:deep(.ol-scale-line) {
|
|
607
846
|
position: absolute;
|
|
@@ -625,10 +864,23 @@ onUnmounted(() => {
|
|
|
625
864
|
|
|
626
865
|
// 移动端适配
|
|
627
866
|
@media screen and (max-width: 768px) {
|
|
628
|
-
.
|
|
867
|
+
.map-controls {
|
|
629
868
|
right: 8px;
|
|
630
869
|
top: 8px;
|
|
870
|
+
gap: 8px;
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
.control-panel {
|
|
874
|
+
padding: 8px;
|
|
875
|
+
min-width: 120px;
|
|
876
|
+
|
|
877
|
+
.control-title {
|
|
878
|
+
font-size: 12px;
|
|
879
|
+
margin-bottom: 6px;
|
|
880
|
+
}
|
|
881
|
+
}
|
|
631
882
|
|
|
883
|
+
.base-layer-control {
|
|
632
884
|
select {
|
|
633
885
|
padding: 4px 20px 4px 8px;
|
|
634
886
|
font-size: 12px;
|
|
@@ -636,6 +888,28 @@ onUnmounted(() => {
|
|
|
636
888
|
}
|
|
637
889
|
}
|
|
638
890
|
|
|
891
|
+
.wms-layer-control {
|
|
892
|
+
.control-buttons {
|
|
893
|
+
gap: 6px;
|
|
894
|
+
|
|
895
|
+
:deep(.van-button) {
|
|
896
|
+
font-size: 12px;
|
|
897
|
+
padding: 0 8px;
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
.point-layer-control {
|
|
903
|
+
.control-buttons {
|
|
904
|
+
gap: 6px;
|
|
905
|
+
|
|
906
|
+
:deep(.van-button) {
|
|
907
|
+
font-size: 12px;
|
|
908
|
+
padding: 0 8px;
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
|
|
639
913
|
:deep(.ol-scale-line) {
|
|
640
914
|
transform: scale(0.8);
|
|
641
915
|
transform-origin: left bottom;
|