赞
踩
一、需要插件
- <!-- 解析KMZ航线-->
- <dependency>
- <groupId>jaxen</groupId>
- <artifactId>jaxen</artifactId>
- <version>1.1.4</version>
- </dependency>
-
-
- <dependency>
- <groupId>dom4j</groupId>
- <artifactId>dom4j</artifactId>
- <version>1.6.1</version>
- </dependency>
二、KMZ解压成KML
- package com.dji.sample.common.util;
-
- import org.dom4j.Document;
- import org.dom4j.io.SAXReader;
-
-
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.InputStream;
- import java.util.zip.ZipEntry;
- import java.util.zip.ZipFile;
- import java.util.zip.ZipInputStream;
-
- //将KMZ航线转成KML航线
- public class KmzKml {
- public Document unzipKmzToKml() throws Exception, Exception {
- String strkmz="/home/ych/KmzKml/航点飞行测试.kmz";
-
- System.out.println("********************** 【KMZ转kml开始】kmz路径: **********************\n"+ strkmz);
-
- File file = new File(strkmz);
-
- ZipFile zipFile = new ZipFile(file);
-
- ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(file));
- InputStream inputStream = null;
- ZipEntry entry = null;
- Document doc = null;
- while ((entry = zipInputStream.getNextEntry()) != null) {
- String zipEntryName = entry.getName();
- //获取所需文件的节点
- if (zipEntryName.equals("wpmz/template.kml")) {
-
- inputStream = zipFile.getInputStream(entry);
- SAXReader reader = new SAXReader();
- doc = (Document) reader.read(inputStream);
-
- inputStream.close();
- }
- }
- zipFile.close();
- zipInputStream.close();
- return doc;
- }
-
- }

三、KML提取航点坐标
- package com.dji.sample.common.util;
-
- import org.dom4j.Document;
- import org.dom4j.DocumentException;
- import org.dom4j.Element;
- import org.dom4j.io.SAXReader;
-
- import java.io.InputStream;
- import java.util.*;
-
- //提取KML航线里的坐标值
- public class Kml {
- public static Collection<? extends String> parseXmlWithDom4j(InputStream input) throws Exception {
- SAXReader reader = new SAXReader();
- Document document = null;
- try {
- document = reader.read(input);
- } catch (DocumentException e) {
- e.printStackTrace();
- }
- Element root = document.getRootElement();//获取kml文件的根结点
- return getCoordinates(root);
- }
-
- //遍历当前节点下的全部节点
- public static Collection<? extends String> getCoordinates(Element node) {
- List<String> coordinatesList = new ArrayList<>();
- if ("coordinates".equals(node.getName())) {
- String coordinatesStr = node.getTextTrim();
- String[] coordinatesArr = coordinatesStr.split(",");
- List<String> coordinatesList1 = Arrays.asList(coordinatesArr);
- coordinatesList.add(String.valueOf(coordinatesList1));
- }
- Iterator<Element> iterator = node.elementIterator();
- while (iterator.hasNext()) {
- Element e = iterator.next();
- coordinatesList.addAll(getCoordinates(e));
- }
- return coordinatesList;
- }
- }

四、调用
- @PostMapping("${url.wayline.prefix}${url.wayline.version}/workspaces/{workspace_id}/waylines/{wayline_id}/kmzKml")
- public HttpResultResponse<?> Kmz() throws Exception {
- KmzKml kmz = new KmzKml();
- Document unzipKmzToKml = kmz.unzipKmzToKml();
-
- // 将dom4j 的document对象转换成String
- // String asXML = unzipKmzToKml.asXML();
-
- SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddhhmmss");
- Date date = new Date();
- String fileName = sdf.format(date);
- String strkml = "/home/ych/KmzKml/航点飞行.kml";
-
- // 创建kml到本地
- OutputFormat format = OutputFormat.createPrettyPrint();
- format.setEncoding("utf-8");
- XMLWriter xmlWriter = new XMLWriter(new FileOutputStream(strkml),format);
- xmlWriter.write(unzipKmzToKml);
- xmlWriter.close();
-
- System.out.println("\n********************** 【KMZ转kml成功】kml路径: **********************\n"+ strkml);
-
- return HttpResultResponse.success();
- }
- @GetMapping("${url.wayline.prefix}${url.wayline.version}/workspaces/{workspace_id}/waylines/{wayline_id}/singlePoint")
- public HttpResultResponse<?> Kml() throws Exception {
- File file = new File("/home/ych/KmzKml/航点飞行.kml");
- InputStream in = new FileInputStream(file);
- Kml kml = new Kml();
- Collection<? extends String> coordinatesList = kml.parseXmlWithDom4j(in);
- List<?> list = (List)coordinatesList;
- System.out.println(list.get(3));
-
- System.out.println("获取到的坐标值:");
- for (String coordinates : coordinatesList) {
- System.out.println(coordinates);
- }
-
-
- return HttpResultResponse.success(list);
- }

