From 6d4779a48a752c164e2fe7559dac6caed00f416f Mon Sep 17 00:00:00 2001
From: liuyg <376836862@qq.com>
Date: Fri, 02 Jul 2021 09:10:16 +0800
Subject: [PATCH] 飞行测试

---
 config.json                        |    7 
 widgets/filyL/js/move.js           |  103 +
 widgets/filyL/Widget.js            |  354 ++++
 widgets/filyL/css/a.css            |  160 ++
 widgets/filyL/flyroute.json        |   55 
 widgets/filyL/FileSaver.js         |  244 +++
 widgets/filyL/fly.js               |  529 +++++++
 widgets/filyL/nls/strings.js       |    7 
 widgets/visibleArea/Widget.js      |    1 
 widgets/filyL/实例临时 copy 2.html     |   30 
 widgets/filyL/nls/zh-cn/strings.js |    5 
 widgets/filyL/nls/es/strings.js    |    5 
 widgets/filyL/css/style.css        |  188 ++
 widgets/filyL/实例临时 copy.html       |  587 ++++++++
 widgets/filyL/js/DrawHelper.js     | 1874 ++++++++++++++++++++++++++
 widgets/filyL/manifest.json        |   17 
 widgets/filyL/Widget.html          |   35 
 17 files changed, 4,199 insertions(+), 2 deletions(-)

diff --git a/config.json b/config.json
index fa25648..6ae1555 100644
--- a/config.json
+++ b/config.json
@@ -284,8 +284,7 @@
       {
         "name": "开敞度分析",
         "uri": "widgets/openAnalysis/Widget"
-      }
-      ,
+      },
       {
         "name": "BOX交互裁剪",
         "uri": "widgets/BOXInteractive/Widget"
@@ -293,6 +292,10 @@
       {
         "name": "Cross裁剪",
         "uri": "widgets/crossTailoring/Widget"
+      },
+      {
+        "name": "飞行",
+        "uri": "widgets/filyL/Widget"
       }
     ],
     "groups": [],
diff --git a/widgets/filyL/FileSaver.js b/widgets/filyL/FileSaver.js
new file mode 100644
index 0000000..bf7a192
--- /dev/null
+++ b/widgets/filyL/FileSaver.js
@@ -0,0 +1,244 @@
+/* FileSaver.js
+ * A saveAs() FileSaver implementation.
+ * 2014-11-29
+ *
+ * By Eli Grey, http://eligrey.com
+ * License: X11/MIT
+ *   See https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md
+ */
+
+/*global self */
+/*jslint bitwise: true, indent: 4, laxbreak: true, laxcomma: true, smarttabs: true, plusplus: true */
+
+/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */
+
+var saveAs = saveAs
+  // IE 10+ (native saveAs)
+  || (typeof navigator !== "undefined" &&
+      navigator.msSaveOrOpenBlob && navigator.msSaveOrOpenBlob.bind(navigator))
+  // Everyone else
+  || (function(view) {
+	"use strict";
+	// IE <10 is explicitly unsupported
+	if (typeof navigator !== "undefined" &&
+	    /MSIE [1-9]\./.test(navigator.userAgent)) {
+		return;
+	}
+	var
+		  doc = view.document
+		  // only get URL when necessary in case Blob.js hasn't overridden it yet
+		, get_URL = function() {
+			return view.URL || view.webkitURL || view;
+		}
+		, save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a")
+		, can_use_save_link = "download" in save_link
+		, click = function(node) {
+			var event = doc.createEvent("MouseEvents");
+			event.initMouseEvent(
+				"click", true, false, view, 0, 0, 0, 0, 0
+				, false, false, false, false, 0, null
+			);
+			node.dispatchEvent(event);
+		}
+		, webkit_req_fs = view.webkitRequestFileSystem
+		, req_fs = view.requestFileSystem || webkit_req_fs || view.mozRequestFileSystem
+		, throw_outside = function(ex) {
+			(view.setImmediate || view.setTimeout)(function() {
+				throw ex;
+			}, 0);
+		}
+		, force_saveable_type = "application/octet-stream"
+		, fs_min_size = 0
+		// See https://code.google.com/p/chromium/issues/detail?id=375297#c7 and
+		// https://github.com/eligrey/FileSaver.js/commit/485930a#commitcomment-8768047
+		// for the reasoning behind the timeout and revocation flow
+		, arbitrary_revoke_timeout = 500 // in ms
+		, revoke = function(file) {
+			var revoker = function() {
+				if (typeof file === "string") { // file is an object URL
+					get_URL().revokeObjectURL(file);
+				} else { // file is a File
+					file.remove();
+				}
+			};
+			if (view.chrome) {
+				revoker();
+			} else {
+				setTimeout(revoker, arbitrary_revoke_timeout);
+			}
+		}
+		, dispatch = function(filesaver, event_types, event) {
+			event_types = [].concat(event_types);
+			var i = event_types.length;
+			while (i--) {
+				var listener = filesaver["on" + event_types[i]];
+				if (typeof listener === "function") {
+					try {
+						listener.call(filesaver, event || filesaver);
+					} catch (ex) {
+						throw_outside(ex);
+					}
+				}
+			}
+		}
+		, FileSaver = function(blob, name) {
+			// First try a.download, then web filesystem, then object URLs
+			var
+				  filesaver = this
+				, type = blob.type
+				, blob_changed = false
+				, object_url
+				, target_view
+				, dispatch_all = function() {
+					dispatch(filesaver, "writestart progress write writeend".split(" "));
+				}
+				// on any filesys errors revert to saving with object URLs
+				, fs_error = function() {
+					// don't create more object URLs than needed
+					if (blob_changed || !object_url) {
+						object_url = get_URL().createObjectURL(blob);
+					}
+					if (target_view) {
+						target_view.location.href = object_url;
+					} else {
+						var new_tab = view.open(object_url, "_blank");
+						if (new_tab == undefined && typeof safari !== "undefined") {
+							//Apple do not allow window.open, see http://bit.ly/1kZffRI
+							view.location.href = object_url
+						}
+					}
+					filesaver.readyState = filesaver.DONE;
+					dispatch_all();
+					revoke(object_url);
+				}
+				, abortable = function(func) {
+					return function() {
+						if (filesaver.readyState !== filesaver.DONE) {
+							return func.apply(this, arguments);
+						}
+					};
+				}
+				, create_if_not_found = {create: true, exclusive: false}
+				, slice
+			;
+			filesaver.readyState = filesaver.INIT;
+			if (!name) {
+				name = "download";
+			}
+			if (can_use_save_link) {
+				object_url = get_URL().createObjectURL(blob);
+				save_link.href = object_url;
+				save_link.download = name;
+				click(save_link);
+				filesaver.readyState = filesaver.DONE;
+				dispatch_all();
+				revoke(object_url);
+				return;
+			}
+			// Object and web filesystem URLs have a problem saving in Google Chrome when
+			// viewed in a tab, so I force save with application/octet-stream
+			// http://code.google.com/p/chromium/issues/detail?id=91158
+			// Update: Google errantly closed 91158, I submitted it again:
+			// https://code.google.com/p/chromium/issues/detail?id=389642
+			if (view.chrome && type && type !== force_saveable_type) {
+				slice = blob.slice || blob.webkitSlice;
+				blob = slice.call(blob, 0, blob.size, force_saveable_type);
+				blob_changed = true;
+			}
+			// Since I can't be sure that the guessed media type will trigger a download
+			// in WebKit, I append .download to the filename.
+			// https://bugs.webkit.org/show_bug.cgi?id=65440
+			if (webkit_req_fs && name !== "download") {
+				name += ".download";
+			}
+			if (type === force_saveable_type || webkit_req_fs) {
+				target_view = view;
+			}
+			if (!req_fs) {
+				fs_error();
+				return;
+			}
+			fs_min_size += blob.size;
+			req_fs(view.TEMPORARY, fs_min_size, abortable(function(fs) {
+				fs.root.getDirectory("saved", create_if_not_found, abortable(function(dir) {
+					var save = function() {
+						dir.getFile(name, create_if_not_found, abortable(function(file) {
+							file.createWriter(abortable(function(writer) {
+								writer.onwriteend = function(event) {
+									target_view.location.href = file.toURL();
+									filesaver.readyState = filesaver.DONE;
+									dispatch(filesaver, "writeend", event);
+									revoke(file);
+								};
+								writer.onerror = function() {
+									var error = writer.error;
+									if (error.code !== error.ABORT_ERR) {
+										fs_error();
+									}
+								};
+								"writestart progress write abort".split(" ").forEach(function(event) {
+									writer["on" + event] = filesaver["on" + event];
+								});
+								writer.write(blob);
+								filesaver.abort = function() {
+									writer.abort();
+									filesaver.readyState = filesaver.DONE;
+								};
+								filesaver.readyState = filesaver.WRITING;
+							}), fs_error);
+						}), fs_error);
+					};
+					dir.getFile(name, {create: false}, abortable(function(file) {
+						// delete file if it already exists
+						file.remove();
+						save();
+					}), abortable(function(ex) {
+						if (ex.code === ex.NOT_FOUND_ERR) {
+							save();
+						} else {
+							fs_error();
+						}
+					}));
+				}), fs_error);
+			}), fs_error);
+		}
+		, FS_proto = FileSaver.prototype
+		, saveAs = function(blob, name) {
+			return new FileSaver(blob, name);
+		}
+	;
+	FS_proto.abort = function() {
+		var filesaver = this;
+		filesaver.readyState = filesaver.DONE;
+		dispatch(filesaver, "abort");
+	};
+	FS_proto.readyState = FS_proto.INIT = 0;
+	FS_proto.WRITING = 1;
+	FS_proto.DONE = 2;
+
+	FS_proto.error =
+	FS_proto.onwritestart =
+	FS_proto.onprogress =
+	FS_proto.onwrite =
+	FS_proto.onabort =
+	FS_proto.onerror =
+	FS_proto.onwriteend =
+		null;
+
+	return saveAs;
+}(
+	   typeof self !== "undefined" && self
+	|| typeof window !== "undefined" && window
+	|| this.content
+));
+// `self` is undefined in Firefox for Android content script context
+// while `this` is nsIContentFrameMessageManager
+// with an attribute `content` that corresponds to the window
+
+if (typeof module !== "undefined" && module !== null) {
+  module.exports = saveAs;
+} else if ((typeof define !== "undefined" && define !== null) && (define.amd != null)) {
+  define([], function() {
+    return saveAs;
+  });
+}
diff --git a/widgets/filyL/Widget.html b/widgets/filyL/Widget.html
new file mode 100644
index 0000000..c0828d7
--- /dev/null
+++ b/widgets/filyL/Widget.html
@@ -0,0 +1,35 @@
+<div>
+    <div class="fly-route-header">
+        <i></i> 飞行漫游
+        <!-- <div class="close-flyrouter"><i class="layui-icon" style="font-size: 20px">&#x1006;</i></div> -->
+    </div>
+    <div class="fly-route-continer">
+        <div class="fly-route-control">
+            <select id="flightRoutefilyL"></select>
+            <div class="fly-route-control-btn">
+                <input type="button" id="ksfilyL" value="开始" />
+                <input type="button" id="ztfilyL" value="暂停" />
+                <input type="button" id="tzfilyL" value="停止" />
+            </div>
+        </div>
+        <div class="fly-route-new">
+            <div class="fly-route-new-top">
+                <span class="fly-text-route">定制路线:</span>
+                <input id="routeNamefilyL" type="text" placeholder="请输入路线名称" />
+            </div>
+            <!--<input id="speed" type="text" placeholder="请输入飞行速度"/>m-->
+            <div class="fly-route-new-btn">
+                <input type="button" id="addfilyL" value="新增途经点" />
+                <input type="button" id="exportfilyL" value="保存路线" />
+                <input type="button" id="detelefilyL" value="清除路线" />
+                <input type="button" id="openViewL" value="开放/固定视角" />
+            </div>
+            <div>
+                <ul id="passPointfilyL"></ul>
+            </div>
+        </div>
+    </div>
+    <i class="layui-icon closeOUR">
+        &#x1006;
+    </i></span>
+</div>
\ No newline at end of file
diff --git a/widgets/filyL/Widget.js b/widgets/filyL/Widget.js
new file mode 100644
index 0000000..d312289
--- /dev/null
+++ b/widgets/filyL/Widget.js
@@ -0,0 +1,354 @@
+define([
+    'dojo/_base/declare',
+    'dojo/_base/lang',
+    'dojo/_base/array',
+    'dojo/_base/html',
+    'dojo/topic',
+    'jimu/BaseWidget',
+    './fly',
+    './FileSaver'
+],
+    function (declare,
+        lang,
+        array,
+        html,
+        topic,
+        BaseWidget
+    ) {
+        return declare([BaseWidget], {
+            baseClass: 'jimu-widget-filyL',
+            name: 'filyL',
+            flightTool: null,
+            allRoutes: null,
+            flag: false,
+            startup: function () {
+                var that = this;
+                topic.subscribe("beginfilyL", lang.hitch(this, this.beginfilyL));
+                topic.subscribe("closesfilyL", lang.hitch(this, this.closesfilyL));
+                // topic.publish('getbeginSlope', that.beginSlope);
+                $(`.${that.baseClass}`).find('.closeOUR').click(() => {
+                    $(`.${that.baseClass}`).hide();
+                    that.closesfilyL();
+                })
+
+
+                // that.beginfilyL();
+
+
+
+            },
+            beginfilyL: function () {
+                console.log(`${this.name}--kaishi`);
+                var that = this;
+                var viewer = that.map;
+                //飞机飞行
+                this.flag = true;
+                this.init();
+
+            },
+            init: function init(evt) {
+                var self = this;
+                var that = this;
+                var viewer = that.map
+                    , scene = viewer.scene;
+                //实例化飞行工具
+                self.flightTool = new Fly_NZC(self.map);
+
+                //获取全部路线数据
+                $.ajax({
+                    url: "./widgets/filyL/flyroute.json",
+                    // http://sw797.com:82/blade-ycreal/flyroute/detail?id=1
+                    // type: "POST",
+                    dataType: "json",
+                    success: function success(data) {
+                        if (data.length == undefined) return;
+                        // let datas = data.data;
+                        self.allRoutes = data;
+
+                        $("#flightRoutefilyL").empty();
+                        $('#passPointfilyL').empty();
+
+                        // if (data.code == 200) {
+                        for (var i = 0; i < data.length; i++) {
+                            $("#flightRoutefilyL").append('<option value = ' + data[i].name + ' > ' + data[i].name + ' </option>');
+                        }
+                        // }
+
+
+                        self._loadRoute(self.allRoutes[0].sites);
+
+                        $("#flightRoutefilyL").on("change", function (e) {
+                            var selectRoute = self.allRoutes.find(function (x) {
+                                return x.name == $("#flightRoutefilyL").val();
+                            });
+                            self._loadRoute(selectRoute.sites);
+                        });
+
+                        //初始加载默认路线
+                        //self._loadRoute(self.allRoutes[0].sites);
+                    }
+                });
+
+                //开始漫游
+                $("#ksfilyL").click(function () {
+                    self.flightTool.flyManager.play();
+                });
+                //暂停漫游
+                $("#ztfilyL").click(function () {
+                    self.flightTool.flyManager.pause();
+                });
+                //停止漫游
+                $("#tzfilyL").click(function () {
+                    self.flightTool.flyManager.stop();
+                });
+                //删除路线
+                $("#detelefilyL").click(function () {
+                    self.flightTool.RouteCollection.removeAllSites();
+
+                    $("#passPointfilyL").empty();
+                });
+
+                //绘制路线
+                // var pointHandler = new Cesium.DrawHandler(viewer, Cesium.DrawMode.Point);//添加鼠标点事件
+                var dataArr = [],
+                    id = 3;
+
+                // pointHandler.drawEvt.addEventListener(function (result) {
+
+                // });
+                var handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
+
+                $("#addfilyL").click(function () {
+                    var liStr = "<li class='item'>途径点" + ($("#passPointfilyL").children().length + 1) + "</li>";
+                    var liDom = $(liStr);
+                    var lat = 0;
+                    var lng = 0;
+                    var height = 0;
+                    // 鼠标移动时间回调
+                    handler.setInputAction(function (e) {
+                        // 若此标记为false,则激活对可视域分析对象的操作
+                        // console.log(e,1213486)
+                        //     //获取鼠标屏幕坐标,并将其转化成笛卡尔坐标
+                        var position = e.endPosition;
+                        var last = scene.pickPosition(position);
+                        console.log(position, 'position')
+                        // 将鼠标当前点坐标转化成经纬度
+                        // var cartographic = Cesium.Cartographic.fromCartesian(last);
+                        // lat = Cesium.Math.toDegrees(cartographic.longitude);
+                        // lng = Cesium.Math.toDegrees(cartographic.latitude);
+                        // height = cartographic.height;
+                        var ray = viewer.camera.getPickRay(position);
+                        var cartesian = viewer.scene.globe.pick(ray, viewer.scene);
+                        // console.log(cartesian, 'cartesian')
+
+                        lat = cartesian.y;
+                        lng = cartesian.x;
+                        height = cartesian.z;
+
+                    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+                    // 鼠标左键时间回调
+                    handler.setInputAction(function (e) {
+                        var data = {};
+                        data.ids = id;
+                        data.position_x = lng;
+                        data.position_y = lat;
+                        data.position_z = height + 10;
+                        data.heading = 0;
+                        data.pitch = -1;
+                        data.roll = 0;
+                        // data.heading = 6.108652381980;
+                        // data.pitch = -0.653625804871;
+                        // data.roll = 0;
+                        data.time = 10;
+                        dataArr.push(data);
+                        // console.log(dataArr, 'dataArr');
+                        // console.log(id, 'id')
+
+                        self.flightTool.RouteCollection.AddSite(data);
+                        // console.log(id, 'id2')
+                        liDom.on('click', data, function (event) {
+                            // console.log(event)
+                            var site = self.flightTool.RouteCollection.getSiteByIndex(event.data.id);
+                            self.flightTool.flyManager.viewToSite(data);
+                        });
+
+                        $('#passPointfilyL').append(liDom);
+                        self.flightTool.RouteCollection.AddSiteByView(id);
+                        id++;
+                        handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+                        handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
+                    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+
+
+                    // var liStr = "<li class='item'>途径点" + ($("#passPointfilyL").children().length + 1) + "</li>";
+                    // var liDom = $(liStr);
+
+                    // var camera = self.map.scene.camera;
+
+                    // var cartographic = Cesium.Cartographic.fromCartesian(camera.position);
+                    // var lat = Cesium.Math.toDegrees(cartographic.latitude);
+                    // var lng = Cesium.Math.toDegrees(cartographic.longitude);
+                    // var height = cartographic.height;
+
+                    // var data = {};
+                    // // data.id = id;
+                    // // data.lgtd = lng;
+                    // // data.lttd = lat;
+                    // // data.height = height;
+                    // // data.heading = Cesium.Math.toDegrees(camera.heading);
+                    // // data.pitch = Cesium.Math.toDegrees(camera.pitch);
+                    // // data.roll = Cesium.Math.toDegrees(camera.roll);
+                    // data.id = id;
+                    // data.lgtd = lng;
+                    // data.lttd = lat;
+                    // data.height = height;
+                    // data.heading = Cesium.Math.toDegrees(camera.heading);
+                    // data.pitch = Cesium.Math.toDegrees(camera.pitch);
+                    // data.roll = Cesium.Math.toDegrees(camera.roll);
+                    // data.time = null;
+                    // dataArr.push(data);
+
+                    // liDom.on('click', data, function (event) {
+                    // });
+
+                    // $('#passPointfilyL').append(liDom);
+
+                    // self.flightTool.RouteCollection.AddSiteByView(id);
+                    // id++;
+                });
+                //视角固定
+                $("#openViewL").click(function () {
+                    self.flightTool.flyManager.openView();
+                })
+                //导出路线
+                $("#exportfilyL").click(function () {
+                    for (var i = 0; i < dataArr.length - 1; i++) {
+                        var a = Cesium.Cartesian3.fromDegrees(dataArr[i].lgtd, dataArr[i].lttd, dataArr[i].height);
+                        var b = Cesium.Cartesian3.fromDegrees(dataArr[i + 1].lgtd, dataArr[i + 1].lttd, dataArr[i + 1].height);
+                        var c = self.getSpaceDistance([a, b]);
+                        dataArr[i].time = c;
+                    }
+
+                    var data = {
+                        name: $('#routeNamefilyL').val(),
+                        sites: dataArr
+                    };
+                    var content = JSON.stringify(data);
+                    var blob = new Blob([content], {
+                        type: "text/plain;charset=utf-8"
+                    });
+                    saveAs(blob, "save.json");
+                    dataArr = [];
+                });
+
+                topic.subscribe("autoRoam", lang.hitch(this, this._executeRoam));
+
+                topic.subscribe("stopflay", lang.hitch(this, this._stopFlay));
+            },
+
+            closesfilyL: function (froms) {
+                console.log(`${this.name}--guanbi`);
+                // var that = this;
+
+                var self = this;
+                if (item == this.name && this.flag == true) {
+                    this.flag = false;
+                    // $('.jimu-widget-filyL').hide();
+                    // $('.jimu-widget-visualAngle .v-a-One').addClass('on').siblings().removeClass('on');
+                    self.flightTool.flyManager.stop();
+                    self.flightTool.RouteCollection.removeAllSites();
+                }
+            },
+            //空间两点距离计算函数
+            getSpaceDistance: function getSpaceDistance(positions) {
+                var distance = 0;
+                for (var i = 0; i < positions.length - 1; i++) {
+
+                    var point1cartographic = Cesium.Cartographic.fromCartesian(positions[i]);
+                    var point2cartographic = Cesium.Cartographic.fromCartesian(positions[i + 1]);
+                    /**根据经纬度计算出距离**/
+                    var geodesic = new Cesium.EllipsoidGeodesic();
+                    geodesic.setEndPoints(point1cartographic, point2cartographic);
+                    var s = geodesic.surfaceDistance;
+                    //返回两点之间的距离
+                    s = Math.sqrt(Math.pow(s, 2) + Math.pow(point2cartographic.height - point1cartographic.height, 2));
+                    distance = distance + s;
+                }
+                return (distance / 70);
+            },
+
+            _executeRoam: function _executeRoam(data) {
+                this.flightTool.flyManager.stop();
+                this.flightTool.RouteCollection.removeAllSites();
+                var selectRoute = this.allRoutes.find(function (x) {
+                    return x.name == data;
+                });
+                for (var i = 0; i < selectRoute.sites.length; i++) {
+                    var cartesian3 = Cesium.Cartesian3.fromDegrees(selectRoute.sites[i].lgtd, selectRoute.sites[i].lttd, selectRoute.sites[i].height);
+                    var site = {
+                        "ids": selectRoute.sites[i].id,
+                        "position_x": cartesian3.x,
+                        "position_y": cartesian3.y,
+                        "position_z": cartesian3.z,
+                        "pitch": Cesium.Math.toRadians(selectRoute.sites[i].pitch),
+                        "heading": Cesium.Math.toRadians(selectRoute.sites[i].heading),
+                        "roll": Cesium.Math.toRadians(selectRoute.sites[i].roll),
+                        "time": selectRoute.sites[i].time
+                    };
+                    this.flightTool.allSites[i] = site;
+                }
+                this.flightTool.flyManager.play();
+            },
+
+            _stopFlay: function _stopFlay(data) {
+                if (data) {
+                    this.flightTool.flyManager.stop();
+                    this.flightTool.RouteCollection.removeAllSites();
+                }
+            },
+
+            _loadRoute: function _loadRoute(route) {
+                console.log(route)
+                var self = this;
+                $("#passPointfilyL").empty();
+                self.flightTool.RouteCollection.AddRoute(route);
+                for (var j = 0; j < route.length; j++) {
+                    var liStr = "<li class='item'>q途径点" + (j + 1) + "</li>";
+                    var liDom = $(liStr);
+                    liDom.on('click', route[j], function (event) {
+                        var site = self.flightTool.RouteCollection.getSiteByIndex(event.data.id);
+                        self.flightTool.flyManager.viewToSite(site);
+                    });
+                    $('#passPointfilyL').append(liDom);
+                }
+            },
+            onOpen: function () {
+
+            },
+
+            onClose: function () {
+                //面板关闭的时候触发 (when this panel is closed trigger)
+                console.log('jies')
+            },
+
+            onMinimize: function () {
+                this.resize();
+            },
+
+            onMaximize: function () {
+                this.resize();
+            },
+
+            resize: function () {
+
+            },
+
+            destroy: function () {
+                //销毁的时候触发
+                //todo
+                //do something before this func
+                this.inherited(arguments);
+            }
+
+        });
+    });
diff --git a/widgets/filyL/css/a.css b/widgets/filyL/css/a.css
new file mode 100644
index 0000000..91e7f99
--- /dev/null
+++ b/widgets/filyL/css/a.css
@@ -0,0 +1,160 @@
+.jimu-widget-FlyRoute {
+    width: 100%;
+    height: 100%;
+    overflow-x: hidden;
+    background-color: rgba(255, 255, 255, 0.8);
+    display: none;
+    font-size: 14px;
+    border: 1px solid rgb(212, 212, 212);
+    border-radius: 5px;
+    color: rgb(0, 0, 0);
+    z-index: 9 !important;
+}
+
+/* 头部 */
+.jimu-widget-FlyRoute .fly-route-header {
+    position: relative;
+    width: 100%;
+    height: 40px;
+    line-height: 40px;
+    font-size: 20px;
+    border-bottom: 1px solid rgb(184, 184, 184);
+}
+
+.jimu-widget-FlyRoute .fly-route-header i {
+    display: inline-block;
+    margin-left: 6px;
+    vertical-align: middle;
+    width: 20px;
+    height: 20px;
+    background: url(../../../images/toolbox.png ) no-repeat 0 -176px;
+    background-size: 20px;
+}
+
+.jimu-widget-FlyRoute .fly-route-header .close-flyrouter {
+    position: absolute;
+    top: 50%;
+    right: 8px;
+    font-size: 38px;
+    font-weight: 400;
+    height: 28px;
+    line-height: 18px;
+    /* display: flex;
+	align-items: center;
+	justify-content: center; */
+
+    cursor: pointer;
+    transform: translateY(-50%);
+}
+
+
+
+.jimu-widget-FlyRoute input,
+.jimu-widget-FlyRoute select {
+    border: 0;
+}
+
+.jimu-widget-FlyRoute .fly-route-continer {
+    /* margin: 10px 8px; */
+    position: absolute;
+    top: 51px;
+    left: 10px;
+    right: 10px;
+    bottom: 10px;
+}
+
+/* 选择框,或者说选择飞行路线 */
+.jimu-widget-FlyRoute .fly-route-control #flightRoute {
+    width: 100%;
+    height: 30px;
+}
+
+/* 控制按钮 */
+.jimu-widget-FlyRoute .fly-route-continer .fly-route-control-btn,
+.jimu-widget-FlyRoute .fly-route-continer .fly-route-new-btn {
+    margin-top: 10px;
+    width: 100%;
+}
+
+.jimu-widget-FlyRoute .fly-route-continer .fly-route-control-btn input,
+.jimu-widget-FlyRoute .fly-route-continer .fly-route-new-btn input {
+    margin: 0 1%;
+    width: 30%;
+    height: 30px;
+    color: #fff;
+    background: rgb(62, 159, 252);
+    border: 1px solid rgb(69, 154, 251);
+    border-radius: 4px;
+    cursor: pointer;
+}
+
+
+.jimu-widget-FlyRoute .fly-route-continer .fly-route-new {
+    position: absolute;
+    top: 80px;
+    bottom: 0px;
+    width: 100%;
+}
+
+.jimu-widget-FlyRoute .fly-route-continer .fly-route-new-top {
+    height: 24px;
+    line-height: 24px;
+    font-size: 16px;
+}
+
+.jimu-widget-FlyRoute .fly-route-continer .fly-route-new-top span {
+    margin: 0;
+    display: inline-block;
+    width: 80px;
+    /* height: 16px !important; */
+}
+
+.jimu-widget-FlyRoute .fly-route-continer .fly-route-new-top input {
+    margin: 0;
+    width: 150px;
+    height: 24px;
+    vertical-align: top;
+    border: none;
+}
+
+.jimu-widget-FlyRoute .fly-route-continer .fly-route-new>div:nth-child(3) {
+    position: absolute;
+    top: 64px;
+    left: 0;
+    bottom: 0;
+    width: 100%;
+    height: auto;
+
+}
+
+.jimu-widget-FlyRoute #passPoint,
+.jimu-widget-FlyRoute #passPoint li {
+    margin: 0;
+    padding: 0;
+}
+
+.jimu-widget-FlyRoute #passPoint {
+    height: 100%;
+    list-style: none;
+    overflow: auto;
+}
+
+.jimu-widget-FlyRoute #passPoint li {
+    margin: 10px 40px;
+}
+
+.jimu-widget-FlyRoute .item {
+    background: #3E9FFC;
+    border-radius: 5px;
+    height: 20px;
+    padding-left: 5px;
+    color: white;
+    font-family: "微软雅黑";
+    text-align: center;
+    margin-bottom: 5px;
+    cursor: pointer;
+}
+
+.jimu-widget-FlyRoute .item:nth-child(1) {
+    margin-top: 20px !important;
+}
\ No newline at end of file
diff --git a/widgets/filyL/css/style.css b/widgets/filyL/css/style.css
new file mode 100644
index 0000000..28ce52f
--- /dev/null
+++ b/widgets/filyL/css/style.css
@@ -0,0 +1,188 @@
+@import url(./a.css);
+.jimu-widget-filyL {
+  position: fixed !important;
+  top: 72px !important;
+  right: 388px !important;
+  width: 300px !important;
+  height: 600px !important;
+  background-color: rgb(255, 255, 255);
+  font-size: 14px;
+  color: rgb(0, 0, 0);
+  z-index: 12 !important;
+  border-radius: 10px;
+  display: none;
+  box-shadow: 0 0 8px #fff;
+  padding: 0px 5px !important;
+}
+
+.jimu-widget-filyL .closeOUR {
+  position: absolute;
+  right: 5px;
+  top: 5px;
+  font-size: 18px;
+  cursor: pointer;
+}
+
+.jimu-widget-filyL .closeOUR:hover {
+  color: red;
+}
+
+/* .jimu-widget-filyL .but {
+  line-height: 30px;
+  width: 80px;
+  height: 30px;
+  font-size: 14px;
+  border-radius: 5px;
+  box-shadow: 2px 2px 15px -5px #378ef1;
+   border: 1px solid transparent;
+  background-color: #fff;
+}
+
+.jimu-widget-filyL .but:hover {
+  box-shadow: 2px 2px 25px -5px #1679eb;
+} */
+
+/* 头部 */
+
+.jimu-widget-filyL .fly-route-header {
+  position: relative;
+  width: 100%;
+  height: 40px;
+  line-height: 40px;
+  font-size: 20px;
+  border-bottom: 1px solid rgb(184, 184, 184);
+}
+
+.jimu-widget-filyL .fly-route-header i {
+  display: inline-block;
+  margin-left: 6px;
+  vertical-align: middle;
+  width: 20px;
+  height: 20px;
+  background: url(../../../images/toolbox.png ) no-repeat 0 -176px;
+  background-size: 20px;
+}
+
+.jimu-widget-filyL .fly-route-header .close-flyrouter {
+  position: absolute;
+  top: 50%;
+  right: 8px;
+  font-size: 38px;
+  font-weight: 400;
+  height: 28px;
+  line-height: 18px;
+  /* display: flex;
+align-items: center;
+justify-content: center; */
+  cursor: pointer;
+  transform: translateY(-50%);
+}
+
+.jimu-widget-filyL input, .jimu-widget-filyL select {
+  border: 0;
+}
+
+.jimu-widget-filyL .fly-route-continer {
+  /* margin: 10px 8px; */
+  position: absolute;
+  top: 51px;
+  left: 10px;
+  right: 10px;
+  bottom: 10px;
+}
+
+/* 选择框,或者说选择飞行路线 */
+
+.jimu-widget-filyL .fly-route-control #flightRoute {
+  width: 100%;
+  height: 30px;
+}
+
+/* 控制按钮 */
+
+.jimu-widget-filyL .fly-route-continer .fly-route-control-btn, .jimu-widget-filyL .fly-route-continer .fly-route-new-btn {
+  margin-top: 10px;
+  width: 100%;
+}
+
+.jimu-widget-filyL .fly-route-continer .fly-route-control-btn input, .jimu-widget-filyL .fly-route-continer .fly-route-new-btn input {
+  margin: 0 1%;
+  /* width: 20%; */
+  height: 30px;
+  color: #fff;
+  background: rgb(62, 159, 252);
+  border: 1px solid rgb(69, 154, 251);
+  border-radius: 4px;
+  cursor: pointer;
+  padding: 0 5px;
+}
+.jimu-widget-filyL .fly-route-continer .fly-route-new {
+  position: absolute;
+  top: 80px;
+  bottom: 0px;
+  width: 100%;
+}
+.jimu-widget-filyL #openViewL{
+  position:relative;
+  top: 5px;
+}
+.jimu-widget-filyL .fly-route-continer .fly-route-new-top {
+  height: 24px;
+  line-height: 24px;
+  font-size: 16px;
+}
+
+.jimu-widget-filyL .fly-route-continer .fly-route-new-top span {
+  margin: 0;
+  display: inline-block;
+  width: 80px;
+  /* height: 16px !important; */
+}
+
+.jimu-widget-filyL .fly-route-continer .fly-route-new-top input {
+  margin: 0;
+  width: 150px;
+  height: 24px;
+  vertical-align: top;
+  border: none;
+}
+
+.jimu-widget-filyL .fly-route-continer .fly-route-new>div:nth-child(3) {
+  position: absolute;
+  top: 90px;
+  left: 0;
+  bottom: 0;
+  width: 100%;
+  height: auto;
+}
+
+.jimu-widget-filyL #passPoint, .jimu-widget-filyL #passPoint li {
+  margin: 0;
+  padding: 0;
+}
+
+.jimu-widget-filyL #passPoint {
+  height: 100%;
+  list-style: none;
+  overflow: auto;
+}
+
+.jimu-widget-filyL #passPoint li {
+  margin: 10px 40px;
+}
+
+.jimu-widget-filyL .item {
+  background: #3E9FFC;
+  border-radius: 5px;
+  height: 20px;
+  padding-left: 5px;
+  color: white;
+  font-family: "微软雅黑";
+  text-align: center;
+  margin-bottom: 5px;
+  cursor: pointer;
+}
+
+.jimu-widget-filyL .item:nth-child(1) {
+  margin-top: 20px !important;
+}
\ No newline at end of file
diff --git a/widgets/filyL/fly.js b/widgets/filyL/fly.js
new file mode 100644
index 0000000..cc5ce27
--- /dev/null
+++ b/widgets/filyL/fly.js
@@ -0,0 +1,529 @@
+function newSite(x, y, z, h, p, time, ids) {
+    if (x != null && y != null && z != null && h != null && p != null && time != null && ids != null) {
+        this.position_x = x;
+        this.position_y = y;
+        this.position_z = z;
+        this.pitch = p;
+        this.heading = h;
+        this.time = time;
+        this.ids = ids;
+    } else {
+        return false;
+    }
+}
+
+function Fly_NZC(viewer) {
+    this.viewer = viewer;
+    this.scene = viewer.scene;
+    this.entities = viewer.entities;
+    //全部飞行站点数组
+    this.allSites = [];
+    var that = this;
+    this.checkIds = function (ids) {
+        console.log(ids, 'cids')
+        console.log(that.allSites, 'that.allSites')
+        for (var i = 0; i < that.allSites.length + 1; i++) {
+            if (i == that.allSites.length) {
+                console.log(i, 'endcids')
+                return false;
+                break;
+            }
+            if (that.allSites[i].ids == ids) {
+                console.log(i, 'havecids')
+                return i;
+                break;
+            }
+        }
+
+        // img_path
+    };
+    this.RouteCollection = {
+        //线颜色
+        //LineColor:Cesium.Color.WHITE,
+        //站点和路线显隐是否开启
+        point_show: true,
+        line_show: true,
+        //站点图片路径
+        img_path: "widgets/FlyRoute/images/location4.png",
+        //飞行路线颜色
+        /* setLineColor:function(){
+              Cesium.Color.WHITE,
+         },*/
+        AddRoute: function (Route) {
+            this.deleteEntities();
+            that.allSites = [];
+            for (var i = 0; i < Route.length; i++) {
+                let cartesian3 = Cesium.Cartesian3.fromDegrees(Route[i].lgtd, Route[i].lttd, Route[i].height);
+                let site = {
+                    "ids": Route[i].id,
+                    "position_x": cartesian3.x,
+                    "position_y": cartesian3.y,
+                    "position_z": cartesian3.z,
+                    "pitch": Cesium.Math.toRadians(Route[i].pitch),
+                    "heading": Cesium.Math.toRadians(Route[i].heading),
+                    "roll": Cesium.Math.toRadians(Route[i].roll),
+                    "time": Route[i].time
+                };
+                that.allSites[i] = site;
+            }
+            this.controlEntities();
+
+        },
+        //设置点图片
+        setPointImg: function (path) {
+
+            this.img_path = path;
+            this.controlEntities();
+
+        },
+        //mod=0为设置点的可见,1为设置线的可见,2为控制点和线的可见
+        setVisible: function (mod, bool) {
+            if (mod === 0) {
+                this.point_show = bool;
+            }
+            if (mod === 1) {
+                this.line_show = bool;
+            }
+            if (mod === 2) {
+                this.point_show = bool;
+                this.line_show = bool;
+            }
+            this.controlEntities();
+
+        },
+        //通过传入站点类添加站点
+        AddSite: function (newSite) {
+            //判断id是否重复
+            console.log(newSite.ids)
+            var bool = that.checkIds(newSite.ids);
+            if (bool) {
+                return false;
+            } else {
+                var Site = {};
+                Site.position_x = newSite.position_x;
+                Site.position_y = newSite.position_y;
+                Site.position_z = newSite.position_z;
+                Site.heading = newSite.heading;
+                Site.pitch = newSite.pitch;
+                //Site.roll=camera.roll;
+                Site.time = newSite.time;
+                Site.ids = newSite.ids;
+                that.allSites.push(Site);
+                this.controlEntities();
+                console.log(that.allSites, '444f')
+                return true;
+            }
+        },
+        //添加当前视角为站点需要传入id
+        AddSiteByView: function (ids) {
+            //判断id是否重复
+            console.log(ids, 'ids')
+            var bool = that.checkIds(ids);
+            if (bool) {
+                return false;
+            } else {
+                try {
+                    var position = that.scene.camera.position;
+                    //获取当前相机位置参数(飞行用)
+                    var Site = {};
+                    Site.position_x = position.x;
+                    Site.position_y = position.y;
+                    Site.position_z = position.z;
+                    Site.heading = that.scene.camera.heading;
+                    Site.pitch = that.scene.camera.pitch;
+                    Site.roll = that.scene.camera.roll;
+                    Site.time = 3;
+                    Site.ids = ids;
+                    //添加到站点数组
+                    // that.allSites.push(Site);
+                    this.controlEntities();
+                    return true;
+                } catch (e) {
+                    return false;
+                }
+
+            }
+        },
+        //根据索引获取站点信息
+        getSiteByIndex: function (index) {
+            console.log(that.allSites[index], 'site.index');
+            return that.allSites[index];
+        },
+        deleteEntities: function () {
+            //50000+为线id
+            for (var i = 0; i < that.allSites.length; i++) {
+                that.entities.removeById(that.allSites[i].ids);
+            }
+            for (var i = 1; i < 500000; i++) {
+                var ids = parseInt(50000 + i);
+                var entities_del = that.entities.getById(ids);
+                if (entities_del) {
+                    that.entities.remove(entities_del);
+                } else {
+                    break;
+                }
+
+            }
+        },
+        controlEntities: function () {
+            var position_1, position_2, x1, x2, y1, y2, z1, z2, point_1_cartographic, point_2_cartographic;
+            //添加和删除站点,更改颜色或图片后,先清空entities,然后重新添加。
+            this.deleteEntities();
+            //添加显示的站点
+            var length = that.allSites.length;
+            if (this.point_show == true) {
+                for (var j = 0; j < length; j++) {
+                    that.entities.add({
+                        position: new Cesium.Cartesian3(that.allSites[j].position_x, that.allSites[j].position_y, that.allSites[j].position_z),
+                        billboard: {
+                            image: this.img_path,
+                            width: 30,
+                            height: 40,
+                        },
+                        //name : 10000+j,
+                        id: that.allSites[j].ids
+                    });
+                }
+            }
+            //添加显示的线
+            if (this.line_show == true) {
+                for (var j = 1; j < length; j++) {
+                    //将笛卡尔坐标转为经纬度坐标,用于绘制线
+                    position_1 = new Cesium.Cartesian3(that.allSites[j].position_x, that.allSites[j].position_y, that.allSites[j].position_z)
+                    point_1_cartographic = Cesium.Cartographic.fromCartesian(position_1);
+                    console.log(position_1, '555f')
+                    x1 = Cesium.Math.toDegrees(point_1_cartographic.longitude);
+                    y1 = Cesium.Math.toDegrees(point_1_cartographic.latitude);
+                    z1 = point_1_cartographic.height;
+
+                    position_2 = new Cesium.Cartesian3(that.allSites[j - 1].position_x, that.allSites[j - 1].position_y, that.allSites[j - 1].position_z)
+                    point_2_cartographic = Cesium.Cartographic.fromCartesian(position_2);
+                    x2 = Cesium.Math.toDegrees(point_2_cartographic.longitude);
+                    y2 = Cesium.Math.toDegrees(point_2_cartographic.latitude);
+                    z2 = point_2_cartographic.height;
+                    that.entities.add({
+                        id: 50000 + j,
+                        // name : drowallStops.length,
+                        polyline: {
+                            positions: Cesium.Cartesian3.fromDegreesArrayHeights([x1, y1, z1, x2, y2, z2]),
+                            width: 5,
+                            material: Cesium.Color.WHITE
+                        }
+                    });
+
+                }
+            }
+            //如果关闭显示了站点和飞行路线,添加的新站点和飞行路线将先不显示
+            if (this.line_show == false) {
+                for (var j = 1; j < length; j++) {
+                    //将笛卡尔坐标转为经纬度坐标,用于绘制线
+                    position_1 = new Cesium.Cartesian3(that.allSites[j].position_x, that.allSites[j].position_y, that.allSites[j].position_z)
+                    point_1_cartographic = Cesium.Cartographic.fromCartesian(position_1);
+                    x1 = Cesium.Math.toDegrees(point_1_cartographic.longitude);
+                    y1 = Cesium.Math.toDegrees(point_1_cartographic.latitude);
+                    z1 = point_1_cartographic.height;
+
+                    position_2 = new Cesium.Cartesian3(that.allSites[j - 1].position_x, that.allSites[j - 1].position_y, that.allSites[j - 1].position_z)
+                    point_2_cartographic = Cesium.Cartographic.fromCartesian(position_2);
+                    x2 = Cesium.Math.toDegrees(point_2_cartographic.longitude);
+                    y2 = Cesium.Math.toDegrees(point_2_cartographic.latitude);
+                    z2 = point_2_cartographic.height;
+                    that.entities.add({
+                        id: 50000 + j,
+                        show: false,
+                        // name : drowallStops.length,
+                        polyline: {
+                            positions: Cesium.Cartesian3.fromDegreesArrayHeights([x1, y1, z1, x2, y2, z2]),
+                            width: 5,
+                            material: Cesium.Color.WHITE
+                        }
+                    });
+
+                }
+
+            }
+            if (this.point_show == false) {
+                for (var j = 0; j < length; j++) {
+                    that.entities.add({
+                        position: new Cesium.Cartesian3(that.allSites[j].position_x, that.allSites[j].position_y, that.allSites[j].position_z),
+                        billboard: {
+                            image: this.img_path,
+                            width: 30,
+                            height: 40,
+                        },
+                        show: false,
+                        //name : 10000+j,
+                        id: that.allSites[j].ids
+                    });
+                }
+            }
+        },
+        removeAllSites: function () {
+            this.deleteEntities();
+            that.allSites = [];
+
+        },
+        removeSiteById: function (ids) {
+            var id = that.checkIds(ids)
+            if (id) {
+                this.deleteEntities();
+                that.allSites.splice(id, 1);
+                this.controlEntities();
+
+            } else {
+                return false
+            }
+
+        }
+
+    };
+    this.l = 0;
+    this.b = 0;
+    //用于判断执行的时暂停还是停止
+    this.play_bool = true;
+    var x, y, z, p, h;
+    this.setInterval_fly = null;
+    this.setcamera = function () {
+        //设置俯仰角
+        var set = that.allSites[that.l].time * 50
+        that.viewer.camera.setView({
+            orientation: {
+                heading: viewer.scene.camera.heading + h / set,
+                pitch: viewer.scene.camera.pitch + p / set,
+                roll: 0.0
+            }
+        });
+        //move移动相机
+        that.viewer.camera.move(new Cesium.Cartesian3(x, y, z), 1 / set);
+        that.b--;
+        if (that.b <= 0) {
+            that.l++;
+            clearInterval(that.setInterval_fly);
+            that.setInterval_fly = null;
+            that.Interval();
+            // that.b=0;
+        }
+    };
+    this.Interval = function () {
+        var l = that.l;
+        if (that.play_bool) {
+            that.b = that.allSites[l].time * 50
+        } else {
+            that.play_bool = true;
+        }
+        if (that.allSites[l + 1]) {
+            x = that.allSites[l + 1].position_x - that.allSites[l].position_x;
+            y = that.allSites[l + 1].position_y - that.allSites[l].position_y;
+            z = that.allSites[l + 1].position_z - that.allSites[l].position_z;
+            p = that.allSites[l + 1].pitch - that.allSites[l].pitch;
+            h = that.allSites[l + 1].heading - that.allSites[l].heading;
+
+            var tem = Cesium.Math.toDegrees(that.allSites[l + 1].heading) - Cesium.Math.toDegrees(that.allSites[l].heading);
+            if (Math.abs(tem) > 180) {
+                if (tem >= 0) {
+                    tem = 360 - tem;
+                } else {
+                    tem = 360 + tem;
+                }
+                h = Cesium.Math.toRadians(tem);
+            }
+            //that.b=that.allSites[l].time*20
+            that.setInterval_fly = setInterval(that.setcamera, 12);
+        } else {
+            that.play_bool = true;
+            that.l = 0;
+            that.scene.screenSpaceCameraController.enableRotate = true;
+            that.scene.screenSpaceCameraController.enableTranslate = true;
+            that.scene.screenSpaceCameraController.enableZoom = true;
+            that.scene.screenSpaceCameraController.enableTilt = true;
+            that.scene.screenSpaceCameraController.enableLook = true;
+        }
+
+    };
+
+    this.flyManager = {
+        img_path: "widgets/FlyRoute/images/location4.png",
+        //用于储存暂停时的位置
+        Site_pause: {},
+        actives: false,
+        isguding: false,
+        openView: function () {
+            if (this.actives == true) {
+                console.log('视角改变');
+                that.scene.screenSpaceCameraController.enableRotate = false;
+                that.scene.screenSpaceCameraController.enableTranslate = false;
+                that.scene.screenSpaceCameraController.enableZoom = false;
+                that.scene.screenSpaceCameraController.enableTilt = false;
+                that.scene.screenSpaceCameraController.enableLook = false;
+
+                // that.scene.screenSpaceCameraController.enableRotate = true;
+                // that.scene.screenSpaceCameraController.enableTranslate = true;
+                // that.scene.screenSpaceCameraController.enableZoom = true;
+                that.scene.screenSpaceCameraController.enableTilt = true;
+                // that.scene.screenSpaceCameraController.enableLook = true;
+                if (this.isguding == true) {
+                    that.scene.screenSpaceCameraController.enableRotate = false;
+                    that.scene.screenSpaceCameraController.enableTranslate = false;
+                    that.scene.screenSpaceCameraController.enableZoom = false;
+                    that.scene.screenSpaceCameraController.enableTilt = false;
+                    that.scene.screenSpaceCameraController.enableLook = false;
+                }
+                this.isguding = !this.isguding;
+            } else {
+                console.log('未开始飞行');
+            }
+        },
+        play: function () {
+            this.actives = true;
+            for (var i = 0; i < that.allSites.length; i++) {
+                that.entities.removeById(that.allSites[i].ids);
+            }
+
+            //如果之前点的时停止重新开始飞行
+            if (that.allSites.length > 1) {
+                that.scene.screenSpaceCameraController.enableRotate = false;
+                that.scene.screenSpaceCameraController.enableTranslate = false;
+                that.scene.screenSpaceCameraController.enableZoom = false;
+                that.scene.screenSpaceCameraController.enableTilt = false;
+                that.scene.screenSpaceCameraController.enableLook = false;
+
+
+                if (that.play_bool) {
+                    //设置初始点
+                    that.scene.camera.setView({
+                        destination: new Cesium.Cartesian3(that.allSites[that.l].position_x, that.allSites[that.l].position_y, that.allSites[that.l].position_z),
+                        orientation: {
+                            heading: that.allSites[that.l].heading,
+                            pitch: that.allSites[that.l].pitch,
+                            roll: that.allSites[that.l].roll
+                        }
+                    });
+                    if (that.setInterval_fly) {
+                        clearInterval(that.setInterval_fly);
+                    }
+                    that.Interval();
+
+                } else {
+                    //如果之前是暂停,继续飞行
+                    that.scene.camera.setView({
+                        //将经度、纬度、高度的坐标转换为笛卡尔坐标
+                        destination: new Cesium.Cartesian3(this.Site_pause.position_x, this.Site_pause.position_y, this.Site_pause.position_z),
+                        orientation: {
+                            heading: this.Site_pause.heading,
+                            pitch: this.Site_pause.pitch,
+                            roll: this.Site_pause.roll
+                        }
+                    });
+
+                    that.Interval();
+                }
+            }
+
+        },
+        stop: function () {
+            //添加显示的站点
+            this.actives = false;
+            var length = that.allSites.length;
+            for (var j = 0; j < length; j++) {
+                var flag = false;
+                for (var i = 0; i < that.entities.values.length; i++) {
+                    if (that.allSites[j].ids == that.entities.values[i].id) {
+                        flag = true
+                    }
+                }
+                if (flag == false) {
+                    that.entities.add({
+                        position: new Cesium.Cartesian3(that.allSites[j].position_x, that.allSites[j].position_y, that.allSites[j].position_z),
+                        billboard: {
+                            image: this.img_path,
+                            width: 30,
+                            height: 40,
+                        },
+                        //name : 10000+j,
+                        id: that.allSites[j].ids
+                    });
+                }
+            }
+            if (that.setInterval_fly != null) {
+                clearInterval(that.setInterval_fly);
+                that.setInterval_fly = null;
+            }
+            that.l = 0;
+            that.play_bool = true;
+            that.scene.screenSpaceCameraController.enableRotate = true;
+            that.scene.screenSpaceCameraController.enableTranslate = true;
+            that.scene.screenSpaceCameraController.enableZoom = true;
+            that.scene.screenSpaceCameraController.enableTilt = true;
+            that.scene.screenSpaceCameraController.enableLook = true;
+        },
+        pause: function () {
+            actives = false;
+            //添加显示的站点
+            var length = that.allSites.length;
+            for (var j = 0; j < length; j++) {
+                var flag = false;
+                for (var i = 0; i < that.entities.values.length; i++) {
+                    if (that.allSites[j].ids == that.entities.values[i].id) {
+                        flag = true
+                    }
+                }
+                if (flag == false) {
+                    that.entities.add({
+                        position: new Cesium.Cartesian3(that.allSites[j].position_x, that.allSites[j].position_y, that.allSites[j].position_z),
+                        billboard: {
+                            image: this.img_path,
+                            width: 30,
+                            height: 40,
+                        },
+                        //name : 10000+j,
+                        id: that.allSites[j].ids
+                    });
+                }
+            }
+            if (that.setInterval_fly != null) {
+                clearInterval(that.setInterval_fly);
+                that.setInterval_fly = null;
+                that.play_bool = false;
+            }
+            //获取暂停时的camera数据
+            var position = that.scene.camera.position;
+            this.Site_pause.position_x = position.x;
+            this.Site_pause.position_y = position.y;
+            this.Site_pause.position_z = position.z;
+            this.Site_pause.heading = that.scene.camera.heading;
+            this.Site_pause.pitch = that.scene.camera.pitch;
+            this.Site_pause.roll = that.scene.camera.roll;
+
+
+            that.scene.screenSpaceCameraController.enableRotate = true;
+            that.scene.screenSpaceCameraController.enableTranslate = true;
+            that.scene.screenSpaceCameraController.enableZoom = true;
+            that.scene.screenSpaceCameraController.enableTilt = true;
+            that.scene.screenSpaceCameraController.enableLook = true;
+
+        },
+        SetStartSite: function (ids) {
+            var bool = that.checkIds(ids);
+            if (bool) {
+                that.l = bool;
+                return true;
+            } else {
+                return false;
+            }
+
+        },
+        viewToSite: function (site) {
+            console.log(site, 'viewto')
+            that.scene.camera.setView({
+                destination: new Cesium.Cartesian3(site.position_x - 1000, site.position_y + 2000, site.position_z),
+                orientation: {
+                    heading: site.heading,
+                    pitch: site.pitch,
+                    roll: site.roll
+                }
+            });
+
+        }
+
+    };
+}
\ No newline at end of file
diff --git a/widgets/filyL/flyroute.json b/widgets/filyL/flyroute.json
new file mode 100644
index 0000000..a78e122
--- /dev/null
+++ b/widgets/filyL/flyroute.json
@@ -0,0 +1,55 @@
+[
+    {
+        "name": "鄱阳湖国家级保护区倾斜飞行路线1",
+        "sites": [{
+            "id": 0,
+            "lgtd": 115.749088,
+            "lttd": 28.674319,
+            "height": 12179.32,
+            "heading": 338.02,
+            "pitch": -70.89,
+            "roll": 0,
+            "time": 10
+        }, {
+            "id": 1,
+            "lgtd": 115.741067,
+            "lttd": 28.695646,
+            "height": 3236.37,
+            "heading": 338.02,
+            "pitch": -70.86,
+            "roll": 0,
+            "time": 10
+        }, {
+            "id": 2,
+            "lgtd": 115.738726,
+            "lttd": 28.702285,
+            "height": 330.00,
+            "heading": 350.00,
+            "pitch": -37.45,
+            "roll": 0,
+            "time": 0
+        }]
+    },
+    {
+        "name": "鄱阳湖国家级保护区倾斜飞行路线2",
+        "sites": [{
+            "id": 0,
+            "lgtd": 115.960852,
+            "lttd": 29.164005,
+            "height": 1497.76,
+            "heading": 87.75,
+            "pitch": -41.49,
+            "roll": 0,
+            "time": 16
+        }, {
+            "id": 1,
+            "lgtd": 116.010312,
+            "lttd": 29.187787,
+            "height": 140.39,
+            "heading": 88.07,
+            "pitch": -24.73,
+            "roll": 0,
+            "time": 0
+        }]
+    }
+]
\ No newline at end of file
diff --git a/widgets/filyL/js/DrawHelper.js b/widgets/filyL/js/DrawHelper.js
new file mode 100644
index 0000000..3427dc4
--- /dev/null
+++ b/widgets/filyL/js/DrawHelper.js
@@ -0,0 +1,1874 @@
+/**
+ * Created by thomas on 9/01/14.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * (c) www.geocento.com
+ * www.metaaps.com
+ *
+ */
+
+var DrawHelper = (function () {
+
+    // static variables
+    var ellipsoid = Cesium.Ellipsoid.WGS84;
+
+    // constructor
+    function _(cesiumWidget) {
+        this._scene = cesiumWidget.scene;
+        this._tooltip = createTooltip(cesiumWidget.container);
+        this._surfaces = [];
+
+        this.initialiseHandlers();
+
+        this.enhancePrimitives();
+
+    }
+
+    _.prototype.initialiseHandlers = function () {
+        var scene = this._scene;
+        var _self = this;
+        // scene events
+        var handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
+        function callPrimitiveCallback(name, position) {
+            if (_self._handlersMuted == true) return;
+            var pickedObject = scene.pick(position);
+            if (pickedObject && pickedObject.primitive && pickedObject.primitive[name]) {
+                pickedObject.primitive[name](position);
+            }
+        }
+        handler.setInputAction(
+            function (movement) {
+                callPrimitiveCallback('leftClick', movement.position);
+            }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+        handler.setInputAction(
+            function (movement) {
+                callPrimitiveCallback('leftDoubleClick', movement.position);
+            }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
+        var mouseOutObject;
+        handler.setInputAction(
+            function (movement) {
+                if (_self._handlersMuted == true) return;
+                var pickedObject = scene.pick(movement.endPosition);
+                if (mouseOutObject && (!pickedObject || mouseOutObject != pickedObject.primitive)) {
+                    !(mouseOutObject.isDestroyed && mouseOutObject.isDestroyed()) && mouseOutObject.mouseOut(movement.endPosition);
+                    mouseOutObject = null;
+                }
+                if (pickedObject && pickedObject.primitive) {
+                    pickedObject = pickedObject.primitive;
+                    if (pickedObject.mouseOut) {
+                        mouseOutObject = pickedObject;
+                    }
+                    if (pickedObject.mouseMove) {
+                        pickedObject.mouseMove(movement.endPosition);
+                    }
+                }
+            }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+        handler.setInputAction(
+            function (movement) {
+                callPrimitiveCallback('leftUp', movement.position);
+            }, Cesium.ScreenSpaceEventType.LEFT_UP);
+        handler.setInputAction(
+            function (movement) {
+                callPrimitiveCallback('leftDown', movement.position);
+            }, Cesium.ScreenSpaceEventType.LEFT_DOWN);
+    }
+
+    _.prototype.setListener = function (primitive, type, callback) {
+        primitive[type] = callback;
+    }
+
+    _.prototype.muteHandlers = function (muted) {
+        this._handlersMuted = muted;
+    }
+
+    // register event handling for an editable shape
+    // shape should implement setEditMode and setHighlighted
+    _.prototype.registerEditableShape = function (surface) {
+        var _self = this;
+
+        // handlers for interactions
+        // highlight polygon when mouse is entering
+        setListener(surface, 'mouseMove', function (position) {
+            surface.setHighlighted(true);
+            if (!surface._editMode) {
+                _self._tooltip.showAt(position, "Click to edit this shape");
+            }
+        });
+        // hide the highlighting when mouse is leaving the polygon
+        setListener(surface, 'mouseOut', function (position) {
+            surface.setHighlighted(false);
+            _self._tooltip.setVisible(false);
+        });
+        setListener(surface, 'leftClick', function (position) {
+            surface.setEditMode(true);
+        });
+    }
+
+    _.prototype.startDrawing = function (cleanUp) {
+        // undo any current edit of shapes
+        this.disableAllEditMode();
+        // check for cleanUp first
+        if (this.editCleanUp) {
+            this.editCleanUp();
+        }
+        this.editCleanUp = cleanUp;
+        this.muteHandlers(true);
+    }
+
+    _.prototype.stopDrawing = function () {
+        // check for cleanUp first
+        if (this.editCleanUp) {
+            this.editCleanUp();
+            this.editCleanUp = null;
+        }
+        this.muteHandlers(false);
+    }
+
+    // make sure only one shape is highlighted at a time
+    _.prototype.disableAllHighlights = function () {
+        this.setHighlighted(undefined);
+    }
+
+    _.prototype.setHighlighted = function (surface) {
+        if (this._highlightedSurface && !this._highlightedSurface.isDestroyed() && this._highlightedSurface != surface) {
+            this._highlightedSurface.setHighlighted(false);
+        }
+        this._highlightedSurface = surface;
+    }
+
+    _.prototype.disableAllEditMode = function () {
+        this.setEdited(undefined);
+    }
+
+    _.prototype.setEdited = function (surface) {
+        if (this._editedSurface && !this._editedSurface.isDestroyed()) {
+            this._editedSurface.setEditMode(false);
+        }
+        this._editedSurface = surface;
+    }
+
+    var material = Cesium.Material.fromType(Cesium.Material.ColorType);
+    material.uniforms.color = new Cesium.Color(1.0, 1.0, 0.0, 0.5);
+
+    var defaultShapeOptions = {
+        ellipsoid: Cesium.Ellipsoid.WGS84,
+        textureRotationAngle: 0.0,
+        height: 0.0,
+        asynchronous: true,
+        show: true,
+        debugShowBoundingVolume: false
+    }
+
+    var defaultSurfaceOptions = copyOptions(defaultShapeOptions, {
+        appearance: new Cesium.EllipsoidSurfaceAppearance({
+            aboveGround: false
+        }),
+        material: material,
+        granularity: Math.PI / 180.0
+    });
+
+    var defaultPolygonOptions = copyOptions(defaultShapeOptions, {});
+    var defaultExtentOptions = copyOptions(defaultShapeOptions, {});
+    var defaultCircleOptions = copyOptions(defaultShapeOptions, {});
+    var defaultEllipseOptions = copyOptions(defaultSurfaceOptions, { rotation: 0 });
+
+    var defaultPolylineOptions = copyOptions(defaultShapeOptions, {
+        width: 5,
+        geodesic: true,
+        granularity: 10000,
+        appearance: new Cesium.PolylineMaterialAppearance({
+            aboveGround: false
+        }),
+        material: material
+    });
+
+    //    Cesium.Polygon.prototype.setStrokeStyle = setStrokeStyle;
+    //    
+    //    Cesium.Polygon.prototype.drawOutline = drawOutline;
+    //
+
+    var ChangeablePrimitive = (function () {
+        function _() {
+        }
+
+        _.prototype.initialiseOptions = function (options) {
+
+            fillOptions(this, options);
+
+            this._ellipsoid = undefined;
+            this._granularity = undefined;
+            this._height = undefined;
+            this._textureRotationAngle = undefined;
+            this._id = undefined;
+
+            // set the flags to initiate a first drawing
+            this._createPrimitive = true;
+            this._primitive = undefined;
+            this._outlinePolygon = undefined;
+
+        }
+
+        _.prototype.setAttribute = function (name, value) {
+            this[name] = value;
+            this._createPrimitive = true;
+        };
+
+        _.prototype.getAttribute = function (name) {
+            return this[name];
+        };
+
+        /**
+         * @private
+         */
+        _.prototype.update = function (context, frameState, commandList) {
+
+            if (!Cesium.defined(this.ellipsoid)) {
+                throw new Cesium.DeveloperError('this.ellipsoid must be defined.');
+            }
+
+            if (!Cesium.defined(this.appearance)) {
+                throw new Cesium.DeveloperError('this.material must be defined.');
+            }
+
+            if (this.granularity < 0.0) {
+                throw new Cesium.DeveloperError('this.granularity and scene2D/scene3D overrides must be greater than zero.');
+            }
+
+            if (!this.show) {
+                return;
+            }
+
+            if (!this._createPrimitive && (!Cesium.defined(this._primitive))) {
+                // No positions/hierarchy to draw
+                return;
+            }
+
+            if (this._createPrimitive ||
+                (this._ellipsoid !== this.ellipsoid) ||
+                (this._granularity !== this.granularity) ||
+                (this._height !== this.height) ||
+                (this._textureRotationAngle !== this.textureRotationAngle) ||
+                (this._id !== this.id)) {
+
+                var geometry = this.getGeometry();
+                if (!geometry) {
+                    return;
+                }
+
+                this._createPrimitive = false;
+                this._ellipsoid = this.ellipsoid;
+                this._granularity = this.granularity;
+                this._height = this.height;
+                this._textureRotationAngle = this.textureRotationAngle;
+                this._id = this.id;
+
+                this._primitive = this._primitive && this._primitive.destroy();
+
+                this._primitive = new Cesium.Primitive({
+                    geometryInstances: new Cesium.GeometryInstance({
+                        geometry: geometry,
+                        id: this.id,
+                        pickPrimitive: this
+                    }),
+                    appearance: this.appearance,
+                    asynchronous: this.asynchronous
+                });
+
+                this._outlinePolygon = this._outlinePolygon && this._outlinePolygon.destroy();
+                if (this.strokeColor && this.getOutlineGeometry) {
+                    // create the highlighting frame
+                    this._outlinePolygon = new Cesium.Primitive({
+                        geometryInstances: new Cesium.GeometryInstance({
+                            geometry: this.getOutlineGeometry(),
+                            attributes: {
+                                color: Cesium.ColorGeometryInstanceAttribute.fromColor(this.strokeColor)
+                            }
+                        }),
+                        appearance: new Cesium.PerInstanceColorAppearance({
+                            flat: true,
+                            renderState: {
+                                depthTest: {
+                                    enabled: true
+                                },
+                                lineWidth: Math.min(this.strokeWidth || 4.0, context._aliasedLineWidthRange[1])
+                            }
+                        })
+                    });
+                }
+            }
+
+            var primitive = this._primitive;
+            primitive.appearance.material = this.material;
+            primitive.debugShowBoundingVolume = this.debugShowBoundingVolume;
+            primitive.update(context, frameState, commandList);
+            this._outlinePolygon && this._outlinePolygon.update(context, frameState, commandList);
+
+        };
+
+        _.prototype.isDestroyed = function () {
+            return false;
+        };
+
+        _.prototype.destroy = function () {
+            this._primitive = this._primitive && this._primitive.destroy();
+            return Cesium.destroyObject(this);
+        };
+
+        _.prototype.setStrokeStyle = function (strokeColor, strokeWidth) {
+            if (!this.strokeColor || !this.strokeColor.equals(strokeColor) || this.strokeWidth != strokeWidth) {
+                this._createPrimitive = true;
+                this.strokeColor = strokeColor;
+                this.strokeWidth = strokeWidth;
+            }
+        }
+
+        return _;
+    })();
+
+    _.ExtentPrimitive = (function () {
+        function _(options) {
+
+            if (!Cesium.defined(options.extent)) {
+                throw new Cesium.DeveloperError('Extent is required');
+            }
+
+            options = copyOptions(options, defaultSurfaceOptions);
+
+            this.initialiseOptions(options);
+
+            this.setExtent(options.extent);
+
+        }
+
+        _.prototype = new ChangeablePrimitive();
+
+        _.prototype.setExtent = function (extent) {
+            this.setAttribute('extent', extent);
+        };
+
+        _.prototype.getExtent = function () {
+            return this.getAttribute('extent');
+        };
+
+        _.prototype.getGeometry = function () {
+
+            if (!Cesium.defined(this.extent)) {
+                return;
+            }
+
+            return new Cesium.RectangleGeometry({
+                rectangle: this.extent,
+                height: this.height,
+                vertexFormat: Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT,
+                stRotation: this.textureRotationAngle,
+                ellipsoid: this.ellipsoid,
+                granularity: this.granularity
+            });
+        };
+
+        _.prototype.getOutlineGeometry = function () {
+            return new Cesium.RectangleOutlineGeometry({
+                rectangle: this.extent
+            });
+        }
+
+        return _;
+    })();
+
+    _.PolygonPrimitive = (function () {
+
+        function _(options) {
+
+            options = copyOptions(options, defaultSurfaceOptions);
+
+            this.initialiseOptions(options);
+
+            this.isPolygon = true;
+
+        }
+
+        _.prototype = new ChangeablePrimitive();
+
+        _.prototype.setPositions = function (positions) {
+            this.setAttribute('positions', positions);
+        };
+
+        _.prototype.getPositions = function () {
+            return this.getAttribute('positions');
+        };
+
+        _.prototype.getGeometry = function () {
+
+            if (!Cesium.defined(this.positions) || this.positions.length < 3) {
+                return;
+            }
+
+            return Cesium.PolygonGeometry.fromPositions({
+                positions: this.positions,
+                height: this.height,
+                vertexFormat: Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT,
+                stRotation: this.textureRotationAngle,
+                ellipsoid: this.ellipsoid,
+                granularity: this.granularity
+            });
+        };
+
+        _.prototype.getOutlineGeometry = function () {
+            return Cesium.PolygonOutlineGeometry.fromPositions({
+                positions: this.getPositions()
+            });
+        }
+
+        return _;
+    })();
+
+    _.CirclePrimitive = (function () {
+
+        function _(options) {
+
+            if (!(Cesium.defined(options.center) && Cesium.defined(options.radius))) {
+                throw new Cesium.DeveloperError('Center and radius are required');
+            }
+
+            options = copyOptions(options, defaultSurfaceOptions);
+
+            this.initialiseOptions(options);
+
+            this.setRadius(options.radius);
+
+        }
+
+        _.prototype = new ChangeablePrimitive();
+
+        _.prototype.setCenter = function (center) {
+            this.setAttribute('center', center);
+        };
+
+        _.prototype.setRadius = function (radius) {
+            this.setAttribute('radius', Math.max(0.1, radius));
+        };
+
+        _.prototype.getCenter = function () {
+            return this.getAttribute('center');
+        };
+
+        _.prototype.getRadius = function () {
+            return this.getAttribute('radius');
+        };
+
+        _.prototype.getGeometry = function () {
+
+            if (!(Cesium.defined(this.center) && Cesium.defined(this.radius))) {
+                return;
+            }
+
+            return new Cesium.CircleGeometry({
+                center: this.center,
+                radius: this.radius,
+                height: this.height,
+                vertexFormat: Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT,
+                stRotation: this.textureRotationAngle,
+                ellipsoid: this.ellipsoid,
+                granularity: this.granularity
+            });
+        };
+
+        _.prototype.getOutlineGeometry = function () {
+            return new Cesium.CircleOutlineGeometry({
+                center: this.getCenter(),
+                radius: this.getRadius()
+            });
+        }
+
+        return _;
+    })();
+
+    _.EllipsePrimitive = (function () {
+        function _(options) {
+
+            if (!(Cesium.defined(options.center) && Cesium.defined(options.semiMajorAxis) && Cesium.defined(options.semiMinorAxis))) {
+                throw new Cesium.DeveloperError('Center and semi major and semi minor axis are required');
+            }
+
+            options = copyOptions(options, defaultEllipseOptions);
+
+            this.initialiseOptions(options);
+
+        }
+
+        _.prototype = new ChangeablePrimitive();
+
+        _.prototype.setCenter = function (center) {
+            this.setAttribute('center', center);
+        };
+
+        _.prototype.setSemiMajorAxis = function (semiMajorAxis) {
+            if (semiMajorAxis < this.getSemiMinorAxis()) return;
+            this.setAttribute('semiMajorAxis', semiMajorAxis);
+        };
+
+        _.prototype.setSemiMinorAxis = function (semiMinorAxis) {
+            if (semiMinorAxis > this.getSemiMajorAxis()) return;
+            this.setAttribute('semiMinorAxis', semiMinorAxis);
+        };
+
+        _.prototype.setRotation = function (rotation) {
+            return this.setAttribute('rotation', rotation);
+        };
+
+        _.prototype.getCenter = function () {
+            return this.getAttribute('center');
+        };
+
+        _.prototype.getSemiMajorAxis = function () {
+            return this.getAttribute('semiMajorAxis');
+        };
+
+        _.prototype.getSemiMinorAxis = function () {
+            return this.getAttribute('semiMinorAxis');
+        };
+
+        _.prototype.getRotation = function () {
+            return this.getAttribute('rotation');
+        };
+
+        _.prototype.getGeometry = function () {
+
+            if (!(Cesium.defined(this.center) && Cesium.defined(this.semiMajorAxis) && Cesium.defined(this.semiMinorAxis))) {
+                return;
+            }
+
+            return new Cesium.EllipseGeometry({
+                ellipsoid: this.ellipsoid,
+                center: this.center,
+                semiMajorAxis: this.semiMajorAxis,
+                semiMinorAxis: this.semiMinorAxis,
+                rotation: this.rotation,
+                height: this.height,
+                vertexFormat: Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT,
+                stRotation: this.textureRotationAngle,
+                ellipsoid: this.ellipsoid,
+                granularity: this.granularity
+            });
+        };
+
+        _.prototype.getOutlineGeometry = function () {
+            return new Cesium.EllipseOutlineGeometry({
+                center: this.getCenter(),
+                semiMajorAxis: this.getSemiMajorAxis(),
+                semiMinorAxis: this.getSemiMinorAxis(),
+                rotation: this.getRotation()
+            });
+        }
+
+        return _;
+    })();
+
+    _.PolylinePrimitive = (function () {
+
+        function _(options) {
+
+            options = copyOptions(options, defaultPolylineOptions);
+
+            this.initialiseOptions(options);
+
+        }
+
+        _.prototype = new ChangeablePrimitive();
+
+        _.prototype.setPositions = function (positions) {
+            this.setAttribute('positions', positions);
+        };
+
+        _.prototype.setWidth = function (width) {
+            this.setAttribute('width', width);
+        };
+
+        _.prototype.setGeodesic = function (geodesic) {
+            this.setAttribute('geodesic', geodesic);
+        };
+
+        _.prototype.getPositions = function () {
+            return this.getAttribute('positions');
+        };
+
+        _.prototype.getWidth = function () {
+            return this.getAttribute('width');
+        };
+
+        _.prototype.getGeodesic = function (geodesic) {
+            return this.getAttribute('geodesic');
+        };
+
+        _.prototype.getGeometry = function () {
+
+            if (!Cesium.defined(this.positions) || this.positions.length < 2) {
+                return;
+            }
+
+            return new Cesium.PolylineGeometry({
+                positions: this.positions,
+                height: this.height,
+                width: this.width < 1 ? 1 : this.width,
+                vertexFormat: Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT,
+                ellipsoid: this.ellipsoid
+            });
+        }
+
+        return _;
+    })();
+
+    var defaultBillboard = {
+        iconUrl: "./img/dragIcon.png",
+        shiftX: 0,
+        shiftY: 0
+    }
+
+    var dragBillboard = {
+        iconUrl: "./img/dragIcon.png",
+        shiftX: 0,
+        shiftY: 0
+    }
+
+    var dragHalfBillboard = {
+        iconUrl: "./img/dragIconLight.png",
+        shiftX: 0,
+        shiftY: 0
+    }
+
+    _.prototype.createBillboardGroup = function (points, options, callbacks) {
+        var markers = new _.BillboardGroup(this, options);
+        markers.addBillboards(points, callbacks);
+        return markers;
+    }
+
+    _.BillboardGroup = function (drawHelper, options) {
+
+        this._drawHelper = drawHelper;
+        this._scene = drawHelper._scene;
+
+        this._options = copyOptions(options, defaultBillboard);
+
+        // create one common billboard collection for all billboards
+        var b = new Cesium.BillboardCollection();
+        this._scene.primitives.add(b);
+        this._billboards = b;
+        // keep an ordered list of billboards
+        this._orderedBillboards = [];
+    }
+
+    _.BillboardGroup.prototype.createBillboard = function (position, callbacks) {
+
+        var billboard = this._billboards.add({
+            show: true,
+            position: position,
+            pixelOffset: new Cesium.Cartesian2(this._options.shiftX, this._options.shiftY),
+            eyeOffset: new Cesium.Cartesian3(0.0, 0.0, 0.0),
+            horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
+            verticalOrigin: Cesium.VerticalOrigin.CENTER,
+            scale: 1.0,
+            image: this._options.iconUrl,
+            color: new Cesium.Color(1.0, 1.0, 1.0, 1.0)
+        });
+
+        // if editable
+        if (callbacks) {
+            var _self = this;
+            var screenSpaceCameraController = this._scene.screenSpaceCameraController;
+            function enableRotation(enable) {
+                screenSpaceCameraController.enableRotate = enable;
+            }
+            function getIndex() {
+                // find index
+                for (var i = 0, I = _self._orderedBillboards.length; i < I && _self._orderedBillboards[i] != billboard; ++i);
+                return i;
+            }
+            if (callbacks.dragHandlers) {
+                var _self = this;
+                setListener(billboard, 'leftDown', function (position) {
+                    // TODO - start the drag handlers here
+                    // create handlers for mouseOut and leftUp for the billboard and a mouseMove
+                    function onDrag(position) {
+                        billboard.position = position;
+                        // find index
+                        for (var i = 0, I = _self._orderedBillboards.length; i < I && _self._orderedBillboards[i] != billboard; ++i);
+                        callbacks.dragHandlers.onDrag && callbacks.dragHandlers.onDrag(getIndex(), position);
+                    }
+                    function onDragEnd(position) {
+                        handler.destroy();
+                        enableRotation(true);
+                        callbacks.dragHandlers.onDragEnd && callbacks.dragHandlers.onDragEnd(getIndex(), position);
+                    }
+
+                    var handler = new Cesium.ScreenSpaceEventHandler(_self._scene.canvas);
+
+                    handler.setInputAction(function (movement) {
+                        var cartesian = _self._scene.camera.pickEllipsoid(movement.endPosition, ellipsoid);
+                        if (cartesian) {
+                            onDrag(cartesian);
+                        } else {
+                            onDragEnd(cartesian);
+                        }
+                    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+
+                    handler.setInputAction(function (movement) {
+                        onDragEnd(_self._scene.camera.pickEllipsoid(movement.position, ellipsoid));
+                    }, Cesium.ScreenSpaceEventType.LEFT_UP);
+
+                    enableRotation(false);
+
+                    callbacks.dragHandlers.onDragStart && callbacks.dragHandlers.onDragStart(getIndex(), _self._scene.camera.pickEllipsoid(position, ellipsoid));
+                });
+            }
+            if (callbacks.onDoubleClick) {
+                setListener(billboard, 'leftDoubleClick', function (position) {
+                    callbacks.onDoubleClick(getIndex());
+                });
+            }
+            if (callbacks.onClick) {
+                setListener(billboard, 'leftClick', function (position) {
+                    callbacks.onClick(getIndex());
+                });
+            }
+            if (callbacks.tooltip) {
+                setListener(billboard, 'mouseMove', function (position) {
+                    _self._drawHelper._tooltip.showAt(position, callbacks.tooltip());
+                });
+                setListener(billboard, 'mouseOut', function (position) {
+                    _self._drawHelper._tooltip.setVisible(false);
+                });
+            }
+        }
+
+        return billboard;
+    }
+
+    _.BillboardGroup.prototype.insertBillboard = function (index, position, callbacks) {
+        this._orderedBillboards.splice(index, 0, this.createBillboard(position, callbacks));
+    }
+
+    _.BillboardGroup.prototype.addBillboard = function (position, callbacks) {
+        this._orderedBillboards.push(this.createBillboard(position, callbacks));
+    }
+
+    _.BillboardGroup.prototype.addBillboards = function (positions, callbacks) {
+        var index = 0;
+        for (; index < positions.length; index++) {
+            this.addBillboard(positions[index], callbacks);
+        }
+    }
+
+    _.BillboardGroup.prototype.updateBillboardsPositions = function (positions) {
+        var index = 0;
+        for (; index < positions.length; index++) {
+            this.getBillboard(index).position = positions[index];
+        }
+    }
+
+    _.BillboardGroup.prototype.countBillboards = function () {
+        return this._orderedBillboards.length;
+    }
+
+    _.BillboardGroup.prototype.getBillboard = function (index) {
+        return this._orderedBillboards[index];
+    }
+
+    _.BillboardGroup.prototype.removeBillboard = function (index) {
+        this._billboards.remove(this.getBillboard(index));
+        this._orderedBillboards.splice(index, 1);
+    }
+
+    _.BillboardGroup.prototype.remove = function () {
+        this._billboards = this._billboards && this._billboards.removeAll() && this._billboards.destroy();
+    }
+
+    _.BillboardGroup.prototype.setOnTop = function () {
+        this._scene.primitives.raiseToTop(this._billboards);
+    }
+
+    _.prototype.startDrawingMarker = function (options) {
+
+        var options = copyOptions(options, defaultBillboard);
+
+        this.startDrawing(
+            function () {
+                markers.remove();
+                mouseHandler.destroy();
+                tooltip.setVisible(false);
+            }
+        );
+
+        var _self = this;
+        var scene = this._scene;
+        var primitives = scene.primitives;
+        var tooltip = this._tooltip;
+
+        var markers = new _.BillboardGroup(this, options);
+
+        var mouseHandler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
+
+        // Now wait for start
+        mouseHandler.setInputAction(function (movement) {
+            if (movement.position != null) {
+                var cartesian = scene.camera.pickEllipsoid(movement.position, ellipsoid);
+                if (cartesian) {
+                    markers.addBillboard(cartesian);
+                    _self.stopDrawing();
+                    options.callback(cartesian);
+                }
+            }
+        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+
+        mouseHandler.setInputAction(function (movement) {
+            var position = movement.endPosition;
+            if (position != null) {
+                var cartesian = scene.camera.pickEllipsoid(position, ellipsoid);
+                if (cartesian) {
+                    tooltip.showAt(position, "<p>Click to add your marker. Position is: </p>" + getDisplayLatLngString(ellipsoid.cartesianToCartographic(cartesian)));
+                } else {
+                    tooltip.showAt(position, "<p>Click on the globe to add your marker.</p>");
+                }
+            }
+        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+
+    }
+
+    _.prototype.startDrawingPolygon = function (options) {
+        var options = copyOptions(options, defaultSurfaceOptions);
+        this.startDrawingPolyshape(true, options);
+    }
+
+    _.prototype.startDrawingPolyline = function (options) {
+        var options = copyOptions(options, defaultPolylineOptions);
+        this.startDrawingPolyshape(false, options);
+    }
+
+    _.prototype.startDrawingPolyshape = function (isPolygon, options) {
+
+        this.startDrawing(
+            function () {
+                primitives.remove(poly);
+                markers.remove();
+                mouseHandler.destroy();
+                tooltip.setVisible(false);
+            }
+        );
+
+        var _self = this;
+        var scene = this._scene;
+        var primitives = scene.primitives;
+        var tooltip = this._tooltip;
+
+        var minPoints = isPolygon ? 3 : 2;
+        var poly;
+        if (isPolygon) {
+            poly = new DrawHelper.PolygonPrimitive(options);
+        } else {
+            poly = new DrawHelper.PolylinePrimitive(options);
+        }
+        poly.asynchronous = false;
+        primitives.add(poly);
+
+        var positions = [];
+        var markers = new _.BillboardGroup(this, defaultBillboard);
+
+        var mouseHandler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
+
+        // Now wait for start
+        mouseHandler.setInputAction(function (movement) {
+            if (movement.position != null) {
+                var cartesian = scene.camera.pickEllipsoid(movement.position, ellipsoid);
+                if (cartesian) {
+                    // first click
+                    if (positions.length == 0) {
+                        positions.push(cartesian.clone());
+                        markers.addBillboard(positions[0]);
+                    }
+                    if (positions.length >= minPoints) {
+                        poly.positions = positions;
+                        poly._createPrimitive = true;
+                    }
+                    // add new point to polygon
+                    // this one will move with the mouse
+                    positions.push(cartesian);
+                    // add marker at the new position
+                    markers.addBillboard(cartesian);
+                }
+            }
+        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+
+        mouseHandler.setInputAction(function (movement) {
+            var position = movement.endPosition;
+            if (position != null) {
+                if (positions.length == 0) {
+                    tooltip.showAt(position, "<p>Click to add first point</p>");
+                } else {
+                    var cartesian = scene.camera.pickEllipsoid(position, ellipsoid);
+                    if (cartesian) {
+                        positions.pop();
+                        // make sure it is slightly different
+                        cartesian.y += (1 + Math.random());
+                        positions.push(cartesian);
+                        if (positions.length >= minPoints) {
+                            poly.positions = positions;
+                            poly._createPrimitive = true;
+                        }
+                        // update marker
+                        markers.getBillboard(positions.length - 1).position = cartesian;
+                        // show tooltip
+                        tooltip.showAt(position, "<p>Click to add new point (" + positions.length + ")</p>" + (positions.length > minPoints ? "<p>Double click to finish drawing</p>" : ""));
+                    }
+                }
+            }
+        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+
+        mouseHandler.setInputAction(function (movement) {
+            var position = movement.position;
+            if (position != null) {
+                if (positions.length < minPoints + 2) {
+                    return;
+                } else {
+                    var cartesian = scene.camera.pickEllipsoid(position, ellipsoid);
+                    if (cartesian) {
+                        _self.stopDrawing();
+                        if (typeof options.callback == 'function') {
+                            // remove overlapping ones
+                            var index = positions.length - 1;
+                            options.callback(positions);
+                        }
+                    }
+                }
+            }
+        }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
+
+    }
+
+    function getExtentCorners(value) {
+        return ellipsoid.cartographicArrayToCartesianArray([Cesium.Rectangle.northwest(value), Cesium.Rectangle.northeast(value), Cesium.Rectangle.southeast(value), Cesium.Rectangle.southwest(value)]);
+    }
+
+    _.prototype.startDrawingExtent = function (options) {
+
+        var options = copyOptions(options, defaultSurfaceOptions);
+
+        this.startDrawing(
+            function () {
+                if (extent != null) {
+                    primitives.remove(extent);
+                }
+                markers.remove();
+                mouseHandler.destroy();
+                tooltip.setVisible(false);
+            }
+        );
+
+        var _self = this;
+        var scene = this._scene;
+        var primitives = this._scene.primitives;
+        var tooltip = this._tooltip;
+
+        var firstPoint = null;
+        var extent = null;
+        var markers = null;
+
+        var mouseHandler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
+
+        function updateExtent(value) {
+            if (extent == null) {
+                extent = new Cesium.RectanglePrimitive();
+                extent.asynchronous = false;
+                primitives.add(extent);
+            }
+            extent.rectangle = value;
+            // update the markers
+            var corners = getExtentCorners(value);
+            // create if they do not yet exist
+            if (markers == null) {
+                markers = new _.BillboardGroup(_self, defaultBillboard);
+                markers.addBillboards(corners);
+            } else {
+                markers.updateBillboardsPositions(corners);
+            }
+        }
+
+        // Now wait for start
+        mouseHandler.setInputAction(function (movement) {
+            if (movement.position != null) {
+                var cartesian = scene.camera.pickEllipsoid(movement.position, ellipsoid);
+                if (cartesian) {
+                    if (extent == null) {
+                        // create the rectangle
+                        firstPoint = ellipsoid.cartesianToCartographic(cartesian);
+                        var value = getExtent(firstPoint, firstPoint);
+                        updateExtent(value);
+                    } else {
+                        _self.stopDrawing();
+                        if (typeof options.callback == 'function') {
+                            options.callback(getExtent(firstPoint, ellipsoid.cartesianToCartographic(cartesian)));
+                        }
+                    }
+                }
+            }
+        }, Cesium.ScreenSpaceEventType.LEFT_DOWN);
+
+        mouseHandler.setInputAction(function (movement) {
+            var position = movement.endPosition;
+            if (position != null) {
+                if (extent == null) {
+                    tooltip.showAt(position, "<p>Click to start drawing rectangle</p>");
+                } else {
+                    var cartesian = scene.camera.pickEllipsoid(position, ellipsoid);
+                    if (cartesian) {
+                        var value = getExtent(firstPoint, ellipsoid.cartesianToCartographic(cartesian));
+                        updateExtent(value);
+                        tooltip.showAt(position, "<p>Drag to change rectangle extent</p><p>Click again to finish drawing</p>");
+                    }
+                }
+            }
+        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+
+    }
+
+    _.prototype.startDrawingCircle = function (options) {
+
+        var options = copyOptions(options, defaultSurfaceOptions);
+
+        this.startDrawing(
+            function cleanUp() {
+                if (circle != null) {
+                    primitives.remove(circle);
+                }
+                markers.remove();
+                mouseHandler.destroy();
+                tooltip.setVisible(false);
+            }
+        );
+
+        var _self = this;
+        var scene = this._scene;
+        var primitives = this._scene.primitives;
+        var tooltip = this._tooltip;
+
+        var circle = null;
+        var markers = null;
+
+        var mouseHandler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
+
+        // Now wait for start
+        mouseHandler.setInputAction(function (movement) {
+            if (movement.position != null) {
+                var cartesian = scene.camera.pickEllipsoid(movement.position, ellipsoid);
+                if (cartesian) {
+                    if (circle == null) {
+                        // create the circle
+                        circle = new _.CirclePrimitive({
+                            center: cartesian,
+                            radius: 0,
+                            asynchronous: false,
+                            material: options.material
+                        });
+                        primitives.add(circle);
+                        markers = new _.BillboardGroup(_self, defaultBillboard);
+                        markers.addBillboards([cartesian]);
+                    } else {
+                        if (typeof options.callback == 'function') {
+                            options.callback(circle.getCenter(), circle.getRadius());
+                        }
+                        _self.stopDrawing();
+                    }
+                }
+            }
+        }, Cesium.ScreenSpaceEventType.LEFT_DOWN);
+
+        mouseHandler.setInputAction(function (movement) {
+            var position = movement.endPosition;
+            if (position != null) {
+                if (circle == null) {
+                    tooltip.showAt(position, "<p>Click to start drawing the circle</p>");
+                } else {
+                    var cartesian = scene.camera.pickEllipsoid(position, ellipsoid);
+                    if (cartesian) {
+                        circle.setRadius(Cesium.Cartesian3.distance(circle.getCenter(), cartesian));
+                        markers.updateBillboardsPositions(cartesian);
+                        tooltip.showAt(position, "<p>Move mouse to change circle radius</p><p>Click again to finish drawing</p>");
+                    }
+                }
+            }
+        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+
+    }
+
+    _.prototype.enhancePrimitives = function () {
+
+        var drawHelper = this;
+
+        Cesium.Billboard.prototype.setEditable = function () {
+
+            if (this._editable) {
+                return;
+            }
+
+            this._editable = true;
+
+            var billboard = this;
+
+            var _self = this;
+
+            function enableRotation(enable) {
+                drawHelper._scene.screenSpaceCameraController.enableRotate = enable;
+            }
+
+            setListener(billboard, 'leftDown', function (position) {
+                // TODO - start the drag handlers here
+                // create handlers for mouseOut and leftUp for the billboard and a mouseMove
+                function onDrag(position) {
+                    billboard.position = position;
+                    _self.executeListeners({ name: 'drag', positions: position });
+                }
+                function onDragEnd(position) {
+                    handler.destroy();
+                    enableRotation(true);
+                    _self.executeListeners({ name: 'dragEnd', positions: position });
+                }
+
+                var handler = new Cesium.ScreenSpaceEventHandler(drawHelper._scene.canvas);
+
+                handler.setInputAction(function (movement) {
+                    var cartesian = drawHelper._scene.camera.pickEllipsoid(movement.endPosition, ellipsoid);
+                    if (cartesian) {
+                        onDrag(cartesian);
+                    } else {
+                        onDragEnd(cartesian);
+                    }
+                }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+
+                handler.setInputAction(function (movement) {
+                    onDragEnd(drawHelper._scene.camera.pickEllipsoid(movement.position, ellipsoid));
+                }, Cesium.ScreenSpaceEventType.LEFT_UP);
+
+                enableRotation(false);
+
+            });
+
+            enhanceWithListeners(billboard);
+
+        }
+
+        function setHighlighted(highlighted) {
+
+            var scene = drawHelper._scene;
+
+            // if no change
+            // if already highlighted, the outline polygon will be available
+            if (this._highlighted && this._highlighted == highlighted) {
+                return;
+            }
+            // disable if already in edit mode
+            if (this._editMode === true) {
+                return;
+            }
+            this._highlighted = highlighted;
+            // highlight by creating an outline polygon matching the polygon points
+            if (highlighted) {
+                // make sure all other shapes are not highlighted
+                drawHelper.setHighlighted(this);
+                this._strokeColor = this.strokeColor;
+                this.setStrokeStyle(Cesium.Color.fromCssColorString('white'), this.strokeWidth);
+            } else {
+                if (this._strokeColor) {
+                    this.setStrokeStyle(this._strokeColor, this.strokeWidth);
+                } else {
+                    this.setStrokeStyle(undefined, undefined);
+                }
+            }
+        }
+
+        function setEditMode(editMode) {
+            // if no change
+            if (this._editMode == editMode) {
+                return;
+            }
+            // make sure all other shapes are not in edit mode before starting the editing of this shape
+            drawHelper.disableAllHighlights();
+            // display markers
+            if (editMode) {
+                drawHelper.setEdited(this);
+                var scene = drawHelper._scene;
+                var _self = this;
+                // create the markers and handlers for the editing
+                if (this._markers == null) {
+                    var markers = new _.BillboardGroup(drawHelper, dragBillboard);
+                    var editMarkers = new _.BillboardGroup(drawHelper, dragHalfBillboard);
+                    // function for updating the edit markers around a certain point
+                    function updateHalfMarkers(index, positions) {
+                        // update the half markers before and after the index
+                        var editIndex = index - 1 < 0 ? positions.length - 1 : index - 1;
+                        if (editIndex < editMarkers.countBillboards()) {
+                            editMarkers.getBillboard(editIndex).position = calculateHalfMarkerPosition(editIndex);
+                        }
+                        editIndex = index;
+                        if (editIndex < editMarkers.countBillboards()) {
+                            editMarkers.getBillboard(editIndex).position = calculateHalfMarkerPosition(editIndex);
+                        }
+                    }
+                    function onEdited() {
+                        _self.executeListeners({ name: 'onEdited', positions: _self.positions });
+                    }
+                    var handleMarkerChanges = {
+                        dragHandlers: {
+                            onDrag: function (index, position) {
+                                _self.positions[index] = position;
+                                updateHalfMarkers(index, _self.positions);
+                                _self._createPrimitive = true;
+                            },
+                            onDragEnd: function (index, position) {
+                                _self._createPrimitive = true;
+                                onEdited();
+                            }
+                        },
+                        onDoubleClick: function (index) {
+                            if (_self.positions.length < 4) {
+                                return;
+                            }
+                            // remove the point and the corresponding markers
+                            _self.positions.splice(index, 1);
+                            _self._createPrimitive = true;
+                            markers.removeBillboard(index);
+                            editMarkers.removeBillboard(index);
+                            updateHalfMarkers(index, _self.positions);
+                            onEdited();
+                        },
+                        tooltip: function () {
+                            if (_self.positions.length > 3) {
+                                return "Double click to remove this point";
+                            }
+                        }
+                    };
+                    // add billboards and keep an ordered list of them for the polygon edges
+                    markers.addBillboards(_self.positions, handleMarkerChanges);
+                    this._markers = markers;
+                    function calculateHalfMarkerPosition(index) {
+                        var positions = _self.positions;
+                        return ellipsoid.cartographicToCartesian(
+                            new Cesium.EllipsoidGeodesic(ellipsoid.cartesianToCartographic(positions[index]),
+                                ellipsoid.cartesianToCartographic(positions[index < positions.length - 1 ? index + 1 : 0])).
+                                interpolateUsingFraction(0.5)
+                        );
+                    }
+                    var halfPositions = [];
+                    var index = 0;
+                    var length = _self.positions.length + (this.isPolygon ? 0 : -1);
+                    for (; index < length; index++) {
+                        halfPositions.push(calculateHalfMarkerPosition(index));
+                    }
+                    var handleEditMarkerChanges = {
+                        dragHandlers: {
+                            onDragStart: function (index, position) {
+                                // add a new position to the polygon but not a new marker yet
+                                this.index = index + 1;
+                                _self.positions.splice(this.index, 0, position);
+                                _self._createPrimitive = true;
+                            },
+                            onDrag: function (index, position) {
+                                _self.positions[this.index] = position;
+                                _self._createPrimitive = true;
+                            },
+                            onDragEnd: function (index, position) {
+                                // create new sets of makers for editing
+                                markers.insertBillboard(this.index, position, handleMarkerChanges);
+                                editMarkers.getBillboard(this.index - 1).position = calculateHalfMarkerPosition(this.index - 1);
+                                editMarkers.insertBillboard(this.index, calculateHalfMarkerPosition(this.index), handleEditMarkerChanges);
+                                _self._createPrimitive = true;
+                                onEdited();
+                            }
+                        },
+                        tooltip: function () {
+                            return "Drag to create a new point";
+                        }
+                    };
+                    editMarkers.addBillboards(halfPositions, handleEditMarkerChanges);
+                    this._editMarkers = editMarkers;
+                    // add a handler for clicking in the globe
+                    this._globeClickhandler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
+                    this._globeClickhandler.setInputAction(
+                        function (movement) {
+                            var pickedObject = scene.pick(movement.position);
+                            if (!(pickedObject && pickedObject.primitive)) {
+                                _self.setEditMode(false);
+                            }
+                        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+
+                    // set on top of the polygon
+                    markers.setOnTop();
+                    editMarkers.setOnTop();
+                }
+                this._editMode = true;
+            } else {
+                if (this._markers != null) {
+                    this._markers.remove();
+                    this._editMarkers.remove();
+                    this._markers = null;
+                    this._editMarkers = null;
+                    this._globeClickhandler.destroy();
+                }
+                this._editMode = false;
+            }
+
+        }
+
+        DrawHelper.PolylinePrimitive.prototype.setEditable = function () {
+
+            if (this.setEditMode) {
+                return;
+            }
+
+            var polyline = this;
+            polyline.isPolygon = false;
+            polyline.asynchronous = false;
+
+            drawHelper.registerEditableShape(polyline);
+
+            polyline.setEditMode = setEditMode;
+
+            var originalWidth = this.width;
+
+            polyline.setHighlighted = function (highlighted) {
+                // disable if already in edit mode
+                if (this._editMode === true) {
+                    return;
+                }
+                if (highlighted) {
+                    drawHelper.setHighlighted(this);
+                    this.setWidth(originalWidth * 2);
+                } else {
+                    this.setWidth(originalWidth);
+                }
+            }
+
+            polyline.getExtent = function () {
+                return Cesium.Extent.fromCartographicArray(ellipsoid.cartesianArrayToCartographicArray(this.positions));
+            }
+
+            enhanceWithListeners(polyline);
+
+            polyline.setEditMode(false);
+
+        }
+
+        DrawHelper.PolygonPrimitive.prototype.setEditable = function () {
+
+            var polygon = this;
+            polygon.asynchronous = false;
+
+            var scene = drawHelper._scene;
+
+            drawHelper.registerEditableShape(polygon);
+
+            polygon.setEditMode = setEditMode;
+
+            polygon.setHighlighted = setHighlighted;
+
+            enhanceWithListeners(polygon);
+
+            polygon.setEditMode(false);
+
+        }
+
+        DrawHelper.ExtentPrimitive.prototype.setEditable = function () {
+
+            if (this.setEditMode) {
+                return;
+            }
+
+            var extent = this;
+            var scene = drawHelper._scene;
+
+            drawHelper.registerEditableShape(extent);
+            extent.asynchronous = false;
+
+            extent.setEditMode = function (editMode) {
+                // if no change
+                if (this._editMode == editMode) {
+                    return;
+                }
+                drawHelper.disableAllHighlights();
+                // display markers
+                if (editMode) {
+                    // make sure all other shapes are not in edit mode before starting the editing of this shape
+                    drawHelper.setEdited(this);
+                    // create the markers and handlers for the editing
+                    if (this._markers == null) {
+                        var markers = new _.BillboardGroup(drawHelper, dragBillboard);
+                        function onEdited() {
+                            extent.executeListeners({ name: 'onEdited', extent: extent.extent });
+                        }
+                        var handleMarkerChanges = {
+                            dragHandlers: {
+                                onDrag: function (index, position) {
+                                    var corner = markers.getBillboard((index + 2) % 4).position;
+                                    extent.setExtent(getExtent(ellipsoid.cartesianToCartographic(corner), ellipsoid.cartesianToCartographic(position)));
+                                    markers.updateBillboardsPositions(getExtentCorners(extent.extent));
+                                },
+                                onDragEnd: function (index, position) {
+                                    onEdited();
+                                }
+                            },
+                            tooltip: function () {
+                                return "Drag to change the corners of this extent";
+                            }
+                        };
+                        markers.addBillboards(getExtentCorners(extent.extent), handleMarkerChanges);
+                        this._markers = markers;
+                        // add a handler for clicking in the globe
+                        this._globeClickhandler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
+                        this._globeClickhandler.setInputAction(
+                            function (movement) {
+                                var pickedObject = scene.pick(movement.position);
+                                // disable edit if pickedobject is different or not an object
+                                if (!(pickedObject && !pickedObject.isDestroyed() && pickedObject.primitive)) {
+                                    extent.setEditMode(false);
+                                }
+                            }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+
+                        // set on top of the polygon
+                        markers.setOnTop();
+                    }
+                    this._editMode = true;
+                } else {
+                    if (this._markers != null) {
+                        this._markers.remove();
+                        this._markers = null;
+                        this._globeClickhandler.destroy();
+                    }
+                    this._editMode = false;
+                }
+            }
+
+            extent.setHighlighted = setHighlighted;
+
+            enhanceWithListeners(extent);
+
+            extent.setEditMode(false);
+
+        }
+
+        _.EllipsePrimitive.prototype.setEditable = function () {
+
+            if (this.setEditMode) {
+                return;
+            }
+
+            var ellipse = this;
+            var scene = drawHelper._scene;
+
+            ellipse.asynchronous = false;
+
+            drawHelper.registerEditableShape(ellipse);
+
+            ellipse.setEditMode = function (editMode) {
+                // if no change
+                if (this._editMode == editMode) {
+                    return;
+                }
+                drawHelper.disableAllHighlights();
+                // display markers
+                if (editMode) {
+                    // make sure all other shapes are not in edit mode before starting the editing of this shape
+                    drawHelper.setEdited(this);
+                    var _self = this;
+                    // create the markers and handlers for the editing
+                    if (this._markers == null) {
+                        var markers = new _.BillboardGroup(drawHelper, dragBillboard);
+                        function getMarkerPositions() {
+                            return Cesium.Shapes.computeEllipseBoundary(ellipsoid, ellipse.getCenter(), ellipse.getSemiMajorAxis(), ellipse.getSemiMinorAxis(), ellipse.getRotation() + Math.PI / 2, Math.PI / 2.0).splice(0, 4);
+                        }
+                        function onEdited() {
+                            ellipse.executeListeners({ name: 'onEdited', center: ellipse.getCenter(), semiMajorAxis: ellipse.getSemiMajorAxis(), semiMinorAxis: ellipse.getSemiMinorAxis(), rotation: 0 });
+                        }
+                        var handleMarkerChanges = {
+                            dragHandlers: {
+                                onDrag: function (index, position) {
+                                    var distance = Cesium.Cartesian3.distance(ellipse.getCenter(), position);
+                                    if (index % 2 == 0) {
+                                        ellipse.setSemiMajorAxis(distance);
+                                    } else {
+                                        ellipse.setSemiMinorAxis(distance);
+                                    }
+                                    markers.updateBillboardsPositions(getMarkerPositions());
+                                },
+                                onDragEnd: function (index, position) {
+                                    onEdited();
+                                }
+                            },
+                            tooltip: function () {
+                                return "Drag to change the excentricity and radius";
+                            }
+                        };
+                        markers.addBillboards(getMarkerPositions(), handleMarkerChanges);
+                        this._markers = markers;
+                        // add a handler for clicking in the globe
+                        this._globeClickhandler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
+                        this._globeClickhandler.setInputAction(
+                            function (movement) {
+                                var pickedObject = scene.pick(movement.position);
+                                if (!(pickedObject && pickedObject.primitive)) {
+                                    _self.setEditMode(false);
+                                }
+                            }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+
+                        // set on top of the polygon
+                        markers.setOnTop();
+                    }
+                    this._editMode = true;
+                } else {
+                    if (this._markers != null) {
+                        this._markers.remove();
+                        this._markers = null;
+                        this._globeClickhandler.destroy();
+                    }
+                    this._editMode = false;
+                }
+            }
+
+            ellipse.setHighlighted = setHighlighted;
+
+            enhanceWithListeners(ellipse);
+
+            ellipse.setEditMode(false);
+        }
+
+        _.CirclePrimitive.prototype.getCircleCartesianCoordinates = function (granularity) {
+            var geometry = Cesium.CircleOutlineGeometry.createGeometry(new Cesium.CircleOutlineGeometry({ ellipsoid: ellipsoid, center: this.getCenter(), radius: this.getRadius(), granularity: granularity }));
+            var count = 0, value, values = [];
+            for (; count < geometry.attributes.position.values.length; count += 3) {
+                value = geometry.attributes.position.values;
+                values.push(new Cesium.Cartesian3(value[count], value[count + 1], value[count + 2]));
+            }
+            return values;
+        };
+
+        _.CirclePrimitive.prototype.setEditable = function () {
+
+            if (this.setEditMode) {
+                return;
+            }
+
+            var circle = this;
+            var scene = drawHelper._scene;
+
+            circle.asynchronous = false;
+
+            drawHelper.registerEditableShape(circle);
+
+            circle.setEditMode = function (editMode) {
+                // if no change
+                if (this._editMode == editMode) {
+                    return;
+                }
+                drawHelper.disableAllHighlights();
+                // display markers
+                if (editMode) {
+                    // make sure all other shapes are not in edit mode before starting the editing of this shape
+                    drawHelper.setEdited(this);
+                    var _self = this;
+                    // create the markers and handlers for the editing
+                    if (this._markers == null) {
+                        var markers = new _.BillboardGroup(drawHelper, dragBillboard);
+                        function getMarkerPositions() {
+                            return _self.getCircleCartesianCoordinates(Cesium.Math.PI_OVER_TWO);
+                        }
+                        function onEdited() {
+                            circle.executeListeners({ name: 'onEdited', center: circle.getCenter(), radius: circle.getRadius() });
+                        }
+                        var handleMarkerChanges = {
+                            dragHandlers: {
+                                onDrag: function (index, position) {
+                                    circle.setRadius(Cesium.Cartesian3.distance(circle.getCenter(), position));
+                                    markers.updateBillboardsPositions(getMarkerPositions());
+                                },
+                                onDragEnd: function (index, position) {
+                                    onEdited();
+                                }
+                            },
+                            tooltip: function () {
+                                return "Drag to change the radius";
+                            }
+                        };
+                        markers.addBillboards(getMarkerPositions(), handleMarkerChanges);
+                        this._markers = markers;
+                        // add a handler for clicking in the globe
+                        this._globeClickhandler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
+                        this._globeClickhandler.setInputAction(
+                            function (movement) {
+                                var pickedObject = scene.pick(movement.position);
+                                if (!(pickedObject && pickedObject.primitive)) {
+                                    _self.setEditMode(false);
+                                }
+                            }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+
+                        // set on top of the polygon
+                        markers.setOnTop();
+                    }
+                    this._editMode = true;
+                } else {
+                    if (this._markers != null) {
+                        this._markers.remove();
+                        this._markers = null;
+                        this._globeClickhandler.destroy();
+                    }
+                    this._editMode = false;
+                }
+            }
+
+            circle.setHighlighted = setHighlighted;
+
+            enhanceWithListeners(circle);
+
+            circle.setEditMode(false);
+        }
+
+    }
+
+    _.DrawHelperWidget = (function () {
+
+        // constructor
+        function _(drawHelper, options) {
+
+            // container must be specified
+            if (!(Cesium.defined(options.container))) {
+                throw new Cesium.DeveloperError('Container is required');
+            }
+
+            var drawOptions = {
+                markerIcon: "./img/glyphicons_242_google_maps.png",
+                polylineIcon: "./img/glyphicons_097_vector_path_line.png",
+                polygonIcon: "./img/glyphicons_096_vector_path_polygon.png",
+                circleIcon: "./img/glyphicons_095_vector_path_circle.png",
+                extentIcon: "./img/glyphicons_094_vector_path_square.png",
+                clearIcon: "./img/glyphicons_067_cleaning.png",
+                polylineDrawingOptions: defaultPolylineOptions,
+                polygonDrawingOptions: defaultPolygonOptions,
+                extentDrawingOptions: defaultExtentOptions,
+                circleDrawingOptions: defaultCircleOptions
+            };
+
+            fillOptions(options, drawOptions);
+
+            var _self = this;
+
+            var toolbar = document.createElement('DIV');
+            toolbar.className = "toolbar";
+            options.container.appendChild(toolbar);
+
+            function addIcon(id, url, title, callback) {
+                var div = document.createElement('DIV');
+                div.className = 'button';
+                div.title = title;
+                toolbar.appendChild(div);
+                div.onclick = callback;
+                var span = document.createElement('SPAN');
+                div.appendChild(span);
+                var image = document.createElement('IMG');
+                image.src = url;
+                span.appendChild(image);
+                return div;
+            }
+
+            var scene = drawHelper._scene;
+
+            addIcon('marker', options.markerIcon, 'Click to start drawing a 2D marker', function () {
+                drawHelper.startDrawingMarker({
+                    callback: function (position) {
+                        _self.executeListeners({ name: 'markerCreated', position: position });
+                    }
+                });
+            })
+
+            addIcon('polyline', options.polylineIcon, 'Click to start drawing a 2D polyline', function () {
+                drawHelper.startDrawingPolyline({
+                    callback: function (positions) {
+                        _self.executeListeners({ name: 'polylineCreated', positions: positions });
+                    }
+                });
+            })
+
+            addIcon('polygon', options.polygonIcon, 'Click to start drawing a 2D polygon', function () {
+                drawHelper.startDrawingPolygon({
+                    callback: function (positions) {
+                        _self.executeListeners({ name: 'polygonCreated', positions: positions });
+                    }
+                });
+            })
+
+            addIcon('extent', options.extentIcon, 'Click to start drawing an Extent', function () {
+                drawHelper.startDrawingExtent({
+                    callback: function (extent) {
+                        _self.executeListeners({ name: 'extentCreated', extent: extent });
+                    }
+                });
+            })
+
+            addIcon('circle', options.circleIcon, 'Click to start drawing a Circle', function () {
+                drawHelper.startDrawingCircle({
+                    callback: function (center, radius) {
+                        _self.executeListeners({ name: 'circleCreated', center: center, radius: radius });
+                    }
+                });
+            })
+
+            // add a clear button at the end
+            // add a divider first
+            var div = document.createElement('DIV');
+            div.className = 'divider';
+            toolbar.appendChild(div);
+            addIcon('clear', options.clearIcon, 'Remove all primitives', function () {
+                scene.primitives.removeAll();
+            });
+
+            enhanceWithListeners(this);
+
+        }
+
+        return _;
+
+    })();
+
+    _.prototype.addToolbar = function (container, options) {
+        options = copyOptions(options, { container: container });
+        return new _.DrawHelperWidget(this, options);
+    }
+
+    function getExtent(mn, mx) {
+        var e = new Cesium.Rectangle();
+
+        // Re-order so west < east and south < north
+        e.west = Math.min(mn.longitude, mx.longitude);
+        e.east = Math.max(mn.longitude, mx.longitude);
+        e.south = Math.min(mn.latitude, mx.latitude);
+        e.north = Math.max(mn.latitude, mx.latitude);
+
+        // Check for approx equal (shouldn't require abs due to re-order)
+        var epsilon = Cesium.Math.EPSILON7;
+
+        if ((e.east - e.west) < epsilon) {
+            e.east += epsilon * 2.0;
+        }
+
+        if ((e.north - e.south) < epsilon) {
+            e.north += epsilon * 2.0;
+        }
+
+        return e;
+    };
+
+    function createTooltip(frameDiv) {
+
+        var tooltip = function (frameDiv) {
+
+            var div = document.createElement('DIV');
+            div.className = "twipsy right";
+
+            var arrow = document.createElement('DIV');
+            arrow.className = "twipsy-arrow";
+            div.appendChild(arrow);
+
+            var title = document.createElement('DIV');
+            title.className = "twipsy-inner";
+            div.appendChild(title);
+
+            this._div = div;
+            this._title = title;
+
+            // add to frame div and display coordinates
+            frameDiv.appendChild(div);
+        }
+
+        tooltip.prototype.setVisible = function (visible) {
+            this._div.style.display = visible ? 'block' : 'none';
+        }
+
+        tooltip.prototype.showAt = function (position, message) {
+            if (position && message) {
+                this.setVisible(true);
+                this._title.innerHTML = message;
+                this._div.style.left = position.x + 10 + "px";
+                this._div.style.top = (position.y - this._div.clientHeight / 2) + "px";
+            }
+        }
+
+        return new tooltip(frameDiv);
+    }
+
+    function getDisplayLatLngString(cartographic, precision) {
+        return cartographic.longitude.toFixed(precision || 3) + ", " + cartographic.latitude.toFixed(precision || 3);
+    }
+
+    function clone(from, to) {
+        if (from == null || typeof from != "object") return from;
+        if (from.constructor != Object && from.constructor != Array) return from;
+        if (from.constructor == Date || from.constructor == RegExp || from.constructor == Function ||
+            from.constructor == String || from.constructor == Number || from.constructor == Boolean)
+            return new from.constructor(from);
+
+        to = to || new from.constructor();
+
+        for (var name in from) {
+            to[name] = typeof to[name] == "undefined" ? clone(from[name], null) : to[name];
+        }
+
+        return to;
+    }
+
+    function fillOptions(options, defaultOptions) {
+        options = options || {};
+        var option;
+        for (option in defaultOptions) {
+            if (options[option] === undefined) {
+                options[option] = clone(defaultOptions[option]);
+            }
+        }
+    }
+
+    // shallow copy
+    function copyOptions(options, defaultOptions) {
+        var newOptions = clone(options), option;
+        for (option in defaultOptions) {
+            if (newOptions[option] === undefined) {
+                newOptions[option] = clone(defaultOptions[option]);
+            }
+        }
+        return newOptions;
+    }
+
+    function setListener(primitive, type, callback) {
+        primitive[type] = callback;
+    }
+
+    function enhanceWithListeners(element) {
+
+        element._listeners = {};
+
+        element.addListener = function (name, callback) {
+            this._listeners[name] = (this._listeners[name] || []);
+            this._listeners[name].push(callback);
+            return this._listeners[name].length;
+        }
+
+        element.executeListeners = function (event, defaultCallback) {
+            if (this._listeners[event.name] && this._listeners[event.name].length > 0) {
+                var index = 0;
+                for (; index < this._listeners[event.name].length; index++) {
+                    this._listeners[event.name][index](event);
+                }
+            } else {
+                if (defaultCallback) {
+                    defaultCallback(event);
+                }
+            }
+        }
+
+    }
+
+    return _;
+})();
\ No newline at end of file
diff --git a/widgets/filyL/js/move.js b/widgets/filyL/js/move.js
new file mode 100644
index 0000000..5a6331f
--- /dev/null
+++ b/widgets/filyL/js/move.js
@@ -0,0 +1,103 @@
+function move(dom, Wx, Wy) {
+    this.dom = $(dom);
+    this.left = 0;
+    this.top = 0;
+    this.moveWhat = () => {
+        this.moveWhats();
+        console.log(this, 'inmoveWhat');
+    };
+    this.moveWhats = () => {
+        console.log(this.dom, 'inmoveWhatS');
+    };
+    var beginrelative = () => {//relative
+        var that = this;
+        this.dom.mousedown((e) => {
+            var a = 'null';
+            var x = e.clientX
+                , y = e.clientY
+                , xx, yy
+                , L = that.left
+                , T = that.top;
+            this.dom.css({
+                'left': that.left,
+                "top": that.top
+            })
+            console.log("dianxia");
+            this.dom.mousemove((e) => {
+                console.log("yidong")
+                a = e;
+                xx = e.clientX;
+                yy = e.clientY;
+                that.left = xx - x + L;
+                that.top = yy - y + T;
+                console.log((x + L + that.left) < e.offsetX)
+                this.dom.css({
+                    'left': that.left,
+                    "top": that.top
+                })
+            })
+            this.dom.mouseup(() => {
+                if (a != 'null') {
+                    this.dom.unbind(a);
+                    a = 'null';
+                    console.log("songkai")
+                }
+            })
+            this.dom.mouseout((e) => {
+                if (a != 'null') {
+                    this.dom.unbind(a);
+                    a = 'null';
+                    console.log("songkai")
+                }
+                this.dom.unbind(e);
+            })
+        })
+    }
+    // beginrelative();
+
+    var beginabsolute = () => {
+        var that = this;
+        this.dom.mousedown((e) => {
+            var a = 'null';
+            var x = e.clientX
+                , y = e.clientY
+                , xx, yy;
+            this.dom.css({
+                'left': that.left,
+                "top": that.top
+            })
+            console.log("dianxia");
+            this.dom.mousemove((e) => {
+                console.log("yidong")
+                a = e;
+                xx = e.clientX;
+                yy = e.clientY;
+                that.left = xx - x;
+                that.top = yy - y;
+                console.log((x + L + that.left) < e.offsetX)
+                this.dom.css({
+                    'left': that.left,
+                    "top": that.top
+                })
+            })
+            this.dom.mouseup(() => {
+                if (a != 'null') {
+                    this.dom.unbind(a);
+                    a = 'null';
+                    console.log("songkai")
+                }
+            })
+            this.dom.mouseout((e) => {
+                if (a != 'null') {
+                    this.dom.unbind(a);
+                    a = 'null';
+                    console.log("songkai")
+                }
+                this.dom.unbind(e);
+            })
+        })
+    }
+    beginabsolute();
+}
+
+
diff --git a/widgets/filyL/manifest.json b/widgets/filyL/manifest.json
new file mode 100644
index 0000000..6695c40
--- /dev/null
+++ b/widgets/filyL/manifest.json
@@ -0,0 +1,17 @@
+{
+  "name": "filyL",
+  "2D": true,
+  "3D": true,
+  "platform": "HTML",
+  "version": "2.10",
+  "wabVersion": "2.10",
+  "author": "liuyg",
+  "description": "",
+  "copyright": "",
+  "license": "",
+  "properties": {
+    "hasConfig": false,
+    "inPanel": false,
+    "hasVersionManager": false
+  }
+}
\ No newline at end of file
diff --git a/widgets/filyL/nls/es/strings.js b/widgets/filyL/nls/es/strings.js
new file mode 100644
index 0000000..23c3bce
--- /dev/null
+++ b/widgets/filyL/nls/es/strings.js
@@ -0,0 +1,5 @@
+define(
+   ({
+    _widgetLabel: "filyL"
+  })
+);
\ No newline at end of file
diff --git a/widgets/filyL/nls/strings.js b/widgets/filyL/nls/strings.js
new file mode 100644
index 0000000..25b84f6
--- /dev/null
+++ b/widgets/filyL/nls/strings.js
@@ -0,0 +1,7 @@
+define({
+  root: ({
+    _widgetLabel: "filyL"
+  }),
+  "es": 1,
+  "zh-cn": 1
+});
\ No newline at end of file
diff --git a/widgets/filyL/nls/zh-cn/strings.js b/widgets/filyL/nls/zh-cn/strings.js
new file mode 100644
index 0000000..429d5e5
--- /dev/null
+++ b/widgets/filyL/nls/zh-cn/strings.js
@@ -0,0 +1,5 @@
+define(
+   ({
+    _widgetLabel: "飞行"
+  })
+);
\ No newline at end of file
diff --git "a/widgets/filyL/\345\256\236\344\276\213\344\270\264\346\227\266 copy 2.html" "b/widgets/filyL/\345\256\236\344\276\213\344\270\264\346\227\266 copy 2.html"
new file mode 100644
index 0000000..fa768ce
--- /dev/null
+++ "b/widgets/filyL/\345\256\236\344\276\213\344\270\264\346\227\266 copy 2.html"
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+	<meta charset="UTF-8">
+	<title>Title</title>
+	<style>
+		#box {
+			width: 100px;
+			height: 100px;
+			border: 3px solid springgreen;
+			/* background-color: teal; */
+			border-radius: 50px;
+			position: absolute;
+		}
+	</style>
+</head>
+
+<body>
+	<script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
+	<script src="./js/move.js"></script>
+	<!-- <script src="js/flycesium.js"></script> -->
+	<div id="box"></div>
+	<script>
+		var m = new move('#box');
+		m.moveWhat();
+	</script>
+</body>
+
+</html>
\ No newline at end of file
diff --git "a/widgets/filyL/\345\256\236\344\276\213\344\270\264\346\227\266 copy.html" "b/widgets/filyL/\345\256\236\344\276\213\344\270\264\346\227\266 copy.html"
new file mode 100644
index 0000000..fe5a50a
--- /dev/null
+++ "b/widgets/filyL/\345\256\236\344\276\213\344\270\264\346\227\266 copy.html"
@@ -0,0 +1,587 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+	<meta charset="UTF-8">
+	<title>Title</title>
+	<link rel="stylesheet" href="js/Cesium1.63/Widgets/widgets.css">
+	<link rel="stylesheet" href="css/bootstrap.css">
+	<link rel="stylesheet" href="css/cesiumviewer.css">
+	<link rel="stylesheet" href="css/DrawHelper.css">
+	<link rel="stylesheet" href="js/jqueryDialog/jDialog/jDialog.css">
+	<link rel="stylesheet" href="css/index.css">
+</head>
+
+<body>
+	
+
+
+	<script src="js/jquery-3.4.1.js"></script>
+	<script src="js/Cesium1.63/Cesium.js"></script>
+	<script src="js/jqueryDialog/jDialog.js"></script>
+	<script src="js/DrawHelper.js"></script>
+	<script src="js/viewerCesiumNavigationMixin.js"></script>
+	<!-- <script src="js/flycesium.js"></script> -->
+	<script>
+		viewer = new Cesium.Viewer('box', {
+			animation: false,
+			baseLayerPicker: false,
+			geocoder: true,
+			timeline: false,
+			sceneModePicker: true,
+			navigationHelpButton: false,
+			useDefaultRenderLoop: true,
+			showRenderLoopErrors: true,
+			fullscreenButton: true,
+			fullscreenElement: 'map3d',
+			infoBox: true,
+			mapProjection: new Cesium.WebMercatorProjection(),
+			imageryProvider: new Cesium.WebMapTileServiceImageryProvider({
+				url: "http://t0.tianditu.com/img_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=img&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default&format=tiles&tk=ebf64362215c081f8317203220f133eb",
+				layer: "tdtBasicLayer",
+				style: "default",
+				format: "image/jpeg",
+				tileMatrixSetID: "GoogleMapsCompatible",
+				show: false,
+				maximumLevel: 18
+			})
+		});
+		var drawHelper = new DrawHelper(viewer);
+		//三维飞行初始化
+		bxmap.FlyCesium.Init(viewer, drawHelper, 'box');//初始化漫游飞行路径功能
+
+		var bxmap = bxmap || {};
+		bxmap.FlyCesium = {
+			cesiumViewer: null,
+			draw3DObj: null,
+			drawHelper: null,
+			isDrawFly: false,//设定路线模式
+			drawPolyline: null,//飞行绘制路线
+			parentID: null,
+			node: null,
+			data: [
+				/*{
+					id:'1',name:'阳江闸坡',geojson:'{"orientation":{"heading":0.07372076173362352,"pitch":-1.5574628887292024,"roll":0},"position":{"x":-2205629.231433604,"y":5509184.64306962,"z":2331219.615547844},"geometry":{"type":"LineString","coordinates":[[111.8181532375421,21.57868178213224],[111.81835028960268,21.578460581633188],[111.81832383076255,21.57812489081727],[111.81847943987464,21.577930686377922],[111.81878489838651,21.57765953027421],[111.81916083936886,21.577412646930927],[111.81958489944898,21.57729241143278],[111.82004766614196,21.57718315464893],[111.8206409631356,21.577000552080584],[111.82134398589339,21.576873639989994],[111.8219423400026,21.576726154070943],[111.822467537162,21.576376210912294],[111.82307030263561,21.576058642812292],[111.8237103973151,21.5756704298083],[111.8240924390803,21.575296152837485],[111.82504071801145,21.575766169089448],[111.82603850185104,21.576124273877287],[111.82694738799758,21.576428149353344],[111.82754018969692,21.576728981595224],[111.828099605676,21.57697046673728],[111.82845968318266,21.577307788777407],[111.8287111214647,21.577998110617774],[111.82881328135024,21.578557636789135],[111.82905095574245,21.57877846306897],[111.82918966895863,21.579074053131905],[111.82928422024466,21.579329257594996],[111.82930019172734,21.579630618390876],[111.82966603969574,21.580020790142015],[111.82960868244719,21.580744679418963],[111.82989219533579,21.581251462292837],[111.83013608532544,21.582236343172],[111.83037855800974,21.58254231013029],[111.83032824715998,21.58299431932842],[111.83001717858694,21.583468817164515],[111.8299185766154,21.584290601587544],[111.82948276544901,21.58496623602712],[111.8289749235787,21.58556878427974],[111.82886305199469,21.585776309810406],[111.8287779821505,21.585946333271792],[111.82865496967007,21.586265136888645],[111.82847674720864,21.586438092096014],[111.82845974740698,21.586567373767977],[111.828355170664,21.586736247366822],[111.82830843296874,21.586863152790087],[111.82825365102633,21.58710380271154],[111.82821734971404,21.587138762444976],[111.82817916952548,21.587294814193356],[111.82787759367034,21.587314539280754],[111.82719468513524,21.587237821164194],[111.82672929414602,21.58716013804561],[111.82658494057793,21.587131014021804],[111.82652478882481,21.587094797111455],[111.82647814913857,21.58694770659332],[111.82649812273736,21.58651375697629],[111.82650209141173,21.586517166652694],[111.82650209141173,21.586517166652694]]}}'
+				}*/
+			],//漫游路径信息模拟数据
+			Init: function (cesiumViewer, drawHelper, parentID) {
+				this.cesiumViewer = cesiumViewer; //cesium对象
+				this.drawHelper = drawHelper;//drawHelper对象
+				this.parentID = parentID;//父容器
+				this.InitHtml();
+				this.InitEvent();
+				this.loadData();
+			},
+			InitHtml: function () {
+				var parent = document.getElementById(bxmap.FlyCesium.parentID);
+				bxmap.FlyCesium.node = `<div id= "fly3DPaths" class="fly3DPaths">
+        <div class="fly3DPaths_title">操作菜单 <span id="fly3DClose" class="fly3DClose"></span></div>
+        <!--新增-->
+        <!-- tab导航部分 -->
+        <div class='fly3DPaths_tab'>
+            <ul style='margin-left:0;' class="fly3DPaths_tab_ul">
+                <li id="overFlyClick"><span><span class='flss'></span><a href='javascript:void(0)'>预设路线</a></span></li>
+                <li id="drawFlyCilck" class="select"><span><span class='flss'></span><a href='javascript:void(0);'>手动绘制</a></span></li>
+            </ul>
+        </div>
+        <!-- tab内容部分 -->
+        <!-- 预设路线 -->
+        <div id='overFlyPage' style='height: 100%;; display:none'>
+            <div style="padding: 5px;margin-top: 5px;">
+                <div class='ydph-table-wrap'>
+                    <div class='ydph-talbe-head'>
+                        <table id='overFly_table' class='table table-bordered'>
+                            <thead>
+                            <tr>
+                                <!--<th class='colspan1'><input type='checkbox' οnchange=''/></th>-->
+                                <th class='colspan4'>名称</th>
+                                <th class='colspan2'>操作</th>
+                                <th class='colspan2'>修改</th>
+                                <th class='colspan2'>删除</th>
+                            </tr>
+                            </thead>
+                            <tbody></tbody>
+                        </table>
+                    </div>
+                </div>
+            </div>
+        </div>
+        <!-- 手动绘制 -->
+        <div id='drawFlyPage' style='height: 100%'>
+            <div class="fly3DPaths_content">
+                <input id="start_Fly3DPaths" class="fly3DPaths_model_id" type="button" value="开始飞行">
+                <input id="pause_Fly3DPaths" class="fly3DPaths_model_id" type="button" value="暂停飞行">
+                <input id="playForward_Fly3DPaths" class="fly3DPaths_model_id" type="button" value="向前飞行">
+                <input id="playReverse_Fly3DPaths" class="fly3DPaths_model_id" type="button" value="向后飞行">
+                <input id="draw_Fly3DPaths" class="fly3DPaths_model_id" type="button" value="设定路线">
+                <input id="save_Fly3DPaths" class="fly3DPaths_model_id" type="button" value="保存路线">
+                <input id="clear_Fly3DPaths" class="fly3DPaths_model_id" type="button" value="清空路线">
+                <input id="stop_Fly3DPaths" class="fly3DPaths_model_id" type="button" value="退出飞行">
+            </div>
+        </div>
+
+    </div>`;
+				$(parent).append(bxmap.FlyCesium.node);
+			},
+			InitEvent: function () {
+				//飞行路径顶端部分的切换事件
+				$(".fly3DPaths_tab li").bind("click", function () {
+					$('.fly3DPaths_tab_ul>li').each(function (index) {
+						$('.fly3DPaths_tab_ul>li').eq(index).removeClass('select');
+					});
+					var $overFlyPage = $("#overFlyPage");
+					var $drawFlyPage = $("#drawFlyPage");
+					//三角形标识切换
+					switch ($(this).index()) {
+						case 0://预设路线
+							$('#overFlyClick').addClass('select');
+							$overFlyPage.css({ display: "block" });
+							$drawFlyPage.css({ display: "none" });
+							bxmap.FlyCesium.loadData();
+							break;
+						case 1://手动绘制
+							$('#drawFlyCilck').addClass('select');
+							$overFlyPage.css({ display: "none" });
+							$drawFlyPage.css({ display: "block" });
+							break;
+					}
+				});
+				//开始飞行
+				$("#start_Fly3DPaths").click(function () {
+					//debugger;
+					if (bxmap.FlyCesium.draw3DObj) {
+						bxmap.FlyCesium.showFly3DPaths(bxmap.FlyCesium.draw3DObj);
+					} else {
+						jDialog.dialog({
+							title: "提示信息",
+							modal: true,// 非模态,即不显示遮罩层
+							autoClose: 1500,
+							content: "漫游路线不存在"
+						});
+					}
+				});
+				//暂停飞行
+				$("#pause_Fly3DPaths").click(function () {
+					bxmap.FlyCesium.pauseFly3DPaths();
+				});
+				//向前飞行
+				$("#playForward_Fly3DPaths").click(function () {
+					bxmap.FlyCesium.playForwardFly3DPaths();
+				});
+				//向后飞行
+				$("#playReverse_Fly3DPaths").click(function () {
+					bxmap.FlyCesium.playReverseFly3DPaths();
+				});
+				//退出飞行
+				$("#stop_Fly3DPaths").click(function () {
+					$("#cesiumFly3DPaths").click();
+					bxmap.FlyCesium.stopFly3DPaths();
+				});
+				//清空路线
+				$("#clear_Fly3DPaths").click(function () {
+					bxmap.FlyCesium.clearFly3DPaths();
+				});
+				//设定路线
+				$("#draw_Fly3DPaths").click(function () {
+					if (!bxmap.FlyCesium.drawHelper) {
+						bxmap.FlyCesium.drawHelper = new DrawHelper(bxmap.FlyCesium.cesiumViewer);
+					}
+					bxmap.FlyCesium.draw3DObj = bxmap.FlyCesium.DrawFly3DPaths(bxmap.FlyCesium.drawHelper);
+				});
+				//保存路线
+				$("#save_Fly3DPaths").click(function () {
+					if (bxmap.FlyCesium.draw3DObj && bxmap.FlyCesium.isDrawFly) {
+						jDialog.dialog({
+							title: '保存路线',
+							content: '<div><span>名称:</span><input type="text" id="FlyAdd_name" value="' + name + '"></div>',
+							width: 300,
+							height: 120,
+							modal: true,// 非模态,即不显示遮罩层
+							buttons: [
+								{
+									text: '确定',
+									handler: function (button, dialog) {
+										var draw3DObj = JSON.stringify(bxmap.FlyCesium.draw3DObj); //将JSON对象转化为JSON字符
+										var TbFly = { id: Math.random().toString(36).substr(2), name: $("#FlyAdd_name").val(), geojson: draw3DObj };
+										bxmap.FlyCesium.data.push(TbFly);
+										$("#overFlyClick").click();
+										dialog.close();
+										bxmap.FlyCesium.clearFly3DPaths();
+
+									}
+								}, {
+									text: '取消',
+									handler: function (button, dialog) {
+										dialog.close();
+									}
+								}
+							]
+						});
+
+					} else {
+						jDialog.dialog({
+							title: "提示信息",
+							modal: true,// 非模态,即不显示遮罩层
+							autoClose: 1500,
+							content: "设定的漫游路线不存在,请绘制再保存"
+						});
+					}
+
+				});
+				//关闭界面
+				$("#fly3DClose").click(function () {
+					var $fly3DPaths = $("#fly3DPaths");
+					bxmap.FlyCesium.clearFly3DPaths();
+					$fly3DPaths.hide(1000, function () {
+						$fly3DPaths.remove();
+					});
+				});
+			},
+			//飞行路径列表表格监听事件
+			flyTableOnclick: function () {
+				$("#overFly_table td").click(function () {
+					var trSeq = $(this).parent().parent().find("tr").index($(this).parent());//选中的哪行
+					var geojson = $("#overFly_table tr:gt(0):eq(" + trSeq + ") td:eq(5)").text();//获取选中行的geojson列值
+					var name = $("#overFly_table tr:gt(0):eq(" + trSeq + ") td:eq(0)").text();//获取选中行的name列值
+					var id = $("#overFly_table tr:gt(0):eq(" + trSeq + ") td:eq(4)").text();//获取选中行的id列值
+					geojson = eval("(" + geojson + ")");
+					var tdSeq = $(this).parent().find("td").index($(this));//选中哪一列
+					switch (tdSeq) {
+						case 0://名称
+							break;
+						case 1://飞行
+							bxmap.FlyCesium.draw3DObj = geojson;
+							//bxmap.FlyCesium.cesium.showFly3DPaths(geojson);
+							bxmap.FlyCesium.showFly3DPaths(geojson);
+							$("#drawFlyCilck").click();
+							break;
+						case 2://修改
+							jDialog.dialog({
+								title: '修改路线',
+								content: '<div><span>名称:</span><input type="text" id="Fly_name" value="' + name + '"></div>',
+								width: 300,
+								height: 120,
+								modal: true,// 非模态,即不显示遮罩层
+								buttons: [
+									{
+										text: '确定',
+										handler: function (button, dialog) {
+											bxmap.FlyCesium.data = bxmap.FlyCesium.modifyElement(bxmap.FlyCesium.data, id, $("#Fly_name").val());
+											$("#overFlyClick").click();
+											dialog.close();
+										}
+									}, {
+										text: '取消',
+										handler: function (button, dialog) {
+											dialog.close();
+										}
+									}
+								]
+							});
+							break;
+						case 3://删除
+							//删除
+							jDialog.dialog({
+								title: '删除路线',
+								modal: true,// 非模态,即不显示遮罩层
+								content: "确定要删除该漫游路线?",
+								buttons: [
+									{
+										text: '确定',
+										handler: function (button, dialog) {
+											bxmap.FlyCesium.data = bxmap.FlyCesium.delElement(bxmap.FlyCesium.data, id);
+											$("#overFlyClick").click();
+											dialog.close();
+										}
+									}, {
+										text: '取消',
+										handler: function (button, dialog) {
+											dialog.close();
+										}
+									}
+								]
+							});
+							break;
+					}
+				})
+			},
+			/**
+			 * 从数组中移除指定的元素,要是存在的话
+			 @ serviceArray筛选数组
+			 @ id移除元素id
+			 */
+			delElement: function (serviceArray, id) {
+				var array = [];
+				for (var i = 0; i < serviceArray.length; i++) {
+					if (serviceArray[i].id !== id) {
+						array.push(serviceArray[i]);
+					}
+				}
+				return array;
+			},
+			/**
+			 * 从数组中修改指定的元素,要是存在的话
+			 @ serviceArray筛选数组
+			 @ id修改元素id
+			 @ name修改元素名称
+			 */
+			modifyElement: function (serviceArray, id, name) {
+				var array = [];
+				for (var i = 0; i < serviceArray.length; i++) {
+					if (serviceArray[i].id === id) {
+						serviceArray[i].name = name;
+					}
+					array.push(serviceArray[i]);
+				}
+				return array;
+			},
+			loadData: function () {
+				var data = bxmap.FlyCesium.data;
+				var html = '';
+				var $overFly_table = $('#overFly_table');
+				if (data.length >= 0) {
+					for (var i = 0; i < data.length; i++) {
+						var flydata = data[i];
+						html += '<tr>' +
+							'<td><a style="color:#fff;text-decoration:none;font-size:12px;">' + flydata.name + '</a></td>' +
+							'<td><button class="btn btn-default btn-xs" style="color:#fff;">飞行</button></td>' +
+							'<td><button class="btn btn-default btn-xs" style="color:#fff;">修改</button></td>' +
+							'<td><button class="btn btn-default btn-xs" style="color:#fff;">删除</button></td>' +
+							"<td><a style='color:black;text-decoration:none;font-size:13px;'>" + flydata.id + "</a></td>" +
+							"<td><a style='color:black;text-decoration:none;font-size:13px;'>" + flydata.geojson + "</a></td>" +
+							"<td><a style='color:black;text-decoration:none;font-size:13px;'>" + flydata.position + "</a></td>" +
+							"<td><a style='color:black;text-decoration:none;font-size:13px;'>" + flydata.orientation + "</a></td>" +
+							'</tr>';
+					}
+					$("#overFly_table tbody").html(html);
+					$overFly_table.find('td:eq(4)').hide();//隐藏id字段列
+					$overFly_table.find('td:eq(5)').hide();//隐藏geojson字段列
+					$overFly_table.find('td:eq(6)').hide();//隐藏position字段列
+					$overFly_table.find('td:eq(7)').hide();//隐藏orientation字段列
+					//表格---行点击事件
+					bxmap.FlyCesium.flyTableOnclick();
+				}
+			},
+			/**
+		 * 清空漫游路径
+		 * @method stopFly3DPaths
+		 * @return
+		 */
+			clearFly3DPaths: function () {
+				this.cesiumViewer.trackedEntity = undefined;
+				bxmap.FlyCesium.isDrawFly = false;
+				bxmap.FlyCesium.draw3DObj = null;
+				this.cesiumViewer.entities.removeAll();//清空所有模型
+				//清空绘制飞行路线
+				if (this.drawPolyline) {
+					this.cesiumViewer.scene.primitives.remove(this.drawPolyline);
+					this.drawPolyline = null;
+				}
+			},
+			/**
+			 * 飞行漫游路径
+			 * @param pathsData
+			 */
+			showFly3DPaths: function (pathsData) {
+				var T = this;
+				this.clearFly3DPaths();
+				T.cesiumViewer.camera.setView({
+					destination: pathsData.position,
+					orientation: pathsData.orientation,
+				});
+				setTimeout(function () {
+					executeFly3D();
+				}, 200);
+				function executeFly3D() {
+					if (pathsData && pathsData.geometry) {
+						var positionA = pathsData.geometry.coordinates;
+						var position = [];
+						if (positionA.length > 0) {
+							for (var i = 0; i < positionA.length; i++) {
+								var x = positionA[i][0];
+								var y = positionA[i][1];
+								position.push({ x: x, y: y });
+							}
+						} else {
+							return;
+						}
+						function computeCirclularFlight() {
+							var property = new Cesium.SampledPositionProperty();
+							for (var i = 0; i < position.length; i++) {
+								if (i === 0) {
+									var time = Cesium.JulianDate.addSeconds(start, i, new Cesium.JulianDate());
+									//var _position = Cesium.Cartesian3.fromDegrees(position[i].x, position[i].y, 1170);
+									var _position = Cesium.Cartesian3.fromDegrees(position[i].x, position[i].y, 0);
+									property.addSample(time, _position);
+								}
+								if (i < 10000 && i > 0) {
+									var position_a = new Cesium.Cartesian3(property._property._values[i * 3 - 3], property._property._values[i * 3 - 2], property._property._values[i * 3 - 1]);
+									if (i < 976) {
+										var _position = Cesium.Cartesian3.fromDegrees(position[i].x, position[i].y, 0);
+									}
+									else if (i > 975 && i < 986) {
+										var _position = Cesium.Cartesian3.fromDegrees(position[i].x, position[i].y, 0);
+									}
+									else if (i > 985) {
+										var _position = Cesium.Cartesian3.fromDegrees(position[i].x, position[i].y, 0);
+									}
+
+									var positions = [Cesium.Ellipsoid.WGS84.cartesianToCartographic(position_a), Cesium.Ellipsoid.WGS84.cartesianToCartographic(_position)];
+									var a = new Cesium.EllipsoidGeodesic(positions[0], positions[1]);
+									var long = a.surfaceDistance;
+									var _time = long / 50;
+									var time = Cesium.JulianDate.addSeconds(property._property._times[i - 1], _time, new Cesium.JulianDate());
+
+									property.addSample(time, _position);
+								}
+							}
+							return property;
+						}
+						var start = Cesium.JulianDate.fromDate(new Date());
+						var stop = Cesium.JulianDate.addSeconds(start, 30000, new Cesium.JulianDate());
+						T.cesiumViewer.clock.startTime = start.clone();
+						T.cesiumViewer.clock.stopTime = stop.clone();
+						T.cesiumViewer.clock.currentTime = start.clone();
+						T.cesiumViewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP;
+						T.cesiumViewer.clock.multiplier = 5;//值越大,飞行越快
+						T.cesiumViewer.clock.canAnimate = false;
+						T.cesiumViewer.clock.shouldAnimate = true;//设置时间轴动态效果
+
+						var _position = computeCirclularFlight();
+
+						T.entityFly = T.cesiumViewer.entities.add({
+							availability: new Cesium.TimeIntervalCollection([new Cesium.TimeInterval({
+								start: start,
+								stop: stop
+							})]),
+							position: _position,
+							orientation: new Cesium.VelocityOrientationProperty(_position),
+							point: {
+								color: Cesium.Color.RED,
+								outlineColor: Cesium.Color.WHITE,
+								outlineWidth: 2,
+								pixelSize: 15,
+							},
+							//Show the path as a pink line sampled in 1 second increments.
+							path: {
+								resolution: 1,
+								material: new Cesium.PolylineGlowMaterialProperty({
+									glowPower: 0.1,
+									color: Cesium.Color.YELLOW
+								}),
+								//width: 30
+								width: 10
+							}
+						});
+						T.cesiumViewer.trackedEntity = T.entityFly;
+						setTimeout(function () {
+							T.cesiumViewer.camera.zoomOut(500.0);//缩小地图,避免底图没有数据
+						}, 100);
+					} else {
+						return;
+					}
+				}
+			},
+			/**
+		 * 暂停飞行漫游路径
+		 * @method pauseFly3DPaths
+		 * @return
+		 */
+			pauseFly3DPaths: function () {
+				var clockViewModel = this.cesiumViewer.clockViewModel;
+				if (clockViewModel.shouldAnimate) {
+					clockViewModel.shouldAnimate = false;
+				} else if (this.cesiumViewer.clockViewModel.canAnimate) {
+					clockViewModel.shouldAnimate = true;
+				}
+			},
+			/**
+		   * 向前飞行漫游路径
+		   * @method playForwardFly3DPaths
+		   * @return
+		   */
+			playForwardFly3DPaths: function () {
+				var clockViewModel = this.cesiumViewer.clockViewModel;
+				var multiplier = clockViewModel.multiplier;
+				if (multiplier < 0) {
+					clockViewModel.multiplier = -multiplier;
+				}
+				clockViewModel.shouldAnimate = true;
+			},
+			/**
+			 * 向后飞行漫游路径
+			 * @method playForwardFly3DPaths
+			 * @return
+			 */
+			playReverseFly3DPaths: function () {
+				var clockViewModel = this.cesiumViewer.clockViewModel;
+				var multiplier = clockViewModel.multiplier;
+				if (multiplier > 0) {
+					clockViewModel.multiplier = -multiplier;
+				}
+				clockViewModel.shouldAnimate = true;
+			},
+			/**
+		  * 设定飞行漫游路径
+		  * @method DrawFly3DPaths
+		  * @return
+		  */
+			DrawFly3DPaths: function (drawHelper) {
+				var T = this;
+				this.clearFly3DPaths();
+				drawHelper.startDrawingPolyline({
+					callback: function (positions) {
+						T.drawPolyline = new DrawHelper.PolylinePrimitive({
+							positions: positions,
+							width: 5,
+							type: "plot",
+							geodesic: true
+						});
+						T.cesiumViewer.scene.primitives.add(T.drawPolyline);
+						T.drawPolyline.setEditable();
+						//构造设定路线的返回信息
+						var coordinates = [];
+						var position = null;
+						var heading = null;
+						var pitch = null;
+						var roll = null;
+						for (var i = 0; i < positions.length; i++) {
+							var cartographic = Cesium.Cartographic.fromCartesian(positions[i]);//世界坐标转地理坐标(弧度)
+							var point = [cartographic.longitude / Math.PI * 180, cartographic.latitude / Math.PI * 180];//地理坐标(弧度)转经纬度坐标
+							//console.log(point);
+							coordinates.push(point);
+						}
+						//orientation":{"heading":2.411783930363565,"pitch":-0.21097267398444197,"roll":0.0015622392231300353},"position": {"x":-2206260.239730831,"y":5510911.392077349,"z":2331987.10863007},
+						position = drawHelper._cameraPosition;
+						heading = drawHelper._cameraHeading;
+						pitch = drawHelper._cameraPitch;
+						roll = drawHelper._cameraRoll;
+						var pathsData = { "orientation": { "heading": heading, "pitch": pitch, "roll": roll }, "position": position, "geometry": { "type": "LineString", "coordinates": coordinates } };
+						if (bxmap.FlyCesium) {
+							bxmap.FlyCesium.draw3DObj = T.draw3DObj = pathsData;
+							bxmap.FlyCesium.isDrawFly = true;
+						}
+						//return T.draw3DObj;
+
+					}
+				});
+			},
+			/**
+		 * 退出飞行漫游路径
+		 * @method stopFly3DPaths
+		 * @return
+		 */
+			stopFly3DPaths: function () {
+				var start = Cesium.JulianDate.fromDate(new Date());
+				this.cesiumViewer.clock.startTime = start.clone();
+				var stop = Cesium.JulianDate.addSeconds(start, 300000000, new Cesium.JulianDate());
+				this.cesiumViewer.clock.stopTime = stop.clone();
+				//this.cesiumViewer.entities.remove(this.entityFly);
+				this.clearFly3DPaths();
+			},
+
+		};
+	</script>
+</body>
+
+</html>
\ No newline at end of file
diff --git a/widgets/visibleArea/Widget.js b/widgets/visibleArea/Widget.js
index e019b37..2e244d6 100644
--- a/widgets/visibleArea/Widget.js
+++ b/widgets/visibleArea/Widget.js
@@ -261,6 +261,7 @@
                             viewshed3D.setDistDirByPoint([longitude, latitude, height]);
                         }
                     }
+                    // handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
                 }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
 
                 handler.setInputAction(function (e) {

--
Gitblit v1.9.3