From 8b14209e043b037f8e7a5a18138fdf2140885bdb Mon Sep 17 00:00:00 2001
From: aix <vip_xiaobin810@163.com>
Date: Tue, 23 Jul 2024 19:14:27 +0800
Subject: [PATCH] 航测功能

---
 src/main/java/com/dji/sample/patches/xml/mode/XMLTemplateModel.java                      |  179 +++++++++++++--
 src/main/java/com/dji/sample/patches/xml/mode/Folder.java                                |    4 
 src/main/java/com/dji/sample/patches/xml/mode/Overlap.java                               |   41 +++
 src/main/java/com/dji/sample/wayline/plane/param/CreateWaylineParam.java                 |   35 +++
 src/main/resources/template/waylines-polygon.xml                                         |  118 ++++++++++
 src/main/java/com/dji/sample/patches/xml/mode/PlacemarkByPolygon.java                    |   84 +++++++
 src/main/java/com/dji/sample/patches/xml/utils/CreateWaylineFileUtils.java               |    4 
 src/main/java/com/dji/sample/patches/xml/mode/WaylineCoordinateSysParam.java             |   42 +++
 src/main/java/com/dji/sample/patches/xml/mode/share/action/utils/FolderUtils.java        |   27 ++
 src/main/resources/template/template-polygon.xml                                         |   79 +++++++
 src/main/java/com/dji/sample/patches/xml/mode/share/action/utils/MissionConfigUtils.java |   19 +
 11 files changed, 597 insertions(+), 35 deletions(-)

diff --git a/src/main/java/com/dji/sample/patches/xml/mode/Folder.java b/src/main/java/com/dji/sample/patches/xml/mode/Folder.java
index bee0519..69b52ec 100644
--- a/src/main/java/com/dji/sample/patches/xml/mode/Folder.java
+++ b/src/main/java/com/dji/sample/patches/xml/mode/Folder.java
@@ -31,7 +31,9 @@
     private String globalWaypointTurnMode;
     private Integer globalUseStraightLine;
 
-    private List<Placemark> placemarkList = new ArrayList<>();
+    private List<Placemark> placemarkList = new ArrayList<>();//航点模板元素
+
+    private PlacemarkByPolygon placemarkByPolygon;//建图航拍模板元素
 
     private PayloadParam payloadParam;
 
diff --git a/src/main/java/com/dji/sample/patches/xml/mode/Overlap.java b/src/main/java/com/dji/sample/patches/xml/mode/Overlap.java
new file mode 100644
index 0000000..ab1d1fe
--- /dev/null
+++ b/src/main/java/com/dji/sample/patches/xml/mode/Overlap.java
@@ -0,0 +1,41 @@
+package com.dji.sample.patches.xml.mode;
+
+import lombok.Builder;
+import lombok.Data;
+
+/**
+ * @Author AIX
+ * @Date 2024/7/20 11:51
+ * @Version 1.0
+ * 重叠率参数
+ */
+@Data
+public class Overlap {
+
+    /**
+     * 可见光航向重叠率
+     */
+    private Integer orthoCameraOverlapH = 80;
+    /**
+     * 可见光旁向重叠率
+     */
+    private Integer orthoCameraOverlapW = 80;
+    /**
+     * 可见光航向重叠率
+     */
+    private Integer inclinedCameraOverlapH = 80;
+    /**
+     * 可见光旁向重叠率
+     */
+    private Integer inclinedCameraOverlapW = 70;
+
+    public Overlap() {}
+
+    public Overlap(Integer orthoCameraOverlapH, Integer orthoCameraOverlapW, Integer inclinedCameraOverlapH, Integer inclinedCameraOverlapW) {
+        this.orthoCameraOverlapH = orthoCameraOverlapH;
+        this.orthoCameraOverlapW = orthoCameraOverlapW;
+        this.inclinedCameraOverlapH = inclinedCameraOverlapH;
+        this.inclinedCameraOverlapW = inclinedCameraOverlapW;
+    }
+
+}
diff --git a/src/main/java/com/dji/sample/patches/xml/mode/PlacemarkByPolygon.java b/src/main/java/com/dji/sample/patches/xml/mode/PlacemarkByPolygon.java
new file mode 100644
index 0000000..e4a7b39
--- /dev/null
+++ b/src/main/java/com/dji/sample/patches/xml/mode/PlacemarkByPolygon.java
@@ -0,0 +1,84 @@
+package com.dji.sample.patches.xml.mode;
+
+import lombok.Data;
+import org.locationtech.jts.geom.Coordinate;
+
+import java.util.List;
+
+/**
+ * @Author AIX
+ * @Date 2024/7/20 11:19
+ * @Version 1.0
+ */
+@Data
+public class PlacemarkByPolygon {
+
+    /**
+     * 是否开启标定飞行
+     * * 注:仅适用于M300 RTK与M350 RTK机型
+     * 0:不开启
+     * 1:开启,航线中自动进行惯导标定,保证模型精度。航线收尾会进行三次加减速飞行,航线拐弯处自动外扩进行加减速飞行。航线过长会均匀插入加减速飞行,每次标定后飞行时间不会超过100s。
+     */
+    private Integer caliFlightEnable = 0;
+
+    /**
+     * 是否开启高程优化
+     * 0:不开启
+     * 1:开启,飞行器会在航线执行完毕后,飞向测区中心采集一组倾斜照片,优化高程精度。
+     */
+    private Integer elevationOptimizeEnable = 1;
+
+    /**
+     * 是否开启智能摆拍
+     * 0:不开启
+     * 1:开启,飞行器在单次建图航拍任务过程中,可通过云台摆动完成正射与倾斜照片拍摄。
+     */
+    private Integer smartObliqueEnable = 0;
+    /**
+     * 是否开启斜立面
+     * 0:不开启
+     * 1:开启
+     */
+    private Integer facadeWaylineEnable = 0;
+
+    private Integer isLookAtSceneSet = 0;
+    /**
+     * 拍照模式
+     * time:等时间拍照
+     * distance:等间隔拍照
+     * * 注:建议使用“time”等时间拍照。
+     * 在template.kml文件中定义“拍照模式”、“重叠率”和“飞行速度”,计算后得出间隔时间或间隔距离距离写入waylines.wpml中。
+     */
+    private String shootType = "time";
+    /**
+     * 航线方向
+     */
+    private Integer direction;
+    /**
+     * 测区外扩距离
+     */
+    private Integer margin = 0;
+
+    /**
+     * 重叠率参数
+     */
+    private Overlap overlap;
+
+    /**
+     * 测区多边形
+     */
+    private List<String> polygons;
+
+    /**
+     * 全局航线高度(椭球高)
+     * * 注:如果 wpml:height 选用相对起飞点高度,则 wpml:ellipsoidHeight 和 wpml:height 相同;
+     * 如果 wpml:height 选用 EGM96 海拔高度或 AGL 相对地面高度,则 wpml:wpml:ellipsoidHeight 由 wpml:height 做相应转换得到。
+     */
+    private double ellipsoidHeight;
+    /**
+     * 全局航线高度(EGM96海拔高/相对起飞点高度/AGL相对地面高度)
+     * * 注:该元素与 wpml:ellipsoidHeight 配合使用,二者是同一位置不同高程参考平面的表达。
+     */
+    private double height;
+
+}
diff --git a/src/main/java/com/dji/sample/patches/xml/mode/WaylineCoordinateSysParam.java b/src/main/java/com/dji/sample/patches/xml/mode/WaylineCoordinateSysParam.java
index 98aac8b..5643e30 100644
--- a/src/main/java/com/dji/sample/patches/xml/mode/WaylineCoordinateSysParam.java
+++ b/src/main/java/com/dji/sample/patches/xml/mode/WaylineCoordinateSysParam.java
@@ -1,5 +1,6 @@
 package com.dji.sample.patches.xml.mode;
 
