上传文件至「/」
This commit is contained in:
@@ -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 的电脑上做一次实测
|
||||||
|
- 若后续进一步提高稳定性,建议把距离匹配逐步切换到米制投影坐标系下处理
|
||||||
|
|
||||||
农场基于设备、灌渠以及田块的水网关系解析
|
|
||||||
Reference in New Issue
Block a user