Browse Source

添加图例

yangtaodemon 2 days ago
parent
commit
74022c4858
1 changed files with 179 additions and 13 deletions
  1. 179 13
      src/views/menu/tencentMapView.vue

+ 179 - 13
src/views/menu/tencentMapView.vue

@@ -11,17 +11,12 @@
         class="compact-region-selector"
         ref="regionSelector"
         @region-change="handleRegionChange" />
+        
     </div>
     <div ref="mapContainer" 
     class="map-container"></div>
     <div v-if="error" class="error">{{ error }}</div>
-    <!-- 覆盖层控制 -->
-    <!-- <div class="control-panel">
-      <label>
-        <input type="checkbox" v-model="state.showOverlay" @change="toggleOverlay" />
-        显示土壤类型覆盖
-      </label>
-    </div> -->
+    
     <div class="control-panel">
       <div class="basemap-toggle">
         <button @click="toggleBaseLayer" :class="{ active: isBaseLayer }">
@@ -43,6 +38,41 @@
         </button>
       </div>
     </div>
+     <div class="map-legend" :class="{ active: isShowLegend }">
+        <div class="legend-controls">
+          <button @click="switchLegendType('cdRisk')">Cd风险</button>
+          <button @click="switchLegendType('safetyQ')">安全指数Q</button>
+        </div>
+      <div class="legend-header">
+        <h1>图例</h1>
+      </div>
+      <div class="legend-header">
+        <h4>{{ currentLegendTitle }}</h4>
+      </div>
+      
+      <!-- Cd风险等级图例 -->
+      <div v-if="currentLegend === 'cdRisk'" class="legend-section">
+        <div class="legend-scale">
+          <div class="scale-item" v-for="(item, index) in cdRiskLegend" :key="index">
+            <div class="color-box" :style="{ backgroundColor: item.color }"></div>
+            <span>{{ item.label }}</span>
+          </div>
+        </div>
+      </div>
+
+      <!-- 安全指数Q图例 -->
+      <div v-if="currentLegend === 'safetyQ'" class="legend-section">
+        <div class="legend-scale">
+          <div class="scale-item" v-for="(item, index) in safetyQLegend" :key="index">
+            <div class="color-box" :style="{ backgroundColor: item.color }"></div>
+            <span>{{ item.label }}</span>
+          </div>
+        </div>
+        <div class="legend-source">
+          <p>注:Q = 阈值/污染物含量</p>
+        </div>
+      </div>
+    </div>
   </div>
 </template>
 
@@ -92,6 +122,40 @@ const categoryColors = { // 分类颜色配置
   '土壤样品': '#2196F3'      // 蓝色
 };
 
+const isShowLegend = ref(true)
+const currentLegend = ref('cdRisk') // 默认显示Cd风险图例
+
+/// 图例配置数据
+const cdRiskLegend = reactive([
+  { label: '无风险', color: '#00C853' },
+  { label: '中低风险', color: '#FFD600' },
+  { label: '高风险', color: '#D50000' }
+])
+
+const safetyQLegend = reactive([
+  { label: 'Q < 1', color: '#00C853' },
+  { label: '1 < Q < 5', color: '#FFD600' },
+  { label: 'Q > 5', color: '#D50000' }
+])
+
+// 图例标题映射
+const legendTitles = {
+  cdRisk: 'Cd污染风险等级',
+  safetyQ: '安全生产指数Q'
+}
+
+const currentLegendTitle = computed(() => legendTitles[currentLegend.value])
+
+// 切换图例显示
+const toggleLegend = () => {
+  isShowLegend.value = !isShowLegend.value
+}
+
+// 切换图例类型
+const switchLegendType = (type) => {
+  currentLegend.value = type
+}
+
 const tMapConfig = reactive({
   key: import.meta.env.VITE_TMAP_KEY, // 请替换为你的开发者密钥
   geocoderURL: 'https://apis.map.qq.com/ws/geocoder/v1/'
@@ -326,7 +390,7 @@ const initMap = async () => {
     //   map: map,
     //   styles: { default: defaultStyle }
     // })
-    const geojsonData = await loadGeoJSON('/data/单元格.geojson');
+    const geojsonData = await loadGeoJSON('https://soilgd.com:8000/api/vector/export/all?table_name=unit_ceil');
     initMapWithGeoJSON(geojsonData, map);
     await initSurveyDataLayer(map);
     filterSurveyDataLayer(currentSurveyFilter.value)
@@ -797,7 +861,7 @@ const initSurveyDataLayer = async (map) => {
   try {
     isLoading.value = true
     const geoJsonFiles = [
-      'https://soilgd.com:8000/api/vector/export/surveydata',
+      'https://soilgd.com:8000/api/vector/export/all?table_name=surveydata',
       '/data/河池土壤样品.geojson',
       '/data/河池农产品样品.geojson',
     ];
@@ -982,10 +1046,7 @@ onBeforeUnmount(() => {
   background: #2b5dc5;
 }
 
-.basemap-toggle button.active {
-  background: #00C853;
-  box-shadow: 0 0 8px rgba(0, 200, 83, 0.5);
-}
+
 
 /* 图层过渡动画 */
 .tmap-geojson-layer {
@@ -1264,4 +1325,109 @@ onBeforeUnmount(() => {
   border-left: 3px solid #00FF00;
   margin-top: 12px;
 }
+.map-legend {
+  position: fixed;
+  left: 20px;
+  bottom: 80px;
+  z-index: 1000;
+  background: rgba(255, 255, 255, 0.95);
+  border-radius: 8px;
+  padding: 15px;
+  backdrop-filter: blur(8px);
+  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
+  transition: all 0.3s ease;
+  width: 220px;
+}
+
+.map-legend.active {
+  bottom: 20px;
+}
+
+.legend-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 12px;
+}
+
+.close-btn {
+  background: none;
+  border: none;
+  font-size: 20px;
+  cursor: pointer;
+  color: #666;
+}
+
+.legend-section {
+  max-height: 180px;
+  overflow-y: auto;
+}
+
+.legend-scale {
+  display: flex;
+  flex-direction: column; /* 改为纵向排列 */
+  gap: 10px;
+}
+
+.scale-item {
+  display: flex;
+  align-items: flex-start;
+  gap: 6px;
+}
+
+.color-box {
+  width: 20px;
+  height: 20px;
+  border-radius: 3px;
+  border: 1px solid #ccc;
+}
+
+.legend-source {
+  font-size: 12px;
+  color: #666;
+  line-height: 1.4;
+}
+
+/* 响应式调整 */
+@media (max-width: 768px) {
+  .map-legend {
+    width: 180px;
+    bottom: 10px;
+  }
+  
+  .scale-item {
+    flex-direction: column;
+    text-align: center;
+  }
+}
+.legend-controls {
+  display: flex;
+  gap: 12px;
+  margin-bottom: 16px;
+  position: relative;
+  z-index: 1001; /* 确保在图例面板之上 */
+}
+
+.legend-controls button {
+  padding: 8px 16px;
+  background: #3876ff;
+  color: white;
+  border: none;
+  border-radius: 20px;
+  cursor: pointer;
+  transition: all 0.3s ease;
+}
+
+.legend-controls button:hover{
+  background: #2b5dc5;
+}
+
+/* 响应式调整 */
+@media (max-width: 768px) {
+  .legend-btn {
+    padding: 8px 16px;
+    font-size: 13px;
+    border-radius: 20px;
+  }
+}
 </style>