大疆的demo中没有带画航线的功能,目前有两个方法,一是在遥控器或者司空2等平台画好航线后下载,将航线导入到自己平台里面。还有一种就是自己开发画航线功能。第一种太麻烦了,文件倒来倒去的,我们肯定要选择第二种。
一、研究航线文件
首先看下大疆的官方文档是怎么介绍的
简单来说,kmz就是一个压缩包文件,里面包含了一个wpmz的文件夹,文件夹里面有两个文件,一个template.kml文件,一个waylines.wpml文件(附字段说明链接),官方文档中也有很详细的字段说明。
看完这些相信大家就有一定的思路了,只需要安装这些字段生成生成templete.kml,waylines.wpml文件,最后一起压缩成kmz文件即可。
二、开发
java端可以使用dom4j或者hutool来生成那俩子文件,当然不仅限于这两个工具,好多工具也可以实现。
/**
* 生成航线kml文件
*
* @param airlineManage 航线信息
* @return String 临时存储文件名
*/
public AirlineManage setTravelsKml(AirlineManage airlineManage) throws IOException {
Element root = DocumentHelper.createElement("kml");
Document document = DocumentHelper.createDocument(root);
Namespace namespace = Namespace.get("http://www.opengis.net/kml/2.2");
root.addAttribute("xmlns", "http://www.opengis.net/kml/2.2");
root.add(namespace);
Element documentElement = root.addElement("Document");
documentElement.addElement("name").addText(airlineManage.getAirlineName()); //名称
Element placeMarkElement = documentElement.addElement("Placemark");//在文件夹中添加一个地标
placeMarkElement.addElement("name").addText("Wayline");
placeMarkElement.addElement("visibility").addText("1");
Element styleElement = placeMarkElement.addElement("Style");
Element lineStyleElement = styleElement.addElement("LineStyle");
lineStyleElement.addElement("color").addText("cc00ffff");
lineStyleElement.addElement("width").addText("5");
Element extendedData = placeMarkElement.addElement("ExtendedData");
Element data = extendedData.addElement("Data");
data.addAttribute("name", "LinePattern");
data.addElement("value").addText("65535");
// 航向间距 计算速度
CameraInfo cameraInfo = cameraInfoMapper.selectCameraInfoByCameraId(airlineManage.getCameraId());
double courseInterval = DrawWayPointUtil.calcNonOverlapDistance(
airlineManage.getRelativeHeight(),
cameraInfo.getSensorHigh(),
cameraInfo.getCameraFocal(),
airlineManage.getCourseOverlaps() / 100
);
// 默认2s
Double photoInterval = airlineManage.getPhotoInterval();
if (StringUtils.isNull(photoInterval) || photoInterval == 0) {
photoInterval = 2d;
}
double flightSpeed = DrawWayPointUtil.calcFlightSpeed(courseInterval, photoInterval);
extendedData.addElement("autoFlightSpeed").addText(String.valueOf(flightSpeed));
Element lineString = placeMarkElement.addElement("LineString");
lineString.addElement("altitudeMode").addText("clampToGround");
Element coordinatesEle = lineString.addElement("coordinates");
StringBuilder coordinatesBuilder = new StringBuilder();
airlineManage.getWaypointList()
.stream()
.forEach(latLng -> coordinatesBuilder.append(latLng.getLon() + "," + latLng.getLat() + "," + airlineManage.getRelativeHeight() + " \n"));
coordinatesEle.addText(coordinatesBuilder.toString());
//创建kml到本地
String kmlSuffix = ".kml";
String kmlTempPath = PvConstants.PV_TEMP_FILE_PATH + airlineManage.getAirlineName() + kmlSuffix;
File tempFile = new File(PvConstants.PV_TEMP_FILE_PATH);
if (!tempFile.exists()) {
tempFile.mkdirs();
}
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("utf-8");
XMLWriter xmlWriter = new XMLWriter(new FileOutputStream(kmlTempPath), format);
xmlWriter.write(document);
xmlWriter.close();
// 压缩
String kmlZipSuffix = ".zip";
String kmlZipTempPath = PvConstants.PV_TEMP_FILE_PATH + airlineManage.getAirlineName() + kmlZipSuffix;
writeKml(Arrays.asList(kmlTempPath), kmlZipTempPath);
String objectUrl = minioUtil.uploadObjectAndObjectUrl(airlineManage.getAirlineName() + kmlZipSuffix, kmlZipTempPath);
airlineManage.setAirlineUrl(objectUrl);
FileUtils.deleteFile(kmlTempPath);
FileUtils.deleteFile(kmlZipTempPath);
return airlineManage;
}
public static void writeKml(List<String> filePathList, String kmlName) throws IOException {
OutputStream os = new BufferedOutputStream(new FileOutputStream(kmlName));
ZipOutputStream zos = new ZipOutputStream(os);
byte[] buf = new byte[8192];
int len;
for (String filePath : filePathList) {
File file = new File(filePath);
if (!file.isFile()) {
continue;
}
ZipEntry ze = new ZipEntry(file.getName());
zos.putNextEntry(ze);
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
while ((len = bis.read(buf)) > 0) {
zos.write(buf, 0, len);
}
zos.closeEntry();
bis.close();
}
zos.closeEntry();
zos.close();
os.close();
}
上面代码参考别的文章(感谢大佬),生成kml文件,压缩zip。
前端只需将文件必须元素值传给后端即可,后端生成kml文件,压缩为zip文件,替换zip后缀为kmz,上传文件服务器。最后,有什么问题大家可以一同探讨,共同学习进步。