Xiajijian
2025-09-29 52039daeb631bc47cfd953f05c8a5c76aa199ede
1.将生成kmz的文件的功能合并智云3.0.
69 files added
1 files modified
3310 ■■■■■ changed files
ard-route/pom.xml 10 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/constant/FileTypeConstants.java 24 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/controller/UavRouteController.java 33 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/domain/ActionTriggerReq.java 24 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/domain/CoordinatePointReq.java 29 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/domain/MappingTypeReq.java 61 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/domain/PointActionReq.java 68 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/domain/RoutePointReq.java 78 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/domain/UavRouteReq.java 95 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/domain/WaypointHeadingReq.java 28 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/domain/WaypointTurnReq.java 30 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlAction.java 19 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlActionActuatorFuncParam.java 161 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlActionGroup.java 34 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlActionTrigger.java 17 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlDocument.java 26 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlDroneInfo.java 16 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlFolder.java 56 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlGlobalWaypointHeadingParam.java 23 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlInfo.java 22 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlLineString.java 13 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlLinearRing.java 13 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlMissionConfig.java 43 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlOuterBoundaryIs.java 12 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlOverlap.java 34 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlParams.java 95 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlPayloadInfo.java 16 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlPayloadParam.java 41 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlPlacemark.java 131 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlPoint.java 13 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlPolygon.java 12 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlWayLineCoordinateSysParam.java 31 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlWaypointGimbalHeadingParam.java 17 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlWaypointHeadingParam.java 23 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlWaypointTurnParam.java 16 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/domain/kml/RoutePointInfo.java 79 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/enums/kml/ActionActuatorFuncEnums.java 45 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/enums/kml/ActionGroupModeEnums.java 34 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/enums/kml/ActionTriggerTypeEnums.java 36 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/enums/kml/AircraftPathModeEnums.java 34 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/enums/kml/CollectionMethodEnums.java 35 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/enums/kml/DroneEnumValueEnums.java 37 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/enums/kml/ExecuteHeightModeEnums.java 36 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/enums/kml/ExecuteRCLostActionEnums.java 36 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/enums/kml/ExitOnRCLostEnums.java 34 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/enums/kml/FinishActionEnums.java 37 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/enums/kml/FlyToWaylineModeEnums.java 34 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/enums/kml/FocusModeEnums.java 34 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/enums/kml/GimbalPitchModeEnums.java 34 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/enums/kml/GlobalWaypointTurnModeEnums.java 36 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/enums/kml/HeightModeEnums.java 36 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/enums/kml/ImageFormatEnums.java 37 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/enums/kml/LensTypeEnums.java 35 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/enums/kml/MeteringModeEnums.java 34 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/enums/kml/PayloadPositionIndexEnums.java 35 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/enums/kml/PayloadTypeEnums.java 45 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/enums/kml/PositioningTypeEnums.java 36 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/enums/kml/ReturnModeEnums.java 35 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/enums/kml/ScanningModeEnums.java 34 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/enums/kml/ShootTypeEnums.java 35 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/enums/kml/TemplateTypeEnums.java 36 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/enums/kml/WaypointHeadingModeEnums.java 37 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/enums/kml/WaypointHeadingPathModeEnums.java 35 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/service/UavRouteService.java 17 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/service/impl/UavRouteServiceImpl.java 108 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/util/Gps.java 19 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/util/PositionUtils.java 153 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/kmz/util/RouteFileUtils.java 598 ●●●●● patch | view | raw | blame | history
file/kmz/更新航线kmz文件.kmz patch | view | raw | blame | history
file/kmz/航线kmz文件.kmz patch | view | raw | blame | history
ard-route/pom.xml
@@ -27,6 +27,16 @@
            <artifactId>lombok</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.20</version>
        </dependency>
        <dependency>
            <groupId>com.thoughtworks.xstream</groupId>
            <artifactId>xstream</artifactId>
            <version>1.4.20</version>
        </dependency>
    </dependencies>
ard-route/src/main/java/com/ard/route/kmz/constant/FileTypeConstants.java
New file
@@ -0,0 +1,24 @@
package com.ard.route.kmz.constant;
public interface FileTypeConstants {
    /**
     * kmz 文件本质上是zip文件
     */
    String KMZ = "zip";
    /**
     * kml 文件
     */
    String KML = "kml";
    /**
     * wpml 文件
     */
    String WPML = "wpml";
    /**
     * 航线导入支持的文件类型
     */
    String ROUTE_SUPPORT_TYPE = "kml,zip";
}
ard-route/src/main/java/com/ard/route/kmz/controller/UavRouteController.java
New file
@@ -0,0 +1,33 @@
package com.ard.route.kmz.controller;
import com.ard.route.kmz.domain.UavRouteReq;
import com.ard.route.kmz.service.UavRouteService;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
public class UavRouteController {
    @Resource
    private UavRouteService routeService;
    /**
     * 编辑kmz文件
     */
    @PostMapping("/updateKmz")
    public void updateKmz(@RequestBody UavRouteReq uavRouteReq) {
        routeService.updateKmz(uavRouteReq);
    }
    /**
     * 生成kmz文件
     */
    @PostMapping("/buildKmz")
    public void buildKmz(@RequestBody UavRouteReq uavRouteReq){
        routeService.buildKmz(uavRouteReq);
    }
}
ard-route/src/main/java/com/ard/route/kmz/domain/ActionTriggerReq.java
New file
@@ -0,0 +1,24 @@
package com.ard.route.kmz.domain;
import lombok.Data;
import java.io.Serializable;
/**
 * Author:songjian
 * Date: 2024/12/22 10:46
 **/
@Data
public class ActionTriggerReq implements Serializable {
    /**
     * 动作触发器类型
     */
    private String actionTriggerType;
    /**
     * 动作触发器参数
     */
    private Double actionTriggerParam;
}
ard-route/src/main/java/com/ard/route/kmz/domain/CoordinatePointReq.java
New file
@@ -0,0 +1,29 @@
package com.ard.route.kmz.domain;
import lombok.Data;
import java.io.Serializable;
/**
 * Author:songjian
 * Date: 2024/12/22 10:46
 **/
@Data
public class CoordinatePointReq implements Serializable {
    /**
     * 经度
     */
    private Double longitude;
    /**
     * 纬度
     */
    private Double latitude;
    /**
     * 高度
     */
    private Double height;
}
ard-route/src/main/java/com/ard/route/kmz/domain/MappingTypeReq.java
New file
@@ -0,0 +1,61 @@
package com.ard.route.kmz.domain;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
 * Author:songjian
 * Date: 2024/12/22 10:46
 **/
@Data
public class MappingTypeReq implements Serializable {
    /**
     * 采集方式
     */
    private String collectionMethod;
    /**
     * 镜头类型
     */
    private String lensType;
    /**
     * 航向重叠率
     */
    private Integer overlapH;
    /**
     * 旁向重叠率
     */
    private Integer overlapW;
    /**
     * 是否开启高程优化
     */
    private Integer elevationOptimizeEnable;
    /**
     * 拍照模式
     */
    private String shootType;
    /**
     * 航线方向
     */
    private String direction;
    /**
     * 测区外扩距离
     */
    private String margin;
    /**
     * 测区多边形坐标  经度,纬度,高度
     */
    private List<CoordinatePointReq> coordinates;
}
ard-route/src/main/java/com/ard/route/kmz/domain/PointActionReq.java
New file
@@ -0,0 +1,68 @@
package com.ard.route.kmz.domain;
import lombok.Data;
//import java.io.Serial;
import java.io.Serializable;
@Data
public class PointActionReq implements Serializable {
//    @Serial
//    private static final long serialVersionUID = -1234025611387201652L;
    /**
     * 动作编号
     */
    private Integer actionIndex;
    /**
     * 飞行器悬停等待时间
     */
    private Integer hoverTime;
    /**
     * 飞行器目标偏航角
     */
    private Double aircraftHeading;
    /**
     * 是否使用全局拍照模式 0:不使用 1:使用
     */
    private Integer useGlobalImageFormat;
    /**
     * 拍照模式(字典)
     */
    private String imageFormat;
    /**
     * 普通拍照0 全景拍照1
     */
    private Integer takePhotoType;
    /**
     * 云台偏航角
     */
    private Double gimbalYawRotateAngle;
    /**
     * 云台俯仰角
     */
    private Double gimbalPitchRotateAngle;
    /**
     * 变焦焦距
     */
    private Double zoom;
    /**
     * 开始录像
     */
    private Boolean startRecord;
    /**
     * 停止录像
     */
    private Boolean stopRecord;
}
ard-route/src/main/java/com/ard/route/kmz/domain/RoutePointReq.java
New file
@@ -0,0 +1,78 @@
package com.ard.route.kmz.domain;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
@Data
public class RoutePointReq implements Serializable {
    /**
     * 航点编号
     */
    private Integer routePointIndex;
    /**
     * 经度
     */
    private Double longitude;
    /**
     * 纬度
     */
    private Double latitude;
    /**
     * 高度
     */
    private Double height;
    /**
     * 飞行速度
     */
    private Double speed;
    /**
     * 航点偏航角
     */
    private WaypointHeadingReq waypointHeadingReq;
    /**
     * 航点转弯模式
     */
    private WaypointTurnReq waypointTurnReq;
    /**
     * 航点云台俯仰角
     */
    private Double gimbalPitchAngle;
    /**
     * 航点动作列表
     */
    private List<PointActionReq> actions;
    /**
     * 航点动作触发
     */
    private ActionTriggerReq actionTriggerReq;
    /**
     * 等时拍照间隔时间 单位s
     */
    private Double timeInterval;
    /**
     * 等距拍照间隔距离 单位m
     */
    private Double distanceInterval;
    /**
     * 停止间隔拍照航点编号
     */
    private Integer endIntervalRouteIndex;
}
ard-route/src/main/java/com/ard/route/kmz/domain/UavRouteReq.java
New file
@@ -0,0 +1,95 @@
package com.ard.route.kmz.domain;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
 * Author:songjian
 * Date: 2024/12/22 10:46
 **/
@Data
public class UavRouteReq implements Serializable {
    /**
     * 航线类型
     */
    private String templateType;
    /**
     * 无人机类型
     */
    private Integer droneType;
    /**
     * 无人机子类型
     */
    private Integer subDroneType;
    /**
     * 负载类型
     */
    private Integer payloadType;
    /**
     * 负载挂载位置
     */
    private Integer payloadPosition;
    /**
     * 负载图片存储类型
     */
    private String imageFormat;
    /**
     * 航线结束动作
     */
    private String finishAction;
    /**
     * 失控动作
     */
    private String exitOnRcLostAction;
    /**
     * 全局航线高度
     */
    private Double globalHeight;
    /**
     * 全局航线飞行速度
     */
    private Double autoFlightSpeed;
    /**
     * 全局偏航角模式
     */
    private WaypointHeadingReq waypointHeadingReq;
    /**
     * 全局航点转弯模式
     */
    private WaypointTurnReq waypointTurnReq;
    /**
     * 云台俯仰角控制模式
     */
    private String gimbalPitchMode;
    /**
     * 参考起飞点
     */
    private String takeOffRefPoint;
    /**
     * 航点列表
     */
    private List<RoutePointReq> routePointList;
    /**
     * 建图航拍、倾斜摄影、航带飞行模板参数
     */
    private MappingTypeReq mappingTypeReq;
}
ard-route/src/main/java/com/ard/route/kmz/domain/WaypointHeadingReq.java
New file
@@ -0,0 +1,28 @@
package com.ard.route.kmz.domain;
import lombok.Data;
import java.io.Serializable;
/**
 * Author:songjian
 * Date: 2024/12/22 13:05
 **/
@Data
public class WaypointHeadingReq implements Serializable {
    /**
     * 偏航角模式
     */
    private String waypointHeadingMode;
    /**
     * 偏航角度
     */
    private Double waypointHeadingAngle;
    /**
     * 兴趣点
     */
    private String waypointPoiPoint;
}
ard-route/src/main/java/com/ard/route/kmz/domain/WaypointTurnReq.java
New file
@@ -0,0 +1,30 @@
package com.ard.route.kmz.domain;
import lombok.Data;
import java.io.Serializable;
/**
 * Author:songjian
 * Date: 2024/12/22 13:05
 **/