+import lombok.Builder;
 import lombok.Data;
 
 /**
@@ -11,7 +12,46 @@
 @Data
 public class WaylineCoordinateSysParam {
 
+    /**
+     * 经纬度坐标系WGS84:当前固定使用
+     * WGS84坐标系
+     */
     private String coordinateMode = "WGS84";
-    private String heightMode = "relativeToStartPoint";
+    /**
+     * 航点高程参考平面
+     * EGM96:使用海拔高编辑
+     * relativeToStartPoint:使用相对点的高度进行编辑
+     * aboveGroundLevel:使用地形数据,AGL下编辑(仅支持司空2平台)
+     * realTimeFollowSurface: 使用实时仿地模式(仅用于建图航拍模版),仅支持M3E/M3T/M3M机型
+     */
+    private String heightMode = "EGM96";
+
+    /**
+     * 飞行器离被摄面高度(相对地面高)
+     * * 注:仅适用于模板类型mapping2d,mapping3d,mappingStrip
+     */
+    private String globalShootHeight;//自定义
+
+    /**
+     * 是否开启仿地飞行 0:不开启1:开启
+     * * 注:仅适用于模板类型mapping2d,mapping3d,mappingStrip
+     */
+    private String surfaceFollowModeEnable = "1";
+
+    private String isRealtimeSurfaceFollow = "0";
+    /**
+     * 仿地飞行离地高度(相对地面高)
+     * * 注:仅适用于模板类型mapping2d,mapping3d,mappingStrip
+     */
+    private String surfaceRelativeHeight;
+
+
+    public WaylineCoordinateSysParam() {}
+
+    public WaylineCoordinateSysParam(String heightMode,String globalShootHeight,String surfaceRelativeHeight) {
+        this.heightMode = heightMode;
+        this.globalShootHeight = globalShootHeight;
+        this.surfaceRelativeHeight = surfaceRelativeHeight;
+    }
 
 }
diff --git a/src/main/java/com/dji/sample/patches/xml/mode/XMLTemplateModel.java b/src/main/java/com/dji/sample/patches/xml/mode/XMLTemplateModel.java
index 56c6b0f..5ea5c10 100644
--- a/src/main/java/com/dji/sample/patches/xml/mode/XMLTemplateModel.java
+++ b/src/main/java/com/dji/sample/patches/xml/mode/XMLTemplateModel.java
@@ -3,11 +3,11 @@
 import com.dji.sample.patches.model.entity.LotInfo;
 import com.dji.sample.patches.utils.GeoToolsUtil;
 import com.dji.sample.patches.utils.PointPO;
-import com.dji.sample.patches.xml.mode.share.ActionGroup;
-import com.dji.sample.patches.xml.mode.share.ActionMode;
-import com.dji.sample.patches.xml.mode.share.ActionTrigger;
+import com.dji.sample.patches.xml.mode.share.*;
 import com.dji.sample.patches.xml.mode.share.action.utils.*;
 import com.dji.sample.patches.xml.utils.CreateWaylineFileUtils;
+import com.dji.sample.wayline.plane.PlaneCourseUtils;
+import com.dji.sample.wayline.plane.param.CreateWaylineParam;
 import freemarker.template.Configuration;
 import freemarker.template.Template;
 import lombok.Builder;