五、效果
- 获取到的坐标值:
- [121.369754843606, 37.5227177120414]
- [121.370733797755, 37.5233089872322]
- [121.370402874547, 37.5243355293892]
- [121.372488283707, 37.5240973025597]
- [121.372337081214, 37.5227352183251]
- [121.370980455301, 37.5213158608334]
- [121.372248708559, 37.5224800846951]
六、航线文件解读
- <?xml version="1.0" encoding="UTF-8"?>
- <kml xmlns="http://www.opengis.net/kml/2.2" xmlns:wpml="http://www.dji.com/wpmz/1.0.2">
- <Document>
-
- <!-- Step 1: Implement File Creation Information -->
- <wpml:author>Name</wpml:author>
- <wpml:createTime>1637600807044</wpml:createTime>
- <wpml:updateTime>1637600875837</wpml:updateTime>
-
- <!-- Step 2: Setup Mission Configuration -->
- <wpml:missionConfig>
- <wpml:flyToWaylineMode>safely</wpml:flyToWaylineMode>
- <wpml:finishAction>goHome</wpml:finishAction>
- <wpml:exitOnRCLost>goContinue</wpml:exitOnRCLost>
- <wpml:executeRCLostAction>hover</wpml:executeRCLostAction>
- <wpml:takeOffSecurityHeight>20</wpml:takeOffSecurityHeight>
- <wpml:takeOffRefPoint>23.98057,115.987663,100</wpml:takeOffRefPoint>
- <wpml:takeOffRefPointAGLHeight>35</wpml:takeOffRefPointAGLHeight>
- <wpml:globalTransitionalSpeed>8</wpml:globalTransitionalSpeed>
- <wpml:droneInfo>
- <!-- Declare drone model with M30 -->
- <wpml:droneEnumValue>67</wpml:droneEnumValue>
- <wpml:droneSubEnumValue>0</wpml:droneSubEnumValue>
- </wpml:droneInfo>
- <wpml:payloadInfo>
- <!-- Declare payload model with M30 -->
- <wpml:payloadEnumValue>52</wpml:payloadEnumValue>
- <wpml:payloadPositionIndex>0</wpml:payloadPositionIndex>
- </wpml:payloadInfo>
- </wpml:missionConfig>
-
- <!-- Step 3: Setup A Folder for Waypoint Template -->
- <Folder>
- <wpml:templateType>waypoint</wpml:templateType>
- <wpml:useGlobalTransitionalSpeed>0</wpml:useGlobalTransitionalSpeed>
- <wpml:templateId>0</wpml:templateId>
- <wpml:waylineCoordinateSysParam>
- <wpml:coordinateMode>WGS84</wpml:coordinateMode>
- <wpml:heightMode>EGM96</wpml:heightMode>
- <wpml:globalShootHeight>50</wpml:globalShootHeight>
- <wpml:positioningType>GPS</wpml:positioningType>
- <wpml:surfaceFollowModeEnable>1</wpml:surfaceFollowModeEnable>
- <wpml:surfaceRelativeHeight>100</wpml:surfaceRelativeHeight>
- </wpml:waylineCoordinateSysParam>
- <wpml:autoFlightSpeed>7</wpml:autoFlightSpeed>
- <wpml:gimbalPitchMode>usePointSetting</wpml:gimbalPitchMode>
- <wpml:globalWaypointHeadingParam>
- <wpml:waypointHeadingMode>followWayline</wpml:waypointHeadingMode>
- <wpml:waypointHeadingAngle>45</wpml:waypointHeadingAngle>
- <wpml:waypointPoiPoint>24.323345,116.324532,31.000000</wpml:waypointPoiPoint>
- <wpml:waypointHeadingPathMode>clockwise</wpml:waypointHeadingPathMode>
- </wpml:globalWaypointHeadingParam>
- <wpml:globalWaypointTurnMode>toPointAndStopWithDiscontinuityCurvature</wpml:globalWaypointTurnMode>
- <wpml:globalUseStraightLine>0</wpml:globalUseStraightLine>
- <Placemark>
- <Point>
- <!-- Fill longitude and latitude here -->
- <coordinates>
- longitude,latitude
- </coordinates>
- </Point>
- <wpml:index>0</wpml:index>
- <wpml:ellipsoidHeight>90.2</wpml:ellipsoidHeight>
- <wpml:height>100</wpml:height>
- <wpml:useGlobalHeight>1</wpml:useGlobalHeight>
- <wpml:useGlobalSpeed>1</wpml:useGlobalSpeed>
- <wpml:useGlobalHeadingParam>1</wpml:useGlobalHeadingParam>
- <wpml:useGlobalTurnParam>1</wpml:useGlobalTurnParam>
- <wpml:gimbalPitchAngle>0</wpml:gimbalPitchAngle>
- </Placemark>
- <Placemark>
- <Point>
- <!-- Fill longitude and latitude here -->
- <coordinates>
- longitude,latitude
- </coordinates>
- </Point>
- <wpml:index>1</wpml:index>
- <wpml:ellipsoidHeight>90.2</wpml:ellipsoidHeight>
- <wpml:height>100</wpml:height>
- <wpml:useGlobalHeight>1</wpml:useGlobalHeight>
- <wpml:useGlobalSpeed>1</wpml:useGlobalSpeed>
- <wpml:useGlobalHeadingParam>1</wpml:useGlobalHeadingParam>
- <wpml:useGlobalTurnParam>1</wpml:useGlobalTurnParam>
- <wpml:gimbalPitchAngle>0</wpml:gimbalPitchAngle>
- <!-- Declare action group for waypoint 1# -->
- <wpml:actionGroup>
- <wpml:actionGroupId>0</wpml:actionGroupId>
- <wpml:actionGroupStartIndex>1</wpml:actionGroupStartIndex>
- <wpml:actionGroupEndIndex>1</wpml:actionGroupEndIndex>
- <wpml:actionGroupMode>sequence</wpml:actionGroupMode>
- <wpml:actionTrigger>
- <wpml:actionTriggerType>reachPoint</wpml:actionTriggerType>
- </wpml:actionTrigger>
- <!-- Declare the 1st action: rotate gimbal -->
- <wpml:action>
- <wpml:actionId>0</wpml:actionId>
- <wpml:actionActuatorFunc>gimbalRotate</wpml:actionActuatorFunc>
- <wpml:actionActuatorFuncParam>
- <wpml:gimbalRotateMode>absoluteAngle</wpml:gimbalRotateMode>
- <wpml:gimbalPitchRotateEnable>0</wpml:gimbalPitchRotateEnable>
- <wpml:gimbalPitchRotateAngle>0</wpml:gimbalPitchRotateAngle>
- <wpml:gimbalRollRotateEnable>0</wpml:gimbalRollRotateEnable>
- <wpml:gimbalRollRotateAngle>0</wpml:gimbalRollRotateAngle>
- <wpml:gimbalYawRotateEnable>1</wpml:gimbalYawRotateEnable>
- <wpml:gimbalYawRotateAngle>30</wpml:gimbalYawRotateAngle>
- <wpml:gimbalRotateTimeEnable>0</wpml:gimbalRotateTimeEnable>
- <wpml:gimbalRotateTime>0</wpml:gimbalRotateTime>
- <wpml:payloadPositionIndex>0</wpml:payloadPositionIndex>
- </wpml:actionActuatorFuncParam>
- </wpml:action>
- <!-- Declare the 2nd action: take photo -->
- <wpml:action>
- <wpml:actionId>1</wpml:actionId>
- <wpml:actionActuatorFunc>takePhoto</wpml:actionActuatorFunc>
- <wpml:actionActuatorFuncParam>
- <wpml:fileSuffix>point1</wpml:fileSuffix>
- <wpml:payloadPositionIndex>0</wpml:payloadPositionIndex>
- </wpml:actionActuatorFuncParam>
- </wpml:action>
- </wpml:actionGroup>
- </Placemark>
- </Folder>
- </Document>
- </kml>

将航线里的<coordinates>标签检测到并读取值即可获得坐标,可以按照该思路获取其它类型的航线,再将坐标系转换即可将航线展示到前端。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。