• 大疆无人机航点飞行KMZ文件提取航点坐标


    一、需要插件

    1. <!-- 解析KMZ航线-->
    2. <dependency>
    3. <groupId>jaxen</groupId>
    4. <artifactId>jaxen</artifactId>
    5. <version>1.1.4</version>
    6. </dependency>
    7. <dependency>
    8. <groupId>dom4j</groupId>
    9. <artifactId>dom4j</artifactId>
    10. <version>1.6.1</version>
    11. </dependency>

    二、KMZ解压成KML

    1. package com.dji.sample.common.util;
    2. import org.dom4j.Document;
    3. import org.dom4j.io.SAXReader;
    4. import java.io.File;
    5. import java.io.FileInputStream;
    6. import java.io.InputStream;
    7. import java.util.zip.ZipEntry;
    8. import java.util.zip.ZipFile;
    9. import java.util.zip.ZipInputStream;
    10. //将KMZ航线转成KML航线
    11. public class KmzKml {
    12. public Document unzipKmzToKml() throws Exception, Exception {
    13. String strkmz="/home/ych/KmzKml/航点飞行测试.kmz";
    14. System.out.println("********************** 【KMZ转kml开始】kmz路径: **********************\n"+ strkmz);
    15. File file = new File(strkmz);
    16. ZipFile zipFile = new ZipFile(file);
    17. ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(file));
    18. InputStream inputStream = null;
    19. ZipEntry entry = null;
    20. Document doc = null;
    21. while ((entry = zipInputStream.getNextEntry()) != null) {
    22. String zipEntryName = entry.getName();
    23. //获取所需文件的节点
    24. if (zipEntryName.equals("wpmz/template.kml")) {
    25. inputStream = zipFile.getInputStream(entry);
    26. SAXReader reader = new SAXReader();
    27. doc = (Document) reader.read(inputStream);
    28. inputStream.close();
    29. }
    30. }
    31. zipFile.close();
    32. zipInputStream.close();
    33. return doc;
    34. }
    35. }

    三、KML提取航点坐标

    1. package com.dji.sample.common.util;
    2. import org.dom4j.Document;
    3. import org.dom4j.io.SAXReader;
    4. import java.io.File;
    5. import java.io.FileInputStream;
    6. import java.io.InputStream;
    7. import java.util.zip.ZipEntry;
    8. import java.util.zip.ZipFile;
    9. import java.util.zip.ZipInputStream;
    10. //将KMZ航线转成KML航线
    11. public class KmzKml {
    12. public Document unzipKmzToKml() throws Exception, Exception {
    13. String strkmz="/home/ych/KmzKml/航点飞行测试.kmz";
    14. System.out.println("********************** 【KMZ转kml开始】kmz路径: **********************\n"+ strkmz);
    15. File file = new File(strkmz);
    16. ZipFile zipFile = new ZipFile(file);
    17. ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(file));
    18. InputStream inputStream = null;
    19. ZipEntry entry = null;
    20. Document doc = null;
    21. while ((entry = zipInputStream.getNextEntry()) != null) {
    22. String zipEntryName = entry.getName();
    23. //获取所需文件的节点
    24. if (zipEntryName.equals("wpmz/template.kml")) {
    25. inputStream = zipFile.getInputStream(entry);
    26. SAXReader reader = new SAXReader();
    27. doc = (Document) reader.read(inputStream);
    28. inputStream.close();
    29. }
    30. }
    31. zipFile.close();
    32. zipInputStream.close();
    33. return doc;
    34. }
    35. }

    四、调用

    1. @PostMapping("${url.wayline.prefix}${url.wayline.version}/workspaces/{workspace_id}/waylines/{wayline_id}/kmzKml")
    2. public HttpResultResponse<?> Kmz() throws Exception {
    3. KmzKml kmz = new KmzKml();
    4. Document unzipKmzToKml = kmz.unzipKmzToKml();
    5. // 将dom4j 的document对象转换成String
    6. // String asXML = unzipKmzToKml.asXML();
    7. SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddhhmmss");
    8. Date date = new Date();
    9. String fileName = sdf.format(date);
    10. String strkml = "/home/ych/KmzKml/航点飞行.kml";
    11. // 创建kml到本地
    12. OutputFormat format = OutputFormat.createPrettyPrint();
    13. format.setEncoding("utf-8");
    14. XMLWriter xmlWriter = new XMLWriter(new FileOutputStream(strkml),format);
    15. xmlWriter.write(unzipKmzToKml);
    16. xmlWriter.close();
    17. System.out.println("\n********************** 【KMZ转kml成功】kml路径: **********************\n"+ strkml);
    18. return HttpResultResponse.success();
    19. }
    20. @GetMapping("${url.wayline.prefix}${url.wayline.version}/workspaces/{workspace_id}/waylines/{wayline_id}/singlePoint")
    21. public HttpResultResponse<?> Kml() throws Exception {
    22. File file = new File("/home/ych/KmzKml/航点飞行.kml");
    23. InputStream in = new FileInputStream(file);
    24. Kml kml = new Kml();
    25. Collection<? extends String> coordinatesList = kml.parseXmlWithDom4j(in);
    26. List<?> list = (List)coordinatesList;
    27. System.out.println(list.get(3));
    28. System.out.println("获取到的坐标值:");
    29. for (String coordinates : coordinatesList) {
    30. System.out.println(coordinates);
    31. }
    32. return HttpResultResponse.success(list);
    33. }

    五、效果

    1. 获取到的坐标值:
    2. [121.369754843606, 37.5227177120414]
    3. [121.370733797755, 37.5233089872322]
    4. [121.370402874547, 37.5243355293892]
    5. [121.372488283707, 37.5240973025597]
    6. [121.372337081214, 37.5227352183251]
    7. [121.370980455301, 37.5213158608334]
    8. [121.372248708559, 37.5224800846951]

    六、航线文件解读

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <kml xmlns="http://www.opengis.net/kml/2.2" xmlns:wpml="http://www.dji.com/wpmz/1.0.2">
    3. <Document>
    4. <!-- Step 1: Implement File Creation Information -->
    5. <wpml:author>Name</wpml:author>
    6. <wpml:createTime>1637600807044</wpml:createTime>
    7. <wpml:updateTime>1637600875837</wpml:updateTime>
    8. <!-- Step 2: Setup Mission Configuration -->
    9. <wpml:missionConfig>
    10. <wpml:flyToWaylineMode>safely</wpml:flyToWaylineMode>
    11. <wpml:finishAction>goHome</wpml:finishAction>
    12. <wpml:exitOnRCLost>goContinue</wpml:exitOnRCLost>
    13. <wpml:executeRCLostAction>hover</wpml:executeRCLostAction>
    14. <wpml:takeOffSecurityHeight>20</wpml:takeOffSecurityHeight>
    15. <wpml:takeOffRefPoint>23.98057,115.987663,100</wpml:takeOffRefPoint>
    16. <wpml:takeOffRefPointAGLHeight>35</wpml:takeOffRefPointAGLHeight>
    17. <wpml:globalTransitionalSpeed>8</wpml:globalTransitionalSpeed>
    18. <wpml:droneInfo>
    19. <!-- Declare drone model with M30 -->
    20. <wpml:droneEnumValue>67</wpml:droneEnumValue>
    21. <wpml:droneSubEnumValue>0</wpml:droneSubEnumValue>
    22. </wpml:droneInfo>
    23. <wpml:payloadInfo>
    24. <!-- Declare payload model with M30 -->
    25. <wpml:payloadEnumValue>52</wpml:payloadEnumValue>
    26. <wpml:payloadPositionIndex>0</wpml:payloadPositionIndex>
    27. </wpml:payloadInfo>
    28. </wpml:missionConfig>
    29. <!-- Step 3: Setup A Folder for Waypoint Template -->
    30. <Folder>
    31. <wpml:templateType>waypoint</wpml:templateType>
    32. <wpml:useGlobalTransitionalSpeed>0</wpml:useGlobalTransitionalSpeed>
    33. <wpml:templateId>0</wpml:templateId>
    34. <wpml:waylineCoordinateSysParam>
    35. <wpml:coordinateMode>WGS84</wpml:coordinateMode>
    36. <wpml:heightMode>EGM96</wpml:heightMode>
    37. <wpml:globalShootHeight>50</wpml:globalShootHeight>
    38. <wpml:positioningType>GPS</wpml:positioningType>
    39. <wpml:surfaceFollowModeEnable>1</wpml:surfaceFollowModeEnable>
    40. <wpml:surfaceRelativeHeight>100</wpml:surfaceRelativeHeight>
    41. </wpml:waylineCoordinateSysParam>
    42. <wpml:autoFlightSpeed>7</wpml:autoFlightSpeed>
    43. <wpml:gimbalPitchMode>usePointSetting</wpml:gimbalPitchMode>
    44. <wpml:globalWaypointHeadingParam>
    45. <wpml:waypointHeadingMode>followWayline</wpml:waypointHeadingMode>
    46. <wpml:waypointHeadingAngle>45</wpml:waypointHeadingAngle>
    47. <wpml:waypointPoiPoint>24.323345,116.324532,31.000000</wpml:waypointPoiPoint>
    48. <wpml:waypointHeadingPathMode>clockwise</wpml:waypointHeadingPathMode>
    49. </wpml:globalWaypointHeadingParam>
    50. <wpml:globalWaypointTurnMode>toPointAndStopWithDiscontinuityCurvature</wpml:globalWaypointTurnMode>
    51. <wpml:globalUseStraightLine>0</wpml:globalUseStraightLine>
    52. <Placemark>
    53. <Point>
    54. <!-- Fill longitude and latitude here -->
    55. <coordinates>
    56. longitude,latitude
    57. </coordinates>
    58. </Point>
    59. <wpml:index>0</wpml:index>
    60. <wpml:ellipsoidHeight>90.2</wpml:ellipsoidHeight>
    61. <wpml:height>100</wpml:height>
    62. <wpml:useGlobalHeight>1</wpml:useGlobalHeight>
    63. <wpml:useGlobalSpeed>1</wpml:useGlobalSpeed>
    64. <wpml:useGlobalHeadingParam>1</wpml:useGlobalHeadingParam>
    65. <wpml:useGlobalTurnParam>1</wpml:useGlobalTurnParam>
    66. <wpml:gimbalPitchAngle>0</wpml:gimbalPitchAngle>
    67. </Placemark>
    68. <Placemark>
    69. <Point>
    70. <!-- Fill longitude and latitude here -->
    71. <coordinates>
    72. longitude,latitude
    73. </coordinates>
    74. </Point>
    75. <wpml:index>1</wpml:index>
    76. <wpml:ellipsoidHeight>90.2</wpml:ellipsoidHeight>
    77. <wpml:height>100</wpml:height>
    78. <wpml:useGlobalHeight>1</wpml:useGlobalHeight>
    79. <wpml:useGlobalSpeed>1</wpml:useGlobalSpeed>
    80. <wpml:useGlobalHeadingParam>1</wpml:useGlobalHeadingParam>
    81. <wpml:useGlobalTurnParam>1</wpml:useGlobalTurnParam>
    82. <wpml:gimbalPitchAngle>0</wpml:gimbalPitchAngle>
    83. <!-- Declare action group for waypoint 1# -->
    84. <wpml:actionGroup>
    85. <wpml:actionGroupId>0</wpml:actionGroupId>
    86. <wpml:actionGroupStartIndex>1</wpml:actionGroupStartIndex>
    87. <wpml:actionGroupEndIndex>1</wpml:actionGroupEndIndex>
    88. <wpml:actionGroupMode>sequence</wpml:actionGroupMode>
    89. <wpml:actionTrigger>
    90. <wpml:actionTriggerType>reachPoint</wpml:actionTriggerType>
    91. </wpml:actionTrigger>
    92. <!-- Declare the 1st action: rotate gimbal -->
    93. <wpml:action>
    94. <wpml:actionId>0</wpml:actionId>
    95. <wpml:actionActuatorFunc>gimbalRotate</wpml:actionActuatorFunc>
    96. <wpml:actionActuatorFuncParam>
    97. <wpml:gimbalRotateMode>absoluteAngle</wpml:gimbalRotateMode>
    98. <wpml:gimbalPitchRotateEnable>0</wpml:gimbalPitchRotateEnable>
    99. <wpml:gimbalPitchRotateAngle>0</wpml:gimbalPitchRotateAngle>
    100. <wpml:gimbalRollRotateEnable>0</wpml:gimbalRollRotateEnable>
    101. <wpml:gimbalRollRotateAngle>0</wpml:gimbalRollRotateAngle>
    102. <wpml:gimbalYawRotateEnable>1</wpml:gimbalYawRotateEnable>
    103. <wpml:gimbalYawRotateAngle>30</wpml:gimbalYawRotateAngle>
    104. <wpml:gimbalRotateTimeEnable>0</wpml:gimbalRotateTimeEnable>
    105. <wpml:gimbalRotateTime>0</wpml:gimbalRotateTime>
    106. <wpml:payloadPositionIndex>0</wpml:payloadPositionIndex>
    107. </wpml:actionActuatorFuncParam>
    108. </wpml:action>
    109. <!-- Declare the 2nd action: take photo -->
    110. <wpml:action>
    111. <wpml:actionId>1</wpml:actionId>
    112. <wpml:actionActuatorFunc>takePhoto</wpml:actionActuatorFunc>
    113. <wpml:actionActuatorFuncParam>
    114. <wpml:fileSuffix>point1</wpml:fileSuffix>
    115. <wpml:payloadPositionIndex>0</wpml:payloadPositionIndex>
    116. </wpml:actionActuatorFuncParam>
    117. </wpml:action>
    118. </wpml:actionGroup>
    119. </Placemark>
    120. </Folder>
    121. </Document>
    122. </kml>

    将航线里的标签检测到并读取值即可获得坐标,可以按照该思路获取其它类型的航线,再将坐标系转换即可将航线展示到前端。

  • 相关阅读:
    PostgreSql学习(基于菜鸟课程)
    Spring-依赖注入补充
    设计模式行为型-模板模式
    celery笔记四之在Django中使用celery
    Debezium系列之:引入对 LATERAL 运算符的支持
    CentOS和Ubantu的Mysql主从配置
    Nacos 安装与部署
    【Node.js】session认证原理和JWT认证原理
    NSS [GWCTF 2019]枯燥的抽奖
    一种有效的基于VPS和RSS的科研小白文献阅读策略
  • 原文地址:https://blog.csdn.net/silent702366/article/details/139864885