@Data
public class WaypointTurnReq implements Serializable {
    /**
     * 航点转弯模式
     */
    private String waypointTurnMode;
    /**
     * 航点转弯截距
     */
    private Double waypointTurnDampingDist;
    /**
     * 该航段是否贴合直线
     */
    private Integer useStraightLine;
}
ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlAction.java
New file
@@ -0,0 +1,19 @@
package com.ard.route.kmz.domain.kml;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import lombok.Data;
@Data
@XStreamAlias("wpml:action")
public class KmlAction {
    @XStreamAlias("wpml:actionId")
    private String actionId;
    @XStreamAlias("wpml:actionActuatorFunc")
    private String actionActuatorFunc;
    @XStreamAlias("wpml:actionActuatorFuncParam")
    private KmlActionActuatorFuncParam actionActuatorFuncParam;
}
ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlActionActuatorFuncParam.java
New file
@@ -0,0 +1,161 @@
package com.ard.route.kmz.domain.kml;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import lombok.Data;
@Data
@XStreamAlias("wpml:actionActuatorFuncParam")
public class KmlActionActuatorFuncParam {
    // takePhoto & startRecord & stopRecord
    @XStreamAlias("wpml:payloadPositionIndex")
    private String payloadPositionIndex;
    @XStreamAlias("wpml:fileSuffix")
    private String fileSuffix;
    @XStreamAlias("wpml:payloadLensIndex")
    private String payloadLensIndex;
    @XStreamAlias("wpml:useGlobalPayloadLensIndex")
    private String useGlobalPayloadLensIndex;
    // focus
    @XStreamAlias("wpml:isPointFocus")
    private String isPointFocus;
    @XStreamAlias("wpml:focusX")
    private String focusX;
    @XStreamAlias("wpml:focusY")
    private String focusY;
    @XStreamAlias("wpml:focusRegionWidth")
    private String focusRegionWidth;
    @XStreamAlias("wpml:focusRegionHeight")
    private String focusRegionHeight;
    @XStreamAlias("wpml:isInfiniteFocus")
    private String isInfiniteFocus;
    // zoom
    @XStreamAlias("wpml:focalLength")
    private String focalLength;
    // customDirName
    @XStreamAlias("wpml:directoryName")
    private String directoryName;
    // gimbalRotate & gimbalEvenlyRotate
    @XStreamAlias("wpml:gimbalHeadingYawBase")
    private String gimbalHeadingYawBase;
    @XStreamAlias("wpml:gimbalRotateMode")
    private String gimbalRotateMode;
    @XStreamAlias("wpml:gimbalPitchRotateEnable")
    private String gimbalPitchRotateEnable;
    @XStreamAlias("wpml:gimbalPitchRotateAngle")
    private String gimbalPitchRotateAngle;
    @XStreamAlias("wpml:gimbalRollRotateEnable")
    private String gimbalRollRotateEnable;
    @XStreamAlias("wpml:gimbalRollRotateAngle")
    private String gimbalRollRotateAngle;
    @XStreamAlias("wpml:gimbalYawRotateEnable")
    private String gimbalYawRotateEnable;
    @XStreamAlias("wpml:gimbalYawRotateAngle")
    private String gimbalYawRotateAngle;
    @XStreamAlias("wpml:gimbalRotateTimeEnable")
    private String gimbalRotateTimeEnable;
    @XStreamAlias("wpml:gimbalRotateTime")
    private String gimbalRotateTime;
    // rotateYaw
    @XStreamAlias("wpml:aircraftHeading")
    private String aircraftHeading;
    @XStreamAlias("wpml:aircraftPathMode")
    private String aircraftPathMode;
    // hover
    @XStreamAlias("wpml:hoverTime")
    private String hoverTime;
    // orientedShoot
    @XStreamAlias("wpml:accurateFrameValid")
    private String accurateFrameValid;
    @XStreamAlias("wpml:targetAngle")
    private String targetAngle;
    @XStreamAlias("wpml:actionUUID")
    private String actionUUID;
    @XStreamAlias("wpml:imageWidth")
    private String imageWidth;
    @XStreamAlias("wpml:imageHeight")
    private String imageHeight;
    @XStreamAlias("wpml:AFPos")
    private String AFPos;
    @XStreamAlias("wpml:gimbalPort")
    private String gimbalPort;
    @XStreamAlias("wpml:orientedCameraType")
    private String orientedCameraType;
    @XStreamAlias("wpml:orientedFilePath")
    private String orientedFilePath;
    @XStreamAlias("wpml:orientedFileMD5")
    private String orientedFileMD5;
    @XStreamAlias("wpml:orientedFileSize")
    private String orientedFileSize;
    @XStreamAlias("wpml:orientedFileSuffix")
    private String orientedFileSuffix;
    @XStreamAlias("wpml:orientedCameraApertue")
    private String orientedCameraApertue;
    @XStreamAlias("wpml:orientedCameraLuminance")
    private String orientedCameraLuminance;
    @XStreamAlias("wpml:orientedCameraShutterTime")
    private String orientedCameraShutterTime;
    @XStreamAlias("wpml:orientedCameraISO")
    private String orientedCameraISO;
    @XStreamAlias("wpml:orientedPhotoMode")
    private String orientedPhotoMode;
    // panoShot
    @XStreamAlias("wpml:panoShotSubMode")
    private String panoShotSubMode;
    // recordPointCloud
    @XStreamAlias("wpml:recordPointCloudOperate")
    private String recordPointCloudOperate;
}
ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlActionGroup.java
New file
@@ -0,0 +1,34 @@
package com.ard.route.kmz.domain.kml;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import lombok.Data;
import java.util.List;
@Data
@XStreamAlias("wpml:actionGroup")
public class KmlActionGroup {
    @XStreamAlias("wpml:actionGroupId")
    private String actionGroupId;
    @XStreamAlias("wpml:actionGroupStartIndex")
    private String actionGroupStartIndex;
    @XStreamAlias("wpml:actionGroupEndIndex")
    private String actionGroupEndIndex;
    @XStreamAlias("wpml:actionGroupMode")
    private String actionGroupMode;
    @XStreamAlias("wpml:actionTrigger")
    private KmlActionTrigger actionTrigger;
    @XStreamAlias("wpml:action")
    private List<KmlAction> action;
}
ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlActionTrigger.java
New file
@@ -0,0 +1,17 @@
package com.ard.route.kmz.domain.kml;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import lombok.Data;
@Data
@XStreamAlias("wpml:actionTrigger")
public class KmlActionTrigger {
    @XStreamAlias("wpml:actionTriggerType")
    private String actionTriggerType;
    @XStreamAlias("wpml:actionTriggerParam")
    private String actionTriggerParam;
}
ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlDocument.java
New file
@@ -0,0 +1,26 @@
package com.ard.route.kmz.domain.kml;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import lombok.Data;
@Data
@XStreamAlias("Document")
public class KmlDocument {
    @XStreamAlias("wpml:author")
    private String author;
    @XStreamAlias("wpml:createTime")
    private String createTime;
    @XStreamAlias("wpml:updateTime")
    private String updateTime;
    @XStreamAlias("wpml:missionConfig")
    private KmlMissionConfig kmlMissionConfig;
    @XStreamAlias("Folder")
    private KmlFolder folder;
}
ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlDroneInfo.java
New file
@@ -0,0 +1,16 @@
package com.ard.route.kmz.domain.kml;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import lombok.Data;
@Data
@XStreamAlias("wpml:droneInfo")
public class KmlDroneInfo {
    @XStreamAlias("wpml:droneEnumValue")
    private String droneEnumValue;
    @XStreamAlias("wpml:droneSubEnumValue")
    private String droneSubEnumValue;
}
ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlFolder.java
New file
@@ -0,0 +1,56 @@
package com.ard.route.kmz.domain.kml;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamImplicit;
import lombok.Data;
import java.util.List;
@Data
@XStreamAlias("Folder")
public class KmlFolder {
    @XStreamAlias("wpml:templateType")
    private String templateType;
    @XStreamAlias("wpml:templateId")
    private String templateId;
    @XStreamAlias("wpml:autoFlightSpeed")
    private String autoFlightSpeed;
    @XStreamAlias("wpml:waylineCoordinateSysParam")
    private KmlWayLineCoordinateSysParam waylineCoordinateSysParam;
    @XStreamAlias("wpml:payloadParam")
    private KmlPayloadParam payloadParam;
    // 以下为航点飞行模板元素
    @XStreamAlias("wpml:globalWaypointTurnMode")
    private String globalWaypointTurnMode;
    @XStreamAlias("wpml:globalUseStraightLine")
    private String globalUseStraightLine;
    @XStreamAlias("wpml:gimbalPitchMode")
    private String gimbalPitchMode;
    @XStreamAlias("wpml:globalHeight")
    private String globalHeight;
    @XStreamAlias("wpml:globalWaypointHeadingParam")
    private KmlGlobalWaypointHeadingParam globalWaypointHeadingParam;
    @XStreamImplicit(itemFieldName = "Placemark")
    private List<KmlPlacemark> placemarkList;
    // 以下为 wpml 文件使用
    @XStreamAlias("wpml:executeHeightMode")
    private String executeHeightMode;
    @XStreamAlias("wpml:waylineId")
    private String waylineId;
    @XStreamAlias("wpml:startActionGroup")
    private KmlActionGroup actionGroup;
}
ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlGlobalWaypointHeadingParam.java
New file
@@ -0,0 +1,23 @@
package com.ard.route.kmz.domain.kml;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import lombok.Data;
@Data
@XStreamAlias("wpml:globalWaypointHeadingParam")
public class KmlGlobalWaypointHeadingParam {
    @XStreamAlias("wpml:waypointHeadingMode")
    private String waypointHeadingMode;
    @XStreamAlias("wpml:waypointHeadingAngle")
    private String waypointHeadingAngle;
    @XStreamAlias("wpml:waypointPoiPoint")
    private String waypointPoiPoint;
    @XStreamAlias("wpml:waypointHeadingPathMode")
    private String waypointHeadingPathMode;
}
ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlInfo.java
New file
@@ -0,0 +1,22 @@
package com.ard.route.kmz.domain.kml;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
import lombok.Data;
@Data
@XStreamAlias("kml")
public class KmlInfo {
    @XStreamAsAttribute
    @XStreamAlias("xmlns")
    private String xmlns = "http://www.opengis.net/kml/2.2";
    @XStreamAsAttribute
    @XStreamAlias("xmlns:wpml")
    private String wpml = "http://www.dji.com/wpmz/1.0.6";
    @XStreamAlias("Document")
    private KmlDocument document;
}
ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlLineString.java
New file
@@ -0,0 +1,13 @@
package com.ard.route.kmz.domain.kml;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import lombok.Data;
@Data
@XStreamAlias("LineString")
public class KmlLineString {
    @XStreamAlias("coordinates")
    private String coordinates;
}
ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlLinearRing.java
New file
@@ -0,0 +1,13 @@
package com.ard.route.kmz.domain.kml;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import lombok.Data;
@Data
@XStreamAlias("LinearRing")
public class KmlLinearRing {
    @XStreamAlias("coordinates")
    private String coordinates;
}
ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlMissionConfig.java
New file
@@ -0,0 +1,43 @@
package com.ard.route.kmz.domain.kml;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import lombok.Data;
@Data
@XStreamAlias("wpml:missionConfig")
public class KmlMissionConfig {
    @XStreamAlias("wpml:flyToWaylineMode")
    private String flyToWayLineMode;
    @XStreamAlias("wpml:finishAction")
    private String finishAction;
    @XStreamAlias("wpml:exitOnRCLost")
    private String exitOnRCLost;
    @XStreamAlias("wpml:executeRCLostAction")
    private String executeRCLostAction;
    @XStreamAlias("wpml:takeOffSecurityHeight")
    private String takeOffSecurityHeight;
    @XStreamAlias("wpml:globalTransitionalSpeed")
    private String globalTransitionalSpeed;
    @XStreamAlias("wpml:globalRTHHeight")
    private String globalRTHHeight;
    @XStreamAlias("wpml:takeOffRefPoint")
    private String takeOffRefPoint;
    @XStreamAlias("wpml:takeOffRefPointAGLHeight")
    private String takeOffRefPointAGLHeight;
    @XStreamAlias("wpml:droneInfo")
    private KmlDroneInfo droneInfo;
    @XStreamAlias("wpml:payloadInfo")
    private KmlPayloadInfo payloadInfo;
}
ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlOuterBoundaryIs.java
New file
@@ -0,0 +1,12 @@
package com.ard.route.kmz.domain.kml;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import lombok.Data;
@Data
@XStreamAlias("outerBoundaryIs")
public class KmlOuterBoundaryIs {
    @XStreamAlias("LinearRing")
    private KmlLinearRing linearRing;
}
ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlOverlap.java
New file
@@ -0,0 +1,34 @@
package com.ard.route.kmz.domain.kml;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import lombok.Data;
@Data
@XStreamAlias("wpml:overlap")
public class KmlOverlap {
    @XStreamAlias("orthoLidarOverlapH")
    private String orthoLidarOverlapH;
    @XStreamAlias("orthoLidarOverlapW")
    private String orthoLidarOverlapW;
    @XStreamAlias("orthoCameraOverlapH")
    private String orthoCameraOverlapH;
    @XStreamAlias("orthoCameraOverlapW")
    private String orthoCameraOverlapW;
    @XStreamAlias("inclinedLidarOverlapH")
    private String inclinedLidarOverlapH;
    @XStreamAlias("inclinedLidarOverlapW")
    private String inclinedLidarOverlapW;
    @XStreamAlias("inclinedCameraOverlapH")
    private String inclinedCameraOverlapH;
    @XStreamAlias("inclinedCameraOverlapW")
    private String inclinedCameraOverlapW;
}
ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlParams.java
New file
@@ -0,0 +1,95 @@
package com.ard.route.kmz.domain.kml;
import com.ard.route.kmz.domain.MappingTypeReq;
import com.ard.route.kmz.domain.WaypointHeadingReq;
import com.ard.route.kmz.domain.WaypointTurnReq;
import lombok.Data;
import java.util.List;
/**
 * 航线文件
 */
@Data
public class KmlParams {
    /**
     * 航线类型
     */
    private String templateType;
    /**
     * 无人机类型
     */
    private Integer droneType;
    /**
     * 无人机子类型
     */
    private Integer subDroneType;
    /**
     * 负载类型
     */
    private Integer payloadType;
    /**
     * 负载挂载位置
     */
    private Integer payloadPosition;
    /**
     * 航线结束动作
     */
    private String finishAction;
    /**
     * 失控动作
     */
    private String exitOnRcLostAction;
    /**
     * 参考起飞点
     */
    private String takeOffRefPoint;
    /**
     * 全局航点转弯模式
     */
    private WaypointTurnReq waypointTurnReq;
    /**
     * 全局航线高度
     */
    private Double globalHeight;
    /**
     * 全局偏航角模式
     */
    private WaypointHeadingReq waypointHeadingReq;
    /**
     * 云台俯仰角控制模式
     */
    private String gimbalPitchMode;
    /**
     * 全局航线飞行速度
     */
    private Double autoFlightSpeed;
    /**
     * 负载图片存储类型
     */
    private String imageFormat;
    /**
     * 建图航拍、倾斜摄影、航带飞行模板参数
     */
    private MappingTypeReq mappingTypeReq;
    private List<RoutePointInfo> routePointList;
}
ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlPayloadInfo.java
New file
@@ -0,0 +1,16 @@
package com.ard.route.kmz.domain.kml;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import lombok.Data;
@Data
@XStreamAlias("wpml:payloadInfo")
public class KmlPayloadInfo {
    @XStreamAlias("wpml:payloadEnumValue")
    private String payloadEnumValue;
    @XStreamAlias("wpml:payloadPositionIndex")
    private String payloadPositionIndex;
}
ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlPayloadParam.java
New file
@@ -0,0 +1,41 @@
package com.ard.route.kmz.domain.kml;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import lombok.Data;
/**
 * 负载设置
 */
@Data
@XStreamAlias("wpml:payloadParam")
public class KmlPayloadParam {
    @XStreamAlias("wpml:payloadPositionIndex")
    private String payloadPositionIndex;
    @XStreamAlias("wpml:focusMode")
    private String focusMode;
    @XStreamAlias("wpml:meteringMode")
    private String meteringMode;
    @XStreamAlias("wpml:dewarpingEnable")
    private String dewarpingEnable;
    @XStreamAlias("wpml:returnMode")
    private String returnMode;
    @XStreamAlias("wpml:samplingRate")
    private String samplingRate;
    @XStreamAlias("wpml:scanningMode")
    private String scanningMode;
    @XStreamAlias("wpml:modelColoringEnable")
    private String modelColoringEnable;
    @XStreamAlias("wpml:imageFormat")
    private String imageFormat;
}
ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlPlacemark.java
New file
@@ -0,0 +1,131 @@
package com.ard.route.kmz.domain.kml;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import lombok.Data;
@Data
@XStreamAlias("Placemark")
public class KmlPlacemark {
    @XStreamAlias("wpml:isRisky")
    private String isRisky;
    @XStreamAlias("Point")
    private KmlPoint kmlPoint;
    @XStreamAlias("wpml:index")
    private String index;
    @XStreamAlias("wpml:useGlobalHeight")
    private String useGlobalHeight;
    @XStreamAlias("wpml:ellipsoidHeight")
    private String ellipsoidHeight;
    @XStreamAlias("wpml:height")
    private String height;
    @XStreamAlias("wpml:useGlobalSpeed")
    private String useGlobalSpeed;
    @XStreamAlias("wpml:waypointSpeed")
    private String waypointSpeed;
    @XStreamAlias("wpml:useGlobalHeadingParam")
    private String useGlobalHeadingParam;
    @XStreamAlias("wpml:waypointHeadingParam")
    private KmlWaypointHeadingParam waypointHeadingParam;
    @XStreamAlias("wpml:useGlobalTurnParam")
    private String useGlobalTurnParam;
    @XStreamAlias("wpml:waypointTurnParam")
    private KmlWaypointTurnParam waypointTurnParam;
    @XStreamAlias("wpml:useStraightLine")
    private String useStraightLine;
    @XStreamAlias("wpml:gimbalPitchAngle")
    private String gimbalPitchAngle;
    @XStreamAlias("wpml:actionGroup")
    private KmlActionGroup actionGroup;
    // 下面 wpml 文件使用
    @XStreamAlias("wpml:executeHeight")
    private String executeHeight;
//    @XStreamAlias("wpml:waypointGimbalHeadingParam")
//    private KmlWaypointGimbalHeadingParam waypointGimbalHeadingParam;
    // 建图航拍模板元素
    @XStreamAlias("wpml:caliFlightEnable")
    private String caliFlightEnable;
    @XStreamAlias("wpml:elevationOptimizeEnable")
    private String elevationOptimizeEnable;
    @XStreamAlias("wpml:smartObliqueEnable")
    private String smartObliqueEnable;
    @XStreamAlias("wpml:smartObliqueGimbalPitch")
    private String smartObliqueGimbalPitch;
    @XStreamAlias("wpml:shootType")
    private String shootType;
    @XStreamAlias("wpml:direction")
    private String direction;
    @XStreamAlias("wpml:margin")
    private String margin;
    @XStreamAlias("wpml:overlap")
    private KmlOverlap overlap;
    @XStreamAlias("wpml:ovefacadeWaylineEnablerlap")
    private String facadeWaylineEnable;
    @XStreamAlias("Polygon")
    private KmlPolygon polygon;
    @XStreamAlias("wpml:mappingHeadingParam")
    private KmlActionGroup mappingHeadingParam;
    @XStreamAlias("wpml:gimbalPitchMode")
    private String gimbalPitchMode;
    // 倾斜摄影模板元素
    @XStreamAlias("wpml:inclinedGimbalPitch")
    private String inclinedGimbalPitch;
    @XStreamAlias("wpml:inclinedFlightSpeed")
    private String inclinedFlightSpeed;
    // 航带飞行模板元素
    @XStreamAlias("wpml:singleLineEnable")
    private String singleLineEnable;
    @XStreamAlias("wpml:cuttingDistance")
    private String cuttingDistance;
    @XStreamAlias("wpml:boundaryOptimEnable")
    private String boundaryOptimEnable;
    @XStreamAlias("wpml:leftExtend")
    private String leftExtend;
    @XStreamAlias("wpml:rightExtend")
    private String rightExtend;
    @XStreamAlias("wpml:includeCenterEnable")
    private String includeCenterEnable;
    @XStreamAlias("wpml:stripUseTemplateAltitude")
    private String stripUseTemplateAltitude;
    @XStreamAlias("LineString")
    private KmlLineString lineString;
}
ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlPoint.java
New file
@@ -0,0 +1,13 @@
package com.ard.route.kmz.domain.kml;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import lombok.Data;
@Data
@XStreamAlias("Point")
public class KmlPoint {
    @XStreamAlias("coordinates")
    private String coordinates;
}
ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlPolygon.java
New file
@@ -0,0 +1,12 @@
package com.ard.route.kmz.domain.kml;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import lombok.Data;
@Data
@XStreamAlias("Polygon")
public class KmlPolygon {
    @XStreamAlias("outerBoundaryIs")
    private KmlOuterBoundaryIs outerBoundaryIs;
}
ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlWayLineCoordinateSysParam.java
New file
@@ -0,0 +1,31 @@
package com.ard.route.kmz.domain.kml;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import lombok.Data;
/**
 * 坐标系参数
 */
@Data
@XStreamAlias("wpml:waylineCoordinateSysParam")
public class KmlWayLineCoordinateSysParam {
    @XStreamAlias("wpml:coordinateMode")
    private String coordinateMode;
    @XStreamAlias("wpml:heightMode")
    private String heightMode;
    @XStreamAlias("wpml:positioningType")
    private String positioningType;
    @XStreamAlias("wpml:globalShootHeight")
    private String globalShootHeight;
    @XStreamAlias("wpml:surfaceFollowModeEnable")
    private String surfaceFollowModeEnable;
    @XStreamAlias("wpml:surfaceRelativeHeight")
    private String surfaceRelativeHeight;
}
ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlWaypointGimbalHeadingParam.java
New file
@@ -0,0 +1,17 @@
package com.ard.route.kmz.domain.kml;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import lombok.Data;
@Data
@XStreamAlias("wpml:waypointGimbalHeadingParam")
public class KmlWaypointGimbalHeadingParam {
    @XStreamAlias("wpml:waypointGimbalPitchAngle")
    private String waypointGimbalPitchAngle;
    @XStreamAlias("wpml:waypointGimbalYawAngle")
    private String waypointGimbalYawAngle;
}
ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlWaypointHeadingParam.java
New file
@@ -0,0 +1,23 @@
package com.ard.route.kmz.domain.kml;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import lombok.Data;
@Data
@XStreamAlias("wpml:waypointHeadingParam")
public class KmlWaypointHeadingParam {
    @XStreamAlias("wpml:waypointHeadingMode")
    private String waypointHeadingMode;
    @XStreamAlias("wpml:waypointHeadingAngle")
    private String waypointHeadingAngle;
    @XStreamAlias("wpml:waypointPoiPoint")
    private String waypointPoiPoint;
    @XStreamAlias("wpml:waypointHeadingPathMode")
    private String waypointHeadingPathMode;
}
ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlWaypointTurnParam.java
New file
@@ -0,0 +1,16 @@
package com.ard.route.kmz.domain.kml;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import lombok.Data;
@Data
@XStreamAlias("wpml:waypointTurnParam")
public class KmlWaypointTurnParam {
    @XStreamAlias("wpml:waypointTurnMode")
    private String waypointTurnMode;
    @XStreamAlias("wpml:waypointTurnDampingDist")
    private String waypointTurnDampingDist;
}
ard-route/src/main/java/com/ard/route/kmz/domain/kml/RoutePointInfo.java
New file
@@ -0,0 +1,79 @@
package com.ard.route.kmz.domain.kml;
import com.ard.route.kmz.domain.PointActionReq;
import com.ard.route.kmz.domain.WaypointHeadingReq;
import com.ard.route.kmz.domain.WaypointTurnReq;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
@Data
public class RoutePointInfo implements Serializable {
    /**
     * 航点编号
     */
    private Integer routePointIndex;
    /**
     * 经度
     */
    private Double longitude;
    /**
     * 纬度
     */
    private Double latitude;
    /**
     * 高度
     */
    private Double height;
    /**
     * 飞行速度
     */
    private Double speed;
    /**
     * 航点偏航角
     */
    private WaypointHeadingReq waypointHeadingReq;
    /**
     * 航点转弯模式
     */
    private WaypointTurnReq waypointTurnReq;
    /**
     * 航点云台俯仰角
     */
    private Double gimbalPitchAngle;
    /**
     * 航点动作列表
     */
    private List<PointActionReq> actions;
    /**
     * 是否首尾航点(首尾航点不能是协调转弯类型)
     */
    private Boolean isStartAndEndPoint = false;
    /**
     * 等时拍照间隔时间 单位s
     */
    private Double timeInterval;
    /**
     * 等距拍照间隔距离 单位m
     */
    private Double distanceInterval;
    /**
     * 停止间隔拍照航点编号
     */
    private Integer endIntervalRouteIndex;
}
ard-route/src/main/java/com/ard/route/kmz/enums/kml/ActionActuatorFuncEnums.java
New file
@@ -0,0 +1,45 @@
package com.ard.route.kmz.enums.kml;
/**
 * wpml:actionActuatorFunc     动作类型
 */
public enum ActionActuatorFuncEnums {
    TAKE_PHOTO("takePhoto", "单拍"),
    START_RECORD("startRecord", "开始录像"),
    STOP_RECORD("stopRecord", "结束录像"),
    FOCUS("focus", "对焦"),
    ZOOM("zoom", "变焦"),
    CUSTOM_DIRNAME("customDirName", "创建新文件夹"),
    GIMBAL_ROTATE("gimbalRotate", "旋转云台"),
    ROTATE_YAW("rotateYaw", "飞行器偏航"),
    HOVER("hover", "悬停等待"),
    GIMBAL_EVENLY_ROTATE("gimbalEvenlyRotate", "航段间均匀转动云台pitch角"),
    ORIENTED_SHOOT("orientedShoot", "精准复拍动作"),
    PANO_SHOT("panoShot", "全景拍照动作"),
    RECORD_POINT_CLOUD("recordPointCloud", "点云录制操作");
    private String value;
    private String description;
    ActionActuatorFuncEnums(String value, String description) {
        this.value = value;
        this.description = description;
    }
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
}
ard-route/src/main/java/com/ard/route/kmz/enums/kml/ActionGroupModeEnums.java
New file
@@ -0,0 +1,34 @@
package com.ard.route.kmz.enums.kml;
/**
 * wpml:actionGroupMode     动作执行模式
 */
public enum ActionGroupModeEnums {
//    MANUAL("manual", "手动控制"),
    SEQUENCE("sequence", "串行执行。即动作组内的动作依次按顺序执行");
    private String value;
    private String description;
    ActionGroupModeEnums(String value, String description) {
        this.value = value;
        this.description = description;
    }
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
}
ard-route/src/main/java/com/ard/route/kmz/enums/kml/ActionTriggerTypeEnums.java
New file
@@ -0,0 +1,36 @@
package com.ard.route.kmz.enums.kml;
/**
 * wpml:actionTriggerType     动作触发器类型
 */
public enum ActionTriggerTypeEnums {
    REACH_POINT("reachPoint", "到达航点时执行"),
    BETWEEN_ADJACENT_POINTS("betweenAdjacentPoints", "航段触发,均匀转云台"),
    MULTIPLE_TIMING("multipleTiming", "等时触发"),
    MULTIPLE_DISTANCE("multipleDistance", "等距触发");
    private String value;
    private String description;
    ActionTriggerTypeEnums(String value, String description) {
        this.value = value;
        this.description = description;
    }
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
}
ard-route/src/main/java/com/ard/route/kmz/enums/kml/AircraftPathModeEnums.java
New file
@@ -0,0 +1,34 @@
package com.ard.route.kmz.enums.kml;
/**
 * wpml:aircraftPathMode     飞行器偏航角转动模式
 */
public enum AircraftPathModeEnums {
    CLOCKWISE("clockwise", "顺时针旋转"),
    COUNTER_CLOCKWISE("counterClockwise", "逆时针旋转");
    private String value;
    private String description;
    AircraftPathModeEnums(String value, String description) {
        this.value = value;
        this.description = description;
    }
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
}
ard-route/src/main/java/com/ard/route/kmz/enums/kml/CollectionMethodEnums.java
New file
@@ -0,0 +1,35 @@
package com.ard.route.kmz.enums.kml;
/**
 * wpml:overlap     采集类型
 */
