本项目(瓦斯数据与赋存规律分析系统)是一个基于 Web 的地理空间数据计算与可视化系统,主要用于渔网点数据的多指标综合评价计算和空间插值分析。系统采用前后端分离架构,前端使用 Leaflet.js 进行地图可视化,后端使用 Node.js + Express 提供 API 服务,Python 脚本执行复杂的数值计算。
系统界面分为三个主要部分:
根据当前模式显示不同的内容:
图层信息模式:
计算编辑模式:
根据当前模式显示不同的内容:
图层信息模式:
计算编辑模式:
适用场景:当需要根据数据本身的变异程度自动确定权重时使用。
操作步骤:
效果说明:
适用场景:当有专家确定的指标重要性排序时使用。
操作步骤:
效果说明:
适用场景:结合主观权重(G1法)和客观权重(熵权法)的优势。
操作步骤:
效果说明:
适用场景:当需要手动指定各指标的权重时使用。
操作步骤:
效果说明:
每个计算结果支持三种渲染方式:
点符号图:
热力图:
阈值分类:
系统提供多种颜色方案:
修改可视化参数后,点击”应用设置”按钮:
wasi_4/
├── client/ # 前端客户端代码
│ ├── edit_calculate.js # 计算编辑面板主逻辑
│ └── edit_calculate.css # 样式文件
├── server/ # 后端服务器代码
│ ├── index.js # Express 服务器入口
│ ├── routes/ # API 路由
│ │ ├── yw.js # 渔网计算相关 API
│ │ ├── interpolate.js # 插值相关 API
│ │ ├── editcalc.js # 数据编辑相关 API
│ │ ├── layers.js # 图层管理 API
│ │ └── rasters.js # 栅格管理 API
│ ├── services/ # 服务层
│ │ ├── pythonRunner.js # Python 脚本执行服务
│ │ └── rasterService.js # 栅格处理服务
│ ├── utils/ # 工具函数
│ │ ├── db_yw.js # 渔网数据库工具
│ │ └── db.js # 通用数据库工具
│ ├── scripts/ # Python 脚本
│ │ ├── interpolate.py # 插值脚本(完整版)
│ │ ├── interpolate_v2.py # 插值脚本(简化版)
│ │ └── interpolate_simple.py # 插值脚本(最小依赖版)
│ ├── compute_yw.py # 渔网计算主脚本
│ └── requirements.txt # Python 依赖
├── sample/ # 示例数据和计算模块
│ ├── Entropy.py # 熵权法计算模块
│ ├── G1.py # G1法计算模块
│ ├── CombineWeight.py # 组合权重计算模块
│ └── 83yuwang/ # 示例 Shapefile 数据
├── db/ # 数据库文件
│ ├── 83yuwang.sqlite # 主数据库(SpatiaLite)
│ └── ...
├── qgis2web_2025_09_19-16_43_01_978602/ # QGIS 导出静态文件
│ ├── index.html # 主 HTML 文件
│ ├── js/ # JavaScript 库
│ ├── css/ # 样式文件
│ └── data/ # 静态数据文件
└── package.json # Node.js 依赖配置
client/edit_calculate.js:
qgis2web_2025_09_19-16_43_01_978602/index.html:
用户操作
↓
edit_calculate.js 处理事件
↓
调用 API(fetch)
↓
后端处理并返回数据
↓
更新前端状态
↓
重新渲染 UI 和地图图层
server/index.js:
server/routes/yw.js:
POST /api/yw/compute:执行计算任务GET /api/yw/runs:获取所有计算任务GET /api/yw/run/:id:获取单个任务详情GET /api/yw/run/:id/geojson:获取任务结果的 GeoJSON(带坐标转换)GET /api/yw/run/:id/values:获取任务结果的数据值PATCH /api/yw/run/:id/name:更新任务名称DELETE /api/yw/run/:id:删除任务server/routes/interpolate.js:
POST /api/interpolate:执行插值计算server/services/pythonRunner.js:
runPython(script, args):执行 Python 脚本runPythonWithStdin(script, args, stdinData):通过 stdin 传递数据(避免命令行编码问题)server/utils/db_yw.js:
openDb():打开数据库连接并加载 SpatiaLite 扩展HTTP 请求
↓
Express 路由
↓
数据库操作 / Python 脚本调用
↓
返回 JSON 响应
表1:yw_point
ogc_fid:主键f1, f2, f3, f4:四个数值字段(构造坡、底板标高、砂体、钻孔瓦斯含量)GEOMETRY:点的几何信息(POINT,SRID=2415)表2:yw_run
run_id:主键(自增)name:任务名称method:计算方法(entropy, g1, combined_luo, combined_gt, weighted_sum)created_at:创建时间params_json:参数配置(JSON 字符串)表3:yw_value
run_id:任务ID(外键)point_id:点ID(外键)value:计算结果值(run_id, point_id)ST_X, ST_Y, AsGeoJSON, Transform 等空间函数server/compute_yw.py:
sample/Entropy.py:
standardize_data():数据标准化calculate_entropy():计算信息熵和权重sample/G1.py:
calculate_g1_weights():根据指标排序和重要度比值计算权重sample/CombineWeight.py:
Luo_combined_weights():罗金辉组合权重方法GT_combined_weights():博弈论组合权重方法solve_optimal_lambda():求解最优组合系数server/scripts/interpolate_v2.py:
公式:
std_value = (value - min) / (max - min)std_value = (max - value) / (max - min)原理:
代码位置:sample/Entropy.py 的 standardize_data() 函数
公式:std_value = (value - mean) / std
原理:
代码位置:sample/Entropy.py 的 standardize_data() 函数
熵权法是一种客观赋权方法,基于信息熵理论。信息熵越大,指标提供的信息量越少,权重越小;反之,信息熵越小,指标提供的信息量越多,权重越大。
步骤1:计算比重矩阵
对于标准化后的数据矩阵,计算每个值在所在列中的比重:
p_ij = x_ij / Σ(x_ij) (i=1,2,...,n; j=1,2,...,m)
其中:
x_ij:第 i 个对象在第 j 个指标上的标准化值n:对象数量m:指标数量步骤2:计算信息熵
E_j = -k * Σ(p_ij * ln(p_ij)) (i=1,2,...,n)
其中:
k = 1 / ln(n):常数,确保熵值在 [0, 1] 区间p_ij = 0 时,p_ij * ln(p_ij) = 0(避免 log(0))步骤3:计算权重
w_j = (1 - E_j) / Σ(1 - E_k) (k=1,2,...,m)
权重归一化,确保 Σw_j = 1。
文件:sample/Entropy.py
关键函数:
calculate_entropy(standardized_data, indicator_names):
p_matrixentropyweights = (1 - entropy) / sum(1 - entropy)调用流程:
compute_yw.py::compute_entropy()
↓
ew.standardize_data() # 标准化
↓
ew.calculate_entropy() # 计算权重
↓
加权求和计算综合得分
G1法是一种主观赋权方法,基于专家确定的指标重要性排序和相邻指标的重要度比值。
步骤1:确定指标排序
专家确定指标的排序关系,例如:
U1 > U2 > U3 > ... > Um
其中 > 表示”重要于”。
步骤2:确定重要度比值
专家确定相邻指标的重要度比值:
r1 = ω1* / ω2* (第1个指标与第2个指标的重要度比)
r2 = ω2* / ω3* (第2个指标与第3个指标的重要度比)
...
r(m-1) = ω(m-1)* / ωm* (第m-1个指标与第m个指标的重要度比)
通常 r 的取值范围为 [1.0, 1.8]:
r = 1.0:两个指标同等重要r = 1.2:前一个指标比后一个指标稍重要r = 1.8:前一个指标比后一个指标明显重要步骤3:计算最次要指标的权重
ωm* = 1 / [1 + Σ(i=1到m-1) Π(g=i到m-1) r_g]
其中:
Π(g=i到m-1) r_g:从 r_i 到 r(m-1) 的连乘积Σ(i=1到m-1):对所有 i 求和步骤4:反向计算其他指标权重
ω(m-1)* = r(m-1) * ωm*
ω(m-2)* = r(m-2) * ω(m-1)*
...
ω1* = r1 * ω2*
步骤5:归一化
ωi = ωi* / Σ(ωj*) (j=1,2,...,m)
文件:sample/G1.py
关键函数:
calculate_g1_weights(indicators, r_values):
omega_m_star调用流程:
compute_yw.py::compute_g1()
↓
g1w.calculate_g1_weights() # 计算 G1 权重
↓
ew.standardize_data() # 标准化数据
↓
加权求和计算综合得分
原理: 组合权重公式:
w = t * w_G1 + (1-t) * w_I
其中:
w_G1:G1法权重(主观权重)w_I:熵权法权重(客观权重)t:组合系数,由 G1 权重的差异系数确定差异系数计算:
G_G1 = std(w_G1) / mean(w_G1)
组合系数计算:
t = (2 / (m-1)) * G_G1
如果 m=1(单指标),则 t=0.5。
约束:t 限制在 [0, 1] 范围内。
代码实现:
sample/CombineWeight.pyLuo_combined_weights(w_G1_weight_map, w_I_weight_map)原理: 通过求解优化问题确定最优组合系数,使组合权重同时接近两种权重。
目标函数:
min ||λ1*w1 + λ2*w2 - w1||² + ||λ1*w1 + λ2*w2 - w2||²
约束条件:
λ1 + λ2 = 1
求解方法:
λ1 和 λ2λ1* = |λ1| / (|λ1| + |λ2|), λ2* = |λ2| / (|λ1| + |λ2|)组合权重:
w = λ1* * w1 + λ2* * w2
代码实现:
sample/CombineWeight.pyGT_combined_weights(w_1, w_2):主函数solve_optimal_lambda(normalized_1, normalized_2):求解最优系数原理: 用户手动指定各指标的权重,直接进行加权求和。
公式:
score_i = Σ(w_j * x_ij) (j=1,2,...,m)
其中:
w_j:第 j 个指标的权重(用户指定,自动归一化)x_ij:第 i 个对象在第 j 个指标上的标准化值代码实现:
server/compute_yw.pycompute_weighted_sum()所有计算方法最终都通过加权求和计算综合得分:
score_i = Σ(w_j * std_ij) (j=1,2,...,m)
其中:
w_j:第 j 个指标的权重(由不同方法计算得到)std_ij:第 i 个对象在第 j 个指标上的标准化值代码位置:server/compute_yw.py 的各个 compute_*() 函数
前端:
后端:
计算: