10 KiB
Irrigation Coding Tool
基于 GeoPandas + Shapely 的灌区空间编码工具,用于对农场数据中的水路、闸门、田块进行批量编号,并输出新的 shp 与 geojson 结果。
当前主程序入口为 src/main.py。
1. 功能概述
本工具主要处理三类空间数据:
- 点文件:设备点,包含泵、闸门、排水口等。
- 线文件:水路,包含主渠、支渠,以及排水渠。
- 面文件:田块。
处理完成后,工具会输出:
- 编码后的水路结果
- 编码后的闸门/泵/排水口点结果
- 编码后的田块结果
- 对应的
GeoJSON结果 - 运行日志
2. 当前代码结构
2.1 主入口
主要职责:
- 批量扫描农场目录
- 调用水路编码
- 调用闸门编码
- 调用田块编码
- 合并点位结果
- 输出
shp/geojson - 提供
tkinter运行窗口与日志输出
2.2 水路编码
主要职责:
- 识别泵点
- 保留已有合法泵编码,缺失时自动补码
- 对非排水渠进行主渠/支渠编号
- 对排水渠单独续编
- 输出
code、type、feed_by
2.3 闸门编码
主要职责:
- 从点文件中筛选闸门
- 匹配闸门所属水路
- 按 DFS 规则生成闸门编号
- 自动补全闸门
类型/type - 输出详细匹配与排序日志
3. 输入数据要求
3.1 文件组织方式
程序按“批处理”方式运行。默认会扫描工具同级目录下的多个农场文件夹。
每个农场文件夹中需要至少有以下三类 shp:
- 点文件:文件名包含
节制闸 - 面文件:文件名包含
田块 - 线文件:文件名包含
水路
示意结构:
某个总目录/
├─ 农场A/
│ ├─ xxx节制闸.shp
│ ├─ xxx田块.shp
│ └─ xxx水路.shp
├─ 农场B/
│ ├─ xxx节制闸.shp
│ ├─ xxx田块.shp
│ └─ xxx水路.shp
└─ src/
├─ main.py
├─ segment_code.py
└─ gate_code.py
3.2 坐标系
当前代码直接在经纬度坐标下处理,默认你的数据为 WGS84 或与之兼容的度单位坐标系。
当前阈值:
- 水路父子关系判定容差:
0.00005 - 闸门匹配渠道容差:
0.00010
近似理解:
0.00005度约等于 5 米0.00010度约等于 10 米
这只是近似值,东西方向实际距离会受纬度影响。
3.3 点文件字段要求
点文件建议至少包含以下字段之一:
类型type
当前点位识别规则:
- 泵:由水路编码模块筛选
- 闸门:
类型为进水闸 / 进排水闸 / 节制闸,或type为inlet-G / inout-G / main-G / branch-G - 排水口:
类型为排水口,或type为drain-G
3.4 水路文件字段要求
水路文件建议至少具备能区分排水渠的字段:
ch_type- 或
渠型
当前排水渠判定规则:
ch_type == "drain-S"- 或
渠型 == "排水渠"
3.5 田块文件字段要求
田块需具备有效面几何。字段没有强制固定要求,但输出时会新增 code、dis_rank。
4. 编码规则说明
4.1 泵编码规则
泵点编码由 src/segment_code.py 处理。
规则如下:
- 如果泵已有
code,且文本中包含P,则认为该编码有效,直接保留。 - 如果没有合法
code,则自动编号为P1、P2、P3... - 泵排序优先按
P后的数字排序。 - 如果去掉
P后无法转成数字,则回退到整体文本排序。
示例:
P1P2P10
如果存在非标准值,例如:
P-APump3
则会按兜底文本排序。
4.2 水路编码规则
非排水渠
非排水渠先进行主渠/支渠编号。
规则如下:
- 先依据泵点识别主渠
- 主渠编码为
S1、S2、S3... - 支渠编码也使用
Sx type字段写入:main-Sbranch-S
feed_by表示该水路由哪条上级水路供给
当前逻辑不是“父渠先抢子渠”,而是先为候选子渠构建更合理的父子关系,再生成编码,可减少相邻水路误匹配。
排水渠
排水渠单独处理,编号接续在非排水渠之后。
规则如下:
code继续沿用Sx- 编号从非排水渠最后一个
S号往后接 - 排序按起点坐标:
- 先纬度从大到小,即北到南
- 再经度从大到小,即东到西
- 排水渠不参与主支关系计算
- 排水渠的:
type = ""feed_by = ""dis_rank = 空
4.3 闸门编码规则
闸门编码由 src/gate_code.py 处理。
规则如下:
- 从点文件中筛出闸门。
- 将闸门匹配到最近的非排水渠,即
main-S / branch-S。 - 计算闸门在所属水路上的投影位置
along_dist。 - 按 DFS 规则排序:
- 当前渠上的闸门与下级支渠入口一起比较
- 按沿渠位置从后往前排序
- 遇到支渠入口时递归进入支渠
- 按全局顺序赋编号:
S1-G1S1-G2S2-G3
当前版本已修正一个关键问题:
- 闸门在线上的顺序计算改为精确投影
line.project(point) - 不再使用分段
buffer推断所在段 - 这能避免闸门靠近分叉点时顺序被算反
闸门类型补全
闸门最终会补全中英文类型:
进水闸->inlet-G进排水闸->inout-G节制闸-> 根据所属水路补成:main-Gbranch-G
4.4 田块编码规则
田块编码由 src/main.py 中的 assign_field_code() 处理。
规则如下:
- 田块优先与非节制闸关联
- 从闸门编码中继承前缀
- 再追加田块序号
示例:
S1-G3-F1S2-G8-F12
田块结果还会生成 dis_rank。
5. 输出结果说明
5.1 输出目录
批处理运行后,会在基础目录下生成:
result_时间戳/result_时间戳_geojson/log_时间戳.txt
5.2 输出文件
每个农场会生成:
- 编码后的水路
shp - 编码后的点位
shp - 编码后的田块
shp - 对应
geojson
5.3 字段保留规则
水路结果
- 原始字段大部分保留
- 会写入或覆盖:
codetypefeed_bydis_rank
点位结果
点位结果不是原点文件直接复制,而是重新合并得到:
- 闸门
- 泵
- 排水口
当前版本已尽量保留各类点位的非核心原始字段,合并时按字段并集输出,缺失字段填空。
田块结果
- 原始字段大部分保留
- 会写入或覆盖:
codedis_rank
6. 运行方式
6.1 直接运行源码
进入 src 目录后运行:
python main.py
程序会弹出黑底日志窗口,并在运行目录附近生成结果目录和日志文件。
6.2 运行窗口说明
当前窗口会输出:
- 输入路径信息
- 水路处理统计
- 闸门匹配明细
- 闸门 DFS 排序明细
- 闸门编号生成过程
- 单个农场汇总
- 批处理最终汇总
最终汇总至少包含:
- 成功数量
- 失败数量
- 泵站检测/完成数
- 水路检测/完成数
- 闸门检测/完成数
- 总耗时
7. 打包说明
7.1 最简单的打包方式
如果你只想从 src 目录直接把 main.py 打包:
cd D:\Desktop\yuelu0402\src
python -m PyInstaller --noconfirm --clean --onedir --windowed --name IrrigationTool_v1.4 main.py
输出目录:
src\dist\IrrigationTool_v1.4\
可执行文件:
src\dist\IrrigationTool_v1.4\IrrigationTool_v1.4.exe
7.2 给没有 Python 的用户使用
如果采用 --onedir 打包:
- 不能只发单独一个
.exe - 必须把整个
IrrigationTool_v1.4文件夹一起发给对方
对方使用方式:
- 解压整个目录
- 双击
IrrigationTool_v1.4.exe - 将待处理农场文件夹与工具目录按要求摆放
7.3 关于 --onefile
本项目依赖:
geopandaspyogriopyprojGDAL
这类 GIS 依赖在 --onefile 模式下较容易出现动态库、数据文件或运行时定位问题。除非有充分测试,否则更建议使用 --onedir。
8. 环境依赖
建议环境:
- Python 3.9
- geopandas
- shapely
- pandas
- pyogrio
- pyproj
- tkinter
- pyinstaller
9. GDAL / PROJ 说明
当前环境如果出现以下警告:
GDAL_DATA is not defined
Cannot find header.dxf
这通常不是业务代码错误,而是 GDAL 没找到自己的数据目录。
典型需要设置的环境变量:
GDAL_DATAPROJ_LIB
示例:
$env:GDAL_DATA="F:\miniforge3\envs\geo_python\Library\share\gdal"
$env:PROJ_LIB="F:\miniforge3\envs\geo_python\Library\share\proj"
python main.py
如果不涉及复杂坐标转换或特殊格式,当前很多情况下只是警告,不一定影响 shp/geojson 主流程。
10. 已完成的关键修正
当前版本已完成以下修正:
- 保留已有合法泵编码,不再强制重排
- 泵排序优先按
P后数字排序,失败后回退文本排序 - 支持排水渠识别与单独续编
- 排水渠不参与
type/feed_by/dis_rank主逻辑 - 水路判定容差收紧到约 5 米
- 闸门匹配水路容差收紧到约 10 米
- 闸门排序位置改为精确投影,修复分叉点附近顺序反转问题
- 点位结果保留更多原始非核心字段
- 运行窗口补回闸门详细信息
- 运行窗口补回最终汇总信息
11. 已知限制
- 当前主要按经纬度坐标直接计算距离,属于近似处理
- 不同纬度下,东西方向距离换算并不完全一致
- 输入文件命名依赖关键字匹配
- 输入字段命名若与当前约定差异较大,需要额外适配
GDAL_DATA / PROJ_LIB未正确设置时,可能出现警告
12. 建议
- 正式批量生产前,先用 1 个农场做完整验证
- 打包后,最好在一台未安装 Python 的电脑上做一次实测
- 若后续进一步提高稳定性,建议把距离匹配逐步切换到米制投影坐标系下处理