public enum CollectionMethodEnums {
    ORTHO("ortho", "正射采集"),
    INCLINED("inclined", "倾斜采集")
    ;
    private String value;
    private String description;
    CollectionMethodEnums(String value, String description) {
        this.value = value;
        this.description = description;
    }
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
}
ard-route/src/main/java/com/ard/route/kmz/enums/kml/DroneEnumValueEnums.java
New file
@@ -0,0 +1,37 @@
package com.ard.route.kmz.enums.kml;
/**
 * wpml:droneEnumValue     飞行器机型主类型
 */
public enum DroneEnumValueEnums {
    M350_RTK(89, "M350 RTK"),
    M300_RTK(60, "M300 RTK"),
    M30_M30T(67, "M30/M30T"),
    M3E_M3T_M3M(77, "M3E/M3T/M3M"),
    M3D_M3TD(91, "M3D/M3TD");
    private Integer value;
    private String description;
    DroneEnumValueEnums(Integer value, String description) {
        this.value = value;
        this.description = description;
    }
    public Integer getValue() {
        return value;
    }
    public void setValue(Integer value) {
        this.value = value;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
}
ard-route/src/main/java/com/ard/route/kmz/enums/kml/ExecuteHeightModeEnums.java
New file
@@ -0,0 +1,36 @@
package com.ard.route.kmz.enums.kml;
/**
 * wpml:executeHeightMode 执行高度模式
 * 该元素仅在waylines.wpml中使用。
 */
public enum ExecuteHeightModeEnums {
    WGS84("WGS84", "椭球高模式"),
    RELATIVE_TO_START_POINT("relativeToStartPoint", "相对起飞点高度模式"),
    REALTIME_FOLLOW_SURFACE("realTimeFollowSurface", "使用实时仿地模式,仅支持M3E/M3T/M3M");
    private String value;
    private String description;
    ExecuteHeightModeEnums(String value, String description) {
        this.value = value;
        this.description = description;
    }
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
}
ard-route/src/main/java/com/ard/route/kmz/enums/kml/ExecuteRCLostActionEnums.java
New file
@@ -0,0 +1,36 @@
package com.ard.route.kmz.enums.kml;
/**
 * wpml:executeRCLostAction     失控动作类型
 * 当 wpml:exitOnRCLost为 executeLostAction 时为必需元素
 */
public enum ExecuteRCLostActionEnums {
    GO_BACK("goBack", "返航"),
    LANDING("landing", "降落"),
    HOVER("hover", "悬停");
    private String value;
    private String description;
    ExecuteRCLostActionEnums(String value, String description) {
        this.value = value;
        this.description = description;
    }
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
}
ard-route/src/main/java/com/ard/route/kmz/enums/kml/ExitOnRCLostEnums.java
New file
@@ -0,0 +1,34 @@
package com.ard.route.kmz.enums.kml;
/**
 * wpml:exitOnRCLost 失控是否继续执行航线
 */
public enum ExitOnRCLostEnums {
    GO_CONTINUE("goContinue", "继续执行航线"),
    EXECUTE_LOST_ACTION("executeLostAction", "退出航线,执行失控动作");
    private String value;
    private String description;
    ExitOnRCLostEnums(String value, String description) {
        this.value = value;
        this.description = description;
    }
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
}
ard-route/src/main/java/com/ard/route/kmz/enums/kml/FinishActionEnums.java
New file
@@ -0,0 +1,37 @@
package com.ard.route.kmz.enums.kml;
/**
 * wpml:finishAction 航线结束动作
 * 注:动作执行过程,若飞行器退出了航线模式且进入失控状态,则会优先执行失控动作。
 */
public enum FinishActionEnums {
    GO_HOME("goHome", "飞行器完成航线任务后,退出航线模式并返航"),
    NO_ACTION("noAction", "飞行器完成航线任务后,退出航线模式"),
    AUTO_LAND("autoLand", "飞行器完成航线任务后,退出航线模式并原地降落"),
    GOTO_FIRST_WAYPOINT("gotoFirstWaypoint", "飞行器完成航线任务后,立即飞向航线起始点,到达后退出航线模式");
    private String value;
    private String description;
    FinishActionEnums(String value, String description) {
        this.value = value;
        this.description = description;
    }
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
}
ard-route/src/main/java/com/ard/route/kmz/enums/kml/FlyToWaylineModeEnums.java
New file
@@ -0,0 +1,34 @@
package com.ard.route.kmz.enums.kml;
/**
 * wpml:flyToWaylineMode 飞向首航点模式
 */
public enum FlyToWaylineModeEnums {
    SAFELY("safely", "安全模式"),
    POINT_TO_POINT("pointToPoint", "倾斜飞行模式");
    private String value;
    private String description;
    FlyToWaylineModeEnums(String value, String description) {
        this.value = value;
        this.description = description;
    }
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
}
ard-route/src/main/java/com/ard/route/kmz/enums/kml/FocusModeEnums.java
New file
@@ -0,0 +1,34 @@
package com.ard.route.kmz.enums.kml;
/**
 * wpml:focusMode         负载对焦模式
 */
public enum FocusModeEnums {
    FIRST_POINT("firstPoint", "首个航点自动对焦"),
    CUSTOM("custom", "标定对焦值对焦");
    private String value;
    private String description;
    FocusModeEnums(String value, String description) {
        this.value = value;
        this.description = description;
    }
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
}
ard-route/src/main/java/com/ard/route/kmz/enums/kml/GimbalPitchModeEnums.java
New file
@@ -0,0 +1,34 @@
package com.ard.route.kmz.enums.kml;
/**
 * wpml:gimbalPitchMode     云台俯仰角控制模式
 */
public enum GimbalPitchModeEnums {
    MANUAL("manual", "手动控制"),
    USE_POINT_SETTING("usePointSetting", "依照每个航点设置");
    private String value;
    private String description;
    GimbalPitchModeEnums(String value, String description) {
        this.value = value;
        this.description = description;
    }
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
}
ard-route/src/main/java/com/ard/route/kmz/enums/kml/GlobalWaypointTurnModeEnums.java
New file
@@ -0,0 +1,36 @@
package com.ard.route.kmz.enums.kml;
/**
 * wpml:globalWaypointTurnMode     全局航点类型(全局航点转弯模式)
 */
public enum GlobalWaypointTurnModeEnums {
    COORDINATE_TURN("coordinateTurn", "协调转弯,不过点,提前转弯"),
    TO_POINT_AND_STOP_WITH_DISCONTINUITY_CURVATURE("toPointAndStopWithDiscontinuityCurvature", "直线飞行,飞行器到点停"),
    TO_POINT_AND_STOP_WITH_CONTINUITY_CURVATURE("toPointAndStopWithContinuityCurvature", "曲线飞行,飞行器到点停"),
    TO_POINT_AND_PASS_WITH_CONTINUITY_CURVATURE("toPointAndPassWithContinuityCurvature", "曲线飞行,飞行器过点不停");
    private String value;
    private String description;
    GlobalWaypointTurnModeEnums(String value, String description) {
        this.value = value;
        this.description = description;
    }
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
}
ard-route/src/main/java/com/ard/route/kmz/enums/kml/HeightModeEnums.java
New file
@@ -0,0 +1,36 @@
package com.ard.route.kmz.enums.kml;
/**
 * wpml:heightMode     航点高程参考平面
 */
public enum HeightModeEnums {
    EGM96("EGM96", "使用海拔高编辑"),
    RELATIVE_TO_START_POINT("relativeToStartPoint", "使用相对点的高度进行编辑"),
    ABOVE_GROUND_LEVEL("aboveGroundLevel", "使用地形数据,AGL下编辑(仅支持司空2平台)"),
    REALTIME_FOLLOW_SURFACE("realTimeFollowSurface", "使用实时仿地模式(仅用于建图航拍模版),仅支持M3E/M3T/M3M机型");
    private String value;
    private String description;
    HeightModeEnums(String value, String description) {
        this.value = value;
        this.description = description;
    }
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
}
ard-route/src/main/java/com/ard/route/kmz/enums/kml/ImageFormatEnums.java
New file
@@ -0,0 +1,37 @@
package com.ard.route.kmz.enums.kml;
/**
 * wpml:imageFormat         图片格式列表
 */
public enum ImageFormatEnums {
    WIDE("wide", "存储广角镜头照片"),
    ZOOM("zoom", "存储变焦镜头照片"),
    IR("ir", "存储红外镜头照片"),
    NARROW_BAND("narrow_band", "存储窄带镜头拍摄照片"),
    VISABLE("visable", "可见光照片");
    private String value;
    private String description;
    ImageFormatEnums(String value, String description) {
        this.value = value;
        this.description = description;
    }
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
}
ard-route/src/main/java/com/ard/route/kmz/enums/kml/LensTypeEnums.java
New file
@@ -0,0 +1,35 @@
package com.ard.route.kmz.enums.kml;
/**
 * wpml:overlap     采集类型
 */
public enum LensTypeEnums {
    LIDAR("lidar", "激光"),
    CAMERA("camera", "可见光")
    ;
    private String value;
    private String description;
    LensTypeEnums(String value, String description) {
        this.value = value;
        this.description = description;
    }
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
}
ard-route/src/main/java/com/ard/route/kmz/enums/kml/MeteringModeEnums.java
New file
@@ -0,0 +1,34 @@
package com.ard.route.kmz.enums.kml;
/**
 * wpml:meteringMode         负载测光模式
 */
public enum MeteringModeEnums {
    AVERAGE("average", "全局测光"),
    SPOT("spot", "点测光");
    private String value;
    private String description;
    MeteringModeEnums(String value, String description) {
        this.value = value;
        this.description = description;
    }
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
}
ard-route/src/main/java/com/ard/route/kmz/enums/kml/PayloadPositionIndexEnums.java
New file
@@ -0,0 +1,35 @@
package com.ard.route.kmz.enums.kml;
/**
 * wpml:payloadPositionIndex     负载挂载位置
 */
public enum PayloadPositionIndexEnums {
    ZERO(0, "飞行器1号挂载位置。M300 RTK,M350 RTK机型,对应机身左前方。其它机型,对应主云台"),
    ONE(1, "飞行器2号挂载位置。M300 RTK,M350 RTK机型,对应机身右前方"),
    TWO(2, "飞行器3号挂载位置。M300 RTK,M350 RTK机型,对应机身上方");
    private Integer value;
    private String description;
    PayloadPositionIndexEnums(Integer value, String description) {
        this.value = value;
        this.description = description;
    }
    public Integer getValue() {
        return value;
    }
    public void setValue(Integer value) {
        this.value = value;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
}
ard-route/src/main/java/com/ard/route/kmz/enums/kml/PayloadTypeEnums.java
New file
@@ -0,0 +1,45 @@
package com.ard.route.kmz.enums.kml;
/**
 * wpml:payloadEnumValue     负载机型主类型
 */
public enum PayloadTypeEnums {
    H20(42, "H20"),
    H20T(43, "H20T"),
    M30(52, "M30双光相机"),
    M30T(53, "M30T三光相机"),
    H20N(61, "H20N"),
    MAVIC_3E(66, "Mavic 3E 相机"),
    MAVIC_3T(67, "Mavic 3T 相机"),
    MAVIC_3M(68, "Mavic 3M 相机"),
    MATRICE_3D(80, "Matrice 3D 相机"),
    MATRICE_3TD(81, "Matrice 3TD 相机"),
    PSDK(65534, "PSDK 负载"),
    H30(82, "H30"),
    H30T(83, "H30T");
    private Integer value;
    private String description;
    PayloadTypeEnums(Integer value, String description) {
        this.value = value;
        this.description = description;
    }
    public Integer getValue() {
        return value;
    }
    public void setValue(Integer value) {
        this.value = value;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
}
ard-route/src/main/java/com/ard/route/kmz/enums/kml/PositioningTypeEnums.java
New file
@@ -0,0 +1,36 @@
package com.ard.route.kmz.enums.kml;
/**
 * wpml:positioningType     经纬度与高度数据源
 */
public enum PositioningTypeEnums {
    GPS("GPS", "位置数据采集来源为GPS/BDS/GLONASS/GALILEO等"),
    RTK_BASE_STATION("RTKBaseStation", "采集位置数据时,使用RTK基站进行差分定位"),
    QIAN_XUN("QianXun", "采集位置数据时,使用千寻网络RTK进行差分定位"),
    CUSTOM("Custom", "采集位置数据时,使用自定义网络RTK进行差分定位");
    private String value;
    private String description;
    PositioningTypeEnums(String value, String description) {
        this.value = value;
        this.description = description;
    }
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
}
ard-route/src/main/java/com/ard/route/kmz/enums/kml/ReturnModeEnums.java
New file
@@ -0,0 +1,35 @@
package com.ard.route.kmz.enums.kml;
/**
 * wpml:returnMode         激光雷达回波模式
 */
public enum ReturnModeEnums {
    SINGLE_RETURN_STRONGEST("singleReturnStrongest", "单回波"),
    DUAL_RETURN("dualReturn", "双回波"),
    TRIPLE_RETURN("tripleReturn", "三回波");
    private String value;
    private String description;
    ReturnModeEnums(String value, String description) {
        this.value = value;
        this.description = description;
    }
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
}
ard-route/src/main/java/com/ard/route/kmz/enums/kml/ScanningModeEnums.java
New file
@@ -0,0 +1,34 @@
package com.ard.route.kmz.enums.kml;
/**
 * wpml:scanningMode         负载扫描模式
 */
public enum ScanningModeEnums {
    REPETITIVE("repetitive", "重复扫描"),
    NON_REPETITIVE("nonRepetitive", "非重复扫描");
    private String value;
    private String description;
    ScanningModeEnums(String value, String description) {
        this.value = value;
        this.description = description;
    }
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
}
ard-route/src/main/java/com/ard/route/kmz/enums/kml/ShootTypeEnums.java
New file
@@ -0,0 +1,35 @@
package com.ard.route.kmz.enums.kml;
/**
 * wpml:shootType 拍照模式(定时或定距)
 */
public enum ShootTypeEnums {
    TIME("time", "等时间拍照"),
    DISTANCE("distance", "等间隔拍照")
    ;
    private String value;
    private String description;
    ShootTypeEnums(String value, String description) {
        this.value = value;
        this.description = description;
    }
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
}
ard-route/src/main/java/com/ard/route/kmz/enums/kml/TemplateTypeEnums.java
New file
@@ -0,0 +1,36 @@
package com.ard.route.kmz.enums.kml;
/**
 * wpml:templateType     预定义模板类型
 */
public enum TemplateTypeEnums {
    WAYPOINT("waypoint", "航点飞行"),
    MAPPING2D("mapping2d", "建图航拍"),
    MAPPING3D("mapping3d", "倾斜摄影"),
    MAPPING_STRIP("mappingStrip", "航带飞行");
    private String value;
    private String description;
    TemplateTypeEnums(String value, String description) {
        this.value = value;
        this.description = description;
    }
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
}
ard-route/src/main/java/com/ard/route/kmz/enums/kml/WaypointHeadingModeEnums.java
New file
@@ -0,0 +1,37 @@
package com.ard.route.kmz.enums.kml;
/**
 * wpml:waypointHeadingMode     飞行器偏航角模式
 */
public enum WaypointHeadingModeEnums {
    FOLLOW_WAYLINE("followWayline", "沿航线方向。飞行器机头沿着航线方向飞至下一航点"),
    MANUALLY("manually", "手动控制。飞行器在飞至下一航点的过程中,用户可以手动控制飞行器机头朝向"),
    FIXED("fixed", "锁定当前偏航角。飞行器机头保持执行完航点动作后的飞行器偏航角飞至下一航点"),
    SMOOTH_TRANSITION("smoothTransition", "自定义。通过“wpml:waypointHeadingAngle”给定某航点的目标偏航角,并在航段飞行过程中均匀过渡至下一航点的目标偏航角。"),
    TOWARD_POI("towardPOI", "朝向兴趣点");
    private String value;
    private String description;
    WaypointHeadingModeEnums(String value, String description) {
        this.value = value;
        this.description = description;
    }
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
}
ard-route/src/main/java/com/ard/route/kmz/enums/kml/WaypointHeadingPathModeEnums.java
New file
@@ -0,0 +1,35 @@
package com.ard.route.kmz.enums.kml;
/**
 * wpml:waypointHeadingPathMode     飞行器偏航角转动方向
 */
public enum WaypointHeadingPathModeEnums {
    CLOCKWISE("clockwise", "顺时针旋转飞行器偏航角"),
    COUNTER_CLOCKWISE("counterClockwise", "逆时针旋转飞行器偏航角"),
    FOLLOW_BAD_ARC("followBadArc", "沿最短路径旋转飞行器偏航角");
    private String value;
    private String description;
    WaypointHeadingPathModeEnums(String value, String description) {
        this.value = value;
        this.description = description;
    }
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
}
ard-route/src/main/java/com/ard/route/kmz/service/UavRouteService.java
New file
@@ -0,0 +1,17 @@
package com.ard.route.kmz.service;
import com.ard.route.kmz.domain.UavRouteReq;
public interface UavRouteService {
    /**
     * 编辑kmz文件
     */
    void updateKmz(UavRouteReq uavRouteReq);
    /**
     * 生成kmz文件(带航点)
     */
    void buildKmz(UavRouteReq uavRouteReq);
}
ard-route/src/main/java/com/ard/route/kmz/service/impl/UavRouteServiceImpl.java
New file
@@ -0,0 +1,108 @@
package com.ard.route.kmz.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.io.FileUtil;
import com.ard.route.kmz.domain.kml.*;
import com.ard.route.kmz.util.RouteFileUtils;
import com.ard.route.kmz.constant.FileTypeConstants;
import com.ard.route.kmz.domain.RoutePointReq;
import com.ard.route.kmz.domain.UavRouteReq;
import com.ard.route.kmz.domain.WaypointHeadingReq;
import com.ard.route.kmz.domain.WaypointTurnReq;
import com.ard.route.kmz.enums.kml.ExitOnRCLostEnums;
import com.ard.route.kmz.service.UavRouteService;
import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.ArchiveInputStream;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
 * Author:songjian
 * Date: 2024/12/22 10:36
 **/
@Service
public class UavRouteServiceImpl implements UavRouteService {
    @Override
    public void updateKmz(UavRouteReq uavRouteReq) {
        // TODO 替换本地文件路径!!!
        File file = FileUtil.file("/Users/songjian/Project/IdeaProjects/dj-uav/file/kmz/航线kmz文件.kmz");
        try (ArchiveInputStream archiveInputStream = new ZipArchiveInputStream(FileUtil.getInputStream(file))) {
            ArchiveEntry entry;
            KmlInfo kmlInfo = new KmlInfo();
            KmlInfo wpmlInfo = new KmlInfo();
            KmlParams kmlParams = new KmlParams();
            while (!Objects.isNull(entry = archiveInputStream.getNextEntry())) {
                String name = entry.getName();
                if (name.toLowerCase().endsWith(".kml")) {
                    kmlInfo = RouteFileUtils.parseKml(archiveInputStream);
                    buildKmlParams(kmlParams, kmlInfo);
                    this.handleRouteUpdate(kmlInfo, uavRouteReq, FileTypeConstants.KML, kmlParams);
                } else if (name.toLowerCase().endsWith(".wpml")) {
                    wpmlInfo = RouteFileUtils.parseKml(archiveInputStream);
                    this.handleRouteUpdate(wpmlInfo, uavRouteReq, FileTypeConstants.WPML, kmlParams);
                }
            }
            RouteFileUtils.buildKmz("更新航线kmz文件", kmlInfo, wpmlInfo);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private static void buildKmlParams(KmlParams kmlParams, KmlInfo kmlInfo) {
        KmlFolder folder = kmlInfo.getDocument().getFolder();
        kmlParams.setGlobalHeight(Double.valueOf(kmlInfo.getDocument().getKmlMissionConfig().getGlobalRTHHeight()));
        kmlParams.setAutoFlightSpeed(Double.valueOf(folder.getAutoFlightSpeed()));
        WaypointHeadingReq waypointHeadingReq = new WaypointHeadingReq();
        waypointHeadingReq.setWaypointHeadingMode(folder.getGlobalWaypointHeadingParam().getWaypointHeadingMode());
        waypointHeadingReq.setWaypointHeadingAngle(StringUtils.isNotBlank(folder.getGlobalWaypointHeadingParam().getWaypointHeadingAngle()) ?
                Double.valueOf(folder.getGlobalWaypointHeadingParam().getWaypointHeadingAngle()) : null);
        waypointHeadingReq.setWaypointPoiPoint(StringUtils.isNotBlank(folder.getGlobalWaypointHeadingParam().getWaypointPoiPoint()) ? folder.getGlobalWaypointHeadingParam().getWaypointPoiPoint() : null);
        kmlParams.setWaypointHeadingReq(waypointHeadingReq);
        WaypointTurnReq waypointTurnReq = new WaypointTurnReq();
        waypointTurnReq.setWaypointTurnMode(folder.getGlobalWaypointTurnMode());
        waypointTurnReq.setUseStraightLine(StringUtils.isNotBlank(folder.getGlobalUseStraightLine()) ? Integer.valueOf(folder.getGlobalUseStraightLine()) : null);
        kmlParams.setWaypointTurnReq(waypointTurnReq);
        kmlParams.setGimbalPitchMode(folder.getGimbalPitchMode());
        kmlParams.setPayloadPosition(Integer.valueOf(kmlInfo.getDocument().getKmlMissionConfig().getPayloadInfo().getPayloadPositionIndex()));
        kmlParams.setImageFormat(folder.getPayloadParam().getImageFormat());
    }
    private void handleRouteUpdate(KmlInfo kmlInfo, UavRouteReq uavRouteReq, String fileType, KmlParams kmlParams) {
        if (StringUtils.isNotBlank(uavRouteReq.getFinishAction())) {
            kmlInfo.getDocument().getKmlMissionConfig().setFinishAction(uavRouteReq.getFinishAction());
        }
        if (StringUtils.isNotBlank(uavRouteReq.getExitOnRcLostAction())) {
            kmlInfo.getDocument().getKmlMissionConfig().setExitOnRCLost(ExitOnRCLostEnums.EXECUTE_LOST_ACTION.getValue());
            kmlInfo.getDocument().getKmlMissionConfig().setExecuteRCLostAction(uavRouteReq.getExitOnRcLostAction());
        }
        if (CollectionUtil.isNotEmpty(uavRouteReq.getRoutePointList())) {
            List<KmlPlacemark> placemarkList = new ArrayList<>();
            for (RoutePointReq routePointReq : uavRouteReq.getRoutePointList()) {
                RoutePointInfo routePointInfo = BeanUtil.copyProperties(routePointReq, RoutePointInfo.class);
                KmlPlacemark kmlPlacemark = RouteFileUtils.buildKmlPlacemark(routePointInfo, kmlParams, fileType);
                placemarkList.add(kmlPlacemark);
            }
            kmlInfo.getDocument().getFolder().setPlacemarkList(placemarkList);
        }
    }
    @Override
    public void buildKmz(UavRouteReq uavRouteReq) {
        KmlParams kmlParams = new KmlParams();
        BeanUtils.copyProperties(uavRouteReq, kmlParams);
        kmlParams.setRoutePointList(BeanUtil.copyToList(uavRouteReq.getRoutePointList(), RoutePointInfo.class));
        RouteFileUtils.buildKmz("航线kmz文件AAAAAA", kmlParams);
    }
}
ard-route/src/main/java/com/ard/route/kmz/util/Gps.java
New file
@@ -0,0 +1,19 @@
package com.ard.route.kmz.util;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class Gps {
    /**
     * 经度
     */
    private double wgLon;
    /**
     * 纬度
     */
    private double wgLat;
}
ard-route/src/main/java/com/ard/route/kmz/util/PositionUtils.java
New file
@@ -0,0 +1,153 @@
package com.ard.route.kmz.util;
/**
 * 各地图API坐标系统比较与转换;
 *
 * WGS84坐标系:即地球坐标系,国际上通用的坐标系。设备一般包含GPS芯片或者北斗芯片获取的经纬度为WGS84地理坐标系,
 * 谷歌地图采用的是WGS84地理坐标系(中国范围除外);
 *
 * GCJ02坐标系:即火星坐标系,是由中国国家测绘局制订的地理信息系统的坐标系统。由WGS84坐标系经加密后的坐标系。
 * 高德地图、腾讯地图、谷歌中国地图和搜搜中国地图采用的是GCJ02地理坐标系;
 *
 * BD09坐标系:即百度坐标系,GCJ02坐标系经加密后的坐标系;
 *
 * 搜狗坐标系、图吧坐标系等,估计也是在GCJ02基础上加密而成的。
 *
 */
public class PositionUtils {
    private static double pi = 3.1415926535897932384626;
    private static double a = 6378245.0;
    private static double ee = 0.00669342162296594323;
    /**
     * 84 to 火星坐标系 (GCJ-02)
     * <p>
     * World Geodetic System ==> Mars Geodetic System
     *
     * @param lat
     * @param lon
     * @return
     */
    public static Gps gps84_To_Gcj02(double lat, double lon) {
        if (outOfChina(lat, lon)) {
            return null;
        }
        double dLat = transformLat(lon - 105.0, lat - 35.0);
        double dLon = transformLon(lon - 105.0, lat - 35.0);
        double radLat = lat / 180.0 * pi;
        double magic = Math.sin(radLat);
        magic = 1 - ee * magic * magic;
        double sqrtMagic = Math.sqrt(magic);
        dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
        dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi);
        double mgLat = lat + dLat;
        double mgLon = lon + dLon;
        return new Gps(mgLat, mgLon);
    }
    /**
     * 火星坐标系 (GCJ-02) to 84
     *
     * @param lon
     * @param lat
     * @return
     */
    public static Gps gcj02_To_Gps84(double lat, double lon) {
        Gps gps = transform(lat, lon);
        double lontitude = lon * 2 - gps.getWgLon();
        double latitude = lat * 2 - gps.getWgLat();
        return new Gps(latitude, lontitude);
    }
    /**
     * 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换算法
     * <p>
     * 将 GCJ-02 坐标转换成 BD-09 坐标
     *
     * @param gg_lat
     * @param gg_lon
     */
    public static Gps gcj02_To_Bd09(double gg_lat, double gg_lon) {
        double x = gg_lon, y = gg_lat;
        double z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * pi);
        double theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * pi);
        double bd_lon = z * Math.cos(theta) + 0.0065;
        double bd_lat = z * Math.sin(theta) + 0.006;
        return new Gps(bd_lat, bd_lon);
    }
    /**
     * 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换算法
     * <p>
     * 将 BD-09 坐标转换成GCJ-02 坐标
     *
     * @param bd_lat
     * @param bd_lon
     * @return
     */
    public static Gps bd09_To_Gcj02(double bd_lat, double bd_lon) {
        double x = bd_lon - 0.0065, y = bd_lat - 0.006;
        double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * pi);
        double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * pi);
        double gg_lon = z * Math.cos(theta);
        double gg_lat = z * Math.sin(theta);
        return new Gps(gg_lat, gg_lon);
    }
    private static boolean outOfChina(double lat, double lon) {
        if (lon < 72.004 || lon > 137.8347)
            return true;
        if (lat < 0.8293 || lat > 55.8271)
            return true;
        return false;
    }
    private static Gps transform(double lat, double lon) {
        if (outOfChina(lat, lon)) {
            return new Gps(lat, lon);
        }
        double dLat = transformLat(lon - 105.0, lat - 35.0);
        double dLon = transformLon(lon - 105.0, lat - 35.0);
        double radLat = lat / 180.0 * pi;
        double magic = Math.sin(radLat);
        magic = 1 - ee * magic * magic;
        double sqrtMagic = Math.sqrt(magic);
        dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
        dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi);
        double mgLat = lat + dLat;
        double mgLon = lon + dLon;
        return new Gps(mgLat, mgLon);
    }
    private static double transformLat(double x, double y) {
        double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y
                + 0.2 * Math.sqrt(Math.abs(x));
        ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
        ret += (20.0 * Math.sin(y * pi) + 40.0 * Math.sin(y / 3.0 * pi)) * 2.0 / 3.0;
        ret += (160.0 * Math.sin(y / 12.0 * pi) + 320 * Math.sin(y * pi / 30.0)) * 2.0 / 3.0;
        return ret;
    }
    private static double transformLon(double x, double y) {
        double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1
                * Math.sqrt(Math.abs(x));
        ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
        ret += (20.0 * Math.sin(x * pi) + 40.0 * Math.sin(x / 3.0 * pi)) * 2.0 / 3.0;
        ret += (150.0 * Math.sin(x / 12.0 * pi) + 300.0 * Math.sin(x / 30.0
                * pi)) * 2.0 / 3.0;
        return ret;
    }
}
ard-route/src/main/java/com/ard/route/kmz/util/RouteFileUtils.java
New file
@@ -0,0 +1,598 @@
package com.ard.route.kmz.util;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.ard.route.kmz.domain.*;
import com.ard.route.kmz.domain.kml.*;
import com.ard.route.kmz.enums.kml.*;
import com.ard.route.kmz.constant.FileTypeConstants;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import org.apache.commons.lang3.StringUtils;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
 * 航线文件操作工具类
 */
