From ff7089c936427e85ea967c0062700eb85628a563 Mon Sep 17 00:00:00 2001 From: zhengzhoawen Date: Fri, 7 Aug 2026 18:03:39 +0000 Subject: [PATCH] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E6=96=87=E4=BB=B6=E8=87=B3?= =?UTF-8?q?=E3=80=8C/=E3=80=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 441 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 439 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7044e07..799bfdd 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,440 @@ -# auto_irrigation_configuration +# Irrigation Coding Tool + +基于 `GeoPandas + Shapely` 的灌区空间编码工具,用于对农场数据中的水路、闸门、田块进行批量编号,并输出新的 `shp` 与 `geojson` 结果。 + +当前主程序入口为 [src/main.py](/d:/Desktop/yuelu0402/src/main.py)。 + +## 1. 功能概述 + +本工具主要处理三类空间数据: + +- 点文件:设备点,包含泵、闸门、排水口等。 +- 线文件:水路,包含主渠、支渠,以及排水渠。 +- 面文件:田块。 + +处理完成后,工具会输出: + +- 编码后的水路结果 +- 编码后的闸门/泵/排水口点结果 +- 编码后的田块结果 +- 对应的 `GeoJSON` 结果 +- 运行日志 + +## 2. 当前代码结构 + +### 2.1 主入口 + +- [src/main.py](/d:/Desktop/yuelu0402/src/main.py) + +主要职责: + +- 批量扫描农场目录 +- 调用水路编码 +- 调用闸门编码 +- 调用田块编码 +- 合并点位结果 +- 输出 `shp` / `geojson` +- 提供 `tkinter` 运行窗口与日志输出 + +### 2.2 水路编码 + +- [src/segment_code.py](/d:/Desktop/yuelu0402/src/segment_code.py) + +主要职责: + +- 识别泵点 +- 保留已有合法泵编码,缺失时自动补码 +- 对非排水渠进行主渠/支渠编号 +- 对排水渠单独续编 +- 输出 `code`、`type`、`feed_by` + +### 2.3 闸门编码 + +- [src/gate_code.py](/d:/Desktop/yuelu0402/src/gate_code.py) + +主要职责: + +- 从点文件中筛选闸门 +- 匹配闸门所属水路 +- 按 DFS 规则生成闸门编号 +- 自动补全闸门 `类型/type` +- 输出详细匹配与排序日志 + +## 3. 输入数据要求 + +### 3.1 文件组织方式 + +程序按“批处理”方式运行。默认会扫描工具同级目录下的多个农场文件夹。 + +每个农场文件夹中需要至少有以下三类 `shp`: + +- 点文件:文件名包含 `节制闸` +- 面文件:文件名包含 `田块` +- 线文件:文件名包含 `水路` + +示意结构: + +```text +某个总目录/ +├─ 农场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](/d:/Desktop/yuelu0402/src/segment_code.py) 处理。 + +规则如下: + +- 如果泵已有 `code`,且文本中包含 `P`,则认为该编码有效,直接保留。 +- 如果没有合法 `code`,则自动编号为 `P1`、`P2`、`P3`... +- 泵排序优先按 `P` 后的数字排序。 +- 如果去掉 `P` 后无法转成数字,则回退到整体文本排序。 + +示例: + +- `P1` +- `P2` +- `P10` + +如果存在非标准值,例如: + +- `P-A` +- `Pump3` + +则会按兜底文本排序。 + +### 4.2 水路编码规则 + +#### 非排水渠 + +非排水渠先进行主渠/支渠编号。 + +规则如下: + +- 先依据泵点识别主渠 +- 主渠编码为 `S1`、`S2`、`S3`... +- 支渠编码也使用 `Sx` +- `type` 字段写入: + - `main-S` + - `branch-S` +- `feed_by` 表示该水路由哪条上级水路供给 + +当前逻辑不是“父渠先抢子渠”,而是先为候选子渠构建更合理的父子关系,再生成编码,可减少相邻水路误匹配。 + +#### 排水渠 + +排水渠单独处理,编号接续在非排水渠之后。 + +规则如下: + +- `code` 继续沿用 `Sx` +- 编号从非排水渠最后一个 `S` 号往后接 +- 排序按起点坐标: + - 先纬度从大到小,即北到南 + - 再经度从大到小,即东到西 +- 排水渠不参与主支关系计算 +- 排水渠的: + - `type = ""` + - `feed_by = ""` + - `dis_rank = 空` + +### 4.3 闸门编码规则 + +闸门编码由 [src/gate_code.py](/d:/Desktop/yuelu0402/src/gate_code.py) 处理。 + +规则如下: + +1. 从点文件中筛出闸门。 +2. 将闸门匹配到最近的非排水渠,即 `main-S / branch-S`。 +3. 计算闸门在所属水路上的投影位置 `along_dist`。 +4. 按 DFS 规则排序: + - 当前渠上的闸门与下级支渠入口一起比较 + - 按沿渠位置从后往前排序 + - 遇到支渠入口时递归进入支渠 +5. 按全局顺序赋编号: + - `S1-G1` + - `S1-G2` + - `S2-G3` + +当前版本已修正一个关键问题: + +- 闸门在线上的顺序计算改为精确投影 `line.project(point)` +- 不再使用分段 `buffer` 推断所在段 +- 这能避免闸门靠近分叉点时顺序被算反 + +#### 闸门类型补全 + +闸门最终会补全中英文类型: + +- `进水闸` -> `inlet-G` +- `进排水闸` -> `inout-G` +- `节制闸` -> 根据所属水路补成: + - `main-G` + - `branch-G` + +### 4.4 田块编码规则 + +田块编码由 [src/main.py](/d:/Desktop/yuelu0402/src/main.py) 中的 `assign_field_code()` 处理。 + +规则如下: + +- 田块优先与非节制闸关联 +- 从闸门编码中继承前缀 +- 再追加田块序号 + +示例: + +- `S1-G3-F1` +- `S2-G8-F12` + +田块结果还会生成 `dis_rank`。 + +## 5. 输出结果说明 + +### 5.1 输出目录 + +批处理运行后,会在基础目录下生成: + +- `result_时间戳/` +- `result_时间戳_geojson/` +- `log_时间戳.txt` + +### 5.2 输出文件 + +每个农场会生成: + +- 编码后的水路 `shp` +- 编码后的点位 `shp` +- 编码后的田块 `shp` +- 对应 `geojson` + +### 5.3 字段保留规则 + +#### 水路结果 + +- 原始字段大部分保留 +- 会写入或覆盖: + - `code` + - `type` + - `feed_by` + - `dis_rank` + +#### 点位结果 + +点位结果不是原点文件直接复制,而是重新合并得到: + +- 闸门 +- 泵 +- 排水口 + +当前版本已尽量保留各类点位的非核心原始字段,合并时按字段并集输出,缺失字段填空。 + +#### 田块结果 + +- 原始字段大部分保留 +- 会写入或覆盖: + - `code` + - `dis_rank` + +## 6. 运行方式 + +### 6.1 直接运行源码 + +进入 `src` 目录后运行: + +```powershell +python main.py +``` + +程序会弹出黑底日志窗口,并在运行目录附近生成结果目录和日志文件。 + +### 6.2 运行窗口说明 + +当前窗口会输出: + +- 输入路径信息 +- 水路处理统计 +- 闸门匹配明细 +- 闸门 DFS 排序明细 +- 闸门编号生成过程 +- 单个农场汇总 +- 批处理最终汇总 + +最终汇总至少包含: + +- 成功数量 +- 失败数量 +- 泵站检测/完成数 +- 水路检测/完成数 +- 闸门检测/完成数 +- 总耗时 + +## 7. 打包说明 + +### 7.1 最简单的打包方式 + +如果你只想从 `src` 目录直接把 `main.py` 打包: + +```powershell +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` 文件夹一起发给对方 + +对方使用方式: + +1. 解压整个目录 +2. 双击 `IrrigationTool_v1.4.exe` +3. 将待处理农场文件夹与工具目录按要求摆放 + +### 7.3 关于 `--onefile` + +本项目依赖: + +- `geopandas` +- `pyogrio` +- `pyproj` +- `GDAL` + +这类 GIS 依赖在 `--onefile` 模式下较容易出现动态库、数据文件或运行时定位问题。除非有充分测试,否则更建议使用 `--onedir`。 + +## 8. 环境依赖 + +建议环境: + +- Python 3.9 +- geopandas +- shapely +- pandas +- pyogrio +- pyproj +- tkinter +- pyinstaller + +## 9. GDAL / PROJ 说明 + +当前环境如果出现以下警告: + +```text +GDAL_DATA is not defined +Cannot find header.dxf +``` + +这通常不是业务代码错误,而是 `GDAL` 没找到自己的数据目录。 + +典型需要设置的环境变量: + +- `GDAL_DATA` +- `PROJ_LIB` + +示例: + +```powershell +$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 的电脑上做一次实测 +- 若后续进一步提高稳定性,建议把距离匹配逐步切换到米制投影坐标系下处理 -农场基于设备、灌渠以及田块的水网关系解析 \ No newline at end of file