大疆KMZ航线文件解析:template.kml与waylines.wpml的区别与实操
很多做测绘、巡检、植保的朋友拿到无人机导出的航线文件看到KMZ这个后缀第一反应是“这跟KML有什么区别”——等用解压工具把KMZ打开发现里面躺着template.kml和waylines.wpml两个文件又开始纠结这俩到底谁才是真正要用的航线。我最早接触大疆航线文件时也在这个地方卡了很久。当时急着从DJI Pilot导出的KMZ里提取航点坐标顺手打开template.kml就开始找航点列表结果翻了几百行全是任务配置和模板信息死活找不到航点数据。后来才搞清楚真正的航点全在waylines.wpml里而template.kml只是“任务说明书”。这篇就专门把KMZ、template.kml、waylines.wpml三者之间的关系讲透同时给出不用写代码和用脚本解析两种实操方案最后再盘一盘我踩过的坑。无论你是要做航线二次开发、格式转换还是只想搞清楚航线文件的结构这篇都值得看完。1. 动手之前先把KMZ这层“包装”拆开1.1 KMZ不是新格式它就是KML的压缩包很多人会把KMZ当成一种独立的“神秘格式”其实KMZ的全称是Keyhole Markup Language Zipped本质上就是KML文件的压缩打包形态。KML是描述地理标注的XML方言搞GIS的人都很熟而KMZ则是把KML以及它依赖的图片、模型等资源文件一起压进zip容器里方便分发和传输。大疆把航线文件设计成KMZ格式主要考虑的是完整性和便携性。一条航线不仅有航点坐标还涉及任务类型、载荷参数、机型信息、动作序列甚至还有飞机3D模型的预览贴图这些散乱的资源如果全部摊开放在文件夹里拷贝、上传、跨平台传输都很容易丢三落四。打包成单个KMZ文件后从遥控器导出、导入到云端或者发给同事一个文件就搞定了。验证这个说法很简单直接把KMZ文件后缀改成.zip双击就能用系统自带的解压工具打开。我经常建议刚接触航线文件的朋友先做这一步因为很多所谓“打不开KMZ”的问题本质上只是电脑没有关联解压软件改个后缀花十秒钟就解决了。1.2 打开KMZ之后你会看到什么用解压工具展开一个典型的大疆航线KMZ里面一般会有这样几个文件template.kml航线模板文件记录任务类型、模板ID、全局参数等元信息。waylines.wpml航线具体数据文件包含每个航点的位置、高度、速度、航向、云台姿态以及动作序列。aircraft.dds飞机3D模型的纹理贴图用于在地面站软件里渲染对应机型的视觉效果。另外某些机型或软件版本导出的KMZ里还会包含别的小文件但上面这三个是绝大多数航线包的“标配”。这就引出了最关键的认知template.kml和waylines.wpml不是同一个东西前者描述“这趟任务是什么”后者描述“这趟任务怎么飞”。后面章节我会把两个文件拆开逐段讲先帮你在脑子里建立这个框架后面解析的时候就不会找错地方了。2. template.kml和waylines.wpml任务说明书 vs 飞行路线图2.1 template.kml告诉飞机“这趟任务长什么样”先看template.kml。这个文件从XML结构上看就是一个标准的KML文档根节点是kml里面套着Document和Folder核心内容集中在Placemark里。Placemark的name标签值是template.kml往后跟着的是大疆自定义命名空间wpmlDJI WayPoint Mission Language下的各种字段。经常能见到的几个核心字段包括wpml:templateType航线模板类型常见的有waypoint航点飞行、mapping建图航拍、strip航带飞行等。这个字段决定了航线任务的“大类”。wpml:templateId模板ID配合templateType标识具体的模板版本。wpml:payloadParam载荷参数比如你使用的相机型号、镜头焦距等挂载信息。这里存的是任务预设的载荷配置。wpml:missionConfig任务全局配置是整个template.kml里信息量最大的一块里面还会拆出多个子节点例如自动飞行速度、结束动作、飞行安全参数等。missionConfig里的东西很多我挑几个最常用的字段解释一下wpml:autoFlightSpeed航线自动飞行速度单位是m/s。这个值是全航线默认速度如果某个航点没有单独配置速度飞机就按这个速度飞。wpml:finishAction航线任务结束后的动作常见有0返航、1悬停、2降落。这个字段非常重要做测绘的人如果不小心把结束动作设置成“返航”飞机可能会飞出测区务必要在任务规划阶段确认清楚。wpml:gimbalPitchRotationEnable云台俯仰旋转使能开关决定飞机在飞行过程中云台是否按预设角度自动俯仰。wpml:globalHeight全局高度定义整条航线的默认飞行高度单位是m。也就是说template.kml里保存的是一切与“任务模板”相关的静态配置。它的作用更像是一份“任务说明书”告诉地面站和飞机这是一条什么类型的航线、用什么载荷、总体按什么速度飞、收尾时干什么。但请注意它并不保存具体的航点列表。2.2 waylines.wpml告诉飞机“每一个点怎么飞”再看waylines.wpml。这个文件同样是KML/XML结构核心的Placemark的name是waylines.wpml但内容编排完全不同。除了同样包含missionConfig和droneInfo之外最关键的是它保存了整条航线的航点序列而且每个航点是一个独立的wpml:waypoint节点。每个航点的核心字段很多我拆开说wpml:index航点序号从0开始递增。航线执行时飞机按这个序号依次飞过每个航点。wpml:waypointPosition航点位置里面包含wpml:longitude经度、wpml:latitude纬度、wpml:height高度。经纬度一般使用WGS84坐标系高度默认是相对起飞点的相对高度部分版本会通过heightType字段区分相对高度和椭球高。wpml:waypointHeadingParam航点航向参数。其中waypointHeadingMode表示机头朝向模式常见有自动朝向、手动锁定、平滑跟随等waypointHeading是手动模式下的具体朝向角单位是度。wpml:waypointTurnParam航点转弯参数。waypointTurnMode决定飞机经过该航点时是定点转弯、协调转弯还是自适应转弯直接影响航线轨迹的光滑程度和转弯半径。wpml:waypointSpeed航点飞行速度。这个字段可以覆盖missionConfig里的默认速度适合在某些需要减速作业的航段单独调速。wpml:waypointGimbalParam云台姿态参数定义飞机到达这个航点时云台的俯仰角等姿态信息。做航测时每个航点的云台俯仰角通常会统一设置成–90度让镜头垂直对地。wpml:actionGroup动作组。一个航点可以挂载一组动作比如到达指定位置后触发拍照、开始录像、结束录像、变焦等。actionGroup里还包含动作序号、动作执行时间范围和动作模式等限定条件更复杂的还可以按航点范围批量执行。所以waylines.wpml才是真正的“飞行路线图”。飞机实际执行轨迹、动作时序全部由这份文件决定。它跟template.kml的关系可以理解成template.kml提供“任务骨架”waylines.wpml填充“执行血肉”。2.3 两者对比一张表看懂核心区别我把两个文件的核心区别整理成一张表方便以后查阅对比维度template.kmlwaylines.wpml文件定位任务模板与全局配置航线航点与动作数据数据粒度航线整体级别逐航点级别核心内容templateType、templateId、payloadParam、missionConfigmissionConfig、droneInfo、waypoint列表、actionGroup是否包含航点坐标不包含具体航点坐标序列包含全部航点的经纬度、高度、速度、航向、云台参数主要作用让地面站识别任务类型和机型载荷让飞机按指定路径和动作执行航线解析航线时关注度低主要看类型和全局参数高提取航点、动作全靠它一句话总结要解析航点去waylines.wpml要看任务类型和机型去template.kml。两者在同一个KMZ里配合使用缺一不可。如果只在template.kml里找航点当然会一无所获。3. 5分钟实操从KMZ里拿到可用航线数据3.1 方法一不写代码的快速查看如果你只是临时想看看某条航线里面有什么内容最直接的方式就是改后缀解压。把.kmz改成.zip解压后右键template.kml和waylines.wpml用文本编辑器打开。这里有一个体验上的小建议waylines.wpml在航线很长时可能达到数MB甚至更大Windows自带的记事本打开大XML文件会非常卡。我习惯先用VS Code或者Notepad打开如果嫌XML标签堆在一起不好看再用XML格式化插件整理一下。搜索关键字段时直接搜wpml:waypoint或者wpml:longitude比肉眼一行行翻高效得多。这个方法适合“读”但如果你想批量提取航点、生成表格甚至二次生成航线就要上脚本了。3.2 方法二Python脚本提取航点到CSV这里给一个可以直接抄走的Python脚本功能是把KMZ里的waylines.wpml解析出来并导出成CSV。思路分三步首先用zipfile解压KMZ读取waylines.wpml的内容接着用xml.etree.ElementTree解析XML最后遍历所有waypoint节点把坐标、高度、速度等字段写入CSV。需要注意的是wpml里所有标签都带命名空间前缀ElementTree解析时如果直接用findall(wpml:waypoint)会找不到节点。正确做法是先取到命名空间再用{命名空间}标签名的方式访问。import zipfile import xml.etree.ElementTree as ET import csv KMZ_PATH example.kmz CSV_PATH waypoints.csv # 1. 读取KMZ里的waylines.wpml with zipfile.ZipFile(KMZ_PATH, r) as z: wpml_bytes z.read(waylines.wpml) # 2. 解析XML root ET.fromstring(wpml_bytes) # 提取命名空间例如 {http://www.dji.com/wpmz/1.0.2} ns {} if root.tag.startswith({): ns[wpml] root.tag.split(})[0] } waypoints [] for wp in root.iter(ns[wpml] waypoint): index wp.findtext(ns[wpml] index, default) lng wp.findtext(ns[wpml] waypointPosition/ ns[wpml] longitude, default) lat wp.findtext(ns[wpml] waypointPosition/ ns[wpml] latitude, default) height wp.findtext(ns[wpml] waypointPosition/ ns[wpml] height, default) speed wp.findtext(ns[wpml] waypointSpeed, default) waypoints.append([index, lng, lat, height, speed]) # 3. 写入CSV with open(CSV_PATH, w, newline, encodingutf-8-sig) as f: writer csv.writer(f) writer.writerow([index, longitude, latitude, height, speed]) writer.writerows(waypoints) print(f解析完成共 {len(waypoints)} 个航点已输出到 {CSV_PATH})这个脚本跑通之后你可以按自己的需求继续扩展比如把actionGroup里的拍照动作也解析出来或者把云台俯仰角一起导出。解析航线数据最核心的目标就是从waylines.wpml里把“飞手规划时看到的东西”还原成结构化数据脚本只是手段。这里再补充一个热词相关的场景很多人搜“kmz怎么转为kml”其实最简单的理解就是“解压KMZ把里面的kml文件取出来”。如果只是想要一个能在Google Earth里看的KML直接把template.kml或waylines.wpml改名成.kml拖进去就行但如果你要的是一个“通用地理标注”的KML最好自己写脚本把waypoint提取出来重新生成标准KML因为wpml的命名空间很多软件并不认识。3.3 方法三浏览器端用JS生成和解析KMZ搜“js生成kmz”的人越来越多说明大家已经不满足于只在本地处理航线文件还想在网页端做航线预览、编辑和导出。前端生成KMZ的方案其实不复杂核心工具就是JSZip这个库它能在浏览器里动态创建zip压缩包。思路是先构造两个XML字符串一个作为template.kml写任务类型和全局配置另一个作为waylines.wpml写入航点列表。然后把这两个字符串连同可选的aircraft.dds一起通过JSZip打包最后生成.kmz文件的blob并触发下载。import JSZip from jszip; import { saveAs } from file-saver; async function generateKmz(waypoints) { const zip new JSZip(); // 构造template.kml const template ?xml version1.0 encodingUTF-8? kml xmlnshttp://www.opengis.net/kml/2.2 xmlns:wpmlhttp://www.dji.com/wpmz/1.0.2 Document Folder Placemark nametemplate.kml/name wpml:templateTypewaypoint/wpml:templateType wpml:templateId1/wpml:templateId wpml:missionConfig wpml:autoFlightSpeed8/wpml:autoFlightSpeed wpml:finishAction1/wpml:finishAction /wpml:missionConfig /Placemark /Folder /Document /kml; // 构造waylines.wpml let waypointXml ; waypoints.forEach((wp, i) { waypointXml wpml:waypoint wpml:index${i}/wpml:index wpml:waypointPosition wpml:longitude${wp.lng}/wpml:longitude wpml:latitude${wp.lat}/wpml:latitude wpml:height${wp.height}/wpml:height /wpml:waypointPosition wpml:waypointSpeed${wp.speed}/wpml:waypointSpeed /wpml:waypoint; }); const waylines ?xml version1.0 encodingUTF-8? kml xmlnshttp://www.opengis.net/kml/2.2 xmlns:wpmlhttp://www.dji.com/wpmz/1.0.2 Document Placemark namewaylines.wpml/name wpml:missionConfig wpml:autoFlightSpeed8/wpml:autoFlightSpeed wpml:finishAction1/wpml:finishAction /wpml:missionConfig ${waypointXml} /Placemark /Document /kml; zip.file(template.kml, template); zip.file(waylines.wpml, waylines); const blob await zip.generateAsync({ type: blob }); saveAs(blob, generated.kmz); }用这段代码生成的KMZ已经可以被主流大疆地面站软件识别为一条航点飞行任务。当然如果你要支持建图航拍、航带飞行等更复杂的任务类型或者在航点上挂载拍照、录像等动作就需要按模板补全更多字段。前端解析KMZ的思路刚好反过来用JSZip读取zip里的waylines.wpml再用DOMParser解析XML提取航点配合地图SDK就能做非常轻量的航线预览工具。4. 踩坑记录航线文件解析最常见的5个问题4.1 拿template.kml当航点数据白忙一场这是我犯过的第一个错误也是新手最容易踩的坑。打开KMZ后按文件名直觉去读template.kml翻遍全文找不到航点坐标会怀疑自己是不是解析错了。解决办法前面已经反复强调航点在waylines.wpml里。如果实在担心找错文件可以在解压后先用文本编辑器搜索wpml:waypoint哪个文件能搜到成批的waypoint节点哪个文件就是真正的航点数据源。template.kml里即使有点位置信息也只是模板的一个占位点不代表航线路径。4.2 自己拼的XML导入大疆App显示“航线不支持”很多人在手动生成KMZ或者修改航点后习惯性把原始XML里的“无关字段”删掉只留下一堆精简标签结果导入DJI Pilot时直接提示“航线不支持”或“任务加载失败”。原因往往是删掉了必要的schema字段比如templateType、templateId、droneInfo或者把命名空间xmlns:wpmlhttp://www.dji.com/wpmz/1.0.2都给丢了。大疆地面站在加载航线时会按特定schema解析整个KMZ任何一个关键字段缺失都可能直接判定航线非法。建议做法是拿原版KMZ做模板不要从零手写改动时尽量只改坐标、速度、高度、动作参数等业务字段保留原有的标签层级和命名空间。做完后先在一个不重要的测试机型上试导入再去现场作业。4.3 坐标偏移解析出来的经纬度和App地图上位置对不上还有一个常见现象从waylines.wpml里解出来的经纬度放到大疆App的飞行地图上看起来位置“偏了”几百米甚至更远。很多人第一时间怀疑是航线文件有问题其实更可能的原因是地图引擎采用的坐标系差异。大疆航线文件里保存的经纬度通常是WGS84坐标而部分地图引擎或在线地图服务在显示时会做坐标纠偏处理导致两边画出来的点不在同一个位置。这属于地图显示偏差不是解析逻辑错误。遇到这种情况可以在纯地理信息软件比如Google Earth里验证原始坐标确认航线本身是对的如果业务上要求在地图上精确叠加就需要在展示层做坐标转换适配。4.4 高度是相对还是绝对一定要先确认航点的高度字段wpml:height的单位是米这没有争议但让人迷惑的是它到底是相对高度还是绝对高度。大疆大部分航线文件默认使用相对起飞点的高度也就是起飞后以RTK或气压计测得的相对高程。但部分航线在规划时会选择WGS84椭球高这个字段会通过heightType之类的子标签标识。解析时如果不看这个标识直接把所有高度当成相对高度导入其他软件生成的3D轨迹就会整体飘起来或沉下去。稳妥的做法是在解析脚本里同时把height和heightType读出来输出CSV时单独加一列记录高度类型如果后续要转换到DEM或DSM场景务必搞清楚高度基准再做换算。4.5 版本差异不同软件导出的wpml字段不完全一样大疆的WPML格式一直在迭代不同版本的地面站软件、不同机型的固件导出的字段细节会有差异。比如某些老机型导出的waylines.wpml里没有waypointGimbalParam节点或者missionConfig里少了globalHeight。新手如果拿新版航线的结构去解析老版本文件代码可能直接报错。这提醒我们两件事一是解析代码要写容错逻辑字段缺失时使用默认值而不是抛异常二是KMZ文件本身不携带格式版本号时尽量先看根节点的xmlns:wpml属性确认是哪个版本。我把上面这些常见问题整理成一张速查表现象可能的根因处理建议template.kml里找不到航点航点在waylines.wpml里在两个文件中搜索waypoint字段确认导入App提示“航线不支持”删除了关键schema字段或命名空间以官方KMZ为模板只改业务字段坐标与地图显示不符地图引擎坐标系差异用Google Earth等工具验证原始WGS84坐标高度在3D场景里明显异常高度基准是相对高度或椭球高未区分解析时读取heightType并单独记录老版本航线解析报错WPML字段版本差异解析逻辑增加默认值容错处理个人经验收尾做了这么久的航线数据解析我自己养成了一个习惯拿到一个陌生KMZ第一件事不是急着写代码而是先解压把template.kml和waylines.wpml两个文件全部通读一遍搞清楚它是哪个机型、哪个软件版本、用的是什么schema。这段“笨功夫”看着浪费时间其实能省掉后面排查问题的大把时间。另外如果你打算长期跟航线文件打交道强烈建议整理一个小工具库把KMZ解压、wpml解析、坐标系校验、字段容错这些基础能力都做成可复用函数。下次不管是接第三方平台的数据还是要批量处理几百条航线都会非常从容。解析航线文件说到底就是“懂结构、选对文件、注意坐标系和版本差异”这三件事做好基本就不会再出什么大问题。
上一篇/下一篇内容由系统自动关联
返回资讯列表 →