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