From 52039daeb631bc47cfd953f05c8a5c76aa199ede Mon Sep 17 00:00:00 2001
From: Xiajijian <1176061145@qq.com>
Date: Mon, 29 Sep 2025 14:46:22 +0800
Subject: [PATCH] 1.将生成kmz的文件的功能合并智云3.0.

---
 ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlPlacemark.java                  |  131 ++
 ard-route/src/main/java/com/ard/route/kmz/enums/kml/FocusModeEnums.java                 |   34 
 ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlInfo.java                       |   22 
 ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlParams.java                     |   95 +
 ard-route/src/main/java/com/ard/route/kmz/enums/kml/ActionGroupModeEnums.java           |   34 
 ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlPolygon.java                    |   12 
 ard-route/src/main/java/com/ard/route/kmz/domain/WaypointHeadingReq.java                |   28 
 ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlLineString.java                 |   13 
 ard-route/src/main/java/com/ard/route/kmz/enums/kml/ExecuteHeightModeEnums.java         |   36 
 ard-route/src/main/java/com/ard/route/kmz/enums/kml/ReturnModeEnums.java                |   35 
 ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlPayloadParam.java               |   41 
 ard-route/src/main/java/com/ard/route/kmz/enums/kml/PayloadPositionIndexEnums.java      |   35 
 ard-route/src/main/java/com/ard/route/kmz/domain/ActionTriggerReq.java                  |   24 
 ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlOuterBoundaryIs.java            |   12 
 ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlFolder.java                     |   56 +
 ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlPoint.java                      |   13 
 ard-route/src/main/java/com/ard/route/kmz/enums/kml/MeteringModeEnums.java              |   34 
 ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlActionActuatorFuncParam.java    |  161 ++
 ard-route/src/main/java/com/ard/route/kmz/enums/kml/ActionTriggerTypeEnums.java         |   36 
 ard-route/src/main/java/com/ard/route/kmz/domain/WaypointTurnReq.java                   |   30 
 ard-route/src/main/java/com/ard/route/kmz/enums/kml/ScanningModeEnums.java              |   34 
 ard-route/src/main/java/com/ard/route/kmz/enums/kml/WaypointHeadingPathModeEnums.java   |   35 
 ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlPayloadInfo.java                |   16 
 ard-route/src/main/java/com/ard/route/kmz/enums/kml/DroneEnumValueEnums.java            |   37 
 ard-route/src/main/java/com/ard/route/kmz/enums/kml/GlobalWaypointTurnModeEnums.java    |   36 
 ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlWaypointGimbalHeadingParam.java |   17 
 ard-route/src/main/java/com/ard/route/kmz/enums/kml/ActionActuatorFuncEnums.java        |   45 
 ard-route/src/main/java/com/ard/route/kmz/enums/kml/ExecuteRCLostActionEnums.java       |   36 
 ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlWayLineCoordinateSysParam.java  |   31 
 ard-route/src/main/java/com/ard/route/kmz/enums/kml/HeightModeEnums.java                |   36 
 ard-route/src/main/java/com/ard/route/kmz/enums/kml/AircraftPathModeEnums.java          |   34 
 ard-route/src/main/java/com/ard/route/kmz/service/UavRouteService.java                  |   17 
 ard-route/src/main/java/com/ard/route/kmz/domain/MappingTypeReq.java                    |   61 +
 ard-route/src/main/java/com/ard/route/kmz/enums/kml/ExitOnRCLostEnums.java              |   34 
 ard-route/src/main/java/com/ard/route/kmz/enums/kml/PayloadTypeEnums.java               |   45 
 ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlLinearRing.java                 |   13 
 ard-route/src/main/java/com/ard/route/kmz/service/impl/UavRouteServiceImpl.java         |  108 +
 ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlWaypointHeadingParam.java       |   23 
 ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlActionTrigger.java              |   17 
 ard-route/src/main/java/com/ard/route/kmz/enums/kml/ShootTypeEnums.java                 |   35 
 ard-route/src/main/java/com/ard/route/kmz/enums/kml/FinishActionEnums.java              |   37 
 ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlMissionConfig.java              |   43 
 ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlAction.java                     |   19 
 ard-route/src/main/java/com/ard/route/kmz/enums/kml/ImageFormatEnums.java               |   37 
 ard-route/src/main/java/com/ard/route/kmz/util/Gps.java                                 |   19 
 ard-route/src/main/java/com/ard/route/kmz/enums/kml/LensTypeEnums.java                  |   35 
 ard-route/src/main/java/com/ard/route/kmz/enums/kml/GimbalPitchModeEnums.java           |   34 
 ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlOverlap.java                    |   34 
 ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlDroneInfo.java                  |   16 
 ard-route/src/main/java/com/ard/route/kmz/enums/kml/PositioningTypeEnums.java           |   36 
 ard-route/src/main/java/com/ard/route/kmz/constant/FileTypeConstants.java               |   24 
 ard-route/src/main/java/com/ard/route/kmz/enums/kml/CollectionMethodEnums.java          |   35 
 ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlActionGroup.java                |   34 
 ard-route/src/main/java/com/ard/route/kmz/enums/kml/WaypointHeadingModeEnums.java       |   37 
 file/kmz/航线kmz文件.kmz                                                                    |    0 
 ard-route/src/main/java/com/ard/route/kmz/controller/UavRouteController.java            |   33 
 ard-route/src/main/java/com/ard/route/kmz/domain/PointActionReq.java                    |   68 +
 ard-route/src/main/java/com/ard/route/kmz/enums/kml/TemplateTypeEnums.java              |   36 
 ard-route/src/main/java/com/ard/route/kmz/domain/CoordinatePointReq.java                |   29 
 ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlWaypointTurnParam.java          |   16 
 ard-route/src/main/java/com/ard/route/kmz/domain/RoutePointReq.java                     |   78 +
 ard-route/src/main/java/com/ard/route/kmz/domain/kml/RoutePointInfo.java                |   79 +
 ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlGlobalWaypointHeadingParam.java |   23 
 ard-route/pom.xml                                                                       |   10 
 file/kmz/更新航线kmz文件.kmz                                                                  |    0 
 ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlDocument.java                   |   26 
 ard-route/src/main/java/com/ard/route/kmz/enums/kml/FlyToWaylineModeEnums.java          |   34 
 ard-route/src/main/java/com/ard/route/kmz/domain/UavRouteReq.java                       |   95 +
 ard-route/src/main/java/com/ard/route/kmz/util/PositionUtils.java                       |  153 ++
 ard-route/src/main/java/com/ard/route/kmz/util/RouteFileUtils.java                      |  598 ++++++++++
 70 files changed, 3,310 insertions(+), 0 deletions(-)

