|
@@ -40,12 +40,12 @@
|
|
|
const CONFIG = {
|
|
const CONFIG = {
|
|
|
center:[25.202903, 113.25383],
|
|
center:[25.202903, 113.25383],
|
|
|
zoom:11,
|
|
zoom:11,
|
|
|
- getPoint:'/api/vector/export/all?table_name=le_soil_data&format=geojson',
|
|
|
|
|
|
|
+ getPoint:'/api/vector/export/all?table_name=le_data_block_map&format=geojson',
|
|
|
geoserver:{
|
|
geoserver:{
|
|
|
url:'/geoserver',
|
|
url:'/geoserver',
|
|
|
workspace:'acidmap',
|
|
workspace:'acidmap',
|
|
|
layerGroup:'leshujukanbanmap',
|
|
layerGroup:'leshujukanbanmap',
|
|
|
- dataLayer:'le_soil_data',
|
|
|
|
|
|
|
+ dataLayer:'le_data_block_map',
|
|
|
wmsUrl:'/geoserver/acidmap/wms',
|
|
wmsUrl:'/geoserver/acidmap/wms',
|
|
|
phField: 'ph_mean'
|
|
phField: 'ph_mean'
|
|
|
},
|
|
},
|
|
@@ -55,9 +55,10 @@
|
|
|
layerGroup:'le_reflux_map',
|
|
layerGroup:'le_reflux_map',
|
|
|
dataLayer:'le_data_reflux_result',
|
|
dataLayer:'le_data_reflux_result',
|
|
|
wmsUrl:'/geoserver/acidmap/wms',
|
|
wmsUrl:'/geoserver/acidmap/wms',
|
|
|
- phField: 'ph_value'
|
|
|
|
|
|
|
+ phField: 'le_data__4'
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+ // 图层配置已验证:正常地图使用 le_data_block_map,反酸地图使用 le_data_reflux_result
|
|
|
|
|
|
|
|
const currentMapType = ref('normal')
|
|
const currentMapType = ref('normal')
|
|
|
|
|
|
|
@@ -132,8 +133,8 @@ function getPHComment(avgPH) {
|
|
|
attribution: '© GeoServer - Acidmap'
|
|
attribution: '© GeoServer - Acidmap'
|
|
|
}).addTo(map)
|
|
}).addTo(map)
|
|
|
|
|
|
|
|
- console.log(`地图已切换到:${mapType === 'rebound' ? '反酸一周期后' : '实施降酸措施'}`)
|
|
|
|
|
- console.log('新图层:', `${config.workspace}:${config.layerGroup}`)
|
|
|
|
|
|
|
+ // console.log(`地图已切换到:${mapType === 'rebound' ? '反酸一周期后' : '实施降酸措施'}`)
|
|
|
|
|
+ // console.log('新图层:', `${config.workspace}:${config.layerGroup}`)
|
|
|
|
|
|
|
|
// 重新加载对应地图的数据和统计
|
|
// 重新加载对应地图的数据和统计
|
|
|
await loadMapData()
|
|
await loadMapData()
|
|
@@ -144,15 +145,31 @@ function getPHComment(avgPH) {
|
|
|
try {
|
|
try {
|
|
|
const config = currentMapType.value === 'rebound' ? CONFIG.reboundGeoserver : CONFIG.geoserver
|
|
const config = currentMapType.value === 'rebound' ? CONFIG.reboundGeoserver : CONFIG.geoserver
|
|
|
|
|
|
|
|
- const response = await fetch(
|
|
|
|
|
- `${config.url}/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=${config.workspace}:${config.dataLayer}&outputFormat=application/json`
|
|
|
|
|
- );
|
|
|
|
|
|
|
+ const url = `${config.url}/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=${config.workspace}:${config.dataLayer}&outputFormat=application/json`
|
|
|
|
|
|
|
|
- if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
|
|
|
|
|
|
|
+ // console.log('🔍 请求 WFS 数据:', url);
|
|
|
|
|
|
|
|
- const geoJsonData = await response.json();
|
|
|
|
|
|
|
+ const response = await fetch(url);
|
|
|
|
|
|
|
|
- console.log('✅ 获取到数据:', geoJsonData.features.length, '条记录');
|
|
|
|
|
|
|
+ if (!response.ok) {
|
|
|
|
|
+ const errorText = await response.text();
|
|
|
|
|
+ console.error('❌ WFS 响应错误:', errorText);
|
|
|
|
|
+ throw new Error(`HTTP error! status: ${response.status}`);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const text = await response.text();
|
|
|
|
|
+ // console.log('📦 原始响应:', text.substring(0, 200));
|
|
|
|
|
+
|
|
|
|
|
+ // 尝试解析 JSON
|
|
|
|
|
+ let geoJsonData;
|
|
|
|
|
+ try {
|
|
|
|
|
+ geoJsonData = JSON.parse(text);
|
|
|
|
|
+ } catch (parseError) {
|
|
|
|
|
+ console.error('❌ JSON 解析失败,响应内容:', text);
|
|
|
|
|
+ throw new Error('GeoServer 返回的数据格式不正确,不是有效的 JSON');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // console.log('✅ 获取到地图数据:', geoJsonData.features?.length || 0, '条记录');
|
|
|
|
|
|
|
|
// 保存数据用于统计和交互
|
|
// 保存数据用于统计和交互
|
|
|
allFeatures = geoJsonData.features;
|
|
allFeatures = geoJsonData.features;
|
|
@@ -269,7 +286,7 @@ function getPHComment(avgPH) {
|
|
|
normalPercent
|
|
normalPercent
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
- console.log('✅ 统计数据加载完成:', statistics.value);
|
|
|
|
|
|
|
+ // console.log('✅ 统计数据加载完成:', statistics.value);
|
|
|
} catch (err) {
|
|
} catch (err) {
|
|
|
console.error('加载统计数据失败:', err);
|
|
console.error('加载统计数据失败:', err);
|
|
|
}
|
|
}
|
|
@@ -278,15 +295,40 @@ function getPHComment(avgPH) {
|
|
|
// 修改为只获取数据用于统计,不渲染到地图
|
|
// 修改为只获取数据用于统计,不渲染到地图
|
|
|
async function fetchDataForStatistics() {
|
|
async function fetchDataForStatistics() {
|
|
|
try {
|
|
try {
|
|
|
- const response = await fetch(
|
|
|
|
|
- `${CONFIG.geoserver.url}/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=${CONFIG.geoserver.workspace}:${CONFIG.geoserver.dataLayer}&outputFormat=application/json`
|
|
|
|
|
- );
|
|
|
|
|
|
|
+ const config = currentMapType.value === 'rebound' ? CONFIG.reboundGeoserver : CONFIG.geoserver
|
|
|
|
|
+
|
|
|
|
|
+ const url = `${config.url}/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=${config.workspace}:${config.dataLayer}&outputFormat=application/json`
|
|
|
|
|
+
|
|
|
|
|
+ // console.log('🔍 请求 WFS 数据:', url);
|
|
|
|
|
|
|
|
- if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
|
|
|
|
|
|
|
+ const response = await fetch(url);
|
|
|
|
|
+
|
|
|
|
|
+ if (!response.ok) {
|
|
|
|
|
+ const errorText = await response.text();
|
|
|
|
|
+ console.error('❌ WFS 响应错误:', errorText);
|
|
|
|
|
+ throw new Error(`HTTP error! status: ${response.status}`);
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- const geoJsonData = await response.json();
|
|
|
|
|
|
|
+ const text = await response.text();
|
|
|
|
|
+ // console.log('📦 原始响应:', text.substring(0, 200));
|
|
|
|
|
|
|
|
- console.log('✅ 获取到数据:', geoJsonData.features.length, '条记录');
|
|
|
|
|
|
|
+ // 尝试解析 JSON
|
|
|
|
|
+ let geoJsonData;
|
|
|
|
|
+ try {
|
|
|
|
|
+ geoJsonData = JSON.parse(text);
|
|
|
|
|
+ } catch (parseError) {
|
|
|
|
|
+ console.error('❌ JSON 解析失败,响应内容:', text);
|
|
|
|
|
+ throw new Error('GeoServer 返回的数据格式不正确,不是有效的 JSON');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // console.log('✅ 获取到数据:', geoJsonData.features?.length || 0, '条记录');
|
|
|
|
|
+
|
|
|
|
|
+ // 调试:打印第一个要素的 properties
|
|
|
|
|
+ // if (geoJsonData.features && geoJsonData.features.length > 0) {
|
|
|
|
|
+ // console.log('📋 第一个要素的 properties:', geoJsonData.features[0].properties);
|
|
|
|
|
+ // console.log('📋 pH 字段值 (ph_mean):', geoJsonData.features[0].properties.ph_mean);
|
|
|
|
|
+ // console.log('📋 pH 字段值 (le_data__4):', geoJsonData.features[0].properties.le_data__4);
|
|
|
|
|
+ // }
|
|
|
|
|
|
|
|
// 保存数据用于统计和交互
|
|
// 保存数据用于统计和交互
|
|
|
allFeatures = geoJsonData.features;
|
|
allFeatures = geoJsonData.features;
|
|
@@ -296,12 +338,8 @@ function getPHComment(avgPH) {
|
|
|
calculatePHDistribution(allFeatures);
|
|
calculatePHDistribution(allFeatures);
|
|
|
loadStatistics();
|
|
loadStatistics();
|
|
|
|
|
|
|
|
- // 添加点击事件监听(不显示标记点)
|
|
|
|
|
- map.on('click', function(e) {
|
|
|
|
|
- const latlng = e.latlng;
|
|
|
|
|
- // 查找最近的采样点
|
|
|
|
|
- findNearestPoint(latlng);
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ // 添加点击事件监听
|
|
|
|
|
+ map.on('click', handleMapClick);
|
|
|
|
|
|
|
|
} catch (err) {
|
|
} catch (err) {
|
|
|
console.error('❌ 加载统计数据失败:', err);
|
|
console.error('❌ 加载统计数据失败:', err);
|
|
@@ -330,47 +368,81 @@ function getPHComment(avgPH) {
|
|
|
phDistribution.value = distribution
|
|
phDistribution.value = distribution
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // 查找最近的采样点
|
|
|
|
|
- function findNearestPoint(latlng) {
|
|
|
|
|
- let nearestPoint = null;
|
|
|
|
|
- let minDistance = Infinity;
|
|
|
|
|
|
|
+ // 处理地图点击,查询地块属性
|
|
|
|
|
+ async function handleMapClick(e) {
|
|
|
|
|
+ const latlng = e.latlng;
|
|
|
|
|
+ // console.log('🔍 地图点击:', latlng);
|
|
|
|
|
|
|
|
- // 根据当前地图类型选择 pH 字段
|
|
|
|
|
- const config = currentMapType.value === 'rebound' ? CONFIG.reboundGeoserver : CONFIG.geoserver
|
|
|
|
|
-
|
|
|
|
|
- allFeatures.forEach(feature => {
|
|
|
|
|
- const coords = feature.geometry.coordinates;
|
|
|
|
|
- if (coords && coords.length >= 2) {
|
|
|
|
|
- const pointLat = coords[1];
|
|
|
|
|
- const pointLng = coords[0];
|
|
|
|
|
- const distance = Math.sqrt(
|
|
|
|
|
- Math.pow(pointLat - latlng.lat, 2) +
|
|
|
|
|
- Math.pow(pointLng - latlng.lng, 2)
|
|
|
|
|
- );
|
|
|
|
|
-
|
|
|
|
|
- if (distance < minDistance && distance < 0.01) { // 10 米范围内
|
|
|
|
|
- minDistance = distance;
|
|
|
|
|
- nearestPoint = feature;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 根据当前地图类型选择配置
|
|
|
|
|
+ const config = currentMapType.value === 'rebound' ? CONFIG.reboundGeoserver : CONFIG.geoserver
|
|
|
|
|
+
|
|
|
|
|
+ // console.log('📋 当前地图类型:', currentMapType.value);
|
|
|
|
|
+ // console.log('📋 查询的数据层:', config.dataLayer);
|
|
|
|
|
+
|
|
|
|
|
+ // 构建 WMS GetFeatureInfo 请求
|
|
|
|
|
+ const size = map.getSize();
|
|
|
|
|
+ const point = map.latLngToContainerPoint(latlng);
|
|
|
|
|
+
|
|
|
|
|
+ const params = new URLSearchParams({
|
|
|
|
|
+ SERVICE: 'WMS',
|
|
|
|
|
+ VERSION: '1.1.1',
|
|
|
|
|
+ REQUEST: 'GetFeatureInfo',
|
|
|
|
|
+ LAYERS: `${config.workspace}:${config.dataLayer}`,
|
|
|
|
|
+ QUERY_LAYERS: `${config.workspace}:${config.dataLayer}`,
|
|
|
|
|
+ STYLES: '',
|
|
|
|
|
+ SRS: 'EPSG:4326',
|
|
|
|
|
+ BBOX: map.getBounds().toBBoxString(),
|
|
|
|
|
+ WIDTH: size.x,
|
|
|
|
|
+ HEIGHT: size.y,
|
|
|
|
|
+ X: Math.round(point.x),
|
|
|
|
|
+ Y: Math.round(point.y),
|
|
|
|
|
+ INFO_FORMAT: 'application/json',
|
|
|
|
|
+ FEATURE_COUNT: 1
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ const url = `${config.wmsUrl}?${params.toString()}`;
|
|
|
|
|
+ // console.log('🔍 查询 URL:', url);
|
|
|
|
|
+
|
|
|
|
|
+ const response = await fetch(url);
|
|
|
|
|
+
|
|
|
|
|
+ if (!response.ok) {
|
|
|
|
|
+ throw new Error(`HTTP error! status: ${response.status}`);
|
|
|
}
|
|
}
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- if (nearestPoint) {
|
|
|
|
|
- const ph = parsePHValue(nearestPoint.properties[config.phField]);
|
|
|
|
|
|
|
|
|
|
- selectedPoint.value = {
|
|
|
|
|
- ph: ph,
|
|
|
|
|
- properties: nearestPoint.properties
|
|
|
|
|
- };
|
|
|
|
|
|
|
+ const data = await response.json();
|
|
|
|
|
+
|
|
|
|
|
+ // console.log('� 查询结果:', data);
|
|
|
|
|
|
|
|
- console.log('✅ 选中地块:', nearestPoint.properties);
|
|
|
|
|
- console.log('pH 字段:', config.phField, '= ', nearestPoint.properties[config.phField]);
|
|
|
|
|
|
|
+ if (data.features && data.features.length > 0) {
|
|
|
|
|
+ const feature = data.features[0];
|
|
|
|
|
+ const ph = parsePHValue(feature.properties[config.phField]);
|
|
|
|
|
+
|
|
|
|
|
+ // console.log('📋 pH 字段:', config.phField);
|
|
|
|
|
+ // console.log('📋 pH 值:', ph);
|
|
|
|
|
+ // console.log('📋 完整属性:', feature.properties);
|
|
|
|
|
+
|
|
|
|
|
+ selectedPoint.value = {
|
|
|
|
|
+ ph: ph,
|
|
|
|
|
+ properties: feature.properties
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ // console.log('✅ 选中地块:', selectedPoint.value);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // console.log('⚠️ 该位置没有地块数据');
|
|
|
|
|
+ selectedPoint.value = null;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ } catch (err) {
|
|
|
|
|
+ console.error('❌ 查询地块信息失败:', err);
|
|
|
|
|
+ alert('查询地块信息失败,请重试');
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
onUnmounted(()=>{
|
|
onUnmounted(()=>{
|
|
|
if(map) {
|
|
if(map) {
|
|
|
|
|
+ map.off('click', handleMapClick) // 移除点击事件监听
|
|
|
map.remove()
|
|
map.remove()
|
|
|
map = null
|
|
map = null
|
|
|
}
|
|
}
|
|
@@ -413,7 +485,7 @@ onUnmounted(()=>{
|
|
|
<h4>📊 乐昌县土壤 pH 统计</h4>
|
|
<h4>📊 乐昌县土壤 pH 统计</h4>
|
|
|
|
|
|
|
|
<div class="stat-row">
|
|
<div class="stat-row">
|
|
|
- <span class="stat-label">采样点总数:</span>
|
|
|
|
|
|
|
+ <span class="stat-label">地块总数:</span>
|
|
|
<span class="stat-value">{{ statistics.totalBlocks }} 个</span>
|
|
<span class="stat-value">{{ statistics.totalBlocks }} 个</span>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
@@ -725,7 +797,7 @@ onUnmounted(()=>{
|
|
|
|
|
|
|
|
.distribution-chart {
|
|
.distribution-chart {
|
|
|
position: absolute;
|
|
position: absolute;
|
|
|
- top:600px;
|
|
|
|
|
|
|
+ top:700px;
|
|
|
right: 10px;
|
|
right: 10px;
|
|
|
background: rgba(255, 255, 255, 0.95);
|
|
background: rgba(255, 255, 255, 0.95);
|
|
|
padding: 15px;
|
|
padding: 15px;
|