@@ -43,6 +43,7 @@
 
     /**
      * 初始化模板对象
+     *
      * @param coordinates
      * @param lotInfos
      * @return
@@ -53,16 +54,16 @@
 
         List<Placemark> placemarkList = new ArrayList<>();
         int i = 0;
-        for (PointPO pointPO:coordinates) {
+        for (PointPO pointPO : coordinates) {
             if (i != 0) {//去除第一个航点
                 Coordinate c = pointPO.getCoordinate();
                 Placemark placemark = PlacemarkUtils.setPlacemark(c.x + "," + c.y);
 
                 // 增加事件组
                 ActionGroup actionGroup = new ActionGroup();
-                actionGroup.setActionGroupId(i-1);//动作组id从0开始单调连续递增。
-                actionGroup.setActionGroupStartIndex(i-1);//动作组开始生效的航点
-                actionGroup.setActionGroupEndIndex(i-1);//动作组结束生效的航点
+                actionGroup.setActionGroupId(i - 1);//动作组id从0开始单调连续递增。
+                actionGroup.setActionGroupStartIndex(i - 1);//动作组开始生效的航点
+                actionGroup.setActionGroupEndIndex(i - 1);//动作组结束生效的航点
                 actionGroup.setActionGroupMode("sequence");
                 ActionTrigger at = new ActionTrigger();
                 at.setActionTriggerType("reachPoint");
@@ -85,7 +86,7 @@
                 actionMode2.setActionId(1);
                 actionMode2.setActionActuatorFunc(CameraActionEnum.GIMBAL_ROTATE.getDescription());//旋转云台
                 //设置转动角度
-                double bearing = GeoToolsUtil.bearing(pointPO.getCoordinate().y,pointPO.getCoordinate().x,pointPO.getCentro().y,pointPO.getCentro().x);
+                double bearing = GeoToolsUtil.bearing(pointPO.getCoordinate().y, pointPO.getCoordinate().x, pointPO.getCentro().y, pointPO.getCentro().x);
 //                System.out.println("角度:" + bearing);
                 actionMode2.setActionActuatorFuncParam(ActionUtils.setGimbalRotate(bearing));
 
@@ -105,7 +106,7 @@
                 placemarkList.add(placemark);
             }
 
-            i = i+1;
+            i = i + 1;
         }
 
         folder.setPlacemarkList(placemarkList);
@@ -121,34 +122,148 @@
         return xtm;
     }
 
+    /**
+     * 面状航线
+     *
+     * @return
+     */
+    public static XMLTemplateModel initPolygon(CreateWaylineParam param) {
+
+        Folder folder = FolderUtils.setFloder(param.getTemplateType(), param.getAutoFlightSpeed());
+
+        //坐标系参数
+        WaylineCoordinateSysParam wcs = new WaylineCoordinateSysParam("EGM96", String.valueOf(param.getHeight()), String.valueOf(param.getHeight()));
+        folder.setWaylineCoordinateSysParam(wcs);
+
+        //建图航拍模板元素
+        PlacemarkByPolygon placemarkByPolygon = new PlacemarkByPolygon();
+        placemarkByPolygon.setDirection(param.getBearing());
+
+
+        // 重叠率参数
+        Overlap overlap = new Overlap((int) (param.getCourseRatio()* 100),
+                (int) (param.getSideRatio()* 100),
+                (int) (param.getCourseRatio()* 100),
+                (int) (param.getSideRatio()* 100));
+        placemarkByPolygon.setOverlap(overlap);
+
+        //测区多边形
+        String polygons = "";
+        List<String> polygonStrList = new ArrayList<>();
+        for (double [] polygon:param.getPolygon()){
+            polygons = polygon[0] + "," + polygon[1] + ",0";
+            polygonStrList.add(polygons);
+        }
+        placemarkByPolygon.setPolygons(polygonStrList);
+
+        //全局航线高度
+        placemarkByPolygon.setEllipsoidHeight(param.getHeight());
+        placemarkByPolygon.setHeight(param.getHeight());
+
+        folder.setPlacemarkByPolygon(placemarkByPolygon);
+
+        //航点
+        List<Coordinate> pointList = PlaneCourseUtils.createWaylinePoints(param);
+        List<Placemark> placemarkList = new ArrayList<>();
+        for (Coordinate c:pointList)  {
+            Placemark placemark = new Placemark();
+            placemark.setCoordinates(c.x + "," + c.y);
+            placemark.setEllipsoidHeight(param.getHeight());
+            placemark.setHeight(param.getHeight());
+
+            placemark.setWaypointSpeed(param.getAutoFlightSpeed() + "");
+            placemark.setUseStraightLine(1);
+            //事件暂时不考虑添加
+
+            placemarkList.add(placemark);
+        }
+
+        folder.setPlacemarkList(placemarkList);
+
+        XMLTemplateModel xtm = XMLTemplateModel.builder()
+                .author("Aix")
+                .createTime(String.valueOf(System.currentTimeMillis()))
+                .updateTime(String.valueOf(System.currentTimeMillis()))
+                .missionConfig(MissionConfigUtils.setMissionConfigByPolygon(param.getCoordinate().y + "," + param.getCoordinate().x + ",0",
+                        param.getAutoFlightSpeed(),
+                        param.getDroneInfo(),
+                        param.getPayloadInfo()))
+                .folder(folder)
+                .build();
+
+        return xtm;
+    }
+
+    //新建面状航线测试
     public static void main(String[] args) {
-
-        //测试
-        List<LotInfo> list = new ArrayList<>();
-        list.add(LotInfo.builder().dkbh("dkbh01").dkfw("POLYGON((115.866465564947 28.6344502965542, 115.86425430209 28.6357383285408, 115.864551734716 28.633120921433, 115.866977149064 28.6338435339976, 115.866465564947 28.6344502965542))").build());
-        list.add(LotInfo.builder().dkbh("dkbh02").dkfw("POLYGON((115.864006690605 28.6202713913694, 115.86002109342 28.6162025130492, 115.866374254306 28.6142037658042, 115.865912044006 28.6172001020759, 115.864006690605 28.6202713913694))").build());
-        list.add(LotInfo.builder().dkbh("dkbh03").dkfw("POLYGON((115.839366933455 28.6161999317332, 115.841288489469 28.6160843601496, 115.840931570318 28.6181544912247, 115.838147600941 28.618654178036, 115.839366933455 28.6161999317332))").build());
-//        list.add(LotInfo.builder().dkbh("dkbh04").dkfw("POLYGON((115.857499052697 28.6784702230642, 115.859109158101 28.6762273976226, 115.863677723232 28.6766081113836, 115.862154868188 28.6790827508297, 115.857499052697 28.6784702230642))").build());
-//        list.add(LotInfo.builder().dkbh("dkbh05").dkfw("POLYGON((115.834974056705 28.6659171428962, 115.833760531592 28.6634960413229, 115.832422084777 28.6624550271329, 115.829745191145 28.6631986086972, 115.831232354274 28.6608191476914, 115.833314382654 28.6603729987527, 115.835545127347 28.6618601618814, 115.837032290475 28.6639421902615, 115.834974056705 28.6659171428962))").build());
-//        list.add(LotInfo.builder().dkbh("dkbh06").dkfw("POLYGON((115.885622116006 28.5766308429787, 115.883936664461 28.5771582901683, 115.883365593819 28.5752547213636, 115.883555950699 28.5740174016407, 115.88365112914 28.5724945465969, 115.885364341064 28.5721138328361, 115.886696839227 28.5725897250371, 115.887458266749 28.5736366878797, 115.886792017668 28.5753498998039, 115.885622116006 28.5766308429787))").build());
-//        list.add(LotInfo.builder().dkbh("dkbh07").dkfw("POLYGON((115.857644341395 28.5750890964568, 115.857572957565 28.5729475815515, 115.858429563527 28.5728761977213, 115.859072017998 28.5738041875136, 115.859072017998 28.5748035611361, 115.857644341395 28.5750890964568))").build());
-//        list.add(LotInfo.builder().dkbh("dkbh08").dkfw("POLYGON((115.912181587649 28.6231542087745, 115.912181587649 28.6215123806805, 115.915893546818 28.6212268453598, 115.916036314478 28.6231542087745, 115.912181587649 28.6231542087745))").build());
-//        list.add(LotInfo.builder().dkbh("dkbh09").dkfw("POLYGON((115.842039042965 28.6314426646115, 115.840992080122 28.631252307731, 115.842324578286 28.6305860586493, 115.843181184248 28.6305860586493, 115.84403779021 28.6304908802091, 115.84394261177 28.6317281999322, 115.842039042965 28.6314426646115))").build());
-//        list.add(LotInfo.builder().dkbh("dkbh10").dkfw("POLYGON((115.807011889796 28.623935465138, 115.805869748513 28.6224126100944, 115.810247956764 28.6220318963334, 115.809581707682 28.623935465138, 115.807011889796 28.623935465138))").build());
-
-        // 机场经纬度
-        double airportLat = 28.624514734; // 机场纬度
-        double airportLon = 115.856725497; // 机场经度
-        // 解析图斑生成航点,按顺序返回
-        List<PointPO> coordinates = GeoToolsUtil.getRoutePointOrder(list, airportLat, airportLon);
+        // 初始化模板对象
+        CreateWaylineParam param = new CreateWaylineParam();
+        param.setBearing(90);
+        param.setCoordinate(new Coordinate(116.020940643,25.8917266));
+        param.setHeight(372.3);
+        param.setCourseRatio(0.8);
+        param.setSideRatio(0.8);
+        param.setFocal(10*6.9999943);
+        param.setFrame(100);
+        List<double[]> polygon = new ArrayList<>();
+        double[] a = {116.028037250229,25.8948290570725};
+        double[] a2 = {116.031565260299,25.8950672687002};
+        double[] a3 = {116.032112214864,25.8901339309971};
+        double[] a4 = {116.028726270654,25.8895106128711};
+        polygon.add(a);
+        polygon.add(a2);
+        polygon.add(a3);
+        polygon.add(a4);
+        param.setPolygon(polygon);
+        param.setTemplateType("mapping2d");
+        param.setAutoFlightSpeed(15);
+        DroneInfo info = new DroneInfo();
+        info.setDroneEnumValue("91");
+        info.setDroneSubEnumValue("0");
+        param.setDroneInfo(info);
+        PayloadInfo payloadInfo = new PayloadInfo();
+        payloadInfo.setPayloadEnumValue("80");
+        payloadInfo.setPayloadPositionIndex("0");
+        payloadInfo.setPayloadSubEnumValue("0");
+        param.setPayloadInfo(payloadInfo);
 
         // 初始化模板对象
-        XMLTemplateModel xmlModel = XMLTemplateModel.init(coordinates, list);
+        XMLTemplateModel xmlModel = XMLTemplateModel.initPolygon(param);
 
         //生成航线文件
-        CreateWaylineFileUtils.createWaylineFile(xmlModel,"src\\main\\resources\\template\\template.xml","src\\main\\resources\\template\\wpmz\\template.xml","src\\main\\resources\\template\\waylines.xml","src\\main\\resources\\template\\wpmz\\waylines.xml");
-
-
+        CreateWaylineFileUtils.createWaylineFileByPolygon(xmlModel, "src\\main\\resources\\template\\template-polygon.xml", "src\\main\\resources\\template\\wpmz2\\template.xml");
+        CreateWaylineFileUtils.createWaylineFileByPolygon(xmlModel, "src\\main\\resources\\template\\waylines-polygon.xml", "src\\main\\resources\\template\\wpmz2\\waylines.xml");
     }
 