diff --git a/ard-route/pom.xml b/ard-route/pom.xml
index c02da71..25e8efc 100644
--- a/ard-route/pom.xml
+++ b/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>
 
diff --git a/ard-route/src/main/java/com/ard/route/kmz/constant/FileTypeConstants.java b/ard-route/src/main/java/com/ard/route/kmz/constant/FileTypeConstants.java
new file mode 100644
index 0000000..9340708
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/constant/FileTypeConstants.java
@@ -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";
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/controller/UavRouteController.java b/ard-route/src/main/java/com/ard/route/kmz/controller/UavRouteController.java
new file mode 100644
index 0000000..c2e1c9e
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/controller/UavRouteController.java
@@ -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);
+    }
+
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/domain/ActionTriggerReq.java b/ard-route/src/main/java/com/ard/route/kmz/domain/ActionTriggerReq.java
new file mode 100644
index 0000000..fe793ea
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/domain/ActionTriggerReq.java
@@ -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;
+
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/domain/CoordinatePointReq.java b/ard-route/src/main/java/com/ard/route/kmz/domain/CoordinatePointReq.java
new file mode 100644
index 0000000..b692a1f
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/domain/CoordinatePointReq.java
@@ -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;
+
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/domain/MappingTypeReq.java b/ard-route/src/main/java/com/ard/route/kmz/domain/MappingTypeReq.java
new file mode 100644
index 0000000..d88690b
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/domain/MappingTypeReq.java
@@ -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;
+
+
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/domain/PointActionReq.java b/ard-route/src/main/java/com/ard/route/kmz/domain/PointActionReq.java
new file mode 100644
index 0000000..ac0870e
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/domain/PointActionReq.java
@@ -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;
+
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/domain/RoutePointReq.java b/ard-route/src/main/java/com/ard/route/kmz/domain/RoutePointReq.java
new file mode 100644
index 0000000..ba528eb
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/domain/RoutePointReq.java
@@ -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;
+
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/domain/UavRouteReq.java b/ard-route/src/main/java/com/ard/route/kmz/domain/UavRouteReq.java
new file mode 100644
index 0000000..64d1917
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/domain/UavRouteReq.java
@@ -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;
+
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/domain/WaypointHeadingReq.java b/ard-route/src/main/java/com/ard/route/kmz/domain/WaypointHeadingReq.java
new file mode 100644
index 0000000..080fc23
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/domain/WaypointHeadingReq.java
@@ -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;
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/domain/WaypointTurnReq.java b/ard-route/src/main/java/com/ard/route/kmz/domain/WaypointTurnReq.java
new file mode 100644
index 0000000..1cd4f6e
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/domain/WaypointTurnReq.java
@@ -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;
+
+
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlAction.java b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlAction.java
new file mode 100644
index 0000000..653b2b4
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlAction.java
@@ -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;
+
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlActionActuatorFuncParam.java b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlActionActuatorFuncParam.java
new file mode 100644
index 0000000..fc40c11
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlActionActuatorFuncParam.java
@@ -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;
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlActionGroup.java b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlActionGroup.java
new file mode 100644
index 0000000..595dd9f
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlActionGroup.java
@@ -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;
+
+
+
+
+
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlActionTrigger.java b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlActionTrigger.java
new file mode 100644
index 0000000..7c8f07b
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlActionTrigger.java
@@ -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;
+
+
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlDocument.java b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlDocument.java
new file mode 100644
index 0000000..cbe125e
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlDocument.java
@@ -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;
+
+
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlDroneInfo.java b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlDroneInfo.java
new file mode 100644
index 0000000..d7b8d73
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlDroneInfo.java
@@ -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;
+
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlFolder.java b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlFolder.java
new file mode 100644
index 0000000..884dd4f
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlFolder.java
@@ -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;
+
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlGlobalWaypointHeadingParam.java b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlGlobalWaypointHeadingParam.java
new file mode 100644
index 0000000..c3867f4
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlGlobalWaypointHeadingParam.java
@@ -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;
+
+
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlInfo.java b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlInfo.java
new file mode 100644
index 0000000..678be78
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlInfo.java
@@ -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;
+
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlLineString.java b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlLineString.java
new file mode 100644
index 0000000..50a86db
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlLineString.java
@@ -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;
+
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlLinearRing.java b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlLinearRing.java
new file mode 100644
index 0000000..e41f28f
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlLinearRing.java
@@ -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;
+
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlMissionConfig.java b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlMissionConfig.java
new file mode 100644
index 0000000..13a3999
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlMissionConfig.java
@@ -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;
+
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlOuterBoundaryIs.java b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlOuterBoundaryIs.java
new file mode 100644
index 0000000..c61b3ea
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlOuterBoundaryIs.java
@@ -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;
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlOverlap.java b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlOverlap.java
new file mode 100644
index 0000000..49e31c1
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlOverlap.java
@@ -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;
+
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlParams.java b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlParams.java
new file mode 100644
index 0000000..4370f94
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlParams.java
@@ -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;
+}
+
diff --git a/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlPayloadInfo.java b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlPayloadInfo.java
new file mode 100644
index 0000000..95f3eee
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlPayloadInfo.java
@@ -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;
+
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlPayloadParam.java b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlPayloadParam.java
new file mode 100644
index 0000000..c127131
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlPayloadParam.java
@@ -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;
+
+
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlPlacemark.java b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlPlacemark.java
new file mode 100644
index 0000000..f3d4bcd
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlPlacemark.java
@@ -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;
+
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlPoint.java b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlPoint.java
new file mode 100644
index 0000000..13adf9f
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlPoint.java
@@ -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;
+
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlPolygon.java b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlPolygon.java
new file mode 100644
index 0000000..7c6b29c
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlPolygon.java
@@ -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;
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlWayLineCoordinateSysParam.java b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlWayLineCoordinateSysParam.java
new file mode 100644
index 0000000..d55754c
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlWayLineCoordinateSysParam.java
@@ -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;
+
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlWaypointGimbalHeadingParam.java b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlWaypointGimbalHeadingParam.java
new file mode 100644
index 0000000..0c96471
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlWaypointGimbalHeadingParam.java
@@ -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;
+
+
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlWaypointHeadingParam.java b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlWaypointHeadingParam.java
new file mode 100644
index 0000000..e484361
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlWaypointHeadingParam.java
@@ -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;
+
+
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlWaypointTurnParam.java b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlWaypointTurnParam.java
new file mode 100644
index 0000000..a8e98e0
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/KmlWaypointTurnParam.java
@@ -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;
+
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/domain/kml/RoutePointInfo.java b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/RoutePointInfo.java
new file mode 100644
index 0000000..a8c7251
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/domain/kml/RoutePointInfo.java
@@ -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;
+
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/enums/kml/ActionActuatorFuncEnums.java b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/ActionActuatorFuncEnums.java
new file mode 100644
index 0000000..b617e99
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/ActionActuatorFuncEnums.java
@@ -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;
+    }
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/enums/kml/ActionGroupModeEnums.java b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/ActionGroupModeEnums.java
new file mode 100644
index 0000000..97cf29b
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/ActionGroupModeEnums.java
@@ -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;
+    }
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/enums/kml/ActionTriggerTypeEnums.java b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/ActionTriggerTypeEnums.java
new file mode 100644
index 0000000..07256fb
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/ActionTriggerTypeEnums.java
@@ -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;
+    }
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/enums/kml/AircraftPathModeEnums.java b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/AircraftPathModeEnums.java
new file mode 100644
index 0000000..be1fa1a
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/AircraftPathModeEnums.java
@@ -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;
+    }
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/enums/kml/CollectionMethodEnums.java b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/CollectionMethodEnums.java
new file mode 100644
index 0000000..54d6792
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/CollectionMethodEnums.java
@@ -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;
+    }
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/enums/kml/DroneEnumValueEnums.java b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/DroneEnumValueEnums.java
new file mode 100644
index 0000000..03beb27
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/DroneEnumValueEnums.java
@@ -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;
+    }
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/enums/kml/ExecuteHeightModeEnums.java b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/ExecuteHeightModeEnums.java
new file mode 100644
index 0000000..c2b9ee3
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/ExecuteHeightModeEnums.java
@@ -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;
+    }
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/enums/kml/ExecuteRCLostActionEnums.java b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/ExecuteRCLostActionEnums.java
new file mode 100644
index 0000000..073c262
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/ExecuteRCLostActionEnums.java
@@ -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;
+    }
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/enums/kml/ExitOnRCLostEnums.java b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/ExitOnRCLostEnums.java
new file mode 100644
index 0000000..b55af40
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/ExitOnRCLostEnums.java
@@ -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;
+    }
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/enums/kml/FinishActionEnums.java b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/FinishActionEnums.java
new file mode 100644
index 0000000..8cc370d
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/FinishActionEnums.java
@@ -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;
+    }
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/enums/kml/FlyToWaylineModeEnums.java b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/FlyToWaylineModeEnums.java
new file mode 100644
index 0000000..1c02254
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/FlyToWaylineModeEnums.java
@@ -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;
+    }
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/enums/kml/FocusModeEnums.java b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/FocusModeEnums.java
new file mode 100644
index 0000000..681c72f
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/FocusModeEnums.java
@@ -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;
+    }
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/enums/kml/GimbalPitchModeEnums.java b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/GimbalPitchModeEnums.java
new file mode 100644
index 0000000..a9e1ac3
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/GimbalPitchModeEnums.java
@@ -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;
+    }
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/enums/kml/GlobalWaypointTurnModeEnums.java b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/GlobalWaypointTurnModeEnums.java
new file mode 100644
index 0000000..1f567d8
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/GlobalWaypointTurnModeEnums.java
@@ -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;
+    }
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/enums/kml/HeightModeEnums.java b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/HeightModeEnums.java
new file mode 100644
index 0000000..6b29695
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/HeightModeEnums.java
@@ -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;
+    }
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/enums/kml/ImageFormatEnums.java b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/ImageFormatEnums.java
new file mode 100644
index 0000000..9a60d2c
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/ImageFormatEnums.java
@@ -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;
+    }
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/enums/kml/LensTypeEnums.java b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/LensTypeEnums.java
new file mode 100644
index 0000000..0f84d97
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/LensTypeEnums.java
@@ -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;
+    }
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/enums/kml/MeteringModeEnums.java b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/MeteringModeEnums.java
new file mode 100644
index 0000000..3b08baa
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/MeteringModeEnums.java
@@ -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;
+    }
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/enums/kml/PayloadPositionIndexEnums.java b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/PayloadPositionIndexEnums.java
new file mode 100644
index 0000000..9b799f7
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/PayloadPositionIndexEnums.java
@@ -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;
+    }
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/enums/kml/PayloadTypeEnums.java b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/PayloadTypeEnums.java
new file mode 100644
index 0000000..6305eca
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/PayloadTypeEnums.java
@@ -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;
+    }
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/enums/kml/PositioningTypeEnums.java b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/PositioningTypeEnums.java
new file mode 100644
index 0000000..290b232
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/PositioningTypeEnums.java
@@ -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;
+    }
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/enums/kml/ReturnModeEnums.java b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/ReturnModeEnums.java
new file mode 100644
index 0000000..457615b
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/ReturnModeEnums.java
@@ -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;
+    }
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/enums/kml/ScanningModeEnums.java b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/ScanningModeEnums.java
new file mode 100644
index 0000000..4941a30
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/ScanningModeEnums.java
@@ -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;
+    }
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/enums/kml/ShootTypeEnums.java b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/ShootTypeEnums.java
new file mode 100644
index 0000000..6f4fb9b
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/ShootTypeEnums.java
@@ -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;
+    }
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/enums/kml/TemplateTypeEnums.java b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/TemplateTypeEnums.java
new file mode 100644
index 0000000..26fdb05
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/TemplateTypeEnums.java
@@ -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;
+    }
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/enums/kml/WaypointHeadingModeEnums.java b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/WaypointHeadingModeEnums.java
new file mode 100644
index 0000000..93dd3e2
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/WaypointHeadingModeEnums.java
@@ -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;
+    }
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/enums/kml/WaypointHeadingPathModeEnums.java b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/WaypointHeadingPathModeEnums.java
new file mode 100644
index 0000000..ad1afdd
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/enums/kml/WaypointHeadingPathModeEnums.java
@@ -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;
+    }
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/service/UavRouteService.java b/ard-route/src/main/java/com/ard/route/kmz/service/UavRouteService.java
new file mode 100644
index 0000000..30434cf
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/service/UavRouteService.java
@@ -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);
+
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/service/impl/UavRouteServiceImpl.java b/ard-route/src/main/java/com/ard/route/kmz/service/impl/UavRouteServiceImpl.java
new file mode 100644
index 0000000..cee3911
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/service/impl/UavRouteServiceImpl.java
@@ -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);
+    }
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/util/Gps.java b/ard-route/src/main/java/com/ard/route/kmz/util/Gps.java
new file mode 100644
index 0000000..402459b
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/util/Gps.java
@@ -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;
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/util/PositionUtils.java b/ard-route/src/main/java/com/ard/route/kmz/util/PositionUtils.java
new file mode 100644
index 0000000..44df1ca
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/util/PositionUtils.java
@@ -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;
+    }
+
+}
diff --git a/ard-route/src/main/java/com/ard/route/kmz/util/RouteFileUtils.java b/ard-route/src/main/java/com/ard/route/kmz/util/RouteFileUtils.java
new file mode 100644
index 0000000..c745a74
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/kmz/util/RouteFileUtils.java
@@ -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;
+    }
+}
diff --git "a/file/kmz/\346\233\264\346\226\260\350\210\252\347\272\277kmz\346\226\207\344\273\266.kmz" "b/file/kmz/\346\233\264\346\226\260\350\210\252\347\272\277kmz\346\226\207\344\273\266.kmz"
new file mode 100644
index 0000000..18c3a39
--- /dev/null
+++ "b/file/kmz/\346\233\264\346\226\260\350\210\252\347\272\277kmz\346\226\207\344\273\266.kmz"
Binary files differ
diff --git "a/file/kmz/\350\210\252\347\272\277kmz\346\226\207\344\273\266.kmz" "b/file/kmz/\350\210\252\347\272\277kmz\346\226\207\344\273\266.kmz"
new file mode 100644
index 0000000..6f94087
--- /dev/null
+++ "b/file/kmz/\350\210\252\347\272\277kmz\346\226\207\344\273\266.kmz"
Binary files differ

--
Gitblit v1.9.3