| @@ -11,20 +11,10 @@ import { | |||
| SceneEvent | |||
| } from '../event' | |||
| import { ViewerOption, CameraOption } from '../option' | |||
| import { | |||
| Attribution, | |||
| ContextMenu, | |||
| LocationBar, | |||
| MapSplit, | |||
| MapSwitch, | |||
| Popup, | |||
| Tooltip, | |||
| HawkeyeMap, | |||
| Compass | |||
| } from '../widget' | |||
| import { DomUtil } from '../utils' | |||
| import Transform from '../transform/Transform' | |||
| import Parse from '../parse/Parse' | |||
| import widget from '../widget' | |||
| const { Cesium } = DC.Namespace | |||
| @@ -80,22 +70,10 @@ class Viewer { | |||
| this._layerCache = {} | |||
| /** | |||
| * Adds default components | |||
| * Adds default widgets | |||
| */ | |||
| this._comps = { | |||
| popup: new Popup(), | |||
| contextMenu: new ContextMenu(), | |||
| tooltip: new Tooltip(), | |||
| mapSwitch: new MapSwitch(), | |||
| mapSplit: new MapSplit(), | |||
| locationBar: new LocationBar(), | |||
| hawkeyeMap: new HawkeyeMap(), | |||
| compass: new Compass(), | |||
| attribution: new Attribution() | |||
| } | |||
| Object.keys(this._comps).forEach(key => { | |||
| this.use(this._comps[key]) | |||
| Object.keys(widget).forEach(key => { | |||
| this.use(widget[key]) | |||
| }) | |||
| } | |||
| @@ -139,38 +117,6 @@ class Viewer { | |||
| return this._viewerEvent | |||
| } | |||
| get popup() { | |||
| return this._comps.popup | |||
| } | |||
| get contextMenu() { | |||
| return this._comps.contextMenu | |||
| } | |||
| get tooltip() { | |||
| return this._comps.tooltip | |||
| } | |||
| get mapSplit() { | |||
| return this._comps.mapSplit | |||
| } | |||
| get mapSwitch() { | |||
| return this._comps.mapSwitch | |||
| } | |||
| get locationBar() { | |||
| return this._comps.locationBar | |||
| } | |||
| get hawkeyeMap() { | |||
| return this._comps.hawkeyeMap | |||
| } | |||
| get compass() { | |||
| return this._comps.compass | |||
| } | |||
| get cameraPosition() { | |||
| let position = Transform.transformCartesianToWGS84(this.camera.positionWC) | |||
| if (position) { | |||
| @@ -325,7 +271,7 @@ class Viewer { | |||
| if (!this._baseLayerPicker.selectedImagery) { | |||
| this._baseLayerPicker.selectedImagery = this._baseLayerPicker.imageryProviderViewModels[0] | |||
| } | |||
| this._comps.mapSwitch.addMap(options) | |||
| this.mapSwitch.addMap(options) | |||
| return this | |||
| } | |||
| @@ -37,6 +37,10 @@ class Compass extends Widget { | |||
| * @private | |||
| */ | |||
| _installHook() { | |||
| Object.defineProperty(this._viewer, 'compass', { | |||
| value: this, | |||
| writable: false | |||
| }) | |||
| this._wrapper.onmousedown = e => { | |||
| this._handleMouseDown(e) | |||
| } | |||
| @@ -25,6 +25,17 @@ class ContextMenu extends Widget { | |||
| return this | |||
| } | |||
| /** | |||
| * | |||
| * @private | |||
| */ | |||
| _installHook() { | |||
| Object.defineProperty(this._viewer, 'contextMenu', { | |||
| value: this, | |||
| writable: false | |||
| }) | |||
| } | |||
| /** | |||
| * | |||
| * @private | |||
| @@ -0,0 +1,141 @@ | |||
| /** | |||
| * @Author: Caven | |||
| * @Date: 2020-12-09 20:54:06 | |||
| */ | |||
| import { DomUtil } from '../utils' | |||
| import { SceneEventType } from '../event' | |||
| import State from '../state/State' | |||
| import Widget from './Widget' | |||
| const { Cesium } = DC.Namespace | |||
| const geodesic = new Cesium.EllipsoidGeodesic() | |||
| const BASE = [1, 2, 3, 5] | |||
| const DIS = [ | |||
| ...BASE, | |||
| ...BASE.map(item => item * 10), | |||
| ...BASE.map(item => item * 100), | |||
| ...BASE.map(item => item * 1000), | |||
| ...BASE.map(item => item * 10000), | |||
| ...BASE.map(item => item * 100000), | |||
| ...BASE.map(item => item * 1000000) | |||
| ] | |||
| class DistanceLegend extends Widget { | |||
| constructor() { | |||
| super() | |||
| this._wrapper = DomUtil.create('div', 'dc-distance-legend') | |||
| this._labelEl = undefined | |||
| this._scaleBar = undefined | |||
| this._lastUpdate = Cesium.getTimestamp() | |||
| this.type = Widget.getWidgetType('distance_legend') | |||
| this._state = State.INITIALIZED | |||
| } | |||
| /** | |||
| * | |||
| * @private | |||
| */ | |||
| _installHook() { | |||
| Object.defineProperty(this._viewer, 'distanceLegend', { | |||
| value: this, | |||
| writable: false | |||
| }) | |||
| } | |||
| /** | |||
| * | |||
| * @private | |||
| */ | |||
| _bindEvent() { | |||
| this._viewer.on( | |||
| SceneEventType.POST_RENDER, | |||
| this._updateDistanceLegend, | |||
| this | |||
| ) | |||
| } | |||
| /** | |||
| * | |||
| * @private | |||
| */ | |||
| _unbindEvent() { | |||
| this._viewer.off( | |||
| SceneEventType.POST_RENDER, | |||
| this._updateDistanceLegend, | |||
| this | |||
| ) | |||
| } | |||
| /** | |||
| * | |||
| * @param scene | |||
| * @param time | |||
| * @returns | |||
| * @private | |||
| */ | |||
| _updateDistanceLegend(scene, time) { | |||
| let now = Cesium.getTimestamp() | |||
| if (now < this._lastUpdate + 250) { | |||
| return | |||
| } | |||
| if (!this._labelEl || !this._scaleBar) { | |||
| return | |||
| } | |||
| this._lastUpdate = now | |||
| let width = scene.canvas.width | |||
| let height = scene.canvas.height | |||
| let left = scene.camera.getPickRay( | |||
| new Cesium.Cartesian2((width / 2) | 0, height - 1) | |||
| ) | |||
| let right = scene.camera.getPickRay( | |||
| new Cesium.Cartesian2((1 + width / 2) | 0, height - 1) | |||
| ) | |||
| let leftPosition = scene.globe.pick(left, scene) | |||
| let rightPosition = scene.globe.pick(right, scene) | |||
| if (!leftPosition || !rightPosition) { | |||
| return | |||
| } | |||
| geodesic.setEndPoints( | |||
| scene.globe.ellipsoid.cartesianToCartographic(leftPosition), | |||
| scene.globe.ellipsoid.cartesianToCartographic(rightPosition) | |||
| ) | |||
| let pixelDistance = geodesic.surfaceDistance | |||
| let maxBarWidth = 100 | |||
| let distance = 0 | |||
| for (let i = DIS.length - 1; i >= 0; --i) { | |||
| if (DIS[i] / pixelDistance < maxBarWidth) { | |||
| distance = DIS[i] | |||
| break | |||
| } | |||
| } | |||
| if (distance) { | |||
| this._labelEl.innerHTML = | |||
| distance >= 1000 ? `${distance / 1000} km` : `${distance} m` | |||
| let barWidth = (distance / pixelDistance) | 0 | |||
| this._scaleBar.style.cssText = `width: ${barWidth}px; left: ${(125 - | |||
| barWidth) / | |||
| 2}px;` | |||
| } else { | |||
| this._labelEl.style.cssText = 'display:none' | |||
| this._scaleBar.style.cssText = 'display:none' | |||
| } | |||
| } | |||
| /** | |||
| * | |||
| * @private | |||
| */ | |||
| _mountContent() { | |||
| this._labelEl = DomUtil.create('div', 'label', this._wrapper) | |||
| this._scaleBar = DomUtil.create('div', 'scale-bar', this._wrapper) | |||
| this._ready = true | |||
| } | |||
| } | |||
| Widget.registerType('distance_legend') | |||
| export default DistanceLegend | |||
| @@ -69,18 +69,39 @@ class HawkeyeMap extends Widget { | |||
| this._ready = true | |||
| } | |||
| /** | |||
| * | |||
| * @private | |||
| */ | |||
| _bindEvent() { | |||
| this._viewer.on(SceneEventType.CAMERA_CHANGED, this._syncMap, this) | |||
| } | |||
| /** | |||
| * | |||
| * @private | |||
| */ | |||
| _unbindEvent() { | |||
| this._viewer.off(SceneEventType.CAMERA_CHANGED, this._syncMap, this) | |||
| } | |||
| /** | |||
| * | |||
| * @private | |||
| */ | |||
| _installHook() { | |||
| Object.defineProperty(this._viewer, 'hawkeyeMap', { | |||
| value: this, | |||
| writable: false | |||
| }) | |||
| this._viewer.camera.percentageChanged = 0.01 | |||
| } | |||
| /** | |||
| * | |||
| * @returns {boolean} | |||
| * @private | |||
| */ | |||
| _syncMap() { | |||
| let viewCenter = new Cesium.Cartesian2( | |||
| Math.floor(this._viewer.canvas.clientWidth / 2), | |||
| @@ -20,6 +20,17 @@ class LocationBar extends Widget { | |||
| this._state = State.INITIALIZED | |||
| } | |||
| /** | |||
| * | |||
| * @private | |||
| */ | |||
| _installHook() { | |||
| Object.defineProperty(this._viewer, 'locationBar', { | |||
| value: this, | |||
| writable: false | |||
| }) | |||
| } | |||
| /** | |||
| * | |||
| * @private | |||
| @@ -20,6 +20,17 @@ class MapSplit extends Widget { | |||
| this._state = State.INITIALIZED | |||
| } | |||
| /** | |||
| * | |||
| * @private | |||
| */ | |||
| _installHook() { | |||
| Object.defineProperty(this._viewer, 'mapSplit', { | |||
| value: this, | |||
| writable: false | |||
| }) | |||
| } | |||
| /** | |||
| * | |||
| * @private | |||
| @@ -32,6 +32,10 @@ class MapSwitch extends Widget { | |||
| * @private | |||
| */ | |||
| _installHook() { | |||
| Object.defineProperty(this._viewer, 'mapSwitch', { | |||
| value: this, | |||
| writable: false | |||
| }) | |||
| this.enable = true | |||
| let self = this | |||
| this._wrapper.onmouseover = () => { | |||
| @@ -38,6 +38,10 @@ class Popup extends Widget { | |||
| */ | |||
| _installHook() { | |||
| this.enable = true | |||
| Object.defineProperty(this._viewer, 'popup', { | |||
| value: this, | |||
| writable: false | |||
| }) | |||
| } | |||
| _updateWindowCoord(windowCoord) { | |||
| @@ -16,6 +16,17 @@ class Tooltip extends Widget { | |||
| this._state = State.INITIALIZED | |||
| } | |||
| /** | |||
| * | |||
| * @private | |||
| */ | |||
| _installHook() { | |||
| Object.defineProperty(this._viewer, 'tooltip', { | |||
| value: this, | |||
| writable: false | |||
| }) | |||
| } | |||
| /** | |||
| * | |||
| * @param {*} windowCoord | |||
| @@ -3,12 +3,26 @@ | |||
| * @Date: 2020-03-05 21:53:35 | |||
| */ | |||
| export { default as Attribution } from './Attribution' | |||
| export { default as ContextMenu } from './ContextMenu' | |||
| export { default as LocationBar } from './LocationBar' | |||
| export { default as MapSplit } from './MapSplit' | |||
| export { default as MapSwitch } from './MapSwitch' | |||
| export { default as Popup } from './Popup' | |||
| export { default as Tooltip } from './Tooltip' | |||
| export { default as HawkeyeMap } from './HawkeyeMap' | |||
| export { default as Compass } from './Compass' | |||
| import Attribution from './Attribution' | |||
| import ContextMenu from './ContextMenu' | |||
| import LocationBar from './LocationBar' | |||
| import MapSplit from './MapSplit' | |||
| import MapSwitch from './MapSwitch' | |||
| import Popup from './Popup' | |||
| import Tooltip from './Tooltip' | |||
| import HawkeyeMap from './HawkeyeMap' | |||
| import Compass from './Compass' | |||
| import DistanceLegend from './DistanceLegend' | |||
| export default { | |||
| attribution: new Attribution(), | |||
| popup: new Popup(), | |||
| contextMenu: new ContextMenu(), | |||
| tooltip: new Tooltip(), | |||
| mapSwitch: new MapSwitch(), | |||
| mapSplit: new MapSplit(), | |||
| locationBar: new LocationBar(), | |||
| hawkeyeMap: new HawkeyeMap(), | |||
| compass: new Compass(), | |||
| distanceLegend: new DistanceLegend() | |||
| } | |||
| @@ -0,0 +1,23 @@ | |||
| .dc-distance-legend{ | |||
| position: absolute; | |||
| left: 120px; | |||
| bottom: 2px; | |||
| width: 125px; | |||
| height: 25px; | |||
| user-select: none; | |||
| .label{ | |||
| font-size: 14px; | |||
| color: rgb(255, 255, 255); | |||
| text-align: center; | |||
| width: 100%; | |||
| font-weight: lighter; | |||
| } | |||
| .scale-bar{ | |||
| position: absolute; | |||
| height: 10px; | |||
| top: 10px; | |||
| border-left: 1px solid rgb(255, 255, 255); | |||
| border-right: 1px solid rgb(255, 255, 255); | |||
| border-bottom: 1px solid rgb(255, 255, 255); | |||
| } | |||
| } | |||
| @@ -13,3 +13,4 @@ import './mapsplit.scss' | |||
| import './hawkeyemap.scss' | |||
| import './compass.scss' | |||
| import './locationbar.scss' | |||
| import './distancelegend.scss' | |||
| @@ -1,6 +1,6 @@ | |||
| .dc-location-bar { | |||
| position: absolute; | |||
| left: 180px; | |||
| left: 270px; | |||
| bottom: 2px; | |||
| font-size: 14px; | |||
| color: rgb(255, 255, 255); | |||