+    //新建点航线测试
+//    public static void main(String[] args) {
+//
+//        //测试
+//        List<LotInfo> list = new ArrayList<>();
+//        list.add(LotInfo.builder().dkbh("dkbh01").dkfw("POLYGON((115.866465564947 28.6344502965542, 115.86425430209 28.6357383285408, 115.864551734716 28.633120921433, 115.866977149064 28.6338435339976, 115.866465564947 28.6344502965542))").build());
+//        list.add(LotInfo.builder().dkbh("dkbh02").dkfw("POLYGON((115.864006690605 28.6202713913694, 115.86002109342 28.6162025130492, 115.866374254306 28.6142037658042, 115.865912044006 28.6172001020759, 115.864006690605 28.6202713913694))").build());
+//        list.add(LotInfo.builder().dkbh("dkbh03").dkfw("POLYGON((115.839366933455 28.6161999317332, 115.841288489469 28.6160843601496, 115.840931570318 28.6181544912247, 115.838147600941 28.618654178036, 115.839366933455 28.6161999317332))").build());
+////        list.add(LotInfo.builder().dkbh("dkbh04").dkfw("POLYGON((115.857499052697 28.6784702230642, 115.859109158101 28.6762273976226, 115.863677723232 28.6766081113836, 115.862154868188 28.6790827508297, 115.857499052697 28.6784702230642))").build());
+////        list.add(LotInfo.builder().dkbh("dkbh05").dkfw("POLYGON((115.834974056705 28.6659171428962, 115.833760531592 28.6634960413229, 115.832422084777 28.6624550271329, 115.829745191145 28.6631986086972, 115.831232354274 28.6608191476914, 115.833314382654 28.6603729987527, 115.835545127347 28.6618601618814, 115.837032290475 28.6639421902615, 115.834974056705 28.6659171428962))").build());
+////        list.add(LotInfo.builder().dkbh("dkbh06").dkfw("POLYGON((115.885622116006 28.5766308429787, 115.883936664461 28.5771582901683, 115.883365593819 28.5752547213636, 115.883555950699 28.5740174016407, 115.88365112914 28.5724945465969, 115.885364341064 28.5721138328361, 115.886696839227 28.5725897250371, 115.887458266749 28.5736366878797, 115.886792017668 28.5753498998039, 115.885622116006 28.5766308429787))").build());
+////        list.add(LotInfo.builder().dkbh("dkbh07").dkfw("POLYGON((115.857644341395 28.5750890964568, 115.857572957565 28.5729475815515, 115.858429563527 28.5728761977213, 115.859072017998 28.5738041875136, 115.859072017998 28.5748035611361, 115.857644341395 28.5750890964568))").build());
+////        list.add(LotInfo.builder().dkbh("dkbh08").dkfw("POLYGON((115.912181587649 28.6231542087745, 115.912181587649 28.6215123806805, 115.915893546818 28.6212268453598, 115.916036314478 28.6231542087745, 115.912181587649 28.6231542087745))").build());
+////        list.add(LotInfo.builder().dkbh("dkbh09").dkfw("POLYGON((115.842039042965 28.6314426646115, 115.840992080122 28.631252307731, 115.842324578286 28.6305860586493, 115.843181184248 28.6305860586493, 115.84403779021 28.6304908802091, 115.84394261177 28.6317281999322, 115.842039042965 28.6314426646115))").build());
+////        list.add(LotInfo.builder().dkbh("dkbh10").dkfw("POLYGON((115.807011889796 28.623935465138, 115.805869748513 28.6224126100944, 115.810247956764 28.6220318963334, 115.809581707682 28.623935465138, 115.807011889796 28.623935465138))").build());
+//
+//        // 机场经纬度
+//        double airportLat = 28.624514734; // 机场纬度
+//        double airportLon = 115.856725497; // 机场经度
+//        // 解析图斑生成航点,按顺序返回
+//        List<PointPO> coordinates = GeoToolsUtil.getRoutePointOrder(list, airportLat, airportLon);
+//
+//        // 初始化模板对象
+//        XMLTemplateModel xmlModel = XMLTemplateModel.init(coordinates, list);
+//
+//        //生成航线文件
+//        CreateWaylineFileUtils.createWaylineFile(xmlModel, "src\\main\\resources\\template\\template.xml", "src\\main\\resources\\template\\wpmz\\template.xml", "src\\main\\resources\\template\\waylines.xml", "src\\main\\resources\\template\\wpmz\\waylines.xml");
+//
+//
+//    }
+
 }
