一、需要插件
<!-- 解析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.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;
}
}
四、调用
@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>标签检测到并读取值即可获得坐标,可以按照该思路获取其它类型的航线,再将坐标系转换即可将航线展示到前端。