浏览代码

完成es6转换

rindy 5 年之前
父节点
当前提交
f725494225
共有 36 个文件被更改,包括 3422 次插入186 次删除
  1. 140 0
      package-lock.json
  2. 3 0
      package.json
  3. 2 2
      public/index.html
  4. 247 1
      src/core/plugins/HeatmapImageryProvider.js
  5. 134 134
      src/core/plugins/SpirographPositionProperty.js
  6. 161 0
      src/core/plugins/cesium-navigation-es6/CesiumNavigation.js
  7. 21 0
      src/core/plugins/cesium-navigation-es6/LICENSE
  8. 69 0
      src/core/plugins/cesium-navigation-es6/README.md
  9. 32 0
      src/core/plugins/cesium-navigation-es6/core/KnockoutHammerBinding.js
  10. 66 0
      src/core/plugins/cesium-navigation-es6/core/KnockoutMarkdownBinding.js
  11. 64 0
      src/core/plugins/cesium-navigation-es6/core/Utils.js
  12. 13 0
      src/core/plugins/cesium-navigation-es6/core/createFragmentFromTemplate.js
  13. 35 0
      src/core/plugins/cesium-navigation-es6/core/loadView.js
  14. 26 0
      src/core/plugins/cesium-navigation-es6/core/registerKnockoutBindings.js
  15. 85 0
      src/core/plugins/cesium-navigation-es6/index.js
  16. 30 0
      src/core/plugins/cesium-navigation-es6/package.json
  17. 286 0
      src/core/plugins/cesium-navigation-es6/styles/Core.less
  18. 42 0
      src/core/plugins/cesium-navigation-es6/styles/DistanceLegend.less
  19. 25 0
      src/core/plugins/cesium-navigation-es6/styles/Floating.less
  20. 146 0
      src/core/plugins/cesium-navigation-es6/styles/Navigation.less
  21. 486 0
      src/core/plugins/cesium-navigation-es6/styles/cesium-navigation.css
  22. 44 0
      src/core/plugins/cesium-navigation-es6/styles/cesium-navigation.less
  23. 4 0
      src/core/plugins/cesium-navigation-es6/svgPaths/svgCompassGyro.js
  24. 4 0
      src/core/plugins/cesium-navigation-es6/svgPaths/svgCompassOuterRing.js
  25. 2 0
      src/core/plugins/cesium-navigation-es6/svgPaths/svgCompassRotationMarker.js
  26. 3 0
      src/core/plugins/cesium-navigation-es6/svgPaths/svgReset.js
  27. 166 0
      src/core/plugins/cesium-navigation-es6/viewModels/DistanceLegendViewModel.js
  28. 17 0
      src/core/plugins/cesium-navigation-es6/viewModels/NavigationControl.js
  29. 585 0
      src/core/plugins/cesium-navigation-es6/viewModels/NavigationViewModel.js
  30. 122 0
      src/core/plugins/cesium-navigation-es6/viewModels/ResetViewNavigationControl.js
  31. 105 0
      src/core/plugins/cesium-navigation-es6/viewModels/UserInterfaceControl.js
  32. 148 0
      src/core/plugins/cesium-navigation-es6/viewModels/ZoomNavigationControl.js
  33. 5 1
      src/core/plugins/fixGltf.js
  34. 22 12
      src/core/mvt.js
  35. 40 19
      src/core/viewer.js
  36. 42 17
      vue.config.js

+ 140 - 0
package-lock.json

@@ -2339,6 +2339,14 @@
       "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
       "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
       "dev": true
       "dev": true
     },
     },
+    "cesium": {
+      "version": "1.63.1",
+      "resolved": "https://registry.npm.taobao.org/cesium/download/cesium-1.63.1.tgz",
+      "integrity": "sha1-rIwUPgyRV9QMCWN/OBXWprquASI=",
+      "requires": {
+        "esm": "^3.2.25"
+      }
+    },
     "chalk": {
     "chalk": {
       "version": "2.4.2",
       "version": "2.4.2",
       "resolved": "https://registry.npm.taobao.org/chalk/download/chalk-2.4.2.tgz?cache=0&sync_timestamp=1573282918610&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fchalk%2Fdownload%2Fchalk-2.4.2.tgz",
       "resolved": "https://registry.npm.taobao.org/chalk/download/chalk-2.4.2.tgz?cache=0&sync_timestamp=1573282918610&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fchalk%2Fdownload%2Fchalk-2.4.2.tgz",
@@ -2715,6 +2723,128 @@
         }
         }
       }
       }
     },
     },
+    "compression-webpack-plugin": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npm.taobao.org/compression-webpack-plugin/download/compression-webpack-plugin-3.0.0.tgz?cache=0&sync_timestamp=1559735131137&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcompression-webpack-plugin%2Fdownload%2Fcompression-webpack-plugin-3.0.0.tgz",
+      "integrity": "sha1-CX0uTZXDoUy1yO0giZAJq1ubvKA=",
+      "dev": true,
+      "requires": {
+        "cacache": "^11.2.0",
+        "find-cache-dir": "^3.0.0",
+        "neo-async": "^2.5.0",
+        "schema-utils": "^1.0.0",
+        "serialize-javascript": "^1.4.0",
+        "webpack-sources": "^1.0.1"
+      },
+      "dependencies": {
+        "cacache": {
+          "version": "11.3.3",
+          "resolved": "https://registry.npm.taobao.org/cacache/download/cacache-11.3.3.tgz",
+          "integrity": "sha1-i9Kd+ManGKbr0tAQ2k15cq47utw=",
+          "dev": true,
+          "requires": {
+            "bluebird": "^3.5.5",
+            "chownr": "^1.1.1",
+            "figgy-pudding": "^3.5.1",
+            "glob": "^7.1.4",
+            "graceful-fs": "^4.1.15",
+            "lru-cache": "^5.1.1",
+            "mississippi": "^3.0.0",
+            "mkdirp": "^0.5.1",
+            "move-concurrently": "^1.0.1",
+            "promise-inflight": "^1.0.1",
+            "rimraf": "^2.6.3",
+            "ssri": "^6.0.1",
+            "unique-filename": "^1.1.1",
+            "y18n": "^4.0.0"
+          }
+        },
+        "find-cache-dir": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npm.taobao.org/find-cache-dir/download/find-cache-dir-3.1.0.tgz",
+          "integrity": "sha1-mTWJSZnevvTPn2d/32RtACxM3ss=",
+          "dev": true,
+          "requires": {
+            "commondir": "^1.0.1",
+            "make-dir": "^3.0.0",
+            "pkg-dir": "^4.1.0"
+          }
+        },
+        "find-up": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npm.taobao.org/find-up/download/find-up-4.1.0.tgz",
+          "integrity": "sha1-l6/n1s3AvFkoWEt8jXsW6KmqXRk=",
+          "dev": true,
+          "requires": {
+            "locate-path": "^5.0.0",
+            "path-exists": "^4.0.0"
+          }
+        },
+        "locate-path": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npm.taobao.org/locate-path/download/locate-path-5.0.0.tgz",
+          "integrity": "sha1-Gvujlq/WdqbUJQTQpno6frn2KqA=",
+          "dev": true,
+          "requires": {
+            "p-locate": "^4.1.0"
+          }
+        },
+        "make-dir": {
+          "version": "3.0.0",
+          "resolved": "http://registry.npm.taobao.org/make-dir/download/make-dir-3.0.0.tgz",
+          "integrity": "sha1-G1859rknDtM/nwVMXA+EMEmJ+AE=",
+          "dev": true,
+          "requires": {
+            "semver": "^6.0.0"
+          }
+        },
+        "p-limit": {
+          "version": "2.2.1",
+          "resolved": "https://registry.npm.taobao.org/p-limit/download/p-limit-2.2.1.tgz",
+          "integrity": "sha1-qgeniMwxUck5tRMfY1cPDdIAlTc=",
+          "dev": true,
+          "requires": {
+            "p-try": "^2.0.0"
+          }
+        },
+        "p-locate": {
+          "version": "4.1.0",
+          "resolved": "http://registry.npm.taobao.org/p-locate/download/p-locate-4.1.0.tgz",
+          "integrity": "sha1-o0KLtwiLOmApL2aRkni3wpetTwc=",
+          "dev": true,
+          "requires": {
+            "p-limit": "^2.2.0"
+          }
+        },
+        "p-try": {
+          "version": "2.2.0",
+          "resolved": "http://registry.npm.taobao.org/p-try/download/p-try-2.2.0.tgz",
+          "integrity": "sha1-yyhoVA4xPWHeWPr741zpAE1VQOY=",
+          "dev": true
+        },
+        "path-exists": {
+          "version": "4.0.0",
+          "resolved": "http://registry.npm.taobao.org/path-exists/download/path-exists-4.0.0.tgz",
+          "integrity": "sha1-UTvb4tO5XXdi6METfvoZXGxhtbM=",
+          "dev": true
+        },
+        "pkg-dir": {
+          "version": "4.2.0",
+          "resolved": "https://registry.npm.taobao.org/pkg-dir/download/pkg-dir-4.2.0.tgz",
+          "integrity": "sha1-8JkTPfft5CLoHR2ESCcO6z5CYfM=",
+          "dev": true,
+          "requires": {
+            "find-up": "^4.0.0"
+          }
+        },
+        "semver": {
+          "version": "6.3.0",
+          "resolved": "https://registry.npm.taobao.org/semver/download/semver-6.3.0.tgz?cache=0&sync_timestamp=1565627380363&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsemver%2Fdownload%2Fsemver-6.3.0.tgz",
+          "integrity": "sha1-7gpkyK9ejO6mdoexM3YeG+y9HT0=",
+          "dev": true
+        }
+      }
+    },
     "concat-map": {
     "concat-map": {
       "version": "0.0.1",
       "version": "0.0.1",
       "resolved": "http://registry.npm.taobao.org/concat-map/download/concat-map-0.0.1.tgz",
       "resolved": "http://registry.npm.taobao.org/concat-map/download/concat-map-0.0.1.tgz",
@@ -3940,6 +4070,11 @@
         "estraverse": "^4.1.1"
         "estraverse": "^4.1.1"
       }
       }
     },
     },
+    "esm": {
+      "version": "3.2.25",
+      "resolved": "https://registry.npm.taobao.org/esm/download/esm-3.2.25.tgz",
+      "integrity": "sha1-NCwYwp1WFXaIulzjH4Qx+7eVzBA="
+    },
     "esprima": {
     "esprima": {
       "version": "4.0.1",
       "version": "4.0.1",
       "resolved": "http://registry.npm.taobao.org/esprima/download/esprima-4.0.1.tgz",
       "resolved": "http://registry.npm.taobao.org/esprima/download/esprima-4.0.1.tgz",
@@ -5155,6 +5290,11 @@
         "pify": "^4.0.1"
         "pify": "^4.0.1"
       }
       }
     },
     },
