|
@@ -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>
|