public class RouteFileUtils {
    /**
     * XML 头部
     */
    private static final String XML_HEADER = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
    /**
     * 生成的本地 kmz 文件存储路径
     */
    private static final String LOCAL_KMZ_FILE_PATH = "file" + File.separator + "kmz" + File.separator;
    /**
     * kml文件解析
     *
     * @param inputStream
     * @return KmlInfo
     */
    public static KmlInfo parseKml(InputStream inputStream) {
        XStream xStream = new XStream();
        xStream.allowTypes(new Class[]{KmlInfo.class, KmlAction.class, KmlWayLineCoordinateSysParam.class, KmlPoint.class});
        xStream.alias("kml", KmlInfo.class);
        xStream.processAnnotations(KmlInfo.class);
        xStream.autodetectAnnotations(true);
        xStream.ignoreUnknownElements();
        xStream.addImplicitCollection(KmlActionGroup.class, "action");
        return (KmlInfo) xStream.fromXML(inputStream);
    }
    /**
     * 生成航线 KMZ 文件
     *
     * @param fileName  文件名
     * @param kmlParams 参数对象
     * @return 本地文件路径
     */
    public static String buildKmz(String fileName, KmlParams kmlParams) {
        KmlInfo kmlInfo = buildKml(kmlParams);
        KmlInfo wpmlInfo = buildWpml(kmlParams);
        return buildKmz(fileName, kmlInfo, wpmlInfo);
    }
    /**
     * 生成航线 KMZ 文件
     *
     * @param fileName 文件名
     * @param kmlInfo  kml 文件信息
     * @param wpmlInfo wpml 文件信息
     * @return 本地文件路径
     */
    public static String buildKmz(String fileName, KmlInfo kmlInfo, KmlInfo wpmlInfo) {
        XStream xStream = new XStream(new DomDriver());
        xStream.processAnnotations(KmlInfo.class);
        xStream.addImplicitCollection(KmlActionGroup.class, "action");
        String kml = XML_HEADER + xStream.toXML(kmlInfo);
        String wpml = XML_HEADER + xStream.toXML(wpmlInfo);
        try (FileOutputStream fileOutputStream = new FileOutputStream(LOCAL_KMZ_FILE_PATH + fileName + ".kmz");
             ZipOutputStream zipOutputStream = new ZipOutputStream(fileOutputStream)) {
            zipOutputStream.setLevel(0); // 0 表示不压缩,存储方式
            // 创建 wpmz 目录中的 template.kml 文件条目
            buildZipFile("wpmz/template.kml", zipOutputStream, kml);
            // 创建 wpmz 目录中的 waylines.wpml 文件条目
            buildZipFile("wpmz/waylines.wpml", zipOutputStream, wpml);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return LOCAL_KMZ_FILE_PATH + fileName + ".kmz";
    }
    private static void buildZipFile(String name, ZipOutputStream zipOutputStream, String content) throws IOException {
        ZipEntry kmlEntry = new ZipEntry(name);
        zipOutputStream.putNextEntry(kmlEntry);
        // 将内容写入 ZIP 条目
        try (ByteArrayInputStream inputStream = new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8))) {
            byte[] buffer = new byte[1024];
            int length;
            while ((length = inputStream.read(buffer)) >= 0) {
                zipOutputStream.write(buffer, 0, length);
            }
        }
        zipOutputStream.closeEntry(); // 关闭条目
    }
    public static KmlInfo buildKml(KmlParams kmlParams) {
        KmlInfo kmlInfo = new KmlInfo();
        kmlInfo.setDocument(buildKmlDocument(FileTypeConstants.KML, kmlParams));
        return kmlInfo;
    }
    public static KmlInfo buildWpml(KmlParams kmlParams) {
        KmlInfo kmlInfo = new KmlInfo();
        kmlInfo.setDocument(buildKmlDocument(FileTypeConstants.WPML, kmlParams));
        return kmlInfo;
    }
    public static KmlDocument buildKmlDocument(String fileType, KmlParams kmlParams) {
        KmlDocument kmlDocument = new KmlDocument();
        if (StringUtils.equals(fileType, FileTypeConstants.KML)) {
            kmlDocument.setAuthor("Cleaner");
            kmlDocument.setCreateTime(String.valueOf(DateUtil.current()));
            kmlDocument.setUpdateTime(String.valueOf(DateUtil.current()));
        }
        kmlDocument.setKmlMissionConfig(buildKmlMissionConfig(kmlParams));
        kmlDocument.setFolder(buildKmlFolder(fileType, kmlParams));
        return kmlDocument;
    }
    public static KmlMissionConfig buildKmlMissionConfig(KmlParams kmlParams) {
        KmlMissionConfig kmlMissionConfig = new KmlMissionConfig();
        kmlMissionConfig.setFlyToWayLineMode(FlyToWaylineModeEnums.SAFELY.getValue());
        kmlMissionConfig.setFinishAction(kmlParams.getFinishAction());
        if (StringUtils.isNotBlank(kmlParams.getExitOnRcLostAction())) {
            kmlMissionConfig.setExitOnRCLost(ExitOnRCLostEnums.EXECUTE_LOST_ACTION.getValue());
            kmlMissionConfig.setExecuteRCLostAction(kmlParams.getExitOnRcLostAction());
        } else {
            kmlMissionConfig.setExitOnRCLost(ExitOnRCLostEnums.GO_CONTINUE.getValue());
        }
        kmlMissionConfig.setTakeOffSecurityHeight("20");
        kmlMissionConfig.setGlobalTransitionalSpeed("15");
        kmlMissionConfig.setGlobalRTHHeight("100");
        kmlMissionConfig.setTakeOffRefPoint(kmlParams.getTakeOffRefPoint());
        kmlMissionConfig.setDroneInfo(buildKmlDroneInfo(kmlParams.getDroneType(), kmlParams.getSubDroneType()));
        kmlMissionConfig.setPayloadInfo(buildKmlPayloadInfo(kmlParams.getPayloadType(), kmlParams.getPayloadPosition()));
        return kmlMissionConfig;
    }
    public static KmlDroneInfo buildKmlDroneInfo(Integer droneType, Integer subDroneType) {
        KmlDroneInfo kmlDroneInfo = new KmlDroneInfo();
        kmlDroneInfo.setDroneEnumValue(String.valueOf(droneType));
        if (Objects.equals(droneType, DroneEnumValueEnums.M30_M30T.getValue()) ||
                Objects.equals(droneType, DroneEnumValueEnums.M3D_M3TD.getValue()) ||
                Objects.equals(droneType, DroneEnumValueEnums.M3E_M3T_M3M.getValue())) {
            kmlDroneInfo.setDroneSubEnumValue(String.valueOf(subDroneType));
        }
        return kmlDroneInfo;
    }
    public static KmlPayloadInfo buildKmlPayloadInfo(Integer payloadType, Integer payloadPosition) {
        KmlPayloadInfo kmlPayloadInfo = new KmlPayloadInfo();
        kmlPayloadInfo.setPayloadEnumValue(String.valueOf(payloadType));
        kmlPayloadInfo.setPayloadPositionIndex(String.valueOf(payloadPosition));
        return kmlPayloadInfo;
    }
    public static KmlFolder buildKmlFolder(String fileType, KmlParams kmlParams) {
        KmlFolder kmlFolder = new KmlFolder();
        kmlFolder.setTemplateId("0");
        kmlFolder.setAutoFlightSpeed(String.valueOf(kmlParams.getAutoFlightSpeed()));
        if (StringUtils.equals(fileType, FileTypeConstants.KML)) {
            kmlFolder.setTemplateType(kmlParams.getTemplateType());
            kmlFolder.setWaylineCoordinateSysParam(buildKmlWayLineCoordinateSysParam(TemplateTypeEnums.WAYPOINT.getValue()));
            kmlFolder.setPayloadParam(buildKmlPayloadParam(kmlParams));
        }
        if (StringUtils.equals(fileType, FileTypeConstants.WPML)) {
            kmlFolder.setWaylineId("0");
            kmlFolder.setExecuteHeightMode(ExecuteHeightModeEnums.RELATIVE_TO_START_POINT.getValue());
            // TODO 航线初始动作
        }
        // 航点类型模板航线配置
        if (StringUtils.equals(kmlFolder.getTemplateType(), TemplateTypeEnums.WAYPOINT.getValue())) {
            WaypointTurnReq waypointTurnReq = kmlParams.getWaypointTurnReq();
            kmlFolder.setGlobalWaypointTurnMode(waypointTurnReq.getWaypointTurnMode());
            if (StringUtils.equals(waypointTurnReq.getWaypointTurnMode(), GlobalWaypointTurnModeEnums.TO_POINT_AND_STOP_WITH_CONTINUITY_CURVATURE.getValue()) ||
                    StringUtils.equals(waypointTurnReq.getWaypointTurnMode(), GlobalWaypointTurnModeEnums.TO_POINT_AND_PASS_WITH_CONTINUITY_CURVATURE.getValue())) {
                kmlFolder.setGlobalUseStraightLine("1");
            }
            kmlFolder.setGimbalPitchMode(kmlParams.getGimbalPitchMode());
            kmlFolder.setGlobalHeight(String.valueOf(kmlParams.getGlobalHeight()));
            WaypointHeadingReq waypointHeadingReq = kmlParams.getWaypointHeadingReq();
            kmlFolder.setGlobalWaypointHeadingParam(buildKmlGlobalWaypointHeadingParam(waypointHeadingReq.getWaypointHeadingMode(), waypointHeadingReq.getWaypointHeadingAngle(), waypointHeadingReq.getWaypointPoiPoint()));
            // 构建航点
            List<RoutePointInfo> routePointList = kmlParams.getRoutePointList();
            if (CollectionUtil.isNotEmpty(routePointList)) {
                routePointList.stream()
                        .min(Comparator.comparing(RoutePointInfo::getRoutePointIndex))
                        .ifPresent(routePointInfo -> routePointInfo.setIsStartAndEndPoint(Boolean.TRUE));
                routePointList.stream()
                        .max(Comparator.comparing(RoutePointInfo::getRoutePointIndex))
                        .ifPresent(routePointInfo -> routePointInfo.setIsStartAndEndPoint(Boolean.TRUE));
                List<KmlPlacemark> kmlPlacemarkList = new ArrayList<>();
                for (RoutePointInfo routePointInfo : routePointList) {
                    kmlPlacemarkList.add(buildKmlPlacemark(routePointInfo, kmlParams, fileType));
                }
                kmlFolder.setPlacemarkList(kmlPlacemarkList);
            }
        } else {
            if (StringUtils.equals(fileType, FileTypeConstants.KML)) {
                List<KmlPlacemark> kmlPlacemarkList = new ArrayList<>();
                kmlPlacemarkList.add(buildMappingKmlPlacemark(kmlParams));
                kmlFolder.setPlacemarkList(kmlPlacemarkList);
            } else {
                // 构建航点
                List<RoutePointInfo> routePointList = kmlParams.getRoutePointList();
                if (CollectionUtil.isNotEmpty(routePointList)) {
                    List<KmlPlacemark> kmlPlacemarkList = new ArrayList<>();
                    for (RoutePointInfo routePointInfo : routePointList) {
//                        ActionTriggerReq actionTriggerReq = new ActionTriggerReq();
//                        actionTriggerReq.setActionTriggerType(StringUtils.equals(kmlParams.getMappingTypeReq().getShootType(), ShootTypeEnums.TIME.getValue()) ?
//                                ActionTriggerTypeEnums.MULTIPLE_TIMING.getValue() :
//                                ActionTriggerTypeEnums.MULTIPLE_DISTANCE.getValue());
//                        actionTriggerReq.setActionTriggerParam(2.0);
//                        RoutePointInfo.setActionTriggerReq(actionTriggerReq);
                        kmlPlacemarkList.add(buildKmlPlacemark(routePointInfo, kmlParams, fileType));
                    }
                    kmlFolder.setPlacemarkList(kmlPlacemarkList);
                }
            }
        }
        return kmlFolder;
    }
    public static KmlWayLineCoordinateSysParam buildKmlWayLineCoordinateSysParam(String templateType) {
        KmlWayLineCoordinateSysParam kmlWayLineCoordinateSysParam = new KmlWayLineCoordinateSysParam();
        kmlWayLineCoordinateSysParam.setCoordinateMode("WGS84");
        kmlWayLineCoordinateSysParam.setHeightMode(HeightModeEnums.RELATIVE_TO_START_POINT.getValue());
        kmlWayLineCoordinateSysParam.setPositioningType(PositioningTypeEnums.GPS.getValue());
        if (StringUtils.equals(templateType, TemplateTypeEnums.MAPPING2D.getValue()) ||
                StringUtils.equals(templateType, TemplateTypeEnums.MAPPING3D.getValue()) ||
                StringUtils.equals(templateType, TemplateTypeEnums.MAPPING_STRIP.getValue())) {
            kmlWayLineCoordinateSysParam.setGlobalShootHeight("50");
            kmlWayLineCoordinateSysParam.setSurfaceFollowModeEnable("1");
            kmlWayLineCoordinateSysParam.setSurfaceRelativeHeight("100");
        }
        return kmlWayLineCoordinateSysParam;
    }
    public static KmlPayloadParam buildKmlPayloadParam(KmlParams kmlParams) {
        KmlPayloadParam kmlPayloadParam = new KmlPayloadParam();
        kmlPayloadParam.setPayloadPositionIndex(String.valueOf(kmlParams.getPayloadPosition()));
        kmlPayloadParam.setFocusMode(FocusModeEnums.FIRST_POINT.getValue());
        kmlPayloadParam.setMeteringMode(MeteringModeEnums.AVERAGE.getValue());
        // 0:不开启 1:开启
        kmlPayloadParam.setDewarpingEnable("1");
        kmlPayloadParam.setReturnMode(ReturnModeEnums.SINGLE_RETURN_STRONGEST.getValue());
        // 60000、80000、120000、160000、180000、240000
        kmlPayloadParam.setSamplingRate("240000");
        kmlPayloadParam.setScanningMode(ScanningModeEnums.REPETITIVE.getValue());
        // 0: 不上色 1: 真彩上色
        kmlPayloadParam.setModelColoringEnable("1");
        kmlPayloadParam.setImageFormat(kmlParams.getImageFormat());
        return kmlPayloadParam;
    }
    public static KmlGlobalWaypointHeadingParam buildKmlGlobalWaypointHeadingParam(String waypointHeadingMode, Double waypointHeadingAngle, String waypointPoiPoint) {
        KmlGlobalWaypointHeadingParam kmlGlobalWaypointHeadingParam = new KmlGlobalWaypointHeadingParam();
        kmlGlobalWaypointHeadingParam.setWaypointHeadingMode(waypointHeadingMode);
        if (StringUtils.equals(waypointHeadingMode, WaypointHeadingModeEnums.SMOOTH_TRANSITION.getValue())) {
            kmlGlobalWaypointHeadingParam.setWaypointHeadingAngle(String.valueOf(waypointHeadingAngle));
        }
        if (StringUtils.equals(waypointHeadingMode, WaypointHeadingModeEnums.TOWARD_POI.getValue())) {
            kmlGlobalWaypointHeadingParam.setWaypointPoiPoint(waypointPoiPoint);
        }
        kmlGlobalWaypointHeadingParam.setWaypointHeadingPathMode(WaypointHeadingPathModeEnums.FOLLOW_BAD_ARC.getValue());
        return kmlGlobalWaypointHeadingParam;
    }
    public static KmlPlacemark buildKmlPlacemark(RoutePointInfo routePointInfo, KmlParams kmlParams, String fileType) {
        KmlPlacemark kmlPlacemark = new KmlPlacemark();
        kmlPlacemark.setIsRisky("0");
        kmlPlacemark.setKmlPoint(buildKmlPoint(String.valueOf(routePointInfo.getLongitude()), String.valueOf(routePointInfo.getLatitude())));
        kmlPlacemark.setIndex(String.valueOf(routePointInfo.getRoutePointIndex()));
        handleHeight(routePointInfo, kmlParams, fileType, kmlPlacemark);
        handleSpeed(routePointInfo, kmlParams, fileType, kmlPlacemark);
        handleWaypointHeadingParam(routePointInfo, kmlParams, fileType, kmlPlacemark);
        handleWaypointTurnParam(routePointInfo, kmlParams, fileType, kmlPlacemark);
        if (StringUtils.equals(fileType, FileTypeConstants.KML)) {
            if (ObjectUtil.isNotEmpty(routePointInfo.getGimbalPitchAngle()) && StringUtils.equals(kmlParams.getGimbalPitchMode(), GimbalPitchModeEnums.USE_POINT_SETTING.getValue())) {
                kmlPlacemark.setGimbalPitchAngle(String.valueOf(routePointInfo.getGimbalPitchAngle()));
            }
        }
        if (CollectionUtil.isNotEmpty(routePointInfo.getActions())) {
            kmlPlacemark.setActionGroup(buildKmlActionGroup(routePointInfo, kmlParams));
        }
        return kmlPlacemark;
    }
    private static KmlPlacemark buildMappingKmlPlacemark(KmlParams kmlParams) {
        KmlPlacemark kmlPlacemark = new KmlPlacemark();
        MappingTypeReq mappingTypeReq = kmlParams.getMappingTypeReq();
        kmlPlacemark.setCaliFlightEnable("0");
        kmlPlacemark.setElevationOptimizeEnable(String.valueOf(mappingTypeReq.getElevationOptimizeEnable()));
        kmlPlacemark.setSmartObliqueEnable("0");
        kmlPlacemark.setShootType(mappingTypeReq.getShootType());
        kmlPlacemark.setDirection(mappingTypeReq.getDirection());
        kmlPlacemark.setMargin(mappingTypeReq.getMargin());
        kmlPlacemark.setOverlap(buildKmlOverlap(mappingTypeReq.getCollectionMethod(), mappingTypeReq.getLensType(), mappingTypeReq.getOverlapH(), mappingTypeReq.getOverlapW()));
        kmlPlacemark.setEllipsoidHeight(String.valueOf(kmlParams.getGlobalHeight()));
        kmlPlacemark.setHeight(String.valueOf(kmlParams.getGlobalHeight()));
        kmlPlacemark.setFacadeWaylineEnable("0");
        kmlPlacemark.setPolygon(buildKmlPolygon(mappingTypeReq.getCoordinates()));
        return kmlPlacemark;
    }
    private static KmlOverlap buildKmlOverlap(String collectionMethod, String lensType, Integer overlapH, Integer overlapW) {
        KmlOverlap overlap = new KmlOverlap();
        if (StringUtils.equals(collectionMethod, CollectionMethodEnums.ORTHO.getValue())) {
            if (StringUtils.equals(lensType, LensTypeEnums.LIDAR.getValue())) {
                overlap.setOrthoLidarOverlapH(String.valueOf(overlapH));
                overlap.setOrthoLidarOverlapW(String.valueOf(overlapW));
            } else {
                overlap.setOrthoCameraOverlapH(String.valueOf(overlapH));
                overlap.setOrthoCameraOverlapW(String.valueOf(overlapW));
            }
        } else {
            if (StringUtils.equals(lensType, LensTypeEnums.LIDAR.getValue())) {
                overlap.setInclinedLidarOverlapH(String.valueOf(overlapH));
                overlap.setInclinedCameraOverlapW(String.valueOf(overlapW));
            } else {
                overlap.setInclinedCameraOverlapH(String.valueOf(overlapH));
                overlap.setInclinedCameraOverlapW(String.valueOf(overlapW));
            }
        }
        return overlap;
    }
    private static KmlPolygon buildKmlPolygon(List<CoordinatePointReq> coordinatePointReqList) {
        KmlPolygon kmlPolygon = new KmlPolygon();
        KmlLinearRing kmlLinearRing = new KmlLinearRing();
        String coordinates = coordinatePointReqList.stream().map(point -> point.getLongitude() + "," + point.getLatitude() + "," + point.getHeight())
                .collect(Collectors.joining(", "));
        kmlLinearRing.setCoordinates(StringUtils.join(coordinates, " "));
        KmlOuterBoundaryIs kmlOuterBoundaryIs = new KmlOuterBoundaryIs();
        kmlOuterBoundaryIs.setLinearRing(kmlLinearRing);
        kmlPolygon.setOuterBoundaryIs(kmlOuterBoundaryIs);
        return kmlPolygon;
    }
    private static void handleWaypointTurnParam(RoutePointInfo routePointInfo, KmlParams kmlParams, String fileType, KmlPlacemark kmlPlacemark) {
        WaypointTurnReq waypointTurnReq = routePointInfo.getWaypointTurnReq();
        // 使用全局航点转弯模式
        if (ObjectUtil.isNotEmpty(waypointTurnReq)) {
            if (StringUtils.equals(fileType, FileTypeConstants.KML)) {
                kmlPlacemark.setUseGlobalTurnParam("0");
            }
            kmlPlacemark.setWaypointTurnParam(buildKmlWaypointTurnParam(waypointTurnReq.getWaypointTurnMode(),
                    waypointTurnReq.getWaypointTurnDampingDist(), waypointTurnReq.getUseStraightLine(), routePointInfo.getIsStartAndEndPoint()));
            if (ObjectUtil.isNotEmpty(waypointTurnReq.getUseStraightLine())) {
                kmlPlacemark.setUseStraightLine(String.valueOf(waypointTurnReq.getUseStraightLine()));
            }
        } else {
            // 使用自定义航点转弯模式
            if (StringUtils.equals(fileType, FileTypeConstants.KML)) {
                kmlPlacemark.setUseGlobalTurnParam("1");
            } else if (StringUtils.equals(fileType, FileTypeConstants.WPML)) {
                WaypointTurnReq globalWaypoint = kmlParams.getWaypointTurnReq();
                kmlPlacemark.setWaypointTurnParam(buildKmlWaypointTurnParam(globalWaypoint.getWaypointTurnMode(),
                        globalWaypoint.getWaypointTurnDampingDist(), globalWaypoint.getUseStraightLine(), routePointInfo.getIsStartAndEndPoint()));
            }
        }
    }
    private static void handleWaypointHeadingParam(RoutePointInfo routePointInfo, KmlParams kmlParams, String fileType, KmlPlacemark kmlPlacemark) {
        WaypointHeadingReq waypointHeadingReq = routePointInfo.getWaypointHeadingReq();
        if (ObjectUtil.isNotEmpty(waypointHeadingReq)) {
            if (StringUtils.equals(fileType, FileTypeConstants.KML)) {
                kmlPlacemark.setUseGlobalHeadingParam("0");
            }
            kmlPlacemark.setWaypointHeadingParam(buildKmlWaypointHeadingParam(waypointHeadingReq.getWaypointHeadingMode(), waypointHeadingReq.getWaypointHeadingAngle(), waypointHeadingReq.getWaypointPoiPoint()));
        } else {
            if (StringUtils.equals(fileType, FileTypeConstants.KML)) {
                kmlPlacemark.setUseGlobalHeadingParam("1");
            } else if (StringUtils.equals(fileType, FileTypeConstants.WPML)) {
                WaypointHeadingReq globalWaypointHeading = kmlParams.getWaypointHeadingReq();
                kmlPlacemark.setWaypointHeadingParam(buildKmlWaypointHeadingParam(globalWaypointHeading.getWaypointHeadingMode(), globalWaypointHeading.getWaypointHeadingAngle(), globalWaypointHeading.getWaypointPoiPoint()));
            }
        }
    }
    private static void handleSpeed(RoutePointInfo routePointInfo, KmlParams kmlParams, String fileType, KmlPlacemark kmlPlacemark) {
        if (ObjectUtil.isNotEmpty(routePointInfo.getSpeed())) {
            if (StringUtils.equals(fileType, FileTypeConstants.KML)) {
                kmlPlacemark.setUseGlobalSpeed("0");
            }
            kmlPlacemark.setWaypointSpeed(String.valueOf(routePointInfo.getSpeed()));
        } else {
            if (StringUtils.equals(fileType, FileTypeConstants.KML)) {
                kmlPlacemark.setUseGlobalSpeed("1");
            } else if (StringUtils.equals(fileType, FileTypeConstants.WPML)) {
                kmlPlacemark.setWaypointSpeed(String.valueOf(kmlParams.getAutoFlightSpeed()));
            }
        }
    }
    private static void handleHeight(RoutePointInfo routePointInfo, KmlParams kmlParams, String fileType, KmlPlacemark kmlPlacemark) {
        if (ObjectUtil.isNotEmpty(routePointInfo.getHeight())) {
            if (StringUtils.equals(fileType, FileTypeConstants.KML)) {
                kmlPlacemark.setUseGlobalHeight("0");
                kmlPlacemark.setEllipsoidHeight(String.valueOf(routePointInfo.getHeight()));
                kmlPlacemark.setHeight(String.valueOf(routePointInfo.getHeight()));
            } else if (StringUtils.equals(fileType, FileTypeConstants.WPML)) {
                kmlPlacemark.setExecuteHeight(String.valueOf(routePointInfo.getHeight()));
            }
        } else {
            if (StringUtils.equals(fileType, FileTypeConstants.KML)) {
                kmlPlacemark.setUseGlobalHeight("1");
            } else if (StringUtils.equals(fileType, FileTypeConstants.WPML)) {
                kmlPlacemark.setExecuteHeight(String.valueOf(kmlParams.getGlobalHeight()));
            }
        }
    }
    public static KmlPoint buildKmlPoint(String longitude, String latitude) {
        KmlPoint kmlPoint = new KmlPoint();
        kmlPoint.setCoordinates(longitude + "," + latitude);
        return kmlPoint;
    }
    public static KmlWaypointHeadingParam buildKmlWaypointHeadingParam(String waypointHeadingMode, Double waypointHeadingAngle, String waypointPoiPoint) {
        KmlWaypointHeadingParam kmlWaypointHeadingParam = new KmlWaypointHeadingParam();
        kmlWaypointHeadingParam.setWaypointHeadingMode(waypointHeadingMode);
        if (StringUtils.equals(waypointHeadingMode, WaypointHeadingModeEnums.SMOOTH_TRANSITION.getValue())) {
            kmlWaypointHeadingParam.setWaypointHeadingAngle(String.valueOf(waypointHeadingAngle));
        }
        if (StringUtils.equals(waypointHeadingMode, WaypointHeadingModeEnums.TOWARD_POI.getValue())) {
            kmlWaypointHeadingParam.setWaypointPoiPoint(waypointPoiPoint);
        }
        kmlWaypointHeadingParam.setWaypointHeadingPathMode(WaypointHeadingPathModeEnums.FOLLOW_BAD_ARC.getValue());
        return kmlWaypointHeadingParam;
    }
    public static KmlWaypointTurnParam buildKmlWaypointTurnParam(String waypointTurnMode, Double waypointTurnDampingDist, Integer useStraightLine, Boolean startAndEndPoint) {
        KmlWaypointTurnParam kmlWaypointTurnParam = new KmlWaypointTurnParam();
        // 首尾航点不能是协调转弯类型
        if (startAndEndPoint && StringUtils.equals(waypointTurnMode, GlobalWaypointTurnModeEnums.COORDINATE_TURN.getValue())) {
            kmlWaypointTurnParam.setWaypointTurnMode(GlobalWaypointTurnModeEnums.TO_POINT_AND_STOP_WITH_DISCONTINUITY_CURVATURE.getValue());
        } else {
            kmlWaypointTurnParam.setWaypointTurnMode(waypointTurnMode);
        }
        if ((StringUtils.equals(waypointTurnMode, GlobalWaypointTurnModeEnums.COORDINATE_TURN.getValue()) ||
                StringUtils.equals(waypointTurnMode, GlobalWaypointTurnModeEnums.TO_POINT_AND_PASS_WITH_CONTINUITY_CURVATURE.getValue())) &&
                ObjectUtil.equals(useStraightLine, 1)) {
            kmlWaypointTurnParam.setWaypointTurnDampingDist(String.valueOf(waypointTurnDampingDist));
        }
        return kmlWaypointTurnParam;
    }
    public static KmlActionGroup buildKmlActionGroup(RoutePointInfo routePointInfo, KmlParams kmlParams) {
        KmlActionGroup kmlActionGroup = new KmlActionGroup();
        kmlActionGroup.setActionGroupId(String.valueOf(routePointInfo.getRoutePointIndex()));
        kmlActionGroup.setActionGroupStartIndex(String.valueOf(routePointInfo.getRoutePointIndex()));
        kmlActionGroup.setActionGroupEndIndex(String.valueOf(ObjectUtil.isNotNull(routePointInfo.getEndIntervalRouteIndex()) ?
                routePointInfo.getEndIntervalRouteIndex() : routePointInfo.getRoutePointIndex()));
        kmlActionGroup.setActionGroupMode(ActionGroupModeEnums.SEQUENCE.getValue());
        String actionTriggerType = ActionTriggerTypeEnums.REACH_POINT.getValue();
        Double actionTriggerParam = 0.0;
        if (ObjectUtil.isNotNull(routePointInfo.getTimeInterval())) {
            actionTriggerType = ActionTriggerTypeEnums.MULTIPLE_TIMING.getValue();
            actionTriggerParam = routePointInfo.getTimeInterval();
        } else if (ObjectUtil.isNotNull(routePointInfo.getDistanceInterval())) {
            actionTriggerType = ActionTriggerTypeEnums.MULTIPLE_DISTANCE.getValue();
            actionTriggerParam = routePointInfo.getDistanceInterval();
        }
        kmlActionGroup.setActionTrigger(buildKmlActionTrigger(actionTriggerType, actionTriggerParam));
        List<KmlAction> kmlActionList = new ArrayList<>();
        for (PointActionReq pointActionReq : routePointInfo.getActions()) {
            if (ObjectUtil.isNotNull(pointActionReq.getHoverTime())) {
                kmlActionList.add(buildKmlAction(String.valueOf(pointActionReq.getActionIndex()), ActionActuatorFuncEnums.HOVER.getValue(), pointActionReq, kmlParams));
            } else if (ObjectUtil.isNotNull(pointActionReq.getAircraftHeading())) {
                kmlActionList.add(buildKmlAction(String.valueOf(pointActionReq.getActionIndex()), ActionActuatorFuncEnums.ROTATE_YAW.getValue(), pointActionReq, kmlParams));
            } else if (ObjectUtil.isNotNull(pointActionReq.getTakePhotoType()) && ObjectUtil.equals(pointActionReq.getTakePhotoType(), 0)) {
                kmlActionList.add(buildKmlAction(String.valueOf(pointActionReq.getActionIndex()), ActionActuatorFuncEnums.TAKE_PHOTO.getValue(), pointActionReq, kmlParams));
            } else if ((ObjectUtil.isNotNull(pointActionReq.getGimbalYawRotateAngle())) || (ObjectUtil.isNotNull(pointActionReq.getGimbalPitchRotateAngle()))) {
                kmlActionList.add(buildKmlAction(String.valueOf(pointActionReq.getActionIndex()), ActionActuatorFuncEnums.GIMBAL_ROTATE.getValue(), pointActionReq, kmlParams));
            } else if (ObjectUtil.isNotNull(pointActionReq.getZoom())) {
                kmlActionList.add(buildKmlAction(String.valueOf(pointActionReq.getActionIndex()), ActionActuatorFuncEnums.ZOOM.getValue(), pointActionReq, kmlParams));
            } else if (ObjectUtil.isNotNull(pointActionReq.getTakePhotoType()) && ObjectUtil.equals(pointActionReq.getTakePhotoType(), 1)) {
                kmlActionList.add(buildKmlAction(String.valueOf(pointActionReq.getActionIndex()), ActionActuatorFuncEnums.PANO_SHOT.getValue(), pointActionReq, kmlParams));
            } else if (ObjectUtil.isNotNull(pointActionReq.getStartRecord()) && pointActionReq.getStartRecord()) {
                kmlActionList.add(buildKmlAction(String.valueOf(pointActionReq.getActionIndex()), ActionActuatorFuncEnums.START_RECORD.getValue(), pointActionReq, kmlParams));
            } else if (ObjectUtil.isNotNull(pointActionReq.getStopRecord()) && pointActionReq.getStopRecord()) {
                kmlActionList.add(buildKmlAction(String.valueOf(pointActionReq.getActionIndex()), ActionActuatorFuncEnums.STOP_RECORD.getValue(), pointActionReq, kmlParams));
            }
        }
        kmlActionGroup.setAction(kmlActionList);
        return kmlActionGroup;
    }
    public static KmlActionTrigger buildKmlActionTrigger(String actionTriggerType, Double actionTriggerParam) {
        KmlActionTrigger kmlActionTrigger = new KmlActionTrigger();
        kmlActionTrigger.setActionTriggerType(actionTriggerType);
        if (StringUtils.equals(actionTriggerType, ActionTriggerTypeEnums.MULTIPLE_TIMING.getValue()) ||
                StringUtils.equals(actionTriggerType, ActionTriggerTypeEnums.MULTIPLE_DISTANCE.getValue())) {
            kmlActionTrigger.setActionTriggerParam(String.valueOf(actionTriggerParam));
        }
        return kmlActionTrigger;
    }
    public static KmlAction buildKmlAction(String actionId, String actionActuatorFunc, PointActionReq pointActionReq, KmlParams kmlParams) {
        KmlAction kmlAction = new KmlAction();
        kmlAction.setActionId(actionId);
        kmlAction.setActionActuatorFunc(actionActuatorFunc);
        kmlAction.setActionActuatorFuncParam(buildKmlActionActuatorFuncParam(actionActuatorFunc, pointActionReq, kmlParams));
        return kmlAction;
    }
    public static KmlActionActuatorFuncParam buildKmlActionActuatorFuncParam(String actionActuatorFunc, PointActionReq pointActionReq, KmlParams kmlParams) {
        KmlActionActuatorFuncParam kmlActionActuatorFuncParam = new KmlActionActuatorFuncParam();
        if (StringUtils.equals(actionActuatorFunc, ActionActuatorFuncEnums.TAKE_PHOTO.getValue()) ||
                StringUtils.equals(actionActuatorFunc, ActionActuatorFuncEnums.START_RECORD.getValue())) {
            kmlActionActuatorFuncParam.setPayloadPositionIndex(String.valueOf(kmlParams.getPayloadPosition()));
            kmlActionActuatorFuncParam.setFileSuffix("");
            kmlActionActuatorFuncParam.setUseGlobalPayloadLensIndex(String.valueOf(pointActionReq.getUseGlobalImageFormat()));
            if (ObjectUtil.equals(pointActionReq.getUseGlobalImageFormat(), 0)) {
                kmlActionActuatorFuncParam.setPayloadLensIndex(pointActionReq.getImageFormat());
            } else {
                kmlActionActuatorFuncParam.setPayloadLensIndex(kmlParams.getImageFormat());
            }
        } else if (StringUtils.equals(actionActuatorFunc, ActionActuatorFuncEnums.STOP_RECORD.getValue())) {
            kmlActionActuatorFuncParam.setPayloadPositionIndex(String.valueOf(kmlParams.getPayloadPosition()));
        } else if (StringUtils.equals(actionActuatorFunc, ActionActuatorFuncEnums.GIMBAL_ROTATE.getValue())) {
            kmlActionActuatorFuncParam.setPayloadPositionIndex(String.valueOf(kmlParams.getPayloadPosition()));
            kmlActionActuatorFuncParam.setGimbalHeadingYawBase("north");
            kmlActionActuatorFuncParam.setGimbalRotateMode("absoluteAngle");
            if (!Objects.isNull(pointActionReq.getGimbalPitchRotateAngle())) {
                kmlActionActuatorFuncParam.setGimbalPitchRotateEnable("1");
                kmlActionActuatorFuncParam.setGimbalPitchRotateAngle(String.valueOf(pointActionReq.getGimbalPitchRotateAngle()));
            } else {
                kmlActionActuatorFuncParam.setGimbalPitchRotateEnable("0");
                kmlActionActuatorFuncParam.setGimbalPitchRotateAngle("0");
            }
            kmlActionActuatorFuncParam.setGimbalRollRotateEnable("0");
            kmlActionActuatorFuncParam.setGimbalRollRotateAngle("0");
            if (!Objects.isNull(pointActionReq.getGimbalYawRotateAngle())) {
                kmlActionActuatorFuncParam.setGimbalYawRotateEnable("1");
                kmlActionActuatorFuncParam.setGimbalYawRotateAngle(String.valueOf(pointActionReq.getGimbalYawRotateAngle()));
            } else {
                kmlActionActuatorFuncParam.setGimbalYawRotateEnable("0");
                kmlActionActuatorFuncParam.setGimbalYawRotateAngle("0");
            }
            kmlActionActuatorFuncParam.setGimbalRotateTimeEnable("0");
            kmlActionActuatorFuncParam.setGimbalRotateTime("0");
        } else if (StringUtils.equals(actionActuatorFunc, ActionActuatorFuncEnums.ROTATE_YAW.getValue())) {
            kmlActionActuatorFuncParam.setAircraftHeading(String.valueOf(pointActionReq.getAircraftHeading()));
            kmlActionActuatorFuncParam.setAircraftPathMode(AircraftPathModeEnums.CLOCKWISE.getValue());
        } else if (StringUtils.equals(actionActuatorFunc, ActionActuatorFuncEnums.HOVER.getValue())) {
            kmlActionActuatorFuncParam.setHoverTime(String.valueOf(pointActionReq.getHoverTime()));
        } else if (StringUtils.equals(actionActuatorFunc, ActionActuatorFuncEnums.ZOOM.getValue())) {
            kmlActionActuatorFuncParam.setPayloadPositionIndex(String.valueOf(kmlParams.getPayloadPosition()));
            kmlActionActuatorFuncParam.setFocalLength(String.valueOf(pointActionReq.getZoom()));
        } else if (StringUtils.equals(actionActuatorFunc, ActionActuatorFuncEnums.PANO_SHOT.getValue())) {
            kmlActionActuatorFuncParam.setPayloadPositionIndex(String.valueOf(kmlParams.getPayloadPosition()));
            kmlActionActuatorFuncParam.setUseGlobalPayloadLensIndex(String.valueOf(pointActionReq.getUseGlobalImageFormat()));
            kmlActionActuatorFuncParam.setPanoShotSubMode("panoShot_360");
            if (ObjectUtil.equals(pointActionReq.getUseGlobalImageFormat(), 0)) {
                kmlActionActuatorFuncParam.setPayloadLensIndex(pointActionReq.getImageFormat());
            } else {
                kmlActionActuatorFuncParam.setPayloadLensIndex(kmlParams.getImageFormat());
            }
        }
        return kmlActionActuatorFuncParam;
    }
}
file/kmz/更新航线kmz文件.kmz
Binary files differ
file/kmz/航线kmz文件.kmz
Binary files differ