diff --git a/src/main/java/com/dji/sample/patches/xml/mode/share/action/utils/FolderUtils.java b/src/main/java/com/dji/sample/patches/xml/mode/share/action/utils/FolderUtils.java
index 9a6d58a..a56b09f 100644
--- a/src/main/java/com/dji/sample/patches/xml/mode/share/action/utils/FolderUtils.java
+++ b/src/main/java/com/dji/sample/patches/xml/mode/share/action/utils/FolderUtils.java
@@ -44,4 +44,31 @@
         return folder;
     }
 
+    public static Folder setFloder(String templateType, double autoFlightSpeed) {
+        Folder folder = new Folder();
+        folder.setPayloadParam(PayloadParamUtils.setPayloadParam());
+        folder.setWaylineCoordinateSysParam(new WaylineCoordinateSysParam());
+        folder.setTemplateType(templateType);//航点模式
+        folder.setTemplateId("0");
+
+        folder.setAutoFlightSpeed(autoFlightSpeed);//全局航线飞行速度
+        folder.setGlobalHeight(100D); //全局航线高度(相对起飞点高度)
+        folder.setCaliFlightEnable(0);// 是否开启标定飞行
+        folder.setGimbalPitchMode("manual");//云台俯仰角控制模式manual:手动控制。飞行器从一个航点飞向下一个航点的过程中,支持用户手动控制云台的俯仰角度。若无用户控制,则保持飞离航点时的云台俯仰角度。 usePointSetting:依照每个航点设置。飞行器从一个航点飞向下一个航点的过程中,云台俯仰角均匀过渡至下一个航点的俯仰角。
+
+        //
+        GlobalWaypointHeadingParam gwhp = new GlobalWaypointHeadingParam();
+        gwhp.setWaypointHeadingMode("followWayline");
+        gwhp.setWaypointHeadingAngle(0);
+        gwhp.setWaypointPoiPoint("0.000000,0.000000,0.000000");
+        gwhp.setWaypointHeadingPathMode("followBadArc");
+        gwhp.setWaypointHeadingPoiIndex("0");
+
+        folder.setGlobalWaypointHeadingParam(gwhp);
+        folder.setGlobalWaypointTurnMode("coordinateTurn");
+        folder.setGlobalUseStraightLine(10);
+
+        return folder;
+    }
+
 }
diff --git a/src/main/java/com/dji/sample/patches/xml/mode/share/action/utils/MissionConfigUtils.java b/src/main/java/com/dji/sample/patches/xml/mode/share/action/utils/MissionConfigUtils.java
index 114c9b6..0605313 100644
--- a/src/main/java/com/dji/sample/patches/xml/mode/share/action/utils/MissionConfigUtils.java
+++ b/src/main/java/com/dji/sample/patches/xml/mode/share/action/utils/MissionConfigUtils.java
@@ -30,4 +30,23 @@
         return mc;
     }
 
+    public static MissionConfig setMissionConfigByPolygon(String xyz,double speed,DroneInfo droneInfo,PayloadInfo payloadInfo) {
+
+        MissionConfig mc = MissionConfig.builder()
+                .flyToWaylineMode("safely")//安全模式
+                .finishAction("goHome")
+                .exitOnRCLost("goContinue")//继续执行航线
+                .executeRCLostAction("goBack")
+                .takeOffSecurityHeight(20D)//安全起飞高度
+                .globalTransitionalSpeed(speed)
+                .globalRTHHeight(100D)
+                .takeOffRefPoint(xyz)
+                .takeOffRefPointAGLHeight(0D)
+                .droneInfo(droneInfo)
+                .payloadInfo(payloadInfo)
+                .build();
+
+        return mc;
+    }
+
 }
diff --git a/src/main/java/com/dji/sample/patches/xml/utils/CreateWaylineFileUtils.java b/src/main/java/com/dji/sample/patches/xml/utils/CreateWaylineFileUtils.java
index e213807..34c06ce 100644
--- a/src/main/java/com/dji/sample/patches/xml/utils/CreateWaylineFileUtils.java
+++ b/src/main/java/com/dji/sample/patches/xml/utils/CreateWaylineFileUtils.java
@@ -30,6 +30,10 @@
         xml2XmlDoc(xmlModel, waylineFilePath, targetWaylineFilePath);
     }
 
+    public static void createWaylineFileByPolygon(XMLTemplateModel xmlModel,String templeFilePath,String targetTempleFilePath) {
+        xml2XmlDoc(xmlModel, templeFilePath, targetTempleFilePath);
+    }
+
     /**
      * 将xml模板转换为newxml
      *
diff --git a/src/main/java/com/dji/sample/wayline/plane/param/CreateWaylineParam.java b/src/main/java/com/dji/sample/wayline/plane/param/CreateWaylineParam.java
index ff6d30f..fb56509 100644
--- a/src/main/java/com/dji/sample/wayline/plane/param/CreateWaylineParam.java
+++ b/src/main/java/com/dji/sample/wayline/plane/param/CreateWaylineParam.java
@@ -1,6 +1,9 @@
 package com.dji.sample.wayline.plane.param;
 
+import com.dji.sample.patches.xml.mode.share.DroneInfo;
+import com.dji.sample.patches.xml.mode.share.PayloadInfo;
 import lombok.Data;
+import org.locationtech.jts.geom.Coordinate;
 
 import javax.validation.constraints.NotNull;
 import java.util.List;
@@ -26,6 +29,36 @@
     @NotNull(message = "旁向重叠率不能为空")
     private double sideRatio;//旁向重叠率
     @NotNull(message = "航线角度不能为空")
-    private double bearing;//航线角度
+    private int bearing;//航线角度
+
+    /**
+     * 全局航线飞行速度   1-15
+     */
+    @NotNull(message = "全局航线飞行速度不能为空")
+    private double autoFlightSpeed;
+    /**
+     * 模板类型
+     * waypoint:航点飞行
+     * mapping2d:建图航拍
+     * mapping3d:倾斜摄影
+     * mappingStrip:航带飞行
+     */
+    @NotNull(message = "模板类型不能为空")
+    private String templateType;
+
+    /**
+     * 机场位置
+     */
+    @NotNull(message = "机场位置不能为空")
+    private Coordinate coordinate;
+
+    /**
+     * 飞行器机型信息
+     */
+    private DroneInfo droneInfo;
+    /**
+     *负载机型信息
+     */
+    private PayloadInfo payloadInfo;
 
 }
diff --git a/src/main/resources/template/template-polygon.xml b/src/main/resources/template/template-polygon.xml
new file mode 100644
index 0000000..2fd5b27
--- /dev/null
+++ b/src/main/resources/template/template-polygon.xml
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:wpml="http://www.dji.com/wpmz/1.0.5">
+  <Document>
+    <wpml:author>${author!''}</wpml:author>
+    <wpml:createTime>${createTime!''}</wpml:createTime>
+    <wpml:updateTime>${updateTime!''}</wpml:updateTime>
+    <wpml:missionConfig>
+      <wpml:flyToWaylineMode>${missionConfig.flyToWaylineMode!''}</wpml:flyToWaylineMode>
+      <wpml:finishAction>${missionConfig.finishAction!''}</wpml:finishAction>
+      <wpml:exitOnRCLost>${missionConfig.exitOnRCLost!''}</wpml:exitOnRCLost>
+      <wpml:executeRCLostAction>${missionConfig.executeRCLostAction!''}</wpml:executeRCLostAction>
+      <wpml:takeOffSecurityHeight>${missionConfig.takeOffSecurityHeight!''}</wpml:takeOffSecurityHeight>
+      <wpml:takeOffRefPoint>${missionConfig.takeOffRefPoint!''}</wpml:takeOffRefPoint>
+      <wpml:takeOffRefPointAGLHeight>${missionConfig.takeOffRefPointAGLHeight!''}</wpml:takeOffRefPointAGLHeight>
+      <wpml:globalTransitionalSpeed>${missionConfig.globalTransitionalSpeed!''}</wpml:globalTransitionalSpeed>
+      <wpml:globalRTHHeight>${missionConfig.globalRTHHeight!''}</wpml:globalRTHHeight>
+      <wpml:droneInfo>
+        <wpml:droneEnumValue>${missionConfig.droneInfo.droneEnumValue!''}</wpml:droneEnumValue>
+        <wpml:droneSubEnumValue>${missionConfig.droneInfo.droneSubEnumValue!''}</wpml:droneSubEnumValue>
+      </wpml:droneInfo>
+      <wpml:payloadInfo>
+        <wpml:payloadEnumValue>${missionConfig.payloadInfo.payloadEnumValue!''}</wpml:payloadEnumValue>
+        <wpml:payloadSubEnumValue>${missionConfig.payloadInfo.payloadSubEnumValue!''}</wpml:payloadSubEnumValue>
+        <wpml:payloadPositionIndex>${missionConfig.payloadInfo.payloadPositionIndex!''}</wpml:payloadPositionIndex>
+      </wpml:payloadInfo>
+    </wpml:missionConfig>
+    <Folder>
+      <wpml:templateType>${folder.templateType!''}</wpml:templateType>
+      <wpml:templateId>${folder.templateId!''}</wpml:templateId>
+      <wpml:waylineCoordinateSysParam>
+        <wpml:coordinateMode>${folder.waylineCoordinateSysParam.coordinateMode!''}</wpml:coordinateMode>
+        <wpml:heightMode>${folder.waylineCoordinateSysParam.heightMode!''}</wpml:heightMode>
+        <wpml:globalShootHeight>${folder.waylineCoordinateSysParam.globalShootHeight!''}</wpml:globalShootHeight>
+        <wpml:surfaceFollowModeEnable>${folder.waylineCoordinateSysParam.surfaceFollowModeEnable!''}</wpml:surfaceFollowModeEnable>
+        <wpml:isRealtimeSurfaceFollow>${folder.waylineCoordinateSysParam.isRealtimeSurfaceFollow!''}</wpml:isRealtimeSurfaceFollow>
+        <wpml:surfaceRelativeHeight>${folder.waylineCoordinateSysParam.surfaceRelativeHeight!''}</wpml:surfaceRelativeHeight>
+      </wpml:waylineCoordinateSysParam>
+      <wpml:autoFlightSpeed>${folder.autoFlightSpeed!''}</wpml:autoFlightSpeed>
+      <Placemark>
+        <wpml:caliFlightEnable>${folder.placemarkByPolygon.caliFlightEnable!''}</wpml:caliFlightEnable>
+        <wpml:elevationOptimizeEnable>${folder.placemarkByPolygon.elevationOptimizeEnable!''}</wpml:elevationOptimizeEnable>
+        <wpml:smartObliqueEnable>${folder.placemarkByPolygon.smartObliqueEnable!''}</wpml:smartObliqueEnable>
+        <wpml:facadeWaylineEnable>${folder.placemarkByPolygon.facadeWaylineEnable!''}</wpml:facadeWaylineEnable>
+        <wpml:isLookAtSceneSet>${folder.placemarkByPolygon.isLookAtSceneSet!''}</wpml:isLookAtSceneSet>
+        <wpml:shootType>${folder.placemarkByPolygon.shootType!''}</wpml:shootType>
+        <wpml:direction>${folder.placemarkByPolygon.direction!''}</wpml:direction>
+        <wpml:margin>${folder.placemarkByPolygon.margin!''}</wpml:margin>
+        <wpml:overlap>
+          <wpml:orthoCameraOverlapH>${folder.placemarkByPolygon.overlap.orthoCameraOverlapH!''}</wpml:orthoCameraOverlapH>
+          <wpml:orthoCameraOverlapW>${folder.placemarkByPolygon.overlap.orthoCameraOverlapW!''}</wpml:orthoCameraOverlapW>
+          <wpml:inclinedCameraOverlapH>${folder.placemarkByPolygon.overlap.inclinedCameraOverlapH!''}</wpml:inclinedCameraOverlapH>
+          <wpml:inclinedCameraOverlapW>${folder.placemarkByPolygon.overlap.inclinedCameraOverlapW!''}</wpml:inclinedCameraOverlapW>
+        </wpml:overlap>
+        <Polygon>
+          <outerBoundaryIs>
+            <LinearRing>
+              <coordinates>
+                <#list folder.placemarkByPolygon.polygons as polygon>
+                ${polygon}
+                </#list>
+              </coordinates>
+            </LinearRing>
+          </outerBoundaryIs>
+        </Polygon>
+        <wpml:ellipsoidHeight>${folder.placemarkByPolygon.ellipsoidHeight!''}</wpml:ellipsoidHeight>
+        <wpml:height>${folder.placemarkByPolygon.height!''}</wpml:height>
+      </Placemark>
+      <wpml:payloadParam>
+        <wpml:payloadPositionIndex>${folder.payloadParam.payloadPositionIndex!''}</wpml:payloadPositionIndex>
+        <wpml:focusMode>${folder.payloadParam.focusMode!''}</wpml:focusMode>
+        <wpml:meteringMode>${folder.payloadParam.meteringMode!''}</wpml:meteringMode>
+        <wpml:returnMode>${folder.payloadParam.returnMode!''}</wpml:returnMode>
+        <wpml:samplingRate>${folder.payloadParam.samplingRate!''}</wpml:samplingRate>
+        <wpml:scanningMode>${folder.payloadParam.scanningMode!''}</wpml:scanningMode>
+        <wpml:imageFormat>${folder.payloadParam.imageFormat!''}</wpml:imageFormat>
+      </wpml:payloadParam>
+    </Folder>
+  </Document>
+</kml>
diff --git a/src/main/resources/template/waylines-polygon.xml b/src/main/resources/template/waylines-polygon.xml
new file mode 100644
index 0000000..e08367d
--- /dev/null
+++ b/src/main/resources/template/waylines-polygon.xml
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:wpml="http://www.dji.com/wpmz/1.0.5">
+  <Document>
+    <wpml:missionConfig>
+      <wpml:flyToWaylineMode>${missionConfig.flyToWaylineMode!''}</wpml:flyToWaylineMode>
+      <wpml:finishAction>${missionConfig.finishAction!''}</wpml:finishAction>
+      <wpml:exitOnRCLost>${missionConfig.exitOnRCLost!''}</wpml:exitOnRCLost>
+      <wpml:executeRCLostAction>${missionConfig.executeRCLostAction!''}</wpml:executeRCLostAction>
+      <wpml:takeOffSecurityHeight>${missionConfig.takeOffSecurityHeight!''}</wpml:takeOffSecurityHeight>
+      <wpml:globalTransitionalSpeed>${missionConfig.globalTransitionalSpeed!''}</wpml:globalTransitionalSpeed>
+      <wpml:globalRTHHeight>${missionConfig.globalRTHHeight!''}</wpml:globalRTHHeight>
+      <wpml:droneInfo>
+        <wpml:droneEnumValue>${missionConfig.droneInfo.droneEnumValue!''}</wpml:droneEnumValue>
+        <wpml:droneSubEnumValue>${missionConfig.droneInfo.droneSubEnumValue!''}</wpml:droneSubEnumValue>
+      </wpml:droneInfo>
+      <wpml:payloadInfo>
+        <wpml:payloadEnumValue>${missionConfig.payloadInfo.payloadEnumValue!''}</wpml:payloadEnumValue>
+        <wpml:payloadSubEnumValue>${missionConfig.payloadInfo.payloadSubEnumValue!''}</wpml:payloadSubEnumValue>
+        <wpml:payloadPositionIndex>${missionConfig.payloadInfo.payloadPositionIndex!''}</wpml:payloadPositionIndex>
+      </wpml:payloadInfo>
+    </wpml:missionConfig>
+    <Folder>
+      <wpml:templateId>${folder.templateId!''}</wpml:templateId>
+      <wpml:executeHeightMode>${folder.waylineCoordinateSysParam.heightMode!''}</wpml:executeHeightMode>
+      <wpml:waylineId>0</wpml:waylineId>
+      <wpml:autoFlightSpeed>${folder.autoFlightSpeed!''}</wpml:autoFlightSpeed>
+      <wpml:startActionGroup>
+        <wpml:action>
+          <wpml:actionId>0</wpml:actionId>
+          <wpml:actionActuatorFunc>gimbalRotate</wpml:actionActuatorFunc>
+          <wpml:actionActuatorFuncParam>
+            <wpml:gimbalHeadingYawBase>aircraft</wpml:gimbalHeadingYawBase>
+            <wpml:gimbalRotateMode>absoluteAngle</wpml:gimbalRotateMode>
+            <wpml:gimbalPitchRotateEnable>1</wpml:gimbalPitchRotateEnable>
+            <wpml:gimbalPitchRotateAngle>-90</wpml:gimbalPitchRotateAngle>
+            <wpml:gimbalRollRotateEnable>0</wpml:gimbalRollRotateEnable>
+            <wpml:gimbalRollRotateAngle>0</wpml:gimbalRollRotateAngle>
+            <wpml:gimbalYawRotateEnable>1</wpml:gimbalYawRotateEnable>
+            <wpml:gimbalYawRotateAngle>0</wpml:gimbalYawRotateAngle>
+            <wpml:gimbalRotateTimeEnable>0</wpml:gimbalRotateTimeEnable>
+            <wpml:gimbalRotateTime>10</wpml:gimbalRotateTime>
+            <wpml:payloadPositionIndex>0</wpml:payloadPositionIndex>
+          </wpml:actionActuatorFuncParam>
+        </wpml:action>
+        <wpml:action>
+          <wpml:actionId>1</wpml:actionId>
+          <wpml:actionActuatorFunc>hover</wpml:actionActuatorFunc>
+          <wpml:actionActuatorFuncParam>
+            <wpml:hoverTime>0.5</wpml:hoverTime>
+          </wpml:actionActuatorFuncParam>
+        </wpml:action>
+        <wpml:action>
+          <wpml:actionId>2</wpml:actionId>
+          <wpml:actionActuatorFunc>setFocusType</wpml:actionActuatorFunc>
+          <wpml:actionActuatorFuncParam>
+            <wpml:cameraFocusType>manual</wpml:cameraFocusType>
+            <wpml:payloadPositionIndex>0</wpml:payloadPositionIndex>
+          </wpml:actionActuatorFuncParam>
+        </wpml:action>
+        <wpml:action>
+          <wpml:actionId>3</wpml:actionId>
+          <wpml:actionActuatorFunc>focus</wpml:actionActuatorFunc>
+          <wpml:actionActuatorFuncParam>
+            <wpml:focusX>0</wpml:focusX>
+            <wpml:focusY>0</wpml:focusY>
+            <wpml:focusRegionWidth>0</wpml:focusRegionWidth>
+            <wpml:focusRegionHeight>0</wpml:focusRegionHeight>
+            <wpml:isPointFocus>0</wpml:isPointFocus>
+            <wpml:isInfiniteFocus>1</wpml:isInfiniteFocus>
+            <wpml:payloadPositionIndex>0</wpml:payloadPositionIndex>
+          </wpml:actionActuatorFuncParam>
+        </wpml:action>
+        <wpml:action>
+          <wpml:actionId>4</wpml:actionId>
+          <wpml:actionActuatorFunc>hover</wpml:actionActuatorFunc>
+          <wpml:actionActuatorFuncParam>
+            <wpml:hoverTime>1</wpml:hoverTime>
+          </wpml:actionActuatorFuncParam>
+        </wpml:action>
+      </wpml:startActionGroup>
+      <#if folder.placemarkList??>
+      <#assign placemarkIndex = 0>
+      <#list folder.placemarkList as placemark>
+        <Placemark>
+          <Point>
+            <coordinates>
+              ${placemark.coordinates!''}
+            </coordinates>
+          </Point>
+          <wpml:index>${placemarkIndex!''}</wpml:index>
+          <#assign placemarkIndex = placemarkIndex + 1>
+          <wpml:executeHeight>${placemark.height!''}</wpml:executeHeight>
+          <wpml:waypointSpeed>${placemark.waypointSpeed!''}</wpml:waypointSpeed>
+          <wpml:waypointHeadingParam>
+            <wpml:waypointHeadingMode>${folder.globalWaypointHeadingParam.waypointHeadingMode!''}</wpml:waypointHeadingMode>
+            <wpml:waypointHeadingAngle>${folder.globalWaypointHeadingParam.waypointHeadingAngle!''}</wpml:waypointHeadingAngle>
+            <wpml:waypointPoiPoint>${folder.globalWaypointHeadingParam.waypointPoiPoint!''}</wpml:waypointPoiPoint>
+            <wpml:waypointHeadingAngleEnable>1</wpml:waypointHeadingAngleEnable>
+            <wpml:waypointHeadingPathMode>${folder.globalWaypointHeadingParam.waypointHeadingPathMode!''}</wpml:waypointHeadingPathMode>
+            <wpml:waypointHeadingPoiIndex>${folder.globalWaypointHeadingParam.waypointHeadingPoiIndex!''}</wpml:waypointHeadingPoiIndex>
+          </wpml:waypointHeadingParam>
+          <wpml:waypointTurnParam>
+            <wpml:waypointTurnMode>${folder.globalWaypointTurnMode!''}</wpml:waypointTurnMode>
+            <wpml:waypointTurnDampingDist>0.2</wpml:waypointTurnDampingDist>
+          </wpml:waypointTurnParam>
+          <wpml:useStraightLine>${folder.globalUseStraightLine!''}</wpml:useStraightLine>
+          <wpml:waypointGimbalHeadingParam>
+            <wpml:waypointGimbalPitchAngle>0</wpml:waypointGimbalPitchAngle>
+            <wpml:waypointGimbalYawAngle>0</wpml:waypointGimbalYawAngle>
+          </wpml:waypointGimbalHeadingParam>
+          <wpml:isRisky>0</wpml:isRisky>
+          <wpml:waypointWorkType>0</wpml:waypointWorkType>
+        </Placemark>
+      </#list>
+      </#if>
+    </Folder>
+  </Document>
+</kml>

--
Gitblit v1.9.3