CollisionAvoidanceSystem/doc/guide/cad_to_yaml_guide.md

198 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 操作指南:从 CAD 图纸生成 airport_roads.yaml 配置文件
## 1. 目标与挑战
本指南旨在说明如何使用免费开源的 GIS 软件 QGIS从机场的 CAD 工程图纸通常使用局部坐标系生成包含精确地理坐标经纬度WGS84`airport_roads.yaml` 配置文件,以供应用程序使用。
主要挑战在于将 CAD 的局部坐标系转换为标准的 WGS84 地理坐标系,这需要准确的地理参考信息。
## 2. 准备工作
在开始之前,请确保你拥有:
* **QGIS 软件**: 从 [QGIS 官网](https://qgis.org/) 下载并安装最新稳定版。
* **机场 CAD 图纸**: `.dwg``.dxf` 格式的文件。最好是包含清晰道路中心线的版本。
* **地面控制点 (GCPs - Ground Control Points)**: **这是最关键的部分!** 你需要获取 CAD 图上至少 3-4 个(越多越好,分布越均匀越好)易于识别的点(如建筑角点、跑道端点、特定标记)的**精确真实世界地理坐标**。坐标可以是:
* **经纬度 (WGS84)**: 例如 `[经度 113.12345, 纬度 22.54321]`
* **投影坐标**: 例如 UTM 坐标,并清楚知道其对应的区域和基准面。
* 获取方式:可能来自现场 GPS 测量、官方测绘数据、高精度卫星地图的比对等。**控制点的精度直接决定了最终结果的精度。**
## 3. QGIS 安装
访问 [QGIS 官网](https://qgis.org/),根据你的操作系统下载并安装 QGIS Desktop。
## 4. CAD 文件准备(可选但推荐)
为了简化后续操作,建议在 CAD 软件中:
* 清理图纸,只保留必要的图层,尤其是**道路中心线**图层和用于**地理配准的参考点**所在图层。
* 确保道路中心线是连接良好的线段 (Polyline)。
* 如果可能,将文件另存为较旧版本的 `.dxf` 格式,有时兼容性更好。
## 5. 导入 CAD 文件到 QGIS
1. 打开 QGIS。
2. 通过菜单 `图层 (Layer)` -> `添加图层 (Add Layer)` -> `添加矢量图层 (Add Vector Layer...)` 打开数据源管理器。
3.`矢量 (Vector)` 选项卡中,选择 `文件 (File)` 类型。
4. 点击 `源 (Source)` 旁边的 `...` 按钮,浏览并选择你的 `.dxf``.dwg` 文件。
5. 点击 `添加 (Add)`。QGIS 可能会询问要导入哪些图层(如果 CAD 文件包含多个图层),选择包含道路中心线和参考点的图层。
6. 关闭数据源管理器。你现在应该能在 QGIS 地图中看到 CAD 图纸的内容。此时,它的坐标系还是未知的或局部的。
## 6. 地理配准 (Georeferencing)
这是将 CAD 局部坐标转换为地理坐标的关键步骤。
1. **打开地理配准器**: 通过菜单 `图层 (Layer)` -> `地理配准器 (Georeferencer...)` 打开工具。
2. **加载 CAD 图层**: 在地理配准器窗口中,点击 `打开栅格 (Open Raster)` 按钮(虽然 CAD 是矢量,但通常在此工具中作为背景加载)。选择你刚刚导入到 QGIS 主窗口中的 CAD 图层。(如果无法直接加载矢量,可能需要先将 CAD 图层导出为图像格式如 TIFF再加载该图像进行配准但这会损失矢量特性优先尝试直接加载
* *备选方案*:如果直接加载 CAD 困难,可以在 QGIS 主窗口将 CAD 图层导出为高分辨率图像(`项目` -> `导入/导出` -> `导出地图为图像`),然后在地理配准器中加载该图像。
3. **添加地面控制点 (GCPs)**:
* 在地理配准器地图窗口中,找到你的第一个已知控制点(例如,某个建筑的角点)。
* 使用工具栏上的 `添加点 (Add Point)` 工具,在图上精确点击该点。
* 会弹出一个 `输入地图坐标 (Enter map coordinates)` 的对话框。**不要输入** X/Y 坐标(那是源坐标,让 QGIS 自动获取),而是点击 `来自地图画布 (From map canvas)`(如果你的控制点在另一地图层可见)或**手动输入该点的真实世界坐标**(经度 Longitude 对应 X纬度 Latitude 对应 Y。**确保输入的是 WGS84 经纬度坐标!** 点击 `确定 (OK)`
* 该控制点会出现在下方的 GCP 表中。
* 重复此过程,为所有已知的控制点添加映射关系(至少 3 个,推荐 4 个以上分布均匀。GCP 表中的 `dX`, `dY``残差 (Residual)` 列可以帮助判断点的精度,残差值越小越好。
4. **设置变换参数**:
* 点击工具栏上的 `变换设置 (Transformation settings)` 按钮(黄色齿轮图标)。
* **变换类型 (Transformation type)**: 根据控制点数量和分布选择。`线性 (Linear)` 适用于只有少数点或简单变换;`Helmert` 或 `多项式1/2/3 (Polynomial 1/2/3)` 更常用,能处理更复杂的形变。`薄板样条 (Thin Plate Spline)` 适用于需要局部精确变形的情况。可以先尝试 `多项式 1``2`
* **重采样方法 (Resampling method)**: 如果是基于栅格配准,选 `最近邻 (Nearest neighbour)`
* **目标坐标系 (Target CRS)**: **极其重要!** 点击 `选择 CRS (Select CRS)` 按钮,搜索并选择 `WGS 84` (其 EPSG 代码通常是 **4326**)。
* **输出栅格 (Output raster)**: 指定配准后文件的保存位置和名称。建议保存为 GeoPackage (`.gpkg`) 或 GeoTIFF (`.tif`) 格式。
* 勾选 `完成后在 QGIS 中加载 (Load in QGIS when done)`
* 点击 `确定 (OK)`
5. **执行地理配准**: 点击工具栏上的 `开始地理配准 (Start Georeferencing)` 按钮(绿色播放图标)。
6. 配准完成后,关闭地理配准器。新的、已地理配准的图层会添加到 QGIS 主窗口。你可以通过添加一个在线地图背景(如 OpenStreetMap来验证配准效果是否准确。
## 7. 数字化道路中心线
现在,以地理配准后的图层为底图,绘制道路中心线并添加属性。
1. **创建新图层**:
* 菜单 `图层 (Layer)` -> `创建图层 (Create Layer)` -> `新建 GeoPackage 图层 (New GeoPackage Layer...)` (推荐) 或 `新建 Shapefile 图层 (New Shapefile Layer...)`
* **文件名**: 指定保存位置和文件名,例如 `airport_roads.gpkg`
* **图层名称**: 例如 `roads_centerline`
* **几何图形类型**: 选择 `线串 (LineString)``多段线 (MultiLineString)`
* **坐标系**: **必须选择 WGS 84 (EPSG:4326)**
* **定义属性字段**: 在 `新建字段 (New Field)` 部分,根据 `airport_roads.yaml` 的结构添加所需的字段。例如:
* `road_id` (类型: 文本 Text/String)
* `name` (类型: 文本 Text/String)
* `width_value` (类型: 十进制数 Decimal/Real)
* `width_unit` (类型: 文本 Text/String, 默认值可设为 'm')
* `speed_limit_value` (类型: 整数 Integer 或 十进制数 Decimal)
* `speed_limit_unit` (类型: 文本 Text/String, 默认值可设为 'km/h')
* `directionality` (类型: 文本 Text/String)
* `prohibited` (类型: 布尔 Boolean 或 整数 Integer 0/1)
* `height_limit_value` (类型: 十进制数 Decimal)
* `height_limit_unit` (类型: 文本 Text/String, 默认值 'm')
* `width_limit_value` (类型: 十进制数 Decimal)
* `width_limit_unit` (类型: 文本 Text/String, 默认值 'm')
* `related_zones` (类型: 文本 Text/String, 用于存储关联区域 ID 列表,可能需要后续处理)
* 点击 `添加到字段列表 (Add to Fields List)` 添加每个字段。
* 点击 `确定 (OK)` 创建图层。
2. **开始编辑**:
*`图层 (Layers)` 面板中选中新建的 `roads_centerline` 图层。
* 点击工具栏上的 `切换编辑模式 (Toggle Editing)` 按钮(铅笔图标)。
* 点击 `添加线要素 (Add Line Feature)` 按钮(带绿色加号的线图标)。
3. **绘制道路**:
* 将鼠标移动到地理配准后的底图上,沿着一条道路的中心线开始点击。
* **左键单击** 添加顶点。对于**曲线**,需要**密集地添加顶点**来近似。
* 完成一条道路的绘制后,**右键单击** 结束绘制。
4. **填充属性**:
* 右键单击结束绘制后,会弹出一个属性表单窗口。
* 为刚刚绘制的道路填入对应的属性值(`road_id`, `name`, `width_value` 等)。
* 点击 `确定 (OK)`
* 重复步骤 3 和 4绘制并录入所有需要的道路。
5. **保存编辑**: 完成绘制后,再次点击 `切换编辑模式 (Toggle Editing)` 按钮,并在提示时选择 `保存 (Save)`
## 8. 导出数字化道路为 GeoJSON
GeoJSON 是易于程序处理的格式。
1.`图层 (Layers)` 面板中,右键单击 `roads_centerline` 图层。
2. 选择 `导出 (Export)` -> `要素另存为... (Save Features As...)`
3. **格式**: 选择 `GeoJSON`
4. **文件名**: 指定导出的 GeoJSON 文件名和保存位置,例如 `airport_roads.geojson`
5. **坐标系 (CRS)**: 确保选择的是 `WGS 84 (EPSG:4326)`
6. **导出字段**: 确保所有需要的属性字段都被勾选导出。
7. **几何图形**: 可以设置坐标精度(小数位数),根据需要调整。
8. 点击 `确定 (OK)`
## 9. 从 GeoJSON 生成 YAML
现在你有了一个包含所有道路几何和属性的 GeoJSON 文件。你需要编写一个脚本(例如 Python来将其转换为 `airport_roads.yaml` 格式。
**脚本逻辑概要 (以 Python 为例):**
```python
import json
import yaml # 需要安装 PyYAML: pip install pyyaml
geojson_file = 'airport_roads.geojson'
yaml_file = 'src/main/resources/config/airport_roads.yaml' # 目标路径
output_data = {
'airport_code': 'XYZ', # 或者从其他地方获取
'roads': []
}
with open(geojson_file, 'r', encoding='utf-8') as f:
geojson_data = json.load(f)
for feature in geojson_data['features']:
props = feature['properties']
coords = feature['geometry']['coordinates']
road_entry = {
'id': props.get('road_id'),
'name': props.get('name'),
'geometry': {
'type': 'LineString',
'coordinates': coords # GeoJSON 的坐标列表可以直接用
},
'width': {
'value': props.get('width_value'),
'unit': props.get('width_unit', 'm')
},
'speed_limit': {
'value': props.get('speed_limit_value'),
'unit': props.get('speed_limit_unit', 'km/h')
},
'directionality': props.get('directionality'),
# ... 其他字段类似处理 ...
# 注意处理 None 或缺失值,以及数据类型转换
'prohibited': bool(props.get('prohibited', False)), # 示例:处理布尔值
# height_limit, width_limit 需要判断值是否存在再添加
# related_zones 可能需要特殊处理,例如如果 GeoJSON 里是逗号分隔字符串,这里要转成列表
}
# 添加可选字段
if props.get('height_limit_value') is not None:
road_entry['height_limit'] = {
'value': props.get('height_limit_value'),
'unit': props.get('height_limit_unit', 'm')
}
if props.get('width_limit_value') is not None:
road_entry['width_limit'] = {
'value': props.get('width_limit_value'),
'unit': props.get('width_limit_unit', 'm')
}
if props.get('related_zones'):
# 假设 related_zones 在 QGIS 中是以逗号分隔的字符串输入的
related_zones_list = [zone.strip() for zone in props.get('related_zones').split(',')]
road_entry['related_zones'] = related_zones_list
output_data['roads'].append(road_entry)
# 写入 YAML 文件
with open(yaml_file, 'w', encoding='utf-8') as f:
yaml.dump(output_data, f, allow_unicode=True, default_flow_style=False, sort_keys=False)
print(f"YAML 文件已生成: {yaml_file}")
```
你需要根据你在 QGIS 中定义的实际字段名和数据类型来调整脚本。
## 10. 总结
通过以上步骤,你可以将 CAD 图纸中的道路信息转换为包含精确地理坐标的 YAML 配置文件。关键在于获取准确的地面控制点 (GCPs) 以及在 QGIS 中细致地完成地理配准和数字化工作。这个过程可能比较耗时,但能确保配置数据的质量。