3. 航点数据结构:航点属性与常见数据格式

航点规划,说白了就是给无人机写一份“行动说明书”。这份说明书里的每一个字——经纬度、高度、速度、航向、停留时间——都直接决定了任务能不能顺利跑完。我见过太多新手把航点数据当成简单的坐标列表,结果飞机在天上乱转,或者干脆悬停不动。嗯,今天我们就来拆解一下,一个合格的航点到底长什么样。

3.1 航点的核心属性

一个航点,本质上是一个多维度的数据点。我个人习惯把它拆成五个必填属性和几个可选属性。你想想看,如果只给飞机一个经纬度,它知道往哪飞,但飞多快、到了之后要不要转个方向、停多久,这些信息缺了,任务就执行不下去。

属性 单位 说明 典型范围
经度 (Longitude) 度 (°) WGS-84 坐标系,东经为正 -180 ~ 180
纬度 (Latitude) 度 (°) WGS-84 坐标系,北纬为正 -90 ~ 90
高度 (Altitude) 米 (m) 相对起飞点或绝对海拔 0 ~ 500(视法规)
速度 (Speed) 米/秒 (m/s) 到达该点时的期望速度 0 ~ 15(典型多旋翼)
航向 (Heading) 度 (°) 机头朝向,0°为正北 0 ~ 360
停留时间 (Loiter Time) 秒 (s) 到达后悬停等待的时间 0 ~ 300

关键点:高度属性最容易踩坑。我在项目中遇到过好几次,有人把相对高度和绝对海拔混用了。比如在海拔2000米的高原起飞,如果设置绝对海拔2500米,飞机实际只飞了500米高;但如果设置相对高度2500米,飞机就会直接爬升到海拔4500米——嗯,很多消费级无人机根本飞不到那个高度。

3.2 常见数据格式

航点数据写好了,怎么存、怎么传?市面上主流的有三种格式:KML、GeoJSON 和自定义 CSV。每种格式都有自己的脾气,我建议你根据任务场景来选。

3.2.1 KML(Keyhole Markup Language)

KML 是 Google Earth 的亲生儿子,最早用于地理标注。它的优点是可视化方便——你可以在 Google Earth 里直接看到航点在地图上的位置。但缺点也很明显:文件结构臃肿,不适合大量航点。

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
  <Document>
    <Placemark>
      <name>WP-001</name>
      <Point>
        <coordinates>116.397,39.908,100</coordinates>
      </Point>
      <ExtendedData>
        <Data name="speed"><value>5</value></Data>
        <Data name="heading"><value>90</value></Data>
        <Data name="loiter_time"><value>10</value></Data>
      </ExtendedData>
    </Placemark>
  </Document>
</kml>

我的经验:KML 适合做前期路径预览。我经常先用 Google Earth 画一条粗略的航线,导出 KML,再写脚本转成其他格式。但注意,KML 默认的高度是绝对海拔,如果你需要相对高度,得在 ExtendedData 里自己加字段。

3.2.2 GeoJSON

GeoJSON 是 Web 地图的宠儿,轻量、结构清晰,特别适合前后端数据交换。它的核心思想是用 FeatureCollection 包裹多个 Feature,每个 Feature 里放 geometry 和 properties。

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [116.397, 39.908, 100]
      },
      "properties": {
        "name": "WP-001",
        "speed": 5,
        "heading": 90,
        "loiter_time": 10
      }
    }
  ]
}

为什么会推荐 GeoJSON?因为它天生支持数组,你可以把几百个航点放在一个 JSON 文件里,解析起来比 KML 快得多。而且很多地面站软件(比如 QGroundControl)原生支持导入 GeoJSON。

注意:GeoJSON 的坐标顺序是 [经度, 纬度, 高度],和 KML 的 [经度,纬度,高度] 一样,但和某些自定义格式的 [纬度,经度] 不同。我曾经在项目里因为搞反了经纬度顺序,让飞机往反方向飞了 2 公里……嗯,从那以后我每次写解析代码都会加一个坐标顺序校验。

3.2.3 自定义 CSV

CSV 是最灵活、最“土”但也是最实用的格式。没有标准约束,你想加什么字段就加什么字段。我个人的习惯是:第一行写字段名,后面每行一个航点。

name,lon,lat,alt,speed,heading,loiter_time
WP-001,116.397,39.908,100,5,90,10
WP-002,116.400,39.910,120,8,180,0
WP-003,116.403,39.912,150,10,270,5

避坑指南:我曾经接手过一个项目,CSV 文件里没有字段名行,全靠代码里硬编码列索引。结果甲方后来要求加一个“拍照动作”字段,整个解析逻辑都得重写。所以我建议:永远保留字段名行,并且用代码自动检测列索引。这样后期加字段,只需要改 CSV 文件,不用改代码。

3.3 三种格式对比

特性 KML GeoJSON 自定义 CSV
可读性 中等(XML 标签多) 高(JSON 结构清晰) 极高(纯文本,一眼看懂)
可视化支持 Google Earth 原生 Leaflet、Mapbox 等 需自行转换
扩展性 差(需嵌套 ExtendedData) 好(properties 自由扩展) 最好(想加就加)
解析性能 慢(XML 解析开销大) 快(JSON 解析快) 最快(逐行读取)
适用场景 前期路径预览 Web 端任务规划 批量数据处理、嵌入式

3.4 航点数据结构总览

下面这张图,是我自己总结的航点数据结构全景。你可以把它当成一个“航点数据字典”,写代码的时候对照着看,基本不会漏字段。

航点数据结构全景 航点 (Waypoint) 经度 (Lon) 纬度 (Lat) 高度 (Alt) 速度 (Speed) 航向 (Heading) 停留时间 (Loiter) 动作 (Action) 半径 (Radius) 常见数据格式 KML Google Earth 原生 GeoJSON Web 地图标准 自定义 CSV 最灵活通用 💡 选择建议:预览用 KML,Web 端用 GeoJSON,批量处理用 CSV 实际项目中,我经常三种格式互相转换,写一个统一的解析器最省心

3.5 实战建议:如何选择数据格式

说了这么多,到底该用哪种?我个人的经验是分场景:

  • 如果你只是做路径预览:用 KML,直接拖进 Google Earth 就能看,省事。
  • 如果你在开发 Web 地面站:用 GeoJSON,前后端解析都方便,而且 Leaflet 和 Mapbox 都原生支持。
  • 如果你在写嵌入式代码或者做批量数据处理:用自定义 CSV,解析简单,内存占用小,而且 Excel 直接打开就能编辑。

一个小技巧:我习惯在项目里写一个“格式转换器”,支持 KML ↔ GeoJSON ↔ CSV 互转。这样不管甲方给什么格式,我都能转成自己系统需要的格式。嗯,这个转换器我用了五年,还在不断加新功能。