makcar/app/src/main/java/com/aros/apron/tools/DomParserWPML.java

288 lines
14 KiB
Java
Raw Normal View History

2026-01-30 11:47:32 +08:00
package com.aros.apron.tools;
import android.text.TextUtils;
import android.util.Log;
import com.aros.apron.entity.FlightMission;
import com.aros.apron.entity.MissionPoint;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.XMLWriter;
import java.io.File;
import java.io.FileWriter;
import java.util.List;
public class DomParserWPML {
private static final String TAG = "DomParserWPML";
private String wpmlFilePath = "";
private String wpmlFileName = "";
private Element docElement;
int actionGroupId = 0;
/**
* 构造
*/
public DomParserWPML(String wpmlFilePath, String wpmlFileName) {
this.wpmlFilePath = wpmlFilePath;
this.wpmlFileName = wpmlFileName;
}
/**
* 创建kml文件
*/
public void createWpml(FlightMission mission) {
String fileName = wpmlFilePath + wpmlFileName;
Document document = DocumentHelper.createDocument();// 建立document对象用来操作xml文件
Element kmlElement = document.addElement("kml", "http://www.opengis.net/kml/2.2");// 建立根节点
kmlElement.addAttribute("xmlns:wpml", "http://www.dji.com/wpmz/1.0.2");
kmlElement.addNamespace("wpml", "http://www.dji.com/wpmz/1.0.2");
docElement = kmlElement.addElement("Document");// 添加一个Document节点
createMissionConfig(mission);
createFolder(mission);
try {
// 设置生成xml的格式
XMLWriter writer = new XMLWriter(new FileWriter(new File(fileName)));
writer.write(document); //写入
writer.close();
} catch (Exception e) {
e.printStackTrace();
Log.e("createWpml","-------");
}
}
/**
* 创建任务信息
*
* @return
*/
private int createMissionConfig(FlightMission flightMission) {
if (docElement != null) {
try {
Element missionConfigElement = docElement.addElement("wpml:missionConfig");
//飞向起始点模式
missionConfigElement.addElement("wpml:flyToWaylineMode").setText("safely");
//航线结束动作
// missionConfigElement.addElement("wpml:finishAction").setText("autoLand");
missionConfigElement.addElement("wpml:finishAction").setText(flightMission.getFinishAction());
//失控是否继续执行航线
missionConfigElement.addElement("wpml:exitOnRCLost").setText("executeLostAction");
//失控执行失控动作时下面元素是必须的的
missionConfigElement.addElement("wpml:executeRCLostAction").setText("goBack");
//安全起飞高度
missionConfigElement.addElement("wpml:takeOffSecurityHeight").setText(String.valueOf(flightMission.getTakeOffSecurityHeight()));
//全局航线过渡速度(飞向航线起点的速度)
missionConfigElement.addElement("wpml:globalTransitionalSpeed").setText(String.valueOf(flightMission.getSpeed()));
//飞行器机型信息
Element droneInfoElement = missionConfigElement.addElement("wpml:droneInfo");
droneInfoElement.addElement("wpml:droneEnumValue").setText(String.valueOf(77));
droneInfoElement.addElement("wpml:droneSubEnumValue").setText(String.valueOf(1));
//飞行器挂载信息
Element payloadInfoElement = missionConfigElement.addElement("wpml:payloadInfo");
payloadInfoElement.addElement("wpml:payloadEnumValue").setText(String.valueOf(66));
payloadInfoElement.addElement("wpml:payloadSubEnumValue").setText(String.valueOf(0));
payloadInfoElement.addElement("wpml:payloadPositionIndex").setText(String.valueOf(0));
} catch (Exception e) {
Log.e(TAG, e.getMessage());
return -1;
}
return 0;
} else {
return -1;
}
}
/**
* 创建模板信息
*
* @return
*/
public int createFolder(FlightMission mission) {
if (docElement != null) {
Element folderElement = docElement.addElement("Folder");
//模板ID,范围:[0, 65535]
folderElement.addElement("wpml:templateId").setText(String.valueOf(mission.getMissionId()));
folderElement.addElement("wpml:executeHeightMode").setText("relativeToStartPoint");
folderElement.addElement("wpml:waylineId").setText("2");
folderElement.addElement("wpml:autoFlightSpeed").setText(String.valueOf(mission.getSpeed()));
if (mission.getPoints() != null && mission.getPoints().size() > 0) {
//航点信息(包括航点经纬度和高度等)
for (int i = 0; i < mission.getPoints().size(); i++) {
addPointToPlacemark(folderElement, mission.getPoints().get(i), i);
}
}
return 0;
} else {
return -1;
}
}
/**
* Placemark添加航点信息
* @param parentElement
*/
private boolean addPointToPlacemark(Element parentElement, MissionPoint missionPoint, int index) {
if (missionPoint == null || TextUtils.isEmpty(missionPoint.getLat())||TextUtils.isEmpty(missionPoint.getLng())) {
return false;
} else {
Element placemarkElement = parentElement.addElement("Placemark");
Element point = placemarkElement.addElement("Point");
//航点经纬度<经度,纬度>
point.addElement("coordinates")
.setText(missionPoint.getLng() + "," + missionPoint.getLat());
//航点序号
placemarkElement.addElement("wpml:index")
.setText(String.valueOf(index));
//航点高度EGM96海拔高度/相对起飞点高度/AGL相对地面高度useGlobalHeight 为0是必需
placemarkElement.addElement("wpml:executeHeight")
.setText(String.valueOf(missionPoint.getExecuteHeight()));
//航点飞行速度
placemarkElement.addElement("wpml:waypointSpeed")
.setText(String.valueOf(missionPoint.getSpeed()));
//该航段是否贴合直线
placemarkElement.addElement("wpml:useStraightLine")
.setText(String.valueOf(1));
//偏航角模式参数,当且仅当“wpml:useGlobalHeadingParam”为“0”时必需
Element waypointHeadingParamElement = placemarkElement.addElement("wpml:waypointHeadingParam");
waypointHeadingParamElement.addElement("wpml:waypointHeadingMode").setText("followWayline");
//航点类型(航点转弯模式),当且仅当“wpml:useGlobalTurnParam”为“0”时必需
Element waypointTurnParamElement = placemarkElement.addElement("wpml:waypointTurnParam");
waypointTurnParamElement.addElement("wpml:waypointTurnMode").setText("toPointAndStopWithDiscontinuityCurvature");
waypointTurnParamElement.addElement("wpml:waypointTurnDampingDist").setText("0");
if (missionPoint.getActions() != null && missionPoint.getActions().size() > 0) {
Element actionGroup = placemarkElement.addElement("wpml:actionGroup");
actionGroup.addElement("wpml:actionGroupId").setText(String.valueOf(actionGroupId++));
actionGroup.addElement("wpml:actionGroupStartIndex").setText(String.valueOf(index));
actionGroup.addElement("wpml:actionGroupEndIndex").setText(String.valueOf(index));
actionGroup.addElement("wpml:actionGroupMode").setText("sequence");
actionGroup.addElement("wpml:actionTrigger").addElement("wpml:actionTriggerType")
.setText("reachPoint");
//添加航点动作
addActionToPoint(actionGroup, index, missionPoint.getActions());
}
return true;
}
}
private void addActionToPoint(Element actionGroup, int index, List<MissionPoint.Action> actions) {
for (int i = 0; i < actions.size(); i++) {
Element action = actionGroup.addElement("wpml:action");
action.addElement("wpml:actionId").setText(String.valueOf(i));
Element actionActuatorFunc = action.addElement("wpml:actionActuatorFunc");
Element actionActuatorFuncParam = action.addElement("wpml:actionActuatorFuncParam");
switch (actions.get(i).getType()) {
//变焦
case 1:
actionActuatorFunc.setText("zoom");
actionActuatorFuncParam.addElement("wpml:focalLength").setText(String.valueOf(Math.round(actions.get(i).getZoom() * 0.2375f)));
//强制使用飞行器1号挂载位置。M300 RTK机型对应机身左前方。其它机型对应主云台。
actionActuatorFuncParam.addElement("wpml:payloadPositionIndex").setText("0");
actionActuatorFuncParam.addElement("isUseFocalFactor").setText("0");
break;
//拍照
case 2:
actionActuatorFunc.setText("takePhoto");
actionActuatorFuncParam.addElement("wpml:fileSuffix").setText("point" + index);
actionActuatorFuncParam.addElement("wpml:payloadPositionIndex").setText("0");
break;
//开始录像
case 3:
actionActuatorFunc.setText("startRecord");
actionActuatorFuncParam.addElement("wpml:fileSuffix").setText("航点" + index);
actionActuatorFuncParam.addElement("wpml:payloadPositionIndex").setText("0");
break;
//结束录像
case 4:
actionActuatorFunc.setText("stopRecord");
actionActuatorFuncParam.addElement("wpml:payloadPositionIndex").setText("0");
break;
//云台偏航角
case 5:
actionActuatorFunc.setText("gimbalRotate");
actionActuatorFuncParam.addElement("wpml:gimbalRotateMode")
.setText("absoluteAngle");
actionActuatorFuncParam.addElement("wpml:gimbalPitchRotateEnable").setText("0");
actionActuatorFuncParam.addElement("wpml:gimbalPitchRotateAngle").setText("0");
actionActuatorFuncParam.addElement("wpml:gimbalRollRotateEnable").setText("0");
actionActuatorFuncParam.addElement("wpml:gimbalRollRotateAngle").setText("0");
actionActuatorFuncParam.addElement("wpml:gimbalYawRotateEnable").setText("1");
actionActuatorFuncParam.addElement("wpml:gimbalYawRotateAngle").setText(String.valueOf(actions.get(i).getGimbalYawAngle() ));
actionActuatorFuncParam.addElement("wpml:gimbalRotateTimeEnable").setText("0");
actionActuatorFuncParam.addElement("wpml:gimbalRotateTime").setText("0");
actionActuatorFuncParam.addElement("wpml:payloadPositionIndex").setText("0");
break;
//云台俯仰角
case 6:
actionActuatorFunc.setText("gimbalRotate");
actionActuatorFuncParam.addElement("wpml:gimbalRotateMode").setText("absoluteAngle");
actionActuatorFuncParam.addElement("wpml:gimbalPitchRotateEnable").setText("1");
actionActuatorFuncParam.addElement("wpml:gimbalPitchRotateAngle").setText(String.valueOf(actions.get(i).getGimbalPitchAngle()));
actionActuatorFuncParam.addElement("wpml:gimbalRollRotateEnable").setText("0");
actionActuatorFuncParam.addElement("wpml:gimbalRollRotateAngle").setText("0");
actionActuatorFuncParam.addElement("wpml:gimbalYawRotateEnable").setText("0");
actionActuatorFuncParam.addElement("wpml:gimbalYawRotateAngle").setText("0");
actionActuatorFuncParam.addElement("wpml:gimbalRotateTimeEnable").setText("0");
actionActuatorFuncParam.addElement("wpml:gimbalRotateTime").setText("0");
actionActuatorFuncParam.addElement("wpml:payloadPositionIndex").setText("0");
break;
//飞行器偏航角
case 7:
actionActuatorFunc.setText("rotateYaw");
actionActuatorFuncParam.addElement("wpml:aircraftHeading").setText(String.valueOf(actions.get(i).getAircraftHeading()));
//强制逆时针旋转
actionActuatorFuncParam.addElement("wpml:aircraftPathMode").setText("counterClockwise");
break;
//悬停
case 8:
actionActuatorFunc.setText("hover");
actionActuatorFuncParam.addElement("wpml:hoverTime").setText(String.valueOf(actions.get(i).getHoverTime()));
break;
default:
}
}
}
/**
* 获取航点任务
* @return
*/
private String getActionActuatorFunc(String action) {
if (action.equals("0")) {
return "startRecord";
} else if (action.equals("2")) {
return "hover";
} else if (action.equals("3")) {
return "stopRecord";
} else {
return "takePhoto";
}
}
}