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.
@@ -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 { Circle as CircleStyle, Fill, Icon, Stroke, Style } from 'ol/style'
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 'vant/lib/index.css' // 添加 Vant 样式
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 PointLayerOptions {
50
- /** 图标URL地址 */
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 PointLayerOptions {
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>('tianditu')
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: 'EPSG:3857',
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: 'EPSG:3857',
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: 'EPSG:3857',
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: 'EPSG:3857',
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 options - 点位图层配置
376
- * @returns 返回图层实例
428
+ * 创建点位要素
429
+ * @param point - 点位数据
430
+ * @param icon - 图标URL
431
+ * @param iconAnchor - 图标锚点
432
+ * @returns 返回要素实例
377
433
  */
378
- function addVectorPoints(options: PointLayerOptions): VectorLayer<VectorSource> | null {
379
- if (!map)
380
- return null
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
- icon,
384
- iconAnchor = [0.5, 1],
385
- data,
386
- onClick,
387
- } = options
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
- zIndex: 1,
477
+ visible: config.show,
478
+ zIndex: config.id === undefined ? 1 : 3, // 根据是否有ID决定层级
393
479
  })
394
480
 
395
- data.forEach((point) => {
396
- const feature = new Feature({
397
- geometry: new Point(fromLonLat([point.longitude, point.latitude])),
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
- map.addLayer(vectorLayer)
419
-
420
- if (onClick) {
421
- map.on('click', (event) => {
422
- map.forEachFeatureAtPixel(event.pixel, (feature) => {
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
- * 渲染海量点(适用于10万+数据量)
438
- * @param options - WebGL渲染配置
505
+ * 渲染点位
506
+ * @param config - 点位图层配置
439
507
  * @returns 返回图层实例
440
508
  */
441
- function addWebGLPoints(options: WebGLPointOptions): VectorLayer<VectorSource> | null {
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
- iconSize = [16, 16],
447
- data,
448
- performance = {
449
- enableChunk: true,
450
- chunkSize: 5000,
451
- enableThrottle: true,
452
- throttleWait: 100,
453
- },
454
- } = options
455
-
456
- // 创建矢量图层,使用 Canvas 渲染器优化性能
457
- const vectorSource = new VectorSource()
458
- const vectorLayer = new VectorLayer({
459
- source: vectorSource,
460
- style: new Style({
461
- image: new CircleStyle({
462
- radius: iconSize[0] / 2,
463
- fill: new Fill({
464
- color: 'rgba(0, 150, 255, 0.8)',
465
- }),
466
- stroke: new Stroke({
467
- color: '#fff',
468
- width: 1,
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
- if (performance.enableChunk) {
479
- const chunkSize = performance.chunkSize || 5000
480
- for (let i = 0; i < data.length; i += chunkSize) {
481
- const chunk = data.slice(i, i + chunkSize)
482
- setTimeout(() => {
483
- const features = chunk.map(point =>
484
- new Feature({
485
- geometry: new Point(fromLonLat([point.longitude, point.latitude])),
486
- properties: {
487
- title: point.title,
488
- ...point.extData,
489
- },
490
- }),
491
- )
492
- vectorSource.addFeatures(features)
493
- }, 0)
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
- const features = data.map(point =>
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
- map.addLayer(vectorLayer)
613
+ return config.id
614
+ }
511
615
 
512
- return vectorLayer
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
- addWebGLPoints,
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="layer-selector">
542
- <select v-model="currentMapType" @change="handleMapChange(currentMapType)">
543
- <option v-for="layer in layerOptions" :key="layer.value" :value="layer.value">
544
- {{ layer.text }}
545
- </option>
546
- </select>
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
- .layer-selector {
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: 2px;
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: none;
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
- background-color: #f5f5f5;
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
- .layer-selector {
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;