+    "hammerjs": {
+      "version": "2.0.8",
+      "resolved": "http://registry.npm.taobao.org/hammerjs/download/hammerjs-2.0.8.tgz",
+      "integrity": "sha1-BO93hiz/K7edMPdpIJWTAiK/YPE="
+    },
     "handle-thing": {
     "handle-thing": {
       "version": "2.0.0",
       "version": "2.0.0",
       "resolved": "http://registry.npm.taobao.org/handle-thing/download/handle-thing-2.0.0.tgz",
       "resolved": "http://registry.npm.taobao.org/handle-thing/download/handle-thing-2.0.0.tgz",

+ 3 - 0
package.json

@@ -8,12 +8,15 @@
     "build": "vue-cli-service build"
     "build": "vue-cli-service build"
   },
   },
   "dependencies": {
   "dependencies": {
+    "cesium": "^1.63.1",
     "core-js": "^2.6.5",
     "core-js": "^2.6.5",
+    "hammerjs": "^2.0.8",
     "vue": "^2.6.10"
     "vue": "^2.6.10"
   },
   },
   "devDependencies": {
   "devDependencies": {
     "@vue/cli-plugin-babel": "^3.11.0",
     "@vue/cli-plugin-babel": "^3.11.0",
     "@vue/cli-service": "^3.11.0",
     "@vue/cli-service": "^3.11.0",
+    "compression-webpack-plugin": "^3.0.0",
     "less": "^3.10.3",
     "less": "^3.10.3",
     "less-loader": "^5.0.0",
     "less-loader": "^5.0.0",
     "vue-template-compiler": "^2.6.10"
     "vue-template-compiler": "^2.6.10"

+ 2 - 2
public/index.html

@@ -14,8 +14,8 @@
     <script src="static/js/mapbox-streets-v6-style.js"></script>
     <script src="static/js/mapbox-streets-v6-style.js"></script>
     <script src="static/js/ol.js"></script>
     <script src="static/js/ol.js"></script>
     <!-- <script src="static/js/mvt.js"></script> -->
     <!-- <script src="static/js/mvt.js"></script> -->
-    <script src="static/Cesium/Cesium.js"></script>
-    <script src="static/js/CesiumNavigationMixin.min.js"></script>
+    <!-- <script src="static/Cesium/Cesium.js"></script>
+    <script src="static/js/CesiumNavigationMixin.min.js"></script> -->
     <script src="static/js/heatmap.min.js"></script>
     <script src="static/js/heatmap.min.js"></script>
 </body>
 </body>
 </html>
 </html>

文件差异内容过多而无法显示
+ 247 - 1
src/core/plugins/HeatmapImageryProvider.js


+ 134 - 134
src/core/plugins/SpirographPositionProperty.js

@@ -1,134 +1,134 @@
-/**
- * Created by G.Cordes on 01.06.16.
- */
-
-(function (Cesium) {
-    /**
-     * A position property that simulates a spirograph
-     * @constructor
-     *
-     * @param {Cesium.Cartographic} center The center of the spirograph
-     * @param {Number} radiusMedian The radius of the median circle
-     * @param {Number} radiusSubCircle the maximum distance to the median circle
-     * @param {Number} durationMedianCircle The duration in milliseconds to orbit the median circle
-     * @param {Number} durationSubCircle The duration in milliseconds to orbit the sub circle
-     * @param {Cesium.Ellipsoid} [ellipsoid=Cesium.Ellipsoid.WGS84] The ellipsoid to convert cartographic to cartesian
-     */
-    var SpirographPositionProperty = function (center, radiusMedian, radiusSubCircle, durationMedianCircle, durationSubCircle, ellipsoid) {
-        this._center = center;
-        this._radiusMedian = radiusMedian;
-        this._radiusSubCircle = radiusSubCircle;
-
-        this._durationMedianCircle = durationMedianCircle;
-        this._durationSubCircle = durationSubCircle;
-
-        if (!Cesium.defined(ellipsoid)) {
-            ellipsoid = Cesium.Ellipsoid.WGS84;
-        }
-        this._ellipsoid = ellipsoid;
-
-        this._definitionChanged = new Cesium.Event();
-    };
-
-    Cesium.defineProperties(SpirographPositionProperty.prototype, {
-        /**
-         * Gets a value indicating if this property is constant.  A property is considered
-         * constant if getValue always returns the same result for the current definition.
-         * @memberof PositionProperty.prototype
-         *
-         * @type {Boolean}
-         * @readonly
-         */
-        isConstant: {
-            get: function () {
-                return this._radiusMedian == 0 && this._radiusSubCircle == 0;
-            }
-        },
-        /**
-         * Gets the event that is raised whenever the definition of this property changes.
-         * The definition is considered to have changed if a call to getValue would return
-         * a different result for the same time.
-         * @memberof PositionProperty.prototype
-         *
-         * @type {Event}
-         * @readonly
-         */
-        definitionChanged: {
-            get: function () {
-                return this._definitionChanged;
-            }
-        },
-        /**
-         * Gets the reference frame that the position is defined in.
-         * @memberof PositionProperty.prototype
-         * @type {ReferenceFrame}
-         */
-        referenceFrame: {
-            get: function () {
-                return Cesium.ReferenceFrame.FIXED;
-            }
-        }
-    });
-
-    /**
-     * Gets the value of the property at the provided time in the fixed frame.
-     * @function
-     *
-     * @param {JulianDate} time The time for which to retrieve the value.
-     * @param {Cartesian3} [result] The object to store the value into, if omitted, a new instance is created and returned.
-     * @returns {Cartesian3} The modified result parameter or a new instance if the result parameter was not supplied.
-     */
-    SpirographPositionProperty.prototype.getValue = function (time, result) {
-        return this.getValueInReferenceFrame(time, Cesium.ReferenceFrame.FIXED, result);
-    };
-
-    var cartographicScratch = new Cesium.Cartographic();
-
-    /**
-     * Gets the value of the property at the provided time and in the provided reference frame.
-     * @function
-     *
-     * @param {JulianDate} time The time for which to retrieve the value.
-     * @param {ReferenceFrame} referenceFrame The desired referenceFrame of the result.
-     * @param {Cartesian3} [result] The object to store the value into, if omitted, a new instance is created and returned.
-     * @returns {Cartesian3} The modified result parameter or a new instance if the result parameter was not supplied.
-     */
-    SpirographPositionProperty.prototype.getValueInReferenceFrame = function (time, referenceFrame, result) {
-        var milliseconds = Cesium.JulianDate.toDate(time).getTime();
-
-        var radius = this._radiusMedian + this._radiusSubCircle * Math.sin(2 * Math.PI * (milliseconds / this._durationSubCircle));
-
-        cartographicScratch.latitude = this._center.latitude + radius * Math.cos(2 * Math.PI * (milliseconds / this._durationMedianCircle));
-        cartographicScratch.longitude = this._center.longitude + radius * Math.sin(2 * Math.PI * (milliseconds / this._durationMedianCircle));
-        cartographicScratch.height = this._center.height;
-
-        result = this._ellipsoid.cartographicToCartesian(cartographicScratch, result);
-
-        if (referenceFrame == Cesium.ReferenceFrame.FIXED) {
-            return result;
-        }
-
-        return Cesium.PositionProperty.convertToReferenceFrame(time, result, Cesium.ReferenceFrame.FIXED, referenceFrame, result);
-    };
-
-    /**
-     * Compares this property to the provided property and returns
-     * <code>true</code> if they are equal, <code>false</code> otherwise.
-     * @function
-     *
-     * @param {Property} [other] The other property.
-     * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise.
-     */
-    SpirographPositionProperty.prototype.equals = function (other) {
-        return other instanceof SpirographPositionProperty
-            && this._center.equals(other._center)
-            && this._radiusMedian == other._radiusMedian
-            && this._radiusSubCircle == other._radiusSubCircle
-            && this._durationMedianCircle == other._durationMedianCircle
-            && this._durationSubCircle == other._durationSubCircle
-            && this._ellipsoid.equals(other._ellipsoid);
-    };
-
-    Cesium.SpirographPositionProperty = SpirographPositionProperty;
-
-})(Cesium);
+// /**
+//  * Created by G.Cordes on 01.06.16.
+//  */
+
+// (function (Cesium) {
+//     /**
+//      * A position property that simulates a spirograph
+//      * @constructor
+//      *
+//      * @param {Cesium.Cartographic} center The center of the spirograph
+//      * @param {Number} radiusMedian The radius of the median circle
+//      * @param {Number} radiusSubCircle the maximum distance to the median circle
+//      * @param {Number} durationMedianCircle The duration in milliseconds to orbit the median circle
+//      * @param {Number} durationSubCircle The duration in milliseconds to orbit the sub circle
+//      * @param {Cesium.Ellipsoid} [ellipsoid=Cesium.Ellipsoid.WGS84] The ellipsoid to convert cartographic to cartesian
+//      */
+//     var SpirographPositionProperty = function (center, radiusMedian, radiusSubCircle, durationMedianCircle, durationSubCircle, ellipsoid) {
+//         this._center = center;
+//         this._radiusMedian = radiusMedian;
+//         this._radiusSubCircle = radiusSubCircle;
+
+//         this._durationMedianCircle = durationMedianCircle;
+//         this._durationSubCircle = durationSubCircle;
+
+//         if (!Cesium.defined(ellipsoid)) {
+//             ellipsoid = Cesium.Ellipsoid.WGS84;
+//         }
+//         this._ellipsoid = ellipsoid;
+
+//         this._definitionChanged = new Cesium.Event();
+//     };
+
+//     Cesium.defineProperties(SpirographPositionProperty.prototype, {
+//         /**
+//          * Gets a value indicating if this property is constant.  A property is considered
+//          * constant if getValue always returns the same result for the current definition.
+//          * @memberof PositionProperty.prototype
+//          *
+//          * @type {Boolean}
+//          * @readonly
+//          */
+//         isConstant: {
+//             get: function () {
+//                 return this._radiusMedian == 0 && this._radiusSubCircle == 0;
+//             }
+//         },
+//         /**
+//          * Gets the event that is raised whenever the definition of this property changes.
+//          * The definition is considered to have changed if a call to getValue would return
+//          * a different result for the same time.
+//          * @memberof PositionProperty.prototype
+//          *
+//          * @type {Event}
+//          * @readonly
+//          */
+//         definitionChanged: {
+//             get: function () {
+//                 return this._definitionChanged;
+//             }
+//         },
+//         /**
+//          * Gets the reference frame that the position is defined in.
+//          * @memberof PositionProperty.prototype
+//          * @type {ReferenceFrame}
+//          */
+//         referenceFrame: {
+//             get: function () {
+//                 return Cesium.ReferenceFrame.FIXED;
+//             }
+//         }
+//     });
+
+//     /**
+//      * Gets the value of the property at the provided time in the fixed frame.
+//      * @function
+//      *
+//      * @param {JulianDate} time The time for which to retrieve the value.
+//      * @param {Cartesian3} [result] The object to store the value into, if omitted, a new instance is created and returned.
+//      * @returns {Cartesian3} The modified result parameter or a new instance if the result parameter was not supplied.
+//      */
+//     SpirographPositionProperty.prototype.getValue = function (time, result) {
+//         return this.getValueInReferenceFrame(time, Cesium.ReferenceFrame.FIXED, result);
+//     };
+
+//     var cartographicScratch = new Cesium.Cartographic();
+
+//     /**
+//      * Gets the value of the property at the provided time and in the provided reference frame.
+//      * @function
+//      *
+//      * @param {JulianDate} time The time for which to retrieve the value.
+//      * @param {ReferenceFrame} referenceFrame The desired referenceFrame of the result.
+//      * @param {Cartesian3} [result] The object to store the value into, if omitted, a new instance is created and returned.
+//      * @returns {Cartesian3} The modified result parameter or a new instance if the result parameter was not supplied.
+//      */
+//     SpirographPositionProperty.prototype.getValueInReferenceFrame = function (time, referenceFrame, result) {
+//         var milliseconds = Cesium.JulianDate.toDate(time).getTime();
+
+//         var radius = this._radiusMedian + this._radiusSubCircle * Math.sin(2 * Math.PI * (milliseconds / this._durationSubCircle));
+
+//         cartographicScratch.latitude = this._center.latitude + radius * Math.cos(2 * Math.PI * (milliseconds / this._durationMedianCircle));
+//         cartographicScratch.longitude = this._center.longitude + radius * Math.sin(2 * Math.PI * (milliseconds / this._durationMedianCircle));
+//         cartographicScratch.height = this._center.height;
+
+//         result = this._ellipsoid.cartographicToCartesian(cartographicScratch, result);
+
+//         if (referenceFrame == Cesium.ReferenceFrame.FIXED) {
+//             return result;
+//         }
+
+//         return Cesium.PositionProperty.convertToReferenceFrame(time, result, Cesium.ReferenceFrame.FIXED, referenceFrame, result);
+//     };
+
+//     /**
+//      * Compares this property to the provided property and returns
+//      * <code>true</code> if they are equal, <code>false</code> otherwise.
+//      * @function
+//      *
+//      * @param {Property} [other] The other property.
+//      * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise.
+//      */
+//     SpirographPositionProperty.prototype.equals = function (other) {
+//         return other instanceof SpirographPositionProperty
+//             && this._center.equals(other._center)
+//             && this._radiusMedian == other._radiusMedian
+//             && this._radiusSubCircle == other._radiusSubCircle
+//             && this._durationMedianCircle == other._durationMedianCircle
+//             && this._durationSubCircle == other._durationSubCircle
+//             && this._ellipsoid.equals(other._ellipsoid);
+//     };
+
+//     Cesium.SpirographPositionProperty = SpirographPositionProperty;
+
+// })(Cesium);

+ 161 - 0
src/core/plugins/cesium-navigation-es6/CesiumNavigation.js

@@ -0,0 +1,161 @@
+/* eslint-disable no-unused-vars */
+import {
+  defined,
+  Event,
+  DeveloperError
+} from 'cesium/Cesium'
+import registerKnockoutBindings from './core/registerKnockoutBindings'
+import DistanceLegendViewModel from './viewModels/DistanceLegendViewModel'
+import NavigationViewModel from './viewModels/NavigationViewModel'
+
+/**
+ * @alias CesiumNavigation
+ * @constructor
+ *
+ * @param {Viewer|CesiumWidget} viewerCesiumWidget The Viewer or CesiumWidget instance
+ */
+var CesiumNavigation = function (viewerCesiumWidget) {
+  initialize.apply(this, arguments)
+
+  this._onDestroyListeners = []
+}
+
+CesiumNavigation.prototype.distanceLegendViewModel = undefined
+CesiumNavigation.prototype.navigationViewModel = undefined
+CesiumNavigation.prototype.navigationDiv = undefined
+CesiumNavigation.prototype.distanceLegendDiv = undefined
+CesiumNavigation.prototype.terria = undefined
+CesiumNavigation.prototype.container = undefined
+CesiumNavigation.prototype._onDestroyListeners = undefined
+CesiumNavigation.prototype._navigationLocked = false
+
+CesiumNavigation.prototype.setNavigationLocked = function (locked) {
+  this._navigationLocked = locked
+  this.navigationViewModel.setNavigationLocked(this._navigationLocked)
+}
+
+CesiumNavigation.prototype.getNavigationLocked = function () {
+  return this._navigationLocked
+}
+
+CesiumNavigation.prototype.destroy = function () {
+  if (defined(this.navigationViewModel)) {
+    this.navigationViewModel.destroy()
+  }
+  if (defined(this.distanceLegendViewModel)) {
+    this.distanceLegendViewModel.destroy()
+  }
+
+  if (defined(this.navigationDiv)) {
+    this.navigationDiv.parentNode.removeChild(this.navigationDiv)
+  }
+  delete this.navigationDiv
+
+  if (defined(this.distanceLegendDiv)) {
+    this.distanceLegendDiv.parentNode.removeChild(this.distanceLegendDiv)
+  }
+  delete this.distanceLegendDiv
+
+  if (defined(this.container)) {
+    this.container.parentNode.removeChild(this.container)
+  }
+  delete this.container
+
+  for (var i = 0; i < this._onDestroyListeners.length; i++) {
+    this._onDestroyListeners[i]()
+  }
+}
+
+CesiumNavigation.prototype.addOnDestroyListener = function (callback) {
+  if (typeof callback === 'function') {
+    this._onDestroyListeners.push(callback)
+  }
+}
+
+/**
+ * @param {Viewer|CesiumWidget} viewerCesiumWidget The Viewer or CesiumWidget instance
+ * @param options
+ */
+function initialize (viewerCesiumWidget, options) {
+  if (!defined(viewerCesiumWidget)) {
+    throw new DeveloperError('CesiumWidget or Viewer is required.')
+  }
+
+  //        options = defaultValue(options, defaultValue.EMPTY_OBJECT);
+
+  var cesiumWidget = defined(viewerCesiumWidget.cesiumWidget) ? viewerCesiumWidget.cesiumWidget : viewerCesiumWidget
+
+  var container = document.createElement('div')
+  container.className = 'cesium-widget-cesiumNavigationContainer'
+  cesiumWidget.container.appendChild(container)
+
+  this.terria = viewerCesiumWidget
+  this.terria.options = (defined(options)) ? options : {}
+  this.terria.afterWidgetChanged = new Event()
+  this.terria.beforeWidgetChanged = new Event()
+  this.container = container
+
+  // this.navigationDiv.setAttribute("id", "navigationDiv");
+
+  // Register custom Knockout.js bindings.  If you're not using the TerriaJS user interface, you can remove this.
+  registerKnockoutBindings()
+
+  if (!defined(this.terria.options.enableDistanceLegend) || this.terria.options.enableDistanceLegend) {
+    this.distanceLegendDiv = document.createElement('div')
+    container.appendChild(this.distanceLegendDiv)
+    this.distanceLegendDiv.setAttribute('id', 'distanceLegendDiv')
+    this.distanceLegendViewModel = DistanceLegendViewModel.create({
+      container: this.distanceLegendDiv,
+      terria: this.terria,
+      mapElement: container,
+      enableDistanceLegend: true
+    })
+  }
+
+  if ((!defined(this.terria.options.enableZoomControls) || this.terria.options.enableZoomControls) && (!defined(this.terria.options.enableCompass) || this.terria.options.enableCompass)) {
+    this.navigationDiv = document.createElement('div')
+    this.navigationDiv.setAttribute('id', 'navigationDiv')
+    container.appendChild(this.navigationDiv)
+    // Create the navigation controls.
+    this.navigationViewModel = NavigationViewModel.create({
+      container: this.navigationDiv,
+      terria: this.terria,
+      enableZoomControls: true,
+      enableCompass: true
+    })
+  } else if ((defined(this.terria.options.enableZoomControls) && !this.terria.options.enableZoomControls) && (!defined(this.terria.options.enableCompass) || this.terria.options.enableCompass)) {
+    this.navigationDiv = document.createElement('div')
+    this.navigationDiv.setAttribute('id', 'navigationDiv')
+    container.appendChild(this.navigationDiv)
+    // Create the navigation controls.
+    this.navigationViewModel = NavigationViewModel.create({
+      container: this.navigationDiv,
+      terria: this.terria,
+      enableZoomControls: false,
+      enableCompass: true
+    })
+  } else if ((!defined(this.terria.options.enableZoomControls) || this.terria.options.enableZoomControls) && (defined(this.terria.options.enableCompass) && !this.terria.options.enableCompass)) {
+    this.navigationDiv = document.createElement('div')
+    this.navigationDiv.setAttribute('id', 'navigationDiv')
+    container.appendChild(this.navigationDiv)
+    // Create the navigation controls.
+    this.navigationViewModel = NavigationViewModel.create({
+      container: this.navigationDiv,
+      terria: this.terria,
+      enableZoomControls: true,
+      enableCompass: false
+    })
+  } else if ((defined(this.terria.options.enableZoomControls) && !this.terria.options.enableZoomControls) && (defined(this.terria.options.enableCompass) && !this.terria.options.enableCompass)) {
+    // this.navigationDiv.setAttribute("id", "navigationDiv");
+    // container.appendChild(this.navigationDiv);
+    // Create the navigation controls.
+    //            this.navigationViewModel = NavigationViewModel.create({
+    //                container: this.navigationDiv,
+    //                terria: this.terria,
+    //                enableZoomControls: false,
+    //                enableCompass: false
+    //            });
+  }
+}
+
+export default CesiumNavigation

+ 21 - 0
src/core/plugins/cesium-navigation-es6/LICENSE

@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2019 richard1015
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

+ 69 - 0
src/core/plugins/cesium-navigation-es6/README.md

@@ -0,0 +1,69 @@
+# cesium-navigation-es6
+This is a Cesium plugin that adds to the Cesium map a user friendly compass, navigator (zoom in/out), and
+distance scale graphical user interface.
+
+
+## Demo
+[cesium plugin /demo](https://richard1015.github.io/cesium/)
+# Code Demo
+[https://github.com/richard1015/cesium-vue-example /(cesium-print,cesium-navigation-es6)](https://github.com/richard1015/cesium-vue-example/blob/master/src/components/CesiumViewer.vue)
+
+![预览](https://github.com/richard1015/richard1015.github.io/blob/master/static/image/cesium-navigation-es6.png "demo.png")
+
+**Why did you build it?**
+
+First of all the Cesiumjs sdk does not includes a compass, navigator (zoom in/out), and distance scale. You can use the mouse to navigate on the map, but this navigation plugin offers more navigation control and capabilities to the user. Some of the capabilities are: reset the compass to point to north, reset the orbit, and
+reset the view to a default bound.
+
+**为什么你建立cesium-navigation插件?**
+
+首先,所有的Cesiumjs sdk 不包括罗盘,导航仪(放大/缩小)和距离刻度。您可以使用鼠标在地图上导航,但这个导航插件可为用户提供更多的导航控制和功能。其中一些功能是:将罗盘重置为指向北部,重置轨道,并将视图重置为默认边界。
+
+**How to use it?**
+
+## QuickStart
+
+<!-- add docs here for user -->
+
+
+
+```bash
+$ npm install cesium-navigation-es6 --save
+```
+
+```HTML
+<template>
+  <div id="cesiumContainer"></div>
+</template>
+<script type="text/javascript">
+import Cesium from "cesium/Cesium";
+import "cesium/Widgets/widgets.css";
+import CesiumNavigation from "cesium-navigation-es6";
+
+var options = {};
+// 用于在使用重置导航重置地图视图时设置默认视图控制。接受的值是Cesium.Cartographic 和 Cesium.Rectangle.
+options.defaultResetView = Cesium.Rectangle.fromDegrees(80, 22, 130, 50);
+// 用于启用或禁用罗盘。true是启用罗盘,false是禁用罗盘。默认值为true。如果将选项设置为false,则罗盘将不会添加到地图中。
+options.enableCompass= true;
+// 用于启用或禁用缩放控件。true是启用,false是禁用。默认值为true。如果将选项设置为false,则缩放控件将不会添加到地图中。
+options.enableZoomControls= false;
+// 用于启用或禁用距离图例。true是启用,false是禁用。默认值为true。如果将选项设置为false,距离图例将不会添加到地图中。
+options.enableDistanceLegend= false;
+// 用于启用或禁用指南针外环。true是启用,false是禁用。默认值为true。如果将选项设置为false,则该环将可见但无效。
+options.enableCompassOuterRing= true;
+
+let viewer = new Cesium.Viewer("cesiumContainer");
+CesiumNavigation(viewer, options);
+```
+
+
+
+## Other Cesium Plugin 
+[cesium-print /github](https://github.com/richard1015/cesium-print)
+
+### 参考文章
+[https://www.jianshu.com/p/dd364b59b774](https://www.jianshu.com/p/dd364b59b774)  
+
+[https://www.jianshu.com/p/fb237c7eb48c](https://www.jianshu.com/p/fb237c7eb48c)  
+
+[https://blog.csdn.net/Prepared/article/details/68940997?locationNum=10&fps=1](https://blog.csdn.net/Prepared/article/details/68940997?locationNum=10&fps=1)

+ 32 - 0
src/core/plugins/cesium-navigation-es6/core/KnockoutHammerBinding.js

@@ -0,0 +1,32 @@
+/* eslint-disable no-unused-vars */
+import Hammer from 'hammerjs'
+import {
+  knockout as Knockout
+} from 'cesium/Cesium'
+
+var KnockoutHammerBinding = {
+  register: function (Knockout) {
+    Knockout.bindingHandlers.swipeLeft = {
+      init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
+        var f = Knockout.unwrap(valueAccessor())
+        new Hammer(element).on('swipeleft', function (e) {
+          var viewModel = bindingContext.$data
+          f.apply(viewModel, arguments)
+        })
+      }
+    }
+
+    Knockout.bindingHandlers.swipeRight = {
+      init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
+        var f = Knockout.unwrap(valueAccessor())
+        new Hammer(element).on('swiperight', function (e) {
+          var viewModel = bindingContext.$data
+          f.apply(viewModel, arguments)
+        })
+      }
+    }
+  }
+
+}
+
+export default KnockoutHammerBinding

+ 66 - 0
src/core/plugins/cesium-navigation-es6/core/KnockoutMarkdownBinding.js

@@ -0,0 +1,66 @@
+// /* eslint-disable no-unused-vars */
+// import MarkdownItSanitizer from 'markdown-it-sanitizer'
+// import MarkdownIt from 'markdown-it'
+
+// var htmlTagRegex = /<html(.|\s)*>(.|\s)*<\/html>/im
+
+// var md = new MarkdownIt({
+//   html: true,
+//   linkify: true
+// })
+
+// md.use(MarkdownItSanitizer, {
+//   imageClass: '',
+//   removeUnbalanced: false,
+//   removeUnknown: false
+// })
+// var KnockoutMarkdownBinding = {
+//   register: function (Knockout) {
+//     Knockout.bindingHandlers.markdown = {
+//       'init': function () {
+//         // Prevent binding on the dynamically-injected HTML (as developers are unlikely to expect that, and it has security implications)
+//         return { 'controlsDescendantBindings': true }
+//       },
+//       'update': function (element, valueAccessor) {
+//         // Remove existing children of this element.
+//         while (element.firstChild) {
+//           Knockout.removeNode(element.firstChild)
+//         }
+
+//         var rawText = Knockout.unwrap(valueAccessor())
+
+//         // If the text contains an <html> tag, don't try to interpret it as Markdown because
+//         // we'll probably break it in the process.
+//         var html
+//         if (htmlTagRegex.test(rawText)) {
+//           html = rawText
+//         } else {
+//           html = md.render(rawText)
+//         }
+
+//         var nodes = Knockout.utils.parseHtmlFragment(html, element)
+//         element.className = element.className + ' markdown'
+
+//         for (var i = 0; i < nodes.length; ++i) {
+//           var node = nodes[i]
+//           setAnchorTargets(node)
+//           element.appendChild(node)
+//         }
+//       }
+//     }
+//   }
+// }
+
+// function setAnchorTargets (element) {
+//   if (element instanceof HTMLAnchorElement) {
+//     element.target = '_blank'
+//   }
+
+//   if (element.childNodes && element.childNodes.length > 0) {
+//     for (var i = 0; i < element.childNodes.length; ++i) {
+//       setAnchorTargets(element.childNodes[i])
+//     }
+//   }
+// }
+
+// export default KnockoutMarkdownBinding

+ 64 - 0
src/core/plugins/cesium-navigation-es6/core/Utils.js

@@ -0,0 +1,64 @@
+/* eslint-disable no-unused-vars */
+import {
+  defined,
+  Ray,
+  Cartesian3,
+  Cartographic,
+  SceneMode
+} from 'cesium/Cesium'
+
+
+var Utils = {}
+
+var unprojectedScratch = new Cartographic()
+var rayScratch = new Ray()
+
+/**
+ * gets the focus point of the camera
+ * @param {Viewer|Widget} terria The terria
+ * @param {boolean} inWorldCoordinates true to get the focus in world coordinates, otherwise get it in projection-specific map coordinates, in meters.
+ * @param {Cartesian3} [result] The object in which the result will be stored.
+ * @return {Cartesian3} The modified result parameter, a new instance if none was provided or undefined if there is no focus point.
+ */
+Utils.getCameraFocus = function (terria, inWorldCoordinates, result) {
+  var scene = terria.scene
+  var camera = scene.camera
+
+  if (scene.mode === SceneMode.MORPHING) {
+    return undefined
+  }
+
+  if (!defined(result)) {
+    result = new Cartesian3()
+  }
+
+  // TODO bug when tracking: if entity moves the current position should be used and not only the one when starting orbiting/rotating
+  // TODO bug when tracking: reset should reset to default view of tracked entity
+
+  if (defined(terria.trackedEntity)) {
+    result = terria.trackedEntity.position.getValue(terria.clock.currentTime, result)
+  } else {
+    rayScratch.origin = camera.positionWC
+    rayScratch.direction = camera.directionWC
+    result = scene.globe.pick(rayScratch, scene, result)
+  }
+
+  if (!defined(result)) {
+    return undefined
+  }
+
+  if (scene.mode === SceneMode.SCENE2D || scene.mode === SceneMode.COLUMBUS_VIEW) {
+    result = camera.worldToCameraCoordinatesPoint(result, result)
+
+    if (inWorldCoordinates) {
+      result = scene.globe.ellipsoid.cartographicToCartesian(scene.mapProjection.unproject(result, unprojectedScratch), result)
+    }
+  } else {
+    if (!inWorldCoordinates) {
+      result = camera.worldToCameraCoordinatesPoint(result, result)
+    }
+  }
+
+  return result
+}
+export default Utils

+ 13 - 0
src/core/plugins/cesium-navigation-es6/core/createFragmentFromTemplate.js

@@ -0,0 +1,13 @@
+
+const createFragmentFromTemplate = function (htmlString) {
+  var holder = document.createElement('div')
+  holder.innerHTML = htmlString
+  var fragment = document.createDocumentFragment()
+  while (holder.firstChild) {
+    fragment.appendChild(holder.firstChild)
+  }
+
+  return fragment
+}
+
+export default createFragmentFromTemplate

+ 35 - 0
src/core/plugins/cesium-navigation-es6/core/loadView.js

@@ -0,0 +1,35 @@
+/* eslint-disable no-unused-vars */
+import {
+  getElement,
+  knockout as Knockout
+} from 'cesium/Cesium'
+import createFragmentFromTemplate from './createFragmentFromTemplate'
+
+var loadView = function (htmlString, container, viewModel) {
+  container = getElement(container)
+
+  var fragment = createFragmentFromTemplate(htmlString)
+
+  // Sadly, fragment.childNodes doesn't have a slice function.
+  // This code could be replaced with Array.prototype.slice.call(fragment.childNodes)
+  // but that seems slightly error prone.
+  var nodes = []
+
+  var i
+  for (i = 0; i < fragment.childNodes.length; ++i) {
+    nodes.push(fragment.childNodes[i])
+  }
+
+  container.appendChild(fragment)
+
+  for (i = 0; i < nodes.length; ++i) {
+    var node = nodes[i]
+    if (node.nodeType === 1 || node.nodeType === 8) {
+      Knockout.applyBindings(viewModel, node)
+    }
+  }
+
+  return nodes
+}
+
+export default loadView

+ 26 - 0
src/core/plugins/cesium-navigation-es6/core/registerKnockoutBindings.js

@@ -0,0 +1,26 @@
+/* eslint-disable no-unused-vars */
+import {
+  knockout,
+  SvgPathBindingHandler
+} from 'cesium/Cesium'
+//import KnockoutMarkdownBinding from './KnockoutMarkdownBinding'
+import KnockoutHammerBinding from './KnockoutHammerBinding'
+
+
+var registerKnockoutBindings = function () {
+  SvgPathBindingHandler.register(knockout)
+  //KnockoutMarkdownBinding.register(Knockout)
+  KnockoutHammerBinding.register(knockout)
+
+  knockout.bindingHandlers.embeddedComponent = {
+    init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
+      var component = knockout.unwrap(valueAccessor())
+      component.show(element)
+      return { controlsDescendantBindings: true }
+    },
+    update: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
+    }
+  }
+}
+
+export default registerKnockoutBindings

+ 85 - 0
src/core/plugins/cesium-navigation-es6/index.js

@@ -0,0 +1,85 @@
+import {
+  defined,
+  defineProperties,
+  DeveloperError
+} from 'cesium/Cesium'
+import CesiumNavigation from './CesiumNavigation'
+import './styles/cesium-navigation.css'
+
+/**
+ * A mixin which adds the Compass/Navigation widget to the Viewer widget.
+ * Rather than being called directly, this function is normally passed as
+ * a parameter to {@link Viewer#extend}, as shown in the example below.
+ * @exports viewerCesiumNavigationMixin
+ *
+ * @param {Viewer} viewer The viewer instance.
+ * @param {{}} options The options.
+ *
+ * @exception {DeveloperError} viewer is required.
+ *
+ * @demo {@link http://localhost:8080/index.html|run local server with examples}
+ *
+ * @example
+ * var viewer = new Cesium.Viewer('cesiumContainer');
+ * viewer.extend(viewerCesiumNavigationMixin);
+ */
+function viewerCesiumNavigationMixin (viewer, options) {
+  if (!defined(viewer)) {
+    throw new DeveloperError('viewer is required.')
+  }
+
+  var cesiumNavigation = init(viewer, options)
+
+  cesiumNavigation.addOnDestroyListener((function (viewer) {
+    return function () {
+      delete viewer.cesiumNavigation
+    }
+  })(viewer))
+
+  defineProperties(viewer, {
+    cesiumNavigation: {
+      configurable: true,
+      get: function () {
+        return viewer.cesiumWidget.cesiumNavigation
+      }
+    }
+  })
+}
+
+/**
+ *
+ * @param {CesiumWidget} cesiumWidget The cesium widget instance.
+ * @param {{}} options The options.
+ */
+viewerCesiumNavigationMixin.mixinWidget = function (cesiumWidget, options) {
+  return init.apply(undefined, arguments)
+}
+
+/**
+ * @param {Viewer|CesiumWidget} viewerCesiumWidget The Viewer or CesiumWidget instance
+ * @param {{}} options the options
+ */
+var init = function (viewerCesiumWidget, options) {
+  var cesiumNavigation = new CesiumNavigation(viewerCesiumWidget, options)
+
+  var cesiumWidget = defined(viewerCesiumWidget.cesiumWidget) ? viewerCesiumWidget.cesiumWidget : viewerCesiumWidget
+
+  defineProperties(cesiumWidget, {
+    cesiumNavigation: {
+      configurable: true,
+      get: function () {
+        return cesiumNavigation
+      }
+    }
+  })
+
+  cesiumNavigation.addOnDestroyListener((function (cesiumWidget) {
+    return function () {
+      delete cesiumWidget.cesiumNavigation
+    }
+  })(cesiumWidget))
+
+  return cesiumNavigation
+}
+
+export default viewerCesiumNavigationMixin

+ 30 - 0
src/core/plugins/cesium-navigation-es6/package.json

@@ -0,0 +1,30 @@
+{
+  "name": "cesium-navigation-es6",
+  "version": "1.0.9",
+  "description": "cesium-navigation-es6",
+  "main": "viewerCesiumNavigationMixin.js",
+  "scripts": {
+    "test": "echo \"Error: no test specified\" && exit 1"
+  },
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/richard1015/cesium-navigation-es6.git"
+  },
+  "dependencies": {
+    "cesium": "^1.52.0",
+    "hammerjs": "^2.0.8",
+    "less": "^3.9.0",
+    "less-loader": "^4.1.0",
+    "markdown-it": "^8.4.2",
+    "markdown-it-sanitizer": "^0.4.3"
+  },
+  "keywords": [
+    "cesium-navigation"
+  ],
+  "author": "richard",
+  "license": "ISC",
+  "bugs": {
+    "url": "https://github.com/richard1015/cesium-navigation-es6/issues"
+  },
+  "homepage": "https://github.com/richard1015/cesium-navigation-es6#readme"
+}

+ 286 - 0
src/core/plugins/cesium-navigation-es6/styles/Core.less

@@ -0,0 +1,286 @@
+/*html {
+    height: 100%;
+    -webkit-font-smoothing: antialiased;
+}
+
+body {
+    height: 100%;
+    width: 100%;
+    margin: 0;
+    overflow: hidden;
+    padding: 0;
+    background: #000;
+    font-size: 15px;
+    font-family: @default-font;
+}*/
+
+.full-window {
+    position: absolute;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    margin: 0;
+    overflow: hidden;
+    padding: 0;
+
+    -webkit-transition: left @explorer-panel-close-animation-length ease-out;
+    -moz-transition: left @explorer-panel-close-animation-length ease-out;
+    -ms-transition: left @explorer-panel-close-animation-length ease-out;
+    -o-transition: left @explorer-panel-close-animation-length ease-out;
+    transition: left @explorer-panel-close-animation-length ease-out;
+}
+
+.transparent-to-input {
+    pointer-events: none;
+}
+
+.opaque-to-input {
+    pointer-events: auto;
+}
+
+.clickable {
+    cursor: pointer;
+}
+
+/*a {
+    text-decoration: none;
+    color: @highlight-color;
+}*/
+
+a:hover {
+    text-decoration: underline;
+}
+/*
+@modal-background-color: @panel-background-color;
+@modal-text-color: @panel-emphasized-text-color;
+@modal-header-background-color: rgba(0,0,0,0.2);
+@modal-header-text-color: @panel-emphasized-text-color;*/
+
+/*.modal-background {
+    .opaque-to-input;
+    position: fixed;
+    left: 0;
+    right: 0;
+    top: 0;
+    bottom: 0;
+    background-color: rgba(0,0,0,0.5);
+    z-index: 1000;  required for IE9 
+}*/
+/*
+.modal {
+    position: absolute;
+    margin: auto;
+    background-color: @modal-background-color;
+    top: 0;
+    left: 0;
+    bottom: 0;
+    right: 0;
+    max-height: 100%;
+    max-width: 100%;
+    font-family: @default-font;
+    color: @modal-text-color;
+}
+
+.modal-header {
+  background-color: @modal-header-background-color;
+  border-bottom: @panel-element-border;
+  font-size: 15px;
+  line-height: 40px;
+  margin: 0;
+}
+
+.modal-header h1 {
+  font-size: 15px;
+  color: @modal-header-text-color;
+  margin-left: 15px;
+}*/
+
+/* Commented out due to conflicts with client apps. 
+.modal-content {
+  margin-left: 15px;
+  margin-right: 15px;
+  margin-bottom: 15px;
+  padding-top: 15px;
+  overflow: auto;
+}*/
+
+/*.modal-close-button {
+    position: absolute;
+    right: 15px;
+    cursor: pointer;
+    font-size: 18px;
+    color: @modal-header-text-color;
+}*/
+
+
+#ui {
+    // This keeps the UI above the map in IE9.
+    z-index: 2100;
+}
+
+@media print {
+    .full-window {
+        position: initial;
+    }
+}
+
+// input fields
+
+/* input[type=text] {
+  height: 38px;
+  background-color: #eeeeee;
+  color: @input-text-color;
+  font-size: 14px;
+}
+
+::-webkit-input-placeholder {
+  color: fade(@input-text-color, 75%);
+  font-style: italic;
+}
+
+:-moz-placeholder { /* Firefox 18- 
+  color: fade(@input-text-color, 75%);
+  font-style: italic;
+}
+
+::-moz-placeholder {  /* Firefox 19+  
+  color: fade(@input-text-color, 75%);
+  font-style: italic;
+}
+
+:-ms-input-placeholder {
+  color: fade(@input-text-color, 75%);
+  font-style: italic;
+}
+
+input:focus {
+    outline-color: #FFFFFF;
+}
+*/
+
+/*select {
+  display: block;
+  background-color: @panel-form-input-background-color;
+  color: @panel-form-input-text-color;
+  height: 40px;
+  border: 0;
+  margin-top: 10px;
+  font-size: 14px;
+  padding-left: 5px;
+}*/
+
+.markdown {
+  img { max-width: 100% }
+  svg { max-height: 100% }
+
+  input,
+  select,
+  textarea,
+  fieldset {
+    font-family: inherit;
+    font-size: 1rem;
+    box-sizing: border-box;
+    margin-top: 0;
+    margin-bottom: 0;
+  }
+
+  label {
+    vertical-align: middle;
+  }
+
+  h1, h2, h3, h4, h5, h6 {
+    font-family: inherit;
+    font-weight: bold;
+    line-height: 1.25;
+    margin-top: 1em;
+    margin-bottom: .5em;
+  }
+
+  h1 { font-size: 2rem }
+  h2 { font-size: 1.5rem }
+  h3 { font-size: 1.25rem }
+  h4 { font-size: 1rem }
+  h5 { font-size: .875rem }
+  h6 { font-size: .75rem }
+
+  p {
+    margin-top: 0;
+    margin-bottom: 1rem;
+  }
+
+  strong { font-weight: bold }
+  em { font-style: italic }
+  small {font-size: 80%;}
+  mark { color: #000; background: #ff0;}
+  u {text-decoration: underline;}
+  s {text-decoration: line-through;}
+
+  dl, ol, ul {
+    margin-top: 0;
+    margin-bottom: 1rem;
+  }
+
+  ol{
+    list-style: decimal inside;
+  }
+
+  ul{
+    list-style: disc inside;
+  }
+
+  pre, code, samp {
+    font-family: monospace;
+    font-size: inherit;
+  }
+
+  pre {
+    margin-top: 0;
+    margin-bottom: 1rem;
+    overflow-x: scroll;
+  }
+
+  a {
+    color: #68ADFE;
+    text-decoration: none;
+  }
+
+  a:hover {
+    text-decoration: underline;
+  }
+
+  pre, code {
+    background-color: transparent;
+    border-radius: 3px;
+  }
+
+  hr {
+    border: 0;
+    border-bottom-style: solid;
+    border-bottom-width: 1px;
+    border-bottom-color: rgba(0,0,0,.125);
+  }
+
+  .left-align   { text-align: left }
+  .center       { text-align: center }
+  .right-align  { text-align: right }
+  .justify      { text-align: justify }
+
+  .truncate {
+    max-width: 100%;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+  }
+
+  ol.upper-roman {list-style-type: upper-roman;}
+  ol.lower-alpha {list-style-type: lower-alpha;}
+
+  ul.circle {list-style-type: circle;}
+  ul.square {list-style-type: square;}
+
+  .list-reset {
+    list-style: none;
+    padding-left: 0;
+  }
+}

+ 42 - 0
src/core/plugins/cesium-navigation-es6/styles/DistanceLegend.less

@@ -0,0 +1,42 @@
+.distance-legend {
+    .floating-horizontal;
+    //right: 25px;
+    bottom: 30px;
+    height: 30px;
+    width: 125px;
+    //border: 1px solid rgba(255,255,255,0.1);
+    box-sizing: content-box;
+}
+
+.distance-legend-label {
+    display: inline-block;
+    font-family: @default-font;
+    font-size: 14px;
+    font-weight: lighter;
+    line-height: 30px;
+    color: @floating-text-color;
+    width: 125px;
+    text-align: center;
+}
+
+.distance-legend-scale-bar {
+    border-left: 1px solid @floating-text-color;
+    border-right: 1px solid @floating-text-color;
+    border-bottom: 1px solid @floating-text-color;
+    position: absolute;
+    height: 10px;
+    top: 15px;
+}
+
+@media print {
+    .distance-legend {
+        display: none;
+    }
+}
+
+// Don't display the distance legend on small screens like mobile phones.
+@media screen and (max-width: 700px), screen and (max-height: 420px) {
+    .distance-legend {
+        display: none;
+    }
+}

+ 25 - 0
src/core/plugins/cesium-navigation-es6/styles/Floating.less

@@ -0,0 +1,25 @@
+.floating {
+    .opaque-to-input;
+    position: absolute;
+    border-radius: 15px;
+    //background-color: @floating-background-color;
+
+}
+
+.floating-horizontal {
+    .floating;
+    padding-left: 5px;
+    padding-right: 5px;
+}
+
+.floating-vertical {
+    .floating;
+    padding-top: 5px;
+    padding-bottom: 5px;
+}
+
+@media print {
+    .floating {
+        display: none;
+    }
+}

+ 146 - 0
src/core/plugins/cesium-navigation-es6/styles/Navigation.less

@@ -0,0 +1,146 @@
+.navigation-controls {
+    //.floating-vertical;
+    position: absolute; 
+    right: 30px;
+    top: 210px;
+    width: 30px;
+    border: 1px solid rgba(255,255,255,0.1);
+    font-weight: 300;
+    // avoids selection of text with rapid zooming
+    -webkit-touch-callout: none;
+    -webkit-user-select: none;
+    -khtml-user-select: none;
+    -moz-user-select: none;
+    -ms-user-select: none;
+    user-select: none;
+}
+
+.navigation-control {
+    .clickable;
+    border-bottom: @floating-element-border;
+}
+
+.naviagation-control:active {
+  color: #FFF;
+}
+
+.navigation-control-last {
+    .navigation-control;
+    border-bottom: 0;
+}
+
+.navigation-control-icon-zoom-in {
+    position: relative;
+    text-align: center;
+    font-size: 20px;
+    color: @floating-text-color;
+    padding-bottom: 4px;
+}
+
+.navigation-control-icon-zoom-out {
+    position: relative;
+    text-align: center;
+    font-size: 20px;
+    color: @floating-text-color;
+}
+
+.navigation-control-icon-reset {
+    position: relative;
+    left: 10px;
+    width: 10px;
+    height: 10px;
+    fill: fade(@floating-text-color, 80%);
+    padding-top: 6px;
+    padding-bottom: 6px;
+    box-sizing: content-box;
+}
+
+
+@compass-diameter: 95px;
+@compass-ring-width: @compass-diameter * 20 / 145;
+@compass-gyro-diameter: @compass-diameter * 50 / 145;
+
+.compass {
+    .opaque-to-input;
+    position: absolute;
+    right: 0px;
+    top: 100px;
+    width: @compass-diameter;
+    height: @compass-diameter;
+    overflow: hidden;
+}
+
+.compass-outer-ring {
+    position: absolute;
+    top: 0;
+    width: @compass-diameter;
+    height: @compass-diameter;
+    fill: rgba(255,255,255,0.5);
+}
+
+.compass-outer-ring-background {
+    position: absolute;
+    top: 14px;
+    left: 14px;
+    width: 44px;
+    height: 44px;
+    border-radius: 44px;
+    border: 12px solid @floating-background-color;
+    box-sizing: content-box;
+}
+
+.compass-gyro {
+    pointer-events: none;
+    position: absolute;
+    top: 0;
+    width: @compass-diameter;
+    height: @compass-diameter;
+    fill: #CCC;
+}
+
+.compass-gyro-active {
+    fill: @highlight-color;
+}
+
+.compass-gyro-background {
+    position: absolute;
+    top: 30px;
+    left: 30px;
+    width: 33px;
+    height: 33px;
+    border-radius: 33px;
+    background-color: @floating-background-color;
+    border: 1px solid rgba(255,255,255,0.2);
+    box-sizing: content-box;
+}
+
+.compass-gyro-background:hover + .compass-gyro {
+    fill: @highlight-color;
+}
+
+.compass-rotation-marker {
+    position: absolute;
+    top: 0;
+    width: @compass-diameter;
+    height: @compass-diameter;
+    fill: @highlight-color;
+}
+
+// Don't display the nav controls on small screens like mobile phones.
+@media screen and (max-width: 700px), screen and (max-height: 420px) {
+    .navigation-controls {
+        display: none;
+    }
+    .compass {
+        display: none;
+    }
+}
+
+@media print {
+    .navigation-controls {
+        display: none;
+    }
+    .compass {
+        display: none;
+    }
+}

+ 486 - 0
src/core/plugins/cesium-navigation-es6/styles/cesium-navigation.css

@@ -0,0 +1,486 @@
+/*html {
+    height: 100%;
+    -webkit-font-smoothing: antialiased;
+}
+
+body {
+    height: 100%;
+    width: 100%;
+    margin: 0;
+    overflow: hidden;
+    padding: 0;
+    background: #000;
+    font-size: 15px;
+    font-family: @default-font;
+}*/
+.full-window {
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  margin: 0;
+  overflow: hidden;
+  padding: 0;
+  -webkit-transition: left 0.25s ease-out;
+  -moz-transition: left 0.25s ease-out;
+  -ms-transition: left 0.25s ease-out;
+  -o-transition: left 0.25s ease-out;
+  transition: left 0.25s ease-out;
+}
+.transparent-to-input {
+  pointer-events: none;
+}
+.opaque-to-input {
+  pointer-events: auto;
+}
+.clickable {
+  cursor: pointer;
+}
+/*a {
+    text-decoration: none;
+    color: @highlight-color;
+}*/
+a:hover {
+  text-decoration: underline;
+}
+/*
+@modal-background-color: @panel-background-color;
+@modal-text-color: @panel-emphasized-text-color;
+@modal-header-background-color: rgba(0,0,0,0.2);
+@modal-header-text-color: @panel-emphasized-text-color;*/
+/*.modal-background {
+    .opaque-to-input;
+    position: fixed;
+    left: 0;
+    right: 0;
+    top: 0;
+    bottom: 0;
+    background-color: rgba(0,0,0,0.5);
+    z-index: 1000;  required for IE9 
+}*/
+/*
+.modal {
+    position: absolute;
+    margin: auto;
+    background-color: @modal-background-color;
+    top: 0;
+    left: 0;
+    bottom: 0;
+    right: 0;
+    max-height: 100%;
+    max-width: 100%;
+    font-family: @default-font;
+    color: @modal-text-color;
+}
+
+.modal-header {
+  background-color: @modal-header-background-color;
+  border-bottom: @panel-element-border;
+  font-size: 15px;
+  line-height: 40px;
+  margin: 0;
+}
+
+.modal-header h1 {
+  font-size: 15px;
+  color: @modal-header-text-color;
+  margin-left: 15px;
+}*/
+/* Commented out due to conflicts with client apps. 
+.modal-content {
+  margin-left: 15px;
+  margin-right: 15px;
+  margin-bottom: 15px;
+  padding-top: 15px;
+  overflow: auto;
+}*/
+/*.modal-close-button {
+    position: absolute;
+    right: 15px;
+    cursor: pointer;
+    font-size: 18px;
+    color: @modal-header-text-color;
+}*/
+#ui {
+  z-index: 2100;
+}
+@media print {
+  .full-window {
+    position: initial;
+  }
+}
+/* input[type=text] {
+  height: 38px;
+  background-color: #eeeeee;
+  color: @input-text-color;
+  font-size: 14px;
+}
+
+::-webkit-input-placeholder {
+  color: fade(@input-text-color, 75%);
+  font-style: italic;
+}
+
+:-moz-placeholder { /* Firefox 18- 
+  color: fade(@input-text-color, 75%);
+  font-style: italic;
+}
+
+::-moz-placeholder {  /* Firefox 19+  
+  color: fade(@input-text-color, 75%);
+  font-style: italic;
+}
+
+:-ms-input-placeholder {
+  color: fade(@input-text-color, 75%);
+  font-style: italic;
+}
+
+input:focus {
+    outline-color: #FFFFFF;
+}
+*/
+/*select {
+  display: block;
+  background-color: @panel-form-input-background-color;
+  color: @panel-form-input-text-color;
+  height: 40px;
+  border: 0;
+  margin-top: 10px;
+  font-size: 14px;
+  padding-left: 5px;
+}*/
+.markdown img {
+  max-width: 100%;
+}
+.markdown svg {
+  max-height: 100%;
+}
+.markdown input,
+.markdown select,
+.markdown textarea,
+.markdown fieldset {
+  font-family: inherit;
+  font-size: 1rem;
+  box-sizing: border-box;
+  margin-top: 0;
+  margin-bottom: 0;
+}
+.markdown label {
+  vertical-align: middle;
+}
+.markdown h1,
+.markdown h2,
+.markdown h3,
+.markdown h4,
+.markdown h5,
+.markdown h6 {
+  font-family: inherit;
+  font-weight: bold;
+  line-height: 1.25;
+  margin-top: 1em;
+  margin-bottom: .5em;
+}
+.markdown h1 {
+  font-size: 2rem;
+}
+.markdown h2 {
+  font-size: 1.5rem;
+}
+.markdown h3 {
+  font-size: 1.25rem;
+}
+.markdown h4 {
+  font-size: 1rem;
+}
+.markdown h5 {
+  font-size: 0.875rem;
+}
+.markdown h6 {
+  font-size: 0.75rem;
+}
+.markdown p {
+  margin-top: 0;
+  margin-bottom: 1rem;
+}
+.markdown strong {
+  font-weight: bold;
+}
+.markdown em {
+  font-style: italic;
+}
+.markdown small {
+  font-size: 80%;
+}
+.markdown mark {
+  color: #000;
+  background: #ff0;
+}
+.markdown u {
+  text-decoration: underline;
+}
+.markdown s {
+  text-decoration: line-through;
+}
+.markdown dl,
+.markdown ol,
+.markdown ul {
+  margin-top: 0;
+  margin-bottom: 1rem;
+}
+.markdown ol {
+  list-style: decimal inside;
+}
+.markdown ul {
+  list-style: disc inside;
+}
+.markdown pre,
+.markdown code,
+.markdown samp {
+  font-family: monospace;
+  font-size: inherit;
+}
+.markdown pre {
+  margin-top: 0;
+  margin-bottom: 1rem;
+  overflow-x: scroll;
+}
+.markdown a {
+  color: #68ADFE;
+  text-decoration: none;
+}
+.markdown a:hover {
+  text-decoration: underline;
+}
+.markdown pre,
+.markdown code {
+  background-color: transparent;
+  border-radius: 3px;
+}
+.markdown hr {
+  border: 0;
+  border-bottom-style: solid;
+  border-bottom-width: 1px;
+  border-bottom-color: rgba(0, 0, 0, 0.125);
+}
+.markdown .left-align {
+  text-align: left;
+}
+.markdown .center {
+  text-align: center;
+}
+.markdown .right-align {
+  text-align: right;
+}
+.markdown .justify {
+  text-align: justify;
+}
+.markdown .truncate {
+  max-width: 100%;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+.markdown ol.upper-roman {
+  list-style-type: upper-roman;
+}
+.markdown ol.lower-alpha {
+  list-style-type: lower-alpha;
+}
+.markdown ul.circle {
+  list-style-type: circle;
+}
+.markdown ul.square {
+  list-style-type: square;
+}
+.markdown .list-reset {
+  list-style: none;
+  padding-left: 0;
+}
+.floating {
+  pointer-events: auto;
+  position: absolute;
+  border-radius: 15px;
+}
+.floating-horizontal {
+  pointer-events: auto;
+  position: absolute;
+  border-radius: 15px;
+  padding-left: 5px;
+  padding-right: 5px;
+}
+.floating-vertical {
+  pointer-events: auto;
+  position: absolute;
+  border-radius: 15px;
+  padding-top: 5px;
+  padding-bottom: 5px;
+}
+@media print {
+  .floating {
+    display: none;
+  }
+}
+.distance-legend {
+  pointer-events: auto;
+  position: absolute;
+  border-radius: 15px;
+  padding-left: 5px;
+  padding-right: 5px;
+  bottom: 30px;
+  height: 30px;
+  width: 125px;
+  box-sizing: content-box;
+}
+.distance-legend-label {
+  display: inline-block;
+  font-family: 'Roboto', sans-serif;
+  font-size: 14px;
+  font-weight: lighter;
+  line-height: 30px;
+  color: #FFFFFF;
+  width: 125px;
+  text-align: center;
+}
+.distance-legend-scale-bar {
+  border-left: 1px solid #FFFFFF;
+  border-right: 1px solid #FFFFFF;
+  border-bottom: 1px solid #FFFFFF;
+  position: absolute;
+  height: 10px;
+  top: 15px;
+}
+@media print {
+  .distance-legend {
+    display: none;
+  }
+}
+@media screen and (max-width: 700px), screen and (max-height: 420px) {
+  .distance-legend {
+    display: none;
+  }
+}
+.navigation-controls {
+  position: absolute;
+  right: 30px;
+  top: 210px;
+  width: 30px;
+  border: 1px solid rgba(255, 255, 255, 0.1);
+  font-weight: 300;
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+  -khtml-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+.navigation-control {
+  cursor: pointer;
+  border-bottom: 1px solid #555555;
+}
+.naviagation-control:active {
+  color: #FFF;
+}
+.navigation-control-last {
+  cursor: pointer;
+  border-bottom: 1px solid #555555;
+  border-bottom: 0;
+}
+.navigation-control-icon-zoom-in {
+  position: relative;
+  text-align: center;
+  font-size: 20px;
+  color: #FFFFFF;
+  padding-bottom: 4px;
+}
+.navigation-control-icon-zoom-out {
+  position: relative;
+  text-align: center;
+  font-size: 20px;
+  color: #FFFFFF;
+}
+.navigation-control-icon-reset {
+  position: relative;
+  left: 10px;
+  width: 10px;
+  height: 10px;
+  fill: rgba(255, 255, 255, 0.8);
+  padding-top: 6px;
+  padding-bottom: 6px;
+  box-sizing: content-box;
+}
+.compass {
+  pointer-events: auto;
+  position: absolute;
+  right: 0px;
+  top: 100px;
+  width: 95px;
+  height: 95px;
+  overflow: hidden;
+}
+.compass-outer-ring {
+  position: absolute;
+  top: 0;
+  width: 95px;
+  height: 95px;
+  fill: rgba(255, 255, 255, 0.5);
+}
+.compass-outer-ring-background {
+  position: absolute;
+  top: 14px;
+  left: 14px;
+  width: 44px;
+  height: 44px;
+  border-radius: 44px;
+  border: 12px solid rgba(47, 53, 60, 0.8);
+  box-sizing: content-box;
+}
+.compass-gyro {
+  pointer-events: none;
+  position: absolute;
+  top: 0;
+  width: 95px;
+  height: 95px;
+  fill: #CCC;
+}
+.compass-gyro-active {
+  fill: #68ADFE;
+}
+.compass-gyro-background {
+  position: absolute;
+  top: 30px;
+  left: 30px;
+  width: 33px;
+  height: 33px;
+  border-radius: 33px;
+  background-color: rgba(47, 53, 60, 0.8);
+  border: 1px solid rgba(255, 255, 255, 0.2);
+  box-sizing: content-box;
+}
+.compass-gyro-background:hover + .compass-gyro {
+  fill: #68ADFE;
+}
+.compass-rotation-marker {
+  position: absolute;
+  top: 0;
+  width: 95px;
+  height: 95px;
+  fill: #68ADFE;
+}
+@media screen and (max-width: 700px), screen and (max-height: 420px) {
+  .navigation-controls {
+    display: none;
+  }
+  .compass {
+    display: none;
+  }
+}
+@media print {
+  .navigation-controls {
+    display: none;
+  }
+  .compass {
+    display: none;
+  }
+}

+ 44 - 0
src/core/plugins/cesium-navigation-es6/styles/cesium-navigation.less

@@ -0,0 +1,44 @@
+@import "Core";
+@import "Floating";
+
+@import "DistanceLegend";
+@import "Navigation";
+
+@default-font: 'Roboto', sans-serif;
+@highlight-color: #68ADFE;
+@left-side-panels-width: 350px;
+
+//Panels
+@panel-background-color: #2F353C;
+@panel-text-color: #CCCCCC;
+@panel-emphasized-text-color: #FFFFFF;
+@panel-selected-text-color: @highlight-color;
+@panel-box-shadow: 2px 2px 5px rgba(0,0,0,0.26);
+@panel-element-border: 1px solid rgba(100,100,100, 0.6);
+@panel-section-background-color: #282D32;
+@panel-form-input-background-color: #838689;
+@panel-form-input-text-color: #FFFFFF;
+@panel-form-button-background-color: #A1A3A6;
+@panel-form-button-text-color: #FFFFFF;
+
+// Explorer panel
+@explorer-panel-width: @left-side-panels-width;
+@explorer-panel-header-background-color: #757f88;
+@explorer-panel-inactive-tab-text-color: @panel-text-color;
+@explorer-panel-active-tab-text-color: @panel-emphasized-text-color;
+
+@explorer-panel-active-tab-underline-color: @highlight-color;
+@explorer-panel-close-animation-length: 0.25s;
+@explorer-panel-tab-switch-animation-length: 0.25s;
+@explorer-panel-badge-background-color: @highlight-color;
+@explorer-panel-badge-text-color: @panel-emphasized-text-color;
+
+//Floating elements
+                        
+@floating-background-color: rgba(47,53,60,80%);
+@floating-text-color: #FFFFFF;
+@floating-element-border: 1px solid #555555;
+
+// Input
+@input-background-color: #A1A3A6;
+@input-text-color: #666666;

文件差异内容过多而无法显示
+ 4 - 0
src/core/plugins/cesium-navigation-es6/svgPaths/svgCompassGyro.js


文件差异内容过多而无法显示
+ 4 - 0
src/core/plugins/cesium-navigation-es6/svgPaths/svgCompassOuterRing.js


+ 2 - 0
src/core/plugins/cesium-navigation-es6/svgPaths/svgCompassRotationMarker.js

@@ -0,0 +1,2 @@
+var svgCompassRotationMarker = 'M 72.46875,22.03125 C 59.505873,22.050338 46.521615,27.004287 36.6875,36.875 L 47.84375,47.96875 C 61.521556,34.240041 83.442603,34.227389 97.125,47.90625 l 11.125,-11.125 C 98.401629,26.935424 85.431627,22.012162 72.46875,22.03125 z'
+export default svgCompassRotationMarker

+ 3 - 0
src/core/plugins/cesium-navigation-es6/svgPaths/svgReset.js

@@ -0,0 +1,3 @@
+var svgReset = 'M 7.5,0 C 3.375,0 0,3.375 0,7.5 0,11.625 3.375,15 7.5,15 c 3.46875,0 6.375,-2.4375 7.21875,-5.625 l -1.96875,0 C 12,11.53125 9.9375,13.125 7.5,13.125 4.40625,13.125 1.875,10.59375 1.875,7.5 1.875,4.40625 4.40625,1.875 7.5,1.875 c 1.59375,0 2.90625,0.65625 3.9375,1.6875 l -3,3 6.5625,0 L 15,0 12.75,2.25 C 11.4375,0.84375 9.5625,0 7.5,0 z'
+
+export default svgReset

+ 166 - 0
src/core/plugins/cesium-navigation-es6/viewModels/DistanceLegendViewModel.js

@@ -0,0 +1,166 @@
+/* eslint-disable no-unused-vars */
+import {
+  defined,
+  DeveloperError,
+  EllipsoidGeodesic,
+  Cartesian2,
+  getTimestamp,
+  EventHelper,
+  knockout
+} from 'cesium/Cesium'
+import loadView from '../core/loadView'
+
+var Knockout = knockout
+
+var DistanceLegendViewModel = function (options) {
+  if (!defined(options) || !defined(options.terria)) {
+    throw new DeveloperError('options.terria is required.')
+  }
+
+  this.terria = options.terria
+  this._removeSubscription = undefined
+  this._lastLegendUpdate = undefined
+  this.eventHelper = new EventHelper()
+
+  this.distanceLabel = undefined
+  this.barWidth = undefined
+
+  this.enableDistanceLegend = (defined(options.enableDistanceLegend)) ? options.enableDistanceLegend : true
+
+  Knockout.track(this, ['distanceLabel', 'barWidth'])
+
+  this.eventHelper.add(this.terria.afterWidgetChanged, function () {
+    if (defined(this._removeSubscription)) {
+      this._removeSubscription()
+      this._removeSubscription = undefined
+    }
+  }, this)
+  //        this.terria.beforeWidgetChanged.addEventListener(function () {
+  //            if (defined(this._removeSubscription)) {
+  //                this._removeSubscription();
+  //                this._removeSubscription = undefined;
+  //            }
+  //        }, this);
+
+  var that = this
+
+  function addUpdateSubscription () {
+    if (defined(that.terria)) {
+      var scene = that.terria.scene
+      that._removeSubscription = scene.postRender.addEventListener(function () {
+        updateDistanceLegendCesium(this, scene)
+      }, that)
+    }
+  }
+
+  addUpdateSubscription()
+  this.eventHelper.add(this.terria.afterWidgetChanged, function () {
+    addUpdateSubscription()
+  }, this)
+  // this.terria.afterWidgetChanged.addEventListener(function() {
+  //    addUpdateSubscription();
+  // }, this);
+}
+
+DistanceLegendViewModel.prototype.destroy = function () {
+  this.eventHelper.removeAll()
+}
+
+DistanceLegendViewModel.prototype.show = function (container) {
+  var testing
+  if (this.enableDistanceLegend) {
+    testing = '<div class="distance-legend" data-bind="visible: distanceLabel && barWidth">' +
+      '<div class="distance-legend-label" data-bind="text: distanceLabel"></div>' +
+      '<div class="distance-legend-scale-bar" data-bind="style: { width: barWidth + \'px\', left: (5 + (125 - barWidth) / 2) + \'px\' }"></div>' +
+      '</div>'
+  } else {
+    testing = '<div class="distance-legend"  style="display: none;" data-bind="visible: distanceLabel && barWidth">' +
+      '<div class="distance-legend-label"  data-bind="text: distanceLabel"></div>' +
+      '<div class="distance-legend-scale-bar"  data-bind="style: { width: barWidth + \'px\', left: (5 + (125 - barWidth) / 2) + \'px\' }"></div>' +
+      '</div>'
+  }
+  loadView(testing, container, this)
+  // loadView(distanceLegendTemplate, container, this);
+  // loadView(require('fs').readFileSync(__dirname + '/../Views/DistanceLegend.html', 'utf8'), container, this);
+}
+
+DistanceLegendViewModel.create = function (options) {
+  var result = new DistanceLegendViewModel(options)
+  result.show(options.container)
+  return result
+}
+
+var geodesic = new EllipsoidGeodesic()
+
+var distances = [
+  1, 2, 3, 5,
+  10, 20, 30, 50,
+  100, 200, 300, 500,
+  1000, 2000, 3000, 5000,
+  10000, 20000, 30000, 50000,
+  100000, 200000, 300000, 500000,
+  1000000, 2000000, 3000000, 5000000,
+  10000000, 20000000, 30000000, 50000000]
+
+function updateDistanceLegendCesium (viewModel, scene) {
+  if (!viewModel.enableDistanceLegend) {
+    viewModel.barWidth = undefined
+    viewModel.distanceLabel = undefined
+    return
+  }
+  var now = getTimestamp()
+  if (now < viewModel._lastLegendUpdate + 250) {
+    return
+  }
+
+  viewModel._lastLegendUpdate = now
+
+  // Find the distance between two pixels at the bottom center of the screen.
+  var width = scene.canvas.clientWidth
+  var height = scene.canvas.clientHeight
+
+  var left = scene.camera.getPickRay(new Cartesian2((width / 2) | 0, height - 1))
+  var right = scene.camera.getPickRay(new Cartesian2(1 + (width / 2) | 0, height - 1))
+
+  var globe = scene.globe
+  var leftPosition = globe.pick(left, scene)
+  var rightPosition = globe.pick(right, scene)
+
+  if (!defined(leftPosition) || !defined(rightPosition)) {
+    viewModel.barWidth = undefined
+    viewModel.distanceLabel = undefined
+    return
+  }
+
+  var leftCartographic = globe.ellipsoid.cartesianToCartographic(leftPosition)
+  var rightCartographic = globe.ellipsoid.cartesianToCartographic(rightPosition)
+
+  geodesic.setEndPoints(leftCartographic, rightCartographic)
+  var pixelDistance = geodesic.surfaceDistance
+
+  // Find the first distance that makes the scale bar less than 100 pixels.
+  var maxBarWidth = 100
+  var distance
+  for (var i = distances.length - 1; !defined(distance) && i >= 0; --i) {
+    if (distances[i] / pixelDistance < maxBarWidth) {
+      distance = distances[i]
+    }
+  }
+
+  if (defined(distance)) {
+    var label
+    if (distance >= 1000) {
+      label = (distance / 1000).toString() + ' km'
+    } else {
+      label = distance.toString() + ' m'
+    }
+
+    viewModel.barWidth = (distance / pixelDistance) | 0
+    viewModel.distanceLabel = label
+  } else {
+    viewModel.barWidth = undefined
+    viewModel.distanceLabel = undefined
+  }
+}
+
+export default DistanceLegendViewModel

+ 17 - 0
src/core/plugins/cesium-navigation-es6/viewModels/NavigationControl.js

@@ -0,0 +1,17 @@
+import UserInterfaceControl from './UserInterfaceControl'
+/**
+ * The view-model for a control in the navigation control tool bar
+ *
+ * @alias NavigationControl
+ * @constructor
+ * @abstract
+ *
+ * @param {Terria} terria The Terria instance.
+ */
+var NavigationControl = function (terria) {
+  UserInterfaceControl.apply(this, arguments)
+}
+
+NavigationControl.prototype = Object.create(UserInterfaceControl.prototype)
+
+export default NavigationControl

+ 585 - 0
src/core/plugins/cesium-navigation-es6/viewModels/NavigationViewModel.js

@@ -0,0 +1,585 @@
+import {
+  defined,
+  Math as CesiumMath,
+  getTimestamp,
+  EventHelper,
+  Transforms,
+  SceneMode,
+  Cartesian2,
+  Cartesian3,
+  Matrix4,
+  BoundingSphere,
+  HeadingPitchRange,
+  knockout as Knockout
+} from 'cesium/Cesium'
+import loadView from '../core/loadView'
+import ResetViewNavigationControl from './ResetViewNavigationControl'
+import ZoomNavigationControl from './ZoomNavigationControl'
+import svgCompassOuterRing from '../svgPaths/svgCompassOuterRing'
+import svgCompassGyro from '../svgPaths/svgCompassGyro'
+import svgCompassRotationMarker from '../svgPaths/svgCompassRotationMarker'
+import Utils from '../core/Utils'
+
+
+var NavigationViewModel = function (options) {
+  this.terria = options.terria
+  this.eventHelper = new EventHelper()
+  this.enableZoomControls = (defined(options.enableZoomControls)) ? options.enableZoomControls : true
+  this.enableCompass = (defined(options.enableCompass)) ? options.enableCompass : true
+  this.navigationLocked = false
+
+  // if (this.showZoomControls)
+  //   {
+  this.controls = options.controls
+  if (!defined(this.controls)) {
+    this.controls = [
+      new ZoomNavigationControl(this.terria, true),
+      new ResetViewNavigationControl(this.terria),      
+      new ZoomNavigationControl(this.terria, false)
+    ]
+  }
+  // }
+
+  this.svgCompassOuterRing = svgCompassOuterRing
+  this.svgCompassGyro = svgCompassGyro
+  this.svgCompassRotationMarker = svgCompassRotationMarker
+
+  this.showCompass = defined(this.terria) && this.enableCompass
+  this.heading = this.showCompass ? this.terria.scene.camera.heading : 0.0
+
+  this.isOrbiting = false
+  this.orbitCursorAngle = 0
+  this.orbitCursorOpacity = 0.0
+  this.orbitLastTimestamp = 0
+  this.orbitFrame = undefined
+  this.orbitIsLook = false
+  this.orbitMouseMoveFunction = undefined
+  this.orbitMouseUpFunction = undefined
+
+  this.isRotating = false
+  this.rotateInitialCursorAngle = undefined
+  this.rotateFrame = undefined
+  this.rotateIsLook = false
+  this.rotateMouseMoveFunction = undefined
+  this.rotateMouseUpFunction = undefined
+
+  this._unsubcribeFromPostRender = undefined
+
+  Knockout.track(this, ['controls', 'showCompass', 'heading', 'isOrbiting', 'orbitCursorAngle', 'isRotating'])
+
+  var that = this
+
+  NavigationViewModel.prototype.setNavigationLocked = function (locked) {
+    this.navigationLocked = locked
+    if (this.controls && this.controls.length > 1) {
+      this.controls[1].setNavigationLocked(this.navigationLocked)
+    }
+  }
+
+  function widgetChange () {
+    if (defined(that.terria)) {
+      if (that._unsubcribeFromPostRender) {
+        that._unsubcribeFromPostRender()
+        that._unsubcribeFromPostRender = undefined
+      }
+
+      that.showCompass = true && that.enableCompass
+
+      that._unsubcribeFromPostRender = that.terria.scene.postRender.addEventListener(function () {
+        that.heading = that.terria.scene.camera.heading
+      })
+    } else {
+      if (that._unsubcribeFromPostRender) {
+        that._unsubcribeFromPostRender()
+        that._unsubcribeFromPostRender = undefined
+      }
+      that.showCompass = false
+    }
+  }
+
+  this.eventHelper.add(this.terria.afterWidgetChanged, widgetChange, this)
+  // this.terria.afterWidgetChanged.addEventListener(widgetChange);
+
+  widgetChange()
+}
+
+NavigationViewModel.prototype.destroy = function () {
+  this.eventHelper.removeAll()
+
+  // loadView(require('fs').readFileSync(baseURLEmpCesium + 'js-lib/terrajs/lib/Views/Navigation.html', 'utf8'), container, this);
+}
+
+NavigationViewModel.prototype.show = function (container) {
+  var testing
+  if (this.enableZoomControls && this.enableCompass) {
+    testing = '<div class="compass" title="" data-bind="visible: showCompass, event: { mousedown: handleMouseDown, dblclick: handleDoubleClick }">' +
+      '<div class="compass-outer-ring-background"></div>' +
+      ' <div class="compass-rotation-marker" data-bind="visible: isOrbiting, style: { transform: \'rotate(-\' + orbitCursorAngle + \'rad)\', \'-webkit-transform\': \'rotate(-\' + orbitCursorAngle + \'rad)\', opacity: orbitCursorOpacity }, cesiumSvgPath: { path: svgCompassRotationMarker, width: 145, height: 145 }"></div>' +
+      ' <div class="compass-outer-ring" title="" data-bind="style: { transform: \'rotate(-\' + heading + \'rad)\', \'-webkit-transform\': \'rotate(-\' + heading + \'rad)\' }, cesiumSvgPath: { path: svgCompassOuterRing, width: 145, height: 145 }"></div>' +
+      ' <div class="compass-gyro-background"></div>' +
+      ' <div class="compass-gyro" data-bind="cesiumSvgPath: { path: svgCompassGyro, width: 145, height: 145 }, css: { \'compass-gyro-active\': isOrbiting }"></div>' +
+      '</div>' +
+      '<div class="navigation-controls">' +
+      '<!-- ko foreach: controls -->' +
+      '<div data-bind="click: activate, attr: { title: $data.name }, css: $root.isLastControl($data) ? \'navigation-control-last\' : \'navigation-control\' ">' +
+      '   <!-- ko if: $data.hasText -->' +
+      '   <div data-bind="text: $data.text, css: $data.isActive ?  \'navigation-control-icon-active \' + $data.cssClass : $data.cssClass"></div>' +
+      '   <!-- /ko -->' +
+      '  <!-- ko ifnot: $data.hasText -->' +
+      '  <div data-bind="cesiumSvgPath: { path: $data.svgIcon, width: $data.svgWidth, height: $data.svgHeight }, css: $data.isActive ?  \'navigation-control-icon-active \' + $data.cssClass : $data.cssClass"></div>' +
+      '  <!-- /ko -->' +
+      ' </div>' +
+      ' <!-- /ko -->' +
+      '</div>'
+  } else if (!this.enableZoomControls && this.enableCompass) {
+    testing = '<div class="compass" title="" data-bind="visible: showCompass, event: { mousedown: handleMouseDown, dblclick: handleDoubleClick }">' +
+      '<div class="compass-outer-ring-background"></div>' +
+      ' <div class="compass-rotation-marker" data-bind="visible: isOrbiting, style: { transform: \'rotate(-\' + orbitCursorAngle + \'rad)\', \'-webkit-transform\': \'rotate(-\' + orbitCursorAngle + \'rad)\', opacity: orbitCursorOpacity }, cesiumSvgPath: { path: svgCompassRotationMarker, width: 145, height: 145 }"></div>' +
+      ' <div class="compass-outer-ring" title="" data-bind="style: { transform: \'rotate(-\' + heading + \'rad)\', \'-webkit-transform\': \'rotate(-\' + heading + \'rad)\' }, cesiumSvgPath: { path: svgCompassOuterRing, width: 145, height: 145 }"></div>' +
+      ' <div class="compass-gyro-background"></div>' +
+      ' <div class="compass-gyro" data-bind="cesiumSvgPath: { path: svgCompassGyro, width: 145, height: 145 }, css: { \'compass-gyro-active\': isOrbiting }"></div>' +
+      '</div>' +
+      '<div class="navigation-controls"  style="display: none;" >' +
+      '<!-- ko foreach: controls -->' +
+      '<div data-bind="click: activate, attr: { title: $data.name }, css: $root.isLastControl($data) ? \'navigation-control-last\' : \'navigation-control\' ">' +
+      '   <!-- ko if: $data.hasText -->' +
+      '   <div data-bind="text: $data.text, css: $data.isActive ?  \'navigation-control-icon-active \' + $data.cssClass : $data.cssClass"></div>' +
+      '   <!-- /ko -->' +
+      '  <!-- ko ifnot: $data.hasText -->' +
+      '  <div data-bind="cesiumSvgPath: { path: $data.svgIcon, width: $data.svgWidth, height: $data.svgHeight }, css: $data.isActive ?  \'navigation-control-icon-active \' + $data.cssClass : $data.cssClass"></div>' +
+      '  <!-- /ko -->' +
+      ' </div>' +
+      ' <!-- /ko -->' +
+      '</div>'
+  } else if (this.enableZoomControls && !this.enableCompass) {
+    testing = '<div class="compass"  style="display: none;" title="" data-bind="visible: showCompass, event: { mousedown: handleMouseDown, dblclick: handleDoubleClick }">' +
+      '<div class="compass-outer-ring-background"></div>' +
+      ' <div class="compass-rotation-marker" data-bind="visible: isOrbiting, style: { transform: \'rotate(-\' + orbitCursorAngle + \'rad)\', \'-webkit-transform\': \'rotate(-\' + orbitCursorAngle + \'rad)\', opacity: orbitCursorOpacity }, cesiumSvgPath: { path: svgCompassRotationMarker, width: 145, height: 145 }"></div>' +
+      ' <div class="compass-outer-ring" title="" data-bind="style: { transform: \'rotate(-\' + heading + \'rad)\', \'-webkit-transform\': \'rotate(-\' + heading + \'rad)\' }, cesiumSvgPath: { path: svgCompassOuterRing, width: 145, height: 145 }"></div>' +
+      ' <div class="compass-gyro-background"></div>' +
+      ' <div class="compass-gyro" data-bind="cesiumSvgPath: { path: svgCompassGyro, width: 145, height: 145 }, css: { \'compass-gyro-active\': isOrbiting }"></div>' +
+      '</div>' +
+      '<div class="navigation-controls"    >' +
+      '<!-- ko foreach: controls -->' +
+      '<div data-bind="click: activate, attr: { title: $data.name }, css: $root.isLastControl($data) ? \'navigation-control-last\' : \'navigation-control\' ">' +
+      '   <!-- ko if: $data.hasText -->' +
+      '   <div data-bind="text: $data.text, css: $data.isActive ?  \'navigation-control-icon-active \' + $data.cssClass : $data.cssClass"></div>' +
+      '   <!-- /ko -->' +
+      '  <!-- ko ifnot: $data.hasText -->' +
+      '  <div data-bind="cesiumSvgPath: { path: $data.svgIcon, width: $data.svgWidth, height: $data.svgHeight }, css: $data.isActive ?  \'navigation-control-icon-active \' + $data.cssClass : $data.cssClass"></div>' +
+      '  <!-- /ko -->' +
+      ' </div>' +
+      ' <!-- /ko -->' +
+      '</div>'
+  } else if (!this.enableZoomControls && !this.enableCompass) {
+    testing = '<div class="compass"  style="display: none;" title="" data-bind="visible: showCompass, event: { mousedown: handleMouseDown, dblclick: handleDoubleClick }">' +
+      '<div class="compass-outer-ring-background"></div>' +
+      ' <div class="compass-rotation-marker" data-bind="visible: isOrbiting, style: { transform: \'rotate(-\' + orbitCursorAngle + \'rad)\', \'-webkit-transform\': \'rotate(-\' + orbitCursorAngle + \'rad)\', opacity: orbitCursorOpacity }, cesiumSvgPath: { path: svgCompassRotationMarker, width: 145, height: 145 }"></div>' +
+      ' <div class="compass-outer-ring" title="" data-bind="style: { transform: \'rotate(-\' + heading + \'rad)\', \'-webkit-transform\': \'rotate(-\' + heading + \'rad)\' }, cesiumSvgPath: { path: svgCompassOuterRing, width: 145, height: 145 }"></div>' +
+      ' <div class="compass-gyro-background"></div>' +
+      ' <div class="compass-gyro" data-bind="cesiumSvgPath: { path: svgCompassGyro, width: 145, height: 145 }, css: { \'compass-gyro-active\': isOrbiting }"></div>' +
+      '</div>' +
+      '<div class="navigation-controls"   style="display: none;" >' +
+      '<!-- ko foreach: controls -->' +
+      '<div data-bind="click: activate, attr: { title: $data.name }, css: $root.isLastControl($data) ? \'navigation-control-last\' : \'navigation-control\' ">' +
+      '   <!-- ko if: $data.hasText -->' +
+      '   <div data-bind="text: $data.text, css: $data.isActive ?  \'navigation-control-icon-active \' + $data.cssClass : $data.cssClass"></div>' +
+      '   <!-- /ko -->' +
+      '  <!-- ko ifnot: $data.hasText -->' +
+      '  <div data-bind="cesiumSvgPath: { path: $data.svgIcon, width: $data.svgWidth, height: $data.svgHeight }, css: $data.isActive ?  \'navigation-control-icon-active \' + $data.cssClass : $data.cssClass"></div>' +
+      '  <!-- /ko -->' +
+      ' </div>' +
+      ' <!-- /ko -->' +
+      '</div>'
+  }
+  loadView(testing, container, this)
+  // loadView(navigatorTemplate, container, this);
+  // loadView(require('fs').readFileSync(baseURLEmpCesium + 'js-lib/terrajs/lib/Views/Navigation.html', 'utf8'), container, this);
+}
+
+/**
+ * Adds a control to this toolbar.
+ * @param {NavControl} control The control to add.
+ */
+NavigationViewModel.prototype.add = function (control) {
+  this.controls.push(control)
+}
+
+/**
+ * Removes a control from this toolbar.
+ * @param {NavControl} control The control to remove.
+ */
+NavigationViewModel.prototype.remove = function (control) {
+  this.controls.remove(control)
+}
+
+/**
+ * Checks if the control given is the last control in the control array.
+ * @param {NavControl} control The control to remove.
+ */
+NavigationViewModel.prototype.isLastControl = function (control) {
+  return (control === this.controls[this.controls.length - 1])
+}
+
+var vectorScratch = new Cartesian2()
+
+NavigationViewModel.prototype.handleMouseDown = function (viewModel, e) {
+  var scene = this.terria.scene
+  if (scene.mode === SceneMode.MORPHING) {
+    return true
+  }
+  if (viewModel.navigationLocked) {
+    return true
+  }
+
+  var compassElement = e.currentTarget
+  var compassRectangle = e.currentTarget.getBoundingClientRect()
+  var maxDistance = compassRectangle.width / 2.0
+  var center = new Cartesian2((compassRectangle.right - compassRectangle.left) / 2.0, (compassRectangle.bottom - compassRectangle.top) / 2.0)
+  var clickLocation = new Cartesian2(e.clientX - compassRectangle.left, e.clientY - compassRectangle.top)
+  var vector = Cartesian2.subtract(clickLocation, center, vectorScratch)
+  var distanceFromCenter = Cartesian2.magnitude(vector)
+
+  var distanceFraction = distanceFromCenter / maxDistance
+
+  var nominalTotalRadius = 145
+  var norminalGyroRadius = 50
+
+  if (distanceFraction < norminalGyroRadius / nominalTotalRadius) {
+    orbit(this, compassElement, vector)
+    //            return false;
+  } else if (distanceFraction < 1.0) {
+    rotate(this, compassElement, vector)
+    //            return false;
+  } else {
+    return true
+  }
+}
+
+var oldTransformScratch = new Matrix4()
+var newTransformScratch = new Matrix4()
+var centerScratch = new Cartesian3()
+
+NavigationViewModel.prototype.handleDoubleClick = function (viewModel, e) {
+  var scene = viewModel.terria.scene
+  var camera = scene.camera
+
+  var sscc = scene.screenSpaceCameraController
+
+  if (scene.mode === SceneMode.MORPHING || !sscc.enableInputs) {
+    return true
+  }
+  if (viewModel.navigationLocked) {
+    return true
+  }
+  if (scene.mode === SceneMode.COLUMBUS_VIEW && !sscc.enableTranslate) {
+    return
+  }
+  if (scene.mode === SceneMode.SCENE3D || scene.mode === SceneMode.COLUMBUS_VIEW) {
+    if (!sscc.enableLook) {
+      return
+    }
+
+    if (scene.mode === SceneMode.SCENE3D) {
+      if (!sscc.enableRotate) {
+        return
+      }
+    }
+  }
+
+  var center = Utils.getCameraFocus(viewModel.terria, true, centerScratch)
+
+  if (!defined(center)) {
+    // Globe is barely visible, so reset to home view.
+
+    this.controls[1].resetView()
+    return
+  }
+
+  var cameraPosition = scene.globe.ellipsoid.cartographicToCartesian(camera.positionCartographic, new Cartesian3())
+
+  var surfaceNormal = scene.globe.ellipsoid.geodeticSurfaceNormal(center)
+
+  var focusBoundingSphere = new BoundingSphere(center, 0)
+
+  camera.flyToBoundingSphere(focusBoundingSphere, {
+    offset: new HeadingPitchRange(0,
+      // do not use camera.pitch since the pitch at the center/target is required
+      CesiumMath.PI_OVER_TWO - Cartesian3.angleBetween(
+        surfaceNormal,
+        camera.directionWC
+      ),
+      // distanceToBoundingSphere returns wrong values when in 2D or Columbus view so do not use
+      // camera.distanceToBoundingSphere(focusBoundingSphere)
+      // instead calculate distance manually
+      Cartesian3.distance(cameraPosition, center)
+    ),
+    duration: 1.5
+  })
+}
+
+NavigationViewModel.create = function (options) {
+  // options.enableZoomControls = this.enableZoomControls;
+  // options.enableCompass = this.enableCompass;
+  var result = new NavigationViewModel(options)
+  result.show(options.container)
+  return result
+}
+
+function orbit (viewModel, compassElement, cursorVector) {
+  var scene = viewModel.terria.scene
+
+  var sscc = scene.screenSpaceCameraController
+
+  // do not orbit if it is disabled
+  if (scene.mode === SceneMode.MORPHING || !sscc.enableInputs) {
+    return
+  }
+  if (viewModel.navigationLocked) {
+    return true
+  }
+
+  switch (scene.mode) {
+    case SceneMode.COLUMBUS_VIEW:
+      if (sscc.enableLook) {
+        break
+      }
+
+      if (!sscc.enableTranslate || !sscc.enableTilt) {
+        return
+      }
+      break
+    case SceneMode.SCENE3D:
+      if (sscc.enableLook) {
+        break
+      }
+
+      if (!sscc.enableTilt || !sscc.enableRotate) {
+        return
+      }
+      break
+    case SceneMode.SCENE2D:
+      if (!sscc.enableTranslate) {
+        return
+      }
+      break
+  }
+
+  // Remove existing event handlers, if any.
+  document.removeEventListener('mousemove', viewModel.orbitMouseMoveFunction, false)
+  document.removeEventListener('mouseup', viewModel.orbitMouseUpFunction, false)
+
+  if (defined(viewModel.orbitTickFunction)) {
+    viewModel.terria.clock.onTick.removeEventListener(viewModel.orbitTickFunction)
+  }
+
+  viewModel.orbitMouseMoveFunction = undefined
+  viewModel.orbitMouseUpFunction = undefined
+  viewModel.orbitTickFunction = undefined
+
+  viewModel.isOrbiting = true
+  viewModel.orbitLastTimestamp = getTimestamp()
+
+  var camera = scene.camera
+
+  if (defined(viewModel.terria.trackedEntity)) {
+    // when tracking an entity simply use that reference frame
+    viewModel.orbitFrame = undefined
+    viewModel.orbitIsLook = false
+  } else {
+    var center = Utils.getCameraFocus(viewModel.terria, true, centerScratch)
+
+    if (!defined(center)) {
+      viewModel.orbitFrame = Transforms.eastNorthUpToFixedFrame(camera.positionWC, scene.globe.ellipsoid, newTransformScratch)
+      viewModel.orbitIsLook = true
+    } else {
+      viewModel.orbitFrame = Transforms.eastNorthUpToFixedFrame(center, scene.globe.ellipsoid, newTransformScratch)
+      viewModel.orbitIsLook = false
+    }
+  }
+
+  viewModel.orbitTickFunction = function (e) {
+    var timestamp = getTimestamp()
+    var deltaT = timestamp - viewModel.orbitLastTimestamp
+    var rate = (viewModel.orbitCursorOpacity - 0.5) * 2.5 / 1000
+    var distance = deltaT * rate
+
+    var angle = viewModel.orbitCursorAngle + CesiumMath.PI_OVER_TWO
+    var x = Math.cos(angle) * distance
+    var y = Math.sin(angle) * distance
+
+    var oldTransform
+
+    if (viewModel.navigationLocked) {
+      return true
+    }
+
+    if (defined(viewModel.orbitFrame)) {
+      oldTransform = Matrix4.clone(camera.transform, oldTransformScratch)
+
+      camera.lookAtTransform(viewModel.orbitFrame)
+    }
+
+    // do not look up/down or rotate in 2D mode
+    if (scene.mode === SceneMode.SCENE2D) {
+      camera.move(new Cartesian3(x, y, 0), Math.max(scene.canvas.clientWidth, scene.canvas.clientHeight) / 100 * camera.positionCartographic.height * distance)
+    } else {
+      if (viewModel.orbitIsLook) {
+        camera.look(Cartesian3.UNIT_Z, -x)
+        camera.look(camera.right, -y)
+      } else {
+        camera.rotateLeft(x)
+        camera.rotateUp(y)
+      }
+    }
+
+    if (defined(viewModel.orbitFrame)) {
+      camera.lookAtTransform(oldTransform)
+    }
+
+    // viewModel.terria.cesium.notifyRepaintRequired();
+
+    viewModel.orbitLastTimestamp = timestamp
+  }
+
+  function updateAngleAndOpacity (vector, compassWidth) {
+    var angle = Math.atan2(-vector.y, vector.x)
+    viewModel.orbitCursorAngle = CesiumMath.zeroToTwoPi(angle - CesiumMath.PI_OVER_TWO)
+
+    var distance = Cartesian2.magnitude(vector)
+    var maxDistance = compassWidth / 2.0
+    var distanceFraction = Math.min(distance / maxDistance, 1.0)
+    var easedOpacity = 0.5 * distanceFraction * distanceFraction + 0.5
+    viewModel.orbitCursorOpacity = easedOpacity
+
+    // viewModel.terria.cesium.notifyRepaintRequired();
+  }
+
+  viewModel.orbitMouseMoveFunction = function (e) {
+    var compassRectangle = compassElement.getBoundingClientRect()
+    var center = new Cartesian2((compassRectangle.right - compassRectangle.left) / 2.0, (compassRectangle.bottom - compassRectangle.top) / 2.0)
+    var clickLocation = new Cartesian2(e.clientX - compassRectangle.left, e.clientY - compassRectangle.top)
+    var vector = Cartesian2.subtract(clickLocation, center, vectorScratch)
+    updateAngleAndOpacity(vector, compassRectangle.width)
+  }
+
+  viewModel.orbitMouseUpFunction = function (e) {
+    // TODO: if mouse didn't move, reset view to looking down, north is up?
+
+    viewModel.isOrbiting = false
+    document.removeEventListener('mousemove', viewModel.orbitMouseMoveFunction, false)
+    document.removeEventListener('mouseup', viewModel.orbitMouseUpFunction, false)
+
+    if (defined(viewModel.orbitTickFunction)) {
+      viewModel.terria.clock.onTick.removeEventListener(viewModel.orbitTickFunction)
+    }
+
+    viewModel.orbitMouseMoveFunction = undefined
+    viewModel.orbitMouseUpFunction = undefined
+    viewModel.orbitTickFunction = undefined
+  }
+
+  document.addEventListener('mousemove', viewModel.orbitMouseMoveFunction, false)
+  document.addEventListener('mouseup', viewModel.orbitMouseUpFunction, false)
+  viewModel.terria.clock.onTick.addEventListener(viewModel.orbitTickFunction)
+
+  updateAngleAndOpacity(cursorVector, compassElement.getBoundingClientRect().width)
+}
+
+function rotate (viewModel, compassElement, cursorVector) {
+  var scene = viewModel.terria.scene
+  var camera = scene.camera
+
+  var sscc = scene.screenSpaceCameraController
+  // do not rotate in 2D mode or if rotating is disabled
+  if (scene.mode === SceneMode.MORPHING || scene.mode === SceneMode.SCENE2D || !sscc.enableInputs) {
+    return
+  }
+  if (viewModel.navigationLocked) {
+    return true
+  }
+
+  if (!sscc.enableLook && (scene.mode === SceneMode.COLUMBUS_VIEW || (scene.mode === SceneMode.SCENE3D && !sscc.enableRotate))) {
+    return
+  }
+
+  // Remove existing event handlers, if any.
+  document.removeEventListener('mousemove', viewModel.rotateMouseMoveFunction, false)
+  document.removeEventListener('mouseup', viewModel.rotateMouseUpFunction, false)
+
+  viewModel.rotateMouseMoveFunction = undefined
+  viewModel.rotateMouseUpFunction = undefined
+
+  viewModel.isRotating = true
+  viewModel.rotateInitialCursorAngle = Math.atan2(-cursorVector.y, cursorVector.x)
+
+  if (defined(viewModel.terria.trackedEntity)) {
+    // when tracking an entity simply use that reference frame
+    viewModel.rotateFrame = undefined
+    viewModel.rotateIsLook = false
+  } else {
+    var viewCenter = Utils.getCameraFocus(viewModel.terria, true, centerScratch)
+
+    if (!defined(viewCenter) || (scene.mode === SceneMode.COLUMBUS_VIEW && !sscc.enableLook && !sscc.enableTranslate)) {
+      viewModel.rotateFrame = Transforms.eastNorthUpToFixedFrame(camera.positionWC, scene.globe.ellipsoid, newTransformScratch)
+      viewModel.rotateIsLook = true
+    } else {
+      viewModel.rotateFrame = Transforms.eastNorthUpToFixedFrame(viewCenter, scene.globe.ellipsoid, newTransformScratch)
+      viewModel.rotateIsLook = false
+    }
+  }
+
+  var oldTransform
+  if (defined(viewModel.rotateFrame)) {
+    oldTransform = Matrix4.clone(camera.transform, oldTransformScratch)
+    camera.lookAtTransform(viewModel.rotateFrame)
+  }
+
+  viewModel.rotateInitialCameraAngle = -camera.heading
+
+  if (defined(viewModel.rotateFrame)) {
+    camera.lookAtTransform(oldTransform)
+  }
+
+  viewModel.rotateMouseMoveFunction = function (e) {
+    var compassRectangle = compassElement.getBoundingClientRect()
+    var center = new Cartesian2((compassRectangle.right - compassRectangle.left) / 2.0, (compassRectangle.bottom - compassRectangle.top) / 2.0)
+    var clickLocation = new Cartesian2(e.clientX - compassRectangle.left, e.clientY - compassRectangle.top)
+    var vector = Cartesian2.subtract(clickLocation, center, vectorScratch)
+    var angle = Math.atan2(-vector.y, vector.x)
+
+    var angleDifference = angle - viewModel.rotateInitialCursorAngle
+    var newCameraAngle = CesiumMath.zeroToTwoPi(viewModel.rotateInitialCameraAngle - angleDifference)
+
+    var camera = viewModel.terria.scene.camera
+
+    var oldTransform
+    if (defined(viewModel.rotateFrame)) {
+      oldTransform = Matrix4.clone(camera.transform, oldTransformScratch)
+      camera.lookAtTransform(viewModel.rotateFrame)
+    }
+
+    var currentCameraAngle = -camera.heading
+    camera.rotateRight(newCameraAngle - currentCameraAngle)
+
+    if (defined(viewModel.rotateFrame)) {
+      camera.lookAtTransform(oldTransform)
+    }
+
+    // viewModel.terria.cesium.notifyRepaintRequired();
+  }
+
+  viewModel.rotateMouseUpFunction = function (e) {
+    viewModel.isRotating = false
+    document.removeEventListener('mousemove', viewModel.rotateMouseMoveFunction, false)
+    document.removeEventListener('mouseup', viewModel.rotateMouseUpFunction, false)
+
+    viewModel.rotateMouseMoveFunction = undefined
+    viewModel.rotateMouseUpFunction = undefined
+  }
+
+  document.addEventListener('mousemove', viewModel.rotateMouseMoveFunction, false)
+  document.addEventListener('mouseup', viewModel.rotateMouseUpFunction, false)
+}
+
+export default NavigationViewModel

+ 122 - 0
src/core/plugins/cesium-navigation-es6/viewModels/ResetViewNavigationControl.js

@@ -0,0 +1,122 @@
+
+import {
+  defined,
+  Camera,
+  Rectangle,
+  Cartographic
+} from 'cesium/Cesium'
+import svgReset from '../svgPaths/svgReset'
+import NavigationControl from './NavigationControl'
+
+/**
+ * The model for a zoom in control in the navigation control tool bar
+ *
+ * @alias ResetViewNavigationControl
+ * @constructor
+ * @abstract
+ *
+ * @param {Terria} terria The Terria instance.
+ */
+var ResetViewNavigationControl = function (terria) {
+  NavigationControl.apply(this, arguments)
+
+  /**
+   * Gets or sets the name of the control which is set as the control's title.
+   * This property is observable.
+   * @type {String}
+   */
+  this.name = '重置视图'
+  this.navigationLocked = false
+
+  /**
+   * Gets or sets the svg icon of the control.  This property is observable.
+   * @type {Object}
+   */
+  this.svgIcon = svgReset
+
+  /**
+   * Gets or sets the height of the svg icon.  This property is observable.
+   * @type {Integer}
+   */
+  this.svgHeight = 15
+
+  /**
+   * Gets or sets the width of the svg icon.  This property is observable.
+   * @type {Integer}
+   */
+  this.svgWidth = 15
+
+  /**
+   * Gets or sets the CSS class of the control. This property is observable.
+   * @type {String}
+   */
+  this.cssClass = 'navigation-control-icon-reset'
+}
+
+ResetViewNavigationControl.prototype = Object.create(NavigationControl.prototype)
+
+ResetViewNavigationControl.prototype.setNavigationLocked = function (locked) {
+  this.navigationLocked = locked
+}
+
+ResetViewNavigationControl.prototype.resetView = function () {
+  // this.terria.analytics.logEvent('navigation', 'click', 'reset');
+  if (this.navigationLocked) {
+    return
+  }
+  var scene = this.terria.scene
+
+  var sscc = scene.screenSpaceCameraController
+  if (!sscc.enableInputs) {
+    return
+  }
+
+  this.isActive = true
+
+  var camera = scene.camera
+
+  if (defined(this.terria.trackedEntity)) {
+    // when tracking do not reset to default view but to default view of tracked entity
+    var trackedEntity = this.terria.trackedEntity
+    this.terria.trackedEntity = undefined
+    this.terria.trackedEntity = trackedEntity
+  } else {
+    // reset to a default position or view defined in the options
+    if (this.terria.options.defaultResetView) {
+      if (this.terria.options.defaultResetView && this.terria.options.defaultResetView instanceof Cartographic) {
+        camera.flyTo({
+          destination: scene.globe.ellipsoid.cartographicToCartesian(this.terria.options.defaultResetView)
+        })
+      } else if (this.terria.options.defaultResetView && this.terria.options.defaultResetView instanceof Rectangle) {
+        try {
+          Rectangle.validate(this.terria.options.defaultResetView)
+          camera.flyTo({
+            destination: this.terria.options.defaultResetView,
+            orientation: {
+              heading: Cesium.Math.toRadians(5.729578)
+            }
+          })
+        } catch (e) {
+          console.log('Cesium-navigation/ResetViewNavigationControl:   options.defaultResetView Cesium rectangle is  invalid!')
+        }
+      }
+    } else if (typeof camera.flyHome === 'function') {
+      camera.flyHome(1)
+    } else {
+      camera.flyTo({'destination': Camera.DEFAULT_VIEW_RECTANGLE, 'duration': 1})
+    }
+  }
+  this.isActive = false
+}
+
+/**
+ * When implemented in a derived class, performs an action when the user clicks
+ * on this control
+ * @abstract
+ * @protected
+ */
+ResetViewNavigationControl.prototype.activate = function () {
+  this.resetView()
+}
+
+export default ResetViewNavigationControl

+ 105 - 0
src/core/plugins/cesium-navigation-es6/viewModels/UserInterfaceControl.js

@@ -0,0 +1,105 @@
+import {
+  defined,
+  defineProperties,
+  DeveloperError,
+  knockout as Knockout
+} from 'cesium/Cesium'
+
+/**
+ * The view-model for a control in the user interface
+ *
+ * @alias UserInterfaceControl
+ * @constructor
+ * @abstract
+ *
+ * @param {Terria} terria The Terria instance.
+ */
+var UserInterfaceControl = function (terria) {
+  if (!defined(terria)) {
+    throw new DeveloperError('terria is required')
+  }
+
+  this._terria = terria
+
+  /**
+   * Gets or sets the name of the control which is set as the controls title.
+   * This property is observable.
+   * @type {String}
+   */
+  this.name = 'Unnamed Control'
+
+  /**
+   * Gets or sets the text to be displayed in the UI control.
+   * This property is observable.
+   * @type {String}
+   */
+  this.text = undefined
+
+  /**
+   * Gets or sets the svg icon of the control.  This property is observable.
+   * @type {Object}
+   */
+  this.svgIcon = undefined
+
+  /**
+   * Gets or sets the height of the svg icon.  This property is observable.
+   * @type {Integer}
+   */
+  this.svgHeight = undefined
+
+  /**
+   * Gets or sets the width of the svg icon.  This property is observable.
+   * @type {Integer}
+   */
+  this.svgWidth = undefined
+
+  /**
+   * Gets or sets the CSS class of the control. This property is observable.
+   * @type {String}
+   */
+  this.cssClass = undefined
+
+  /**
+   * Gets or sets the property describing whether or not the control is in the active state.
+   * This property is observable.
+   * @type {Boolean}
+   */
+  this.isActive = false
+
+  Knockout.track(this, ['name', 'svgIcon', 'svgHeight', 'svgWidth', 'cssClass', 'isActive'])
+}
+
+defineProperties(UserInterfaceControl.prototype, {
+  /**
+   * Gets the Terria instance.
+   * @memberOf UserInterfaceControl.prototype
+   * @type {Terria}
+   */
+   terria: {
+    get: function () {
+      return this._terria
+    }
+  },
+  /**
+   * Gets a value indicating whether this button has text associated with it.
+   * @type {Object}
+   */
+  hasText: {
+    get: function () {
+      return defined(this.text) && typeof this.text === 'string'
+    }
+  }
+
+})
+
+/**
+ * When implemented in a derived class, performs an action when the user clicks
+ * on this control.
+ * @abstract
+ * @protected
+ */
+UserInterfaceControl.prototype.activate = function () {
+  throw new DeveloperError('activate must be implemented in the derived class.')
+}
+
+export default UserInterfaceControl

+ 148 - 0
src/core/plugins/cesium-navigation-es6/viewModels/ZoomNavigationControl.js

@@ -0,0 +1,148 @@
+import {
+  defined,
+  Ray,
+  IntersectionTests,
+  Cartesian3,
+  SceneMode
+} from 'cesium/Cesium'
+import NavigationControl from './NavigationControl'
+import Utils from '../core/Utils'
+
+
+/**
+ * The model for a zoom in control in the navigation control tool bar
+ *
+ * @alias ZoomOutNavigationControl
+ * @constructor
+ * @abstract
+ *
+ * @param {Terria} terria The Terria instance.
+ * @param {boolean} zoomIn is used for zooming in (true) or out (false)
+ */
+var ZoomNavigationControl = function (terria, zoomIn) {
+  NavigationControl.apply(this, arguments)
+
+  /**
+   * Gets or sets the name of the control which is set as the control's title.
+   * This property is observable.
+   * @type {String}
+   */
+  this.name = 'Zoom ' + (zoomIn ? 'In' : 'Out')
+
+  /**
+   * Gets or sets the text to be displayed in the nav control. Controls that
+   * have text do not display the svgIcon.
+   * This property is observable.
+   * @type {String}
+   */
+  this.text = zoomIn ? '+' : '-'
+
+  /**
+   * Gets or sets the CSS class of the control. This property is observable.
+   * @type {String}
+   */
+  this.cssClass = 'navigation-control-icon-zoom-' + (zoomIn ? 'in' : 'out')
+
+  this.relativeAmount = 2
+
+  if (zoomIn) {
+    // this ensures that zooming in is the inverse of zooming out and vice versa
+    // e.g. the camera position remains when zooming in and out
+    this.relativeAmount = 1 / this.relativeAmount
+  }
+}
+
+ZoomNavigationControl.prototype.relativeAmount = 1
+
+ZoomNavigationControl.prototype = Object.create(NavigationControl.prototype)
+
+/**
+ * When implemented in a derived class, performs an action when the user clicks
+ * on this control
+ * @abstract
+ * @protected
+ */
+ZoomNavigationControl.prototype.activate = function () {
+  this.zoom(this.relativeAmount)
+}
+
+var cartesian3Scratch = new Cartesian3()
+
+ZoomNavigationControl.prototype.zoom = function (relativeAmount) {
+  // this.terria.analytics.logEvent('navigation', 'click', 'zoomIn');
+
+  this.isActive = true
+
+  if (defined(this.terria)) {
+    var scene = this.terria.scene
+
+    var sscc = scene.screenSpaceCameraController
+    // do not zoom if it is disabled
+    if (!sscc.enableInputs || !sscc.enableZoom) {
+      return
+    }
+    // TODO
+    //            if(scene.mode == SceneMode.COLUMBUS_VIEW && !sscc.enableTranslate) {
+    //                return;
+    //            }
+
+    var camera = scene.camera
+    var orientation
+
+    switch (scene.mode) {
+      case SceneMode.MORPHING:
+        break
+      case SceneMode.SCENE2D:
+        camera.zoomIn(camera.positionCartographic.height * (1 - this.relativeAmount))
+        break
+      default:
+        var focus
+
+        if (defined(this.terria.trackedEntity)) {
+          focus = new Cartesian3()
+        } else {
+          focus = Utils.getCameraFocus(this.terria, false)
+        }
+
+        if (!defined(focus)) {
+          // Camera direction is not pointing at the globe, so use the ellipsoid horizon point as
+          // the focal point.
+          var ray = new Ray(camera.worldToCameraCoordinatesPoint(scene.globe.ellipsoid.cartographicToCartesian(camera.positionCartographic)), camera.directionWC)
+          focus = IntersectionTests.grazingAltitudeLocation(ray, scene.globe.ellipsoid)
+
+          orientation = {
+            heading: camera.heading,
+            pitch: camera.pitch,
+            roll: camera.roll
+          }
+        } else {
+          orientation = {
+            direction: camera.direction,
+            up: camera.up
+          }
+        }
+
+        var direction = Cartesian3.subtract(camera.position, focus, cartesian3Scratch)
+        var movementVector = Cartesian3.multiplyByScalar(direction, relativeAmount, direction)
+        var endPosition = Cartesian3.add(focus, movementVector, focus)
+
+        if (defined(this.terria.trackedEntity) || scene.mode === SceneMode.COLUMBUS_VIEW) {
+          // sometimes flyTo does not work (jumps to wrong position) so just set the position without any animation
+          // do not use flyTo when tracking an entity because during animatiuon the position of the entity may change
+          camera.position = endPosition
+        } else {
+          camera.flyTo({
+            destination: endPosition,
+            orientation: orientation,
+            duration: 0.5,
+            convert: false
+          })
+        }
+    }
+  }
+
+  // this.terria.notifyRepaintRequired();
+  this.isActive = false
+}
+
+export default ZoomNavigationControl

+ 5 - 1
src/core/plugins/fixGltf.js

@@ -1,3 +1,7 @@
+import {
+    Model
+} from "cesium/Cesium";
+
 var fixGltf = function(gltf) {
 var fixGltf = function(gltf) {
     if (!gltf.extensionsUsed) {
     if (!gltf.extensionsUsed) {
         return;
         return;
@@ -48,7 +52,7 @@ var fixGltf = function(gltf) {
     }
     }
 }
 }
 
 
-Object.defineProperties(Cesium.Model.prototype, {
+Object.defineProperties(Model.prototype, {
     _cachedGltf: {
     _cachedGltf: {
         set: function(value) {
         set: function(value) {
             this._vtxf_cachedGltf = value;
             this._vtxf_cachedGltf = value;

+ 22 - 12
src/core/mvt.js

@@ -1,17 +1,27 @@
-export function createMVTWithStyle(Cesium, ol, createMapboxStreetsV6Style, options) {
+import {
+    defined,
+    defaultValue,
+    when,
+    Resource,
+    defineProperties,
+    WebMercatorTilingScheme,
+    TileReplacementQueue
+} from "cesium/Cesium";
+
+export function renderStyle(ol, createMapboxStreetsV6Style, options) {
     function MVTProvider(options) {
     function MVTProvider(options) {
-        options = Cesium.defaultValue(options, Cesium.defaultValue.EMPTY_OBJECT);
+        options = defaultValue(options, defaultValue.EMPTY_OBJECT);
 
 
-        this._tilingScheme = Cesium.defined(options.tilingScheme) ? options.tilingScheme : new Cesium.WebMercatorTilingScheme({ ellipsoid: options.ellipsoid });
-        this._tileWidth = Cesium.defaultValue(options.tileWidth, 512);
-        this._tileHeight = Cesium.defaultValue(options.tileHeight, 512);
-        this._readyPromise = Cesium.when.resolve(true);
+        this._tilingScheme = defined(options.tilingScheme) ? options.tilingScheme : new WebMercatorTilingScheme({ ellipsoid: options.ellipsoid });
+        this._tileWidth = defaultValue(options.tileWidth, 512);
+        this._tileHeight = defaultValue(options.tileHeight, 512);
+        this._readyPromise = when.resolve(true);
         this._ol = ol;
         this._ol = ol;
         this._mvtParser = new this._ol.format.MVT();
         this._mvtParser = new this._ol.format.MVT();
 
 
         this._styleFun = createMapboxStreetsV6Style;
         this._styleFun = createMapboxStreetsV6Style;
-        this._key = Cesium.defaultValue(options.key, "");
-        this._url = Cesium.defaultValue(options.url, "https://a.tiles.mapbox.com/v4/mapbox.mapbox-streets-v6/{z}/{x}/{y}.vector.pbf?access_token={k}");
+        this._key = defaultValue(options.key, "");
+        this._url = defaultValue(options.url, "https://a.tiles.mapbox.com/v4/mapbox.mapbox-streets-v6/{z}/{x}/{y}.vector.pbf?access_token={k}");
 
 
         var sw = this._tilingScheme._rectangleSouthwestInMeters;
         var sw = this._tilingScheme._rectangleSouthwestInMeters;
         var ne = this._tilingScheme._rectangleNortheastInMeters;
         var ne = this._tilingScheme._rectangleNortheastInMeters;
@@ -23,11 +33,11 @@ export function createMVTWithStyle(Cesium, ol, createMapboxStreetsV6Style, optio
         this._transform = [0.125, 0, 0, 0.125, 0, 0];
         this._transform = [0.125, 0, 0, 0.125, 0, 0];
         this._replays = ["Default", "Image", "Polygon", "LineString", "Text"];
         this._replays = ["Default", "Image", "Polygon", "LineString", "Text"];
 
 
-        this._tileQueue = new Cesium.TileReplacementQueue();
+        this._tileQueue = new TileReplacementQueue();
         this._cacheSize = 1000;
         this._cacheSize = 1000;
     }
     }
 
 
-    Cesium.defineProperties(MVTProvider.prototype, {
+    defineProperties(MVTProvider.prototype, {
         proxy: {
         proxy: {
             get: function() {
             get: function() {
                 return undefined;
                 return undefined;
@@ -148,7 +158,7 @@ export function createMVTWithStyle(Cesium, ol, createMapboxStreetsV6Style, optio
     function trimTiles(tileQueue, maximumTiles) {
     function trimTiles(tileQueue, maximumTiles) {
         var tileToTrim = tileQueue.tail;
         var tileToTrim = tileQueue.tail;
         while (tileQueue.count > maximumTiles &&
         while (tileQueue.count > maximumTiles &&
-            Cesium.defined(tileToTrim)) {
+            defined(tileToTrim)) {
             var previous = tileToTrim.replacementPrevious;
             var previous = tileToTrim.replacementPrevious;
 
 
             remove(tileQueue, tileToTrim);
             remove(tileQueue, tileToTrim);
@@ -178,7 +188,7 @@ export function createMVTWithStyle(Cesium, ol, createMapboxStreetsV6Style, optio
 
 
                 try {
                 try {
 
 
-                    var resource = Cesium.Resource.createIfNeeded(url);
+                    var resource = Resource.createIfNeeded(url);
                     arrayBuffer = await resource.fetchArrayBuffer()
                     arrayBuffer = await resource.fetchArrayBuffer()
                 } catch (ex) {
                 } catch (ex) {
                     arrayBuffer = new ArrayBuffer(0)
                     arrayBuffer = new ArrayBuffer(0)

+ 40 - 19
src/core/viewer.js

@@ -1,7 +1,22 @@
+import {
+    UrlTemplateImageryProvider,
+    WebMapTileServiceImageryProvider,
+    GeographicTilingScheme,
+    Viewer,
+    ScreenSpaceEventHandler,
+    Cesium3DTileset,
+    SceneMode,
+    formatError,
+    Cartesian3,
+    Rectangle
+} from "cesium/Cesium";
+import CesiumNavigation from "./plugins/cesium-navigation-es6";
+import HeatmapImageryProvider from './plugins/HeatmapImageryProvider'
+
 import './plugins/fixGltf'
 import './plugins/fixGltf'
-import './plugins/HeatmapImageryProvider'
+
 import './plugins/SpirographPositionProperty'
 import './plugins/SpirographPositionProperty'
-import { createMVTWithStyle } from './mvt'
+import { renderStyle } from './plugins/mvt'
 
 
 import {
 import {
     drawRectangle
     drawRectangle
@@ -15,12 +30,12 @@ function main() {
     var viewer;
     var viewer;
     try {
     try {
 
 
-        var Google = new Cesium.UrlTemplateImageryProvider({
+        var Google = new UrlTemplateImageryProvider({
             url: "http://mt3.google.cn/vt/lyrs=y@110&hl=zh-CN&gl=cn&src=app&x={x}&y={y}&z={z}&s=Ga",
             url: "http://mt3.google.cn/vt/lyrs=y@110&hl=zh-CN&gl=cn&src=app&x={x}&y={y}&z={z}&s=Ga",
         })
         })
 
 
         //天地图影像服务
         //天地图影像服务
-        var tdtImagerLayerProvider = new Cesium.WebMapTileServiceImageryProvider({
+        var tdtImagerLayerProvider = new WebMapTileServiceImageryProvider({
             url: "http://{s}.tianditu.gov.cn/img_c/wmts?tk=463a3e5ee4e35c17ae02564f18f95655&service=wmts&request=GetTile&version=1.0.0" +
             url: "http://{s}.tianditu.gov.cn/img_c/wmts?tk=463a3e5ee4e35c17ae02564f18f95655&service=wmts&request=GetTile&version=1.0.0" +
                 "&LAYER=img&tileMatrixSet=c&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}" +
                 "&LAYER=img&tileMatrixSet=c&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}" +
                 "&style=default&format=tiles",
                 "&style=default&format=tiles",
@@ -29,14 +44,14 @@ function main() {
             format: "tiles",
             format: "tiles",
             tileMatrixSetID: "c",
             tileMatrixSetID: "c",
             subdomains: ["t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7"],
             subdomains: ["t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7"],
-            tilingScheme: new Cesium.GeographicTilingScheme(),
+            tilingScheme: new GeographicTilingScheme(),
             tileMatrixLabels: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19"],
             tileMatrixLabels: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19"],
             maximumLevel: 18,
             maximumLevel: 18,
             show: false
             show: false
         })
         })
 
 
 
 
-        var PBF = createMVTWithStyle(Cesium, ol, createMapboxStreetsV6Style, {
+        var PBF = renderStyle(ol, createMapboxStreetsV6Style, {
             url: 'pbf/{z}/{x}/{y}.pbf',
             url: 'pbf/{z}/{x}/{y}.pbf',
             key: "pk.eyJ1IjoibXV5YW8xOTg3IiwiYSI6ImNpcm9ueHd6cjAwNzZoa20xazY1aWlubjIifQ.5tLtC5j1rh8Eqjlyrq3OaA"
             key: "pk.eyJ1IjoibXV5YW8xOTg3IiwiYSI6ImNpcm9ueHd6cjAwNzZoa20xazY1aWlubjIifQ.5tLtC5j1rh8Eqjlyrq3OaA"
         });
         });
@@ -44,7 +59,7 @@ function main() {
         
         
 
 
 
 
-        viewer = window.viewer = new Cesium.Viewer('cesiumContainer', {
+        viewer = window.viewer = new Viewer('cesiumContainer', {
             resolutionScale: 1,
             resolutionScale: 1,
             terrainProviderViewModels: [],
             terrainProviderViewModels: [],
             animation: false, //动画控制不显示     
             animation: false, //动画控制不显示     
@@ -63,7 +78,13 @@ function main() {
             imageryProvider: tdtImagerLayerProvider,
             imageryProvider: tdtImagerLayerProvider,
         });
         });
 
 
-        viewer.extend(Cesium.viewerCesiumNavigationMixin, {});
+        CesiumNavigation(viewer, {
+           // defaultResetView : Rectangle.fromDegrees(80, 22, 130, 50),
+            enableCompass:true,
+            enableZoomControls:true,
+            enableDistanceLegend:true,
+            enableCompassOuterRing:true
+        });
 
 
         //viewer.scene.debugShowFramesPerSecond = true;
         //viewer.scene.debugShowFramesPerSecond = true;
         //viewer.scene.screenSpaceCameraController.enableTranslate = false;
         //viewer.scene.screenSpaceCameraController.enableTranslate = false;
@@ -76,7 +97,7 @@ function main() {
 
 
 
 
         viewer.camera.setView({
         viewer.camera.setView({
-            destination: Cesium.Cartesian3.fromDegrees(113.07242100, 22.58652789, 1000.0),
+            destination: Cartesian3.fromDegrees(113.07242100, 22.58652789, 1000.0),
             orientation: {
             orientation: {
                 heading: 5.205384767667713,
                 heading: 5.205384767667713,
                 pitch: -1.0220630084744524,
                 pitch: -1.0220630084744524,
@@ -85,7 +106,7 @@ function main() {
         })
         })
 
 
 
 
-        var heatmap = new Cesium.HeatmapImageryProvider({
+        var heatmap = new HeatmapImageryProvider({
             data: points2,
             data: points2,
             heatmapoptions: {
             heatmapoptions: {
                 radius: 30,
                 radius: 30,
@@ -98,15 +119,15 @@ function main() {
 
 
         viewer.imageryLayers.addImageryProvider(heatmap)
         viewer.imageryLayers.addImageryProvider(heatmap)
 
 
-        var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
+        var handler = new ScreenSpaceEventHandler(viewer.scene.canvas);
 
 
-        drawRectangle(Cesium, viewer, handler, function(coords) {
-            console.log(coords)
-            var heatMap1 = createHeatMap(getData(1000).max, getData(1000).data);
-            createRectangle(viewer, [coords.west, coords.south, coords.east, coords.north], heatMap1);
-        });
+        // drawRectangle(Cesium, viewer, handler, function(coords) {
+        //     console.log(coords)
+        //     var heatMap1 = createHeatMap(getData(1000).max, getData(1000).data);
+        //     createRectangle(viewer, [coords.west, coords.south, coords.east, coords.north], heatMap1);
+        // });
 
 
-        var tileset = viewer.scene.primitives.add(new Cesium.Cesium3DTileset({
+        var tileset = viewer.scene.primitives.add(new Cesium3DTileset({
             url: "/static/tiles/temp/tileset.json", //Cesium.IonResource.fromAssetId(item) //'static/tiles/tileset.json'
             url: "/static/tiles/temp/tileset.json", //Cesium.IonResource.fromAssetId(item) //'static/tiles/tileset.json'
             //maximumMemoryUsage:200
             //maximumMemoryUsage:200
             maximumScreenSpaceError: 25,
             maximumScreenSpaceError: 25,
@@ -128,7 +149,7 @@ function main() {
 
 
         viewer.camera.changed.addEventListener(
         viewer.camera.changed.addEventListener(
             function() {
             function() {
-                if (viewer.camera._suspendTerrainAdjustment && viewer.scene.mode === Cesium.SceneMode.SCENE3D) {
+                if (viewer.camera._suspendTerrainAdjustment && viewer.scene.mode === SceneMode.SCENE3D) {
                     viewer.camera._suspendTerrainAdjustment = false;
                     viewer.camera._suspendTerrainAdjustment = false;
                     viewer.camera._adjustHeightForTerrain();
                     viewer.camera._adjustHeightForTerrain();
                 }
                 }
@@ -138,7 +159,7 @@ function main() {
 
 
     } catch (exception) {
     } catch (exception) {
         $loadingIndicator.style.display = 'none';
         $loadingIndicator.style.display = 'none';
-        var message = Cesium.formatError(exception);
+        var message = formatError(exception);
         console.error(message);
         console.error(message);
         if (!document.querySelector('.cesium-widget-errorPanel')) {
         if (!document.querySelector('.cesium-widget-errorPanel')) {
             window.alert(message); //eslint-disable-line no-alert
             window.alert(message); //eslint-disable-line no-alert

+ 42 - 17
vue.config.js

@@ -1,26 +1,51 @@
 const path = require('path')
 const path = require('path')
+const webpack = require('webpack')
+const CopyWebpackPlugin = require('copy-webpack-plugin')
+const CompressionPlugin = require("compression-webpack-plugin")
+let cesiumSource = './node_modules/cesium/Source'
+let cesiumWorkers = '../Build/Cesium/Workers'
+
+
+const plugins = []
 
 
 module.exports = {
 module.exports = {
     assetsDir: process.env.VUE_APP_STATIC_URL,
     assetsDir: process.env.VUE_APP_STATIC_URL,
     publicPath: process.env.NODE_ENV === 'production' ? '' : '',
     publicPath: process.env.NODE_ENV === 'production' ? '' : '',
     productionSourceMap: false,
     productionSourceMap: false,
-    configureWebpack: {
-        externals: {
-            three: 'THREE',
-        },
-        // resolve: {
-        //     extensions: ['.js', '.vue', '.json'],
-        //     alias: {
-        //         '@': path.join(__dirname,'src')
-        //     }
-        // },
-    },
-    css: {
-        loaderOptions: {
-            less:{
-                globalVars:{
-                    color:'#05c8ae'
+    configureWebpack: config => {
+        if (process.env.NODE_ENV === 'production') {
+            plugins.push(new CompressionPlugin({
+                test: /\.js$|\.html$|.\css/, //匹配文件名
+                threshold: 10240, //对超过10k的数据压缩
+                deleteOriginalAssets: false //不删除源文件
+            }))
+        }
+        return {
+            amd: {
+                toUrlUndefined: true
+            },
+            output: {
+                sourcePrefix: ' '
+            },
+            resolve: {
+                alias: {
+                    'vue$': 'vue/dist/vue.esm.js',
+                    '@': path.resolve('src'),
+                    'cesium': path.resolve(__dirname, cesiumSource)
                 }
                 }
+            },
+            plugins: [
+                new CopyWebpackPlugin([{ from: path.join(cesiumSource, cesiumWorkers), to: 'Workers' }]),
+                new CopyWebpackPlugin([{ from: path.join(cesiumSource, 'Assets'), to: 'Assets' }]),
+                new CopyWebpackPlugin([{ from: path.join(cesiumSource, 'Widgets'), to: 'Widgets' }]),
+                new CopyWebpackPlugin([{ from: path.join(cesiumSource, 'ThirdParty/Workers'), to: 'ThirdParty/Workers' }]),
+                new webpack.DefinePlugin({
+                    CESIUM_BASE_URL: JSON.stringify('./')
+                })
+            ].concat(plugins),
+            module: {
+                unknownContextCritical: /^.\/.*$/,
+                unknownContextCritical: false // 6
             }
             }
         }
         }
     },
     },
@@ -28,6 +53,6 @@ module.exports = {
         proxy: 'http://192.168.0.248:8082',
         proxy: 'http://192.168.0.248:8082',
     },
     },
     chainWebpack: config => {
     chainWebpack: config => {
-
+        
     }
     }
 }
 }