Pārlūkot izejas kodu

添加行政区域底图

yangtaodemon 1 mēnesi atpakaļ
vecāks
revīzija
bca2195ad4
1 mainītis faili ar 142 papildinājumiem un 5 dzēšanām
  1. 142 5
      src/views/menu/tencentMapView.vue

+ 142 - 5
src/views/menu/tencentMapView.vue

@@ -7,7 +7,8 @@
         ref="regionSelector"
         @region-change="handleRegionChange" />
     </div>
-    <div ref="mapContainer" class="map-container"></div>
+    <div ref="mapContainer" 
+    class="map-container"></div>
     <div v-if="error" class="error">{{ error }}</div>
     <!-- 覆盖层控制 -->
     <!-- <div class="control-panel">
@@ -17,6 +18,11 @@
       </label>
     </div> -->
     <div class="control-panel">
+      <div class="basemap-toggle">
+        <button @click="toggleBaseLayer" :class="{ active: isBaseLayer }">
+          {{ isBaseLayer ? '纯净地图' : '腾讯地图' }}
+        </button>
+      </div>
       <label>
         <input type="checkbox" v-model="state.showSoilTypes" @change="toggleSoilTypeLayer" />
         显示韶关市评估单元
@@ -37,7 +43,6 @@
 
 <script setup>
 import { ref, reactive, onMounted, onBeforeUnmount } from 'vue'
-import axios from 'axios'
 import html2canvas from 'html2canvas'
 import RegionSelector from '@/components/RegionSelector.vue'
 
@@ -67,7 +72,6 @@ let soilTypeLayer = null
 let geoJSONLayer; 
 let currentInfoWindow = null;
 const surveyDataLayer = ref(null); // 保持响应式引用
-let currentLayerId = 0; // 添加图层版本控制[3,4](@ref)
 let multiPolygon;
 const districtLayers = ref(new Map()) // 存储区县图层
 const combinedSurveyFeatures = ref([]); // 存储原始数据
@@ -85,6 +89,109 @@ const tMapConfig = reactive({
   geocoderURL: 'https://apis.map.qq.com/ws/geocoder/v1/'
 })
 
+const isBaseLayer = ref(false)
+const layerVisibility = reactive({
+  province: false,
+  city: false,
+  county: false
+})
+const currentZoom = ref(12)
+
+// 预加载所有GeoJSON图层
+const geoLayers = reactive({
+  province: null,
+  city: null,
+  county: null
+})
+
+const initBaseLayers = async () => {
+  try {
+    // 按层级加载GeoJSON(需替换实际路径)
+    geoLayers.province = await loadAndCreateLayer('/data/省.geojson', 'province')
+    geoLayers.city = await loadAndCreateLayer('/data/市.geojson', 'city')
+    geoLayers.county = await loadAndCreateLayer('/data/县.geojson', 'county')
+    
+    // 初始化默认状态
+    updateLayerVisibility()
+  } catch (error) {
+    console.error('加载地理数据失败:', error)
+    error.value = '地理数据加载失败'
+  }
+}
+
+// 创建带样式的图层
+const loadAndCreateLayer = async (url, type) => {
+  const geoData = await loadGeoJSON(url)
+  return new TMap.value.vector.GeoJSONLayer({
+    map: map,
+    data: geoData,
+    zIndex: 5,
+    polygonStyle: new TMap.value.PolygonStyle({
+      color: 'rgba(242, 241, 237, 1)',
+      borderColor: '#000000',
+      borderWidth: 1
+    })
+  })
+}
+
+// 智能切换核心方法
+const toggleBaseLayer = () => {
+  isBaseLayer.value = !isBaseLayer.value
+  // 新增地图样式切换逻辑
+  if (map) {
+    map.setMapStyleId(isBaseLayer.value ? '1' : '0')
+  }
+  
+  if (isBaseLayer.value) {
+    map.on('zoom', handleZoomChange)
+    updateLayerVisibility()
+  } else {
+    map.off('zoom', handleZoomChange)
+    hideAllLayers()
+  }
+}
+
+// 缩放事件处理
+const handleZoomChange = () => {
+  currentZoom.value = map.getZoom()
+  updateLayerVisibility()
+}
+
+// 图层可见性逻辑
+const updateLayerVisibility = () => {
+  const zoom = currentZoom.value
+  const rules = [
+    { min: 0, max: 5, types: ['province'] },
+    { min: 5, max: 10, types: ['city'] },
+    { min: 10, max: 20, types: ['county'] }
+  ]
+
+  rules.forEach(rule => {
+    const isActive = zoom >= rule.min && zoom <= rule.max
+    rule.types.forEach(type => {
+      layerVisibility[type] = isActive && isBaseLayer.value
+      geoLayers[type]?.setVisible(isActive && isBaseLayer.value)
+    })
+  })
+}
+
+const getLayerColor = (type) => {
+  const colors = { 
+    province: 'rgba(255, 170, 0, 1)',  
+    city: 'rgba(0, 168, 255, 1)',      
+    county: 'rgba(76, 175, 80, 1)'     
+  };
+  return colors[type]
+}
+
+// 清理方法
+const hideAllLayers = () => {
+  Object.values(geoLayers).forEach(layer => {
+    if (layer) layer.setVisible(false)
+  })
+}
+
+
 
 const loadSDK = () => {
   return new Promise((resolve, reject) => {
@@ -637,7 +744,7 @@ function initMapWithGeoJSON(geojsonData, map) {
   geoJSONLayer = new TMap.value.vector.GeoJSONLayer({
     map: map,
     data: geojsonData,
-    zIndex: 1,
+    zIndex: 10,
     polygonStyle: new TMap.value.PolygonStyle({ // 必须用 PolygonStyle 类实例
       color: 'rgba(255, 0, 0, 0.25)', 
       showBorder: true,
@@ -652,7 +759,7 @@ function initMapWithGeoJSON(geojsonData, map) {
   // 高亮选中图层
   const highlightLayer = new TMap.value.MultiPolygon({
         map,
-        zIndex: 2,
+        zIndex: 20,
         styles: {
           highlight: new TMap.value.PolygonStyle({ // 注意要改为 PolygonStyle
             color: 'rgba(0, 123, 255, 0.5)',      // 半透明蓝色填充
@@ -822,6 +929,7 @@ onMounted(async () => {
     await loadSDK()
     initData()
     await initMap()
+    await initBaseLayers()
   } catch (err) {
     error.value = err.message
   }
@@ -845,10 +953,39 @@ onBeforeUnmount(() => {
     surveyDataLayer.value.setMap(null);
     surveyDataLayer.value.destroy();
   }
+  map.off('zoom', handleZoomChange)
 })
 </script>
 
 <style scoped>
+.basemap-toggle {
+  margin-top: 8px;
+}
+
+.basemap-toggle button {
+  padding: 8px 16px;
+  background: #3876ff;
+  color: white;
+  border: none;
+  border-radius: 20px;
+  cursor: pointer;
+  transition: all 0.3s ease;
+}
+
+.basemap-toggle button:hover {
+  background: #2b5dc5;
+}
+
+.basemap-toggle button.active {
+  background: #00C853;
+  box-shadow: 0 0 8px rgba(0, 200, 83, 0.5);
+}
+
+/* 图层过渡动画 */
+.tmap-geojson-layer {
+  transition: opacity 0.3s ease, visibility 0.3s ease;
+}
+
 .map-toolbar {
   position: relative; /* 确保层级上下文 */
   z-index: 1000;     /* 低于子组件下拉菜单的z-index */