| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699 |
- /**
- * @Author: Caven
- * @Date: 2019-12-27 17:13:24
- */
-
- import { Cesium } from '@dc-modules/namespace'
- import Parse from '@dc-modules/parse/Parse'
- import {
- LayerGroupEventType,
- LayerEventType,
- MouseEvent,
- ViewerEvent,
- SceneEvent
- } from '@dc-modules/event'
- import { ViewerOption, CameraOption } from '@dc-modules/option'
- import { Util, DomUtil } from '@dc-modules/utils'
- import { Transform } from '@dc-modules/transform'
- import createWidgets from '@dc-modules/widget'
- import createTools from '@dc-modules/tools'
-
- const DEF_OPTS = {
- animation: false, //Whether to create animated widgets, lower left corner of the meter
- baseLayerPicker: false, //Whether to display the layer selector
- imageryProvider: false, // Whether to display the default imagery
- fullscreenButton: false, //Whether to display the full-screen button
- geocoder: false, //To display the geocoder widget, query the button in the upper right corner
- homeButton: false, //Whether to display the Home button
- infoBox: false, //Whether to display the information box
- sceneModePicker: false, //Whether to display 3D/2D selector
- selectionIndicator: false, //Whether to display the selection indicator component
- timeline: false, //Whether to display the timeline
- navigationHelpButton: false, //Whether to display the help button in the upper right corner
- navigationInstructionsInitiallyVisible: false,
- creditContainer: undefined,
- shouldAnimate: true
- }
-
- class Viewer {
- constructor(id, options = {}) {
- if (!id || (typeof id === 'string' && !document.getElementById(id))) {
- throw new Error('Viewer:the id is empty')
- }
-
- this._delegate = new Cesium.Viewer(id, {
- ...DEF_OPTS,
- ...options
- }) // Initialize the viewer
-
- /**
- * Registers events
- */
- new MouseEvent(this) // Register global mouse events
- this._viewerEvent = new ViewerEvent() // Register viewer events
- this._sceneEvent = new SceneEvent(this) // Register scene events
-
- this._viewerOption = new ViewerOption(this) // Initialize the viewer option
- this._cameraOption = new CameraOption(this) // Initialize the camera option
-
- this._dcContainer = DomUtil.create(
- 'div',
- 'dc-container',
- typeof id === 'string' ? document.getElementById(id) : id
- ) //Register the custom container
-
- this._baseLayerPicker = new Cesium.BaseLayerPickerViewModel({
- globe: this._delegate.scene.globe
- }) //Initialize the baseLayer picker
-
- this._layerGroupCache = {}
- this._layerCache = {}
-
- /**
- * Registers default widgets
- */
- let widgets = createWidgets()
- Object.keys(widgets).forEach(key => {
- this.use(widgets[key])
- })
-
- /**
- * Registers default tools
- */
- let tools = createTools()
- Object.keys(tools).forEach(key => {
- this.use(tools[key])
- })
- }
-
- get delegate() {
- return this._delegate
- }
-
- get dcContainer() {
- return this._dcContainer
- }
-
- get scene() {
- return this._delegate.scene
- }
-
- get camera() {
- return this._delegate.camera
- }
-
- get canvas() {
- return this._delegate.scene.canvas
- }
-
- get dataSources() {
- return this._delegate.dataSources
- }
-
- get imageryLayers() {
- return this._delegate.imageryLayers
- }
-
- get terrainProvider() {
- return this._delegate.terrainProvider
- }
-
- get entities() {
- return this._delegate.entities
- }
-
- get postProcessStages() {
- return this._delegate.scene.postProcessStages
- }
-
- get clock() {
- return this._delegate.clock
- }
-
- get viewerEvent() {
- return this._viewerEvent
- }
-
- get cameraPosition() {
- let position = Transform.transformCartesianToWGS84(this.camera.positionWC)
- if (position) {
- position.heading = Cesium.Math.toDegrees(this.camera.heading)
- position.pitch = Cesium.Math.toDegrees(this.camera.pitch)
- position.roll = Cesium.Math.toDegrees(this.camera.roll)
- }
- return position
- }
-
- get resolution() {
- let width = this.scene.canvas.width
- let height = this.scene.canvas.height
- let min = Transform.transformWindowToWGS84(
- new Cesium.Cartesian2((width / 2) | 0, height - 1),
- this
- )
- let max = Transform.transformWindowToWGS84(
- new Cesium.Cartesian2((1 + width / 2) | 0, height - 1),
- this
- )
- if (!min || !max) {
- return 1
- }
- return Math.abs(min.lng - max.lng)
- }
-
- get viewBounds() {
- let width = this.scene.canvas.width
- let height = this.scene.canvas.height
- let min = Transform.transformWindowToWGS84(
- new Cesium.Cartesian2(0, height),
- this
- )
- let max = Transform.transformWindowToWGS84(
- new Cesium.Cartesian2(width, 0),
- this
- )
- if (!min || !max) {
- return Cesium.Rectangle.MAX_VALUE
- }
- return Cesium.Rectangle.fromDegrees(min.lng, min.lat, max.lng, max.lat)
- }
-
- get level() {
- return this._delegate.scene.globe._surface._debug.maxDepthVisited
- }
-
- /***
- *
- * @param layerGroup
- * @private
- */
- _addLayerGroup(layerGroup) {
- if (
- layerGroup?.layerGroupEvent &&
- !Object(this._layerGroupCache).hasOwnProperty(layerGroup.id)
- ) {
- layerGroup.layerGroupEvent.fire(LayerGroupEventType.ADD, this)
- this._layerGroupCache[layerGroup.id] = layerGroup
- }
- }
-
- /**
- *
- * @param layerGroup
- * @private
- */
- _removeLayerGroup(layerGroup) {
- if (
- layerGroup?.layerGroupEvent &&
- Object(this._layerGroupCache).hasOwnProperty(layerGroup.id)
- ) {
- layerGroup.layerGroupEvent.fire(LayerGroupEventType.REMOVE, this)
- delete this._layerGroupCache[layerGroup.id]
- }
- }
-
- /**
- * @param layer
- * @private
- */
- _addLayer(layer) {
- !this._layerCache[layer.type] && (this._layerCache[layer.type] = {})
- if (!Object(this._layerCache[layer.type]).hasOwnProperty(layer.id)) {
- layer.fire(LayerEventType.ADD, this)
- this._layerCache[layer.type][layer.id] = layer
- }
- }
-
- /**
- * @param layer
- * @private
- */
- _removeLayer(layer) {
- if (Object(this._layerCache[layer.type]).hasOwnProperty(layer.id)) {
- layer.fire(LayerEventType.REMOVE, this)
- delete this._layerCache[layer.type][layer.id]
- }
- }
-
- /**
- * Sets viewer options
- * @param options
- * @returns {Viewer}
- */
- setOptions(options) {
- this._viewerOption.setOptions(options)
- return this
- }
-
- /**
- * Sets camera pitch range
- * @param min
- * @param max
- * @returns {Viewer}
- */
- setPitchRange(min = -90, max = -20) {
- this._cameraOption.setPitchRange(min, max)
- return this
- }
-
- /**
- * @param west
- * @param south
- * @param east
- * @param north
- * @returns {Viewer}
- */
- setBounds(west, south, east, north) {
- this._cameraOption.setBounds(west, south, east, north)
- return this
- }
-
- /**
- * Changes Scene Mode,2:2D,2.5:2.5D,3:3D
- * @param sceneMode
- * @param duration
- * @returns {Viewer}
- */
- changeSceneMode(sceneMode, duration = 0) {
- if (sceneMode === 2) {
- this._delegate.scene.morphTo2D(duration)
- } else if (sceneMode === 3) {
- this._delegate.scene.morphTo3D(duration)
- } else if (sceneMode === 2.5) {
- this._delegate.scene.morphToColumbusView(duration)
- }
- return this
- }
-
- /**
- * Changes Mouse Mode,0:Default,1: Change the tiltEventTypes to CameraEventType.RIGHT_DRAG
- * @param mouseMode
- * @returns {Viewer}
- */
- changeMouseMode(mouseMode) {
- this._cameraOption.changeMouseMode(mouseMode)
- return this
- }
-
- /**
- * Adds the baseLayer .
- * The baseLayer can be a single or an array,
- * and when the baseLayer is an array, the baseLayer will be loaded together
- * @param baseLayers
- * @param options
- * @returns {Viewer}
- */
- addBaseLayer(baseLayers, options = {}) {
- if (!baseLayers) {
- return this
- }
- this._baseLayerPicker.imageryProviderViewModels.push(
- new Cesium.ProviderViewModel({
- name: options.name || '地图',
- tooltip: options.tooltip || '地图',
- iconUrl: '',
- creationFunction: () => {
- return baseLayers
- }
- })
- )
- if (!this._baseLayerPicker.selectedImagery) {
- this._baseLayerPicker.selectedImagery = this._baseLayerPicker.imageryProviderViewModels[0]
- }
- this.mapSwitch && this.mapSwitch.addMap(options)
- return this
- }
-
- /**
- * Changes the current globe display of the baseLayer
- * @param index
- * @returns {Viewer}
- */
- changeBaseLayer(index) {
- if (this._baseLayerPicker && index >= 0) {
- this._baseLayerPicker.selectedImagery = this._baseLayerPicker.imageryProviderViewModels[
- index
- ]
- }
- return this
- }
-
- /**
- *
- * @param windowPosition
- * @returns {Promise}
- */
- getImageryLayerInfo(windowPosition) {
- let ray = this._delegate.camera.getPickRay(windowPosition)
- return this._delegate.imageryLayers.pickImageryLayerFeatures(
- ray,
- this._delegate.scene
- )
- }
-
- /**
- * Adds the terrain
- * @param terrain
- * @param options
- * @returns {Viewer}
- */
- addTerrain(terrain, options = {}) {
- if (!terrain) {
- return this
- }
- this._baseLayerPicker.terrainProviderViewModels.push(
- new Cesium.ProviderViewModel({
- name: options.name || '地形',
- creationFunction: () => {
- return terrain
- }
- })
- )
- if (!this._baseLayerPicker.selectedTerrain) {
- this._baseLayerPicker.selectedTerrain = this._baseLayerPicker.terrainProviderViewModels[0]
- }
- return this
- }
-
- /**
- * Changes the current globe display of the terrain
- * @param index
- * @returns {Viewer}
- */
- changeTerrain(index) {
- if (this._baseLayerPicker && index >= 0) {
- this._baseLayerPicker.selectedTerrain = this._baseLayerPicker.terrainProviderViewModels[
- index
- ]
- }
- return this
- }
-
- /**
- * Removes terrain
- * @returns {Viewer}
- */
- removeTerrain() {
- this._baseLayerPicker.terrainProviderViewModels = []
- this._baseLayerPicker.selectedTerrain = undefined
- this._delegate.terrainProvider = new Cesium.EllipsoidTerrainProvider()
- return this
- }
-
- /**
- *
- * @param layerGroup
- * @returns {Viewer}
- */
- addLayerGroup(layerGroup) {
- this._addLayerGroup(layerGroup)
- return this
- }
-
- /**
- *
- * @param layerGroup
- * @returns {Viewer}
- */
- removeLayerGroup(layerGroup) {
- this._removeLayerGroup(layerGroup)
- return this
- }
-
- /**
- *
- * @param id
- * @returns {undefined}
- */
- getLayerGroup(id) {
- return this._layerGroupCache[id] || undefined
- }
-
- /**
- * add a layer
- * @param layer
- * @returns {Viewer}
- */
- addLayer(layer) {
- this._addLayer(layer)
- return this
- }
-
- /**
- * Removes a layer
- * @param layer
- * @returns {Viewer}
- */
- removeLayer(layer) {
- this._removeLayer(layer)
- return this
- }
-
- /**
- * Checks to see if the layer is included
- * @param layer
- * @returns {boolean}
- */
- hasLayer(layer) {
- return Object(this._layerCache[layer.type]).hasOwnProperty(layer.id)
- }
-
- /**
- * Returns a layer by id
- * @param id
- * @returns {*|undefined}
- */
- getLayer(id) {
- let filters = this.getLayers().filter(item => item.id === id)
- return filters && filters.length ? filters[0] : undefined
- }
-
- /**
- * Returns all layers
- * @returns {[]}
- */
- getLayers() {
- let result = []
- Object.keys(this._layerCache).forEach(type => {
- let cache = this._layerCache[type]
- Object.keys(cache).forEach(layerId => {
- result.push(cache[layerId])
- })
- })
- return result
- }
-
- /**
- * Iterate through each layer and pass it as an argument to the callback function
- * @param method
- * @param context
- * @returns {Viewer}
- */
- eachLayer(method, context) {
- Object.keys(this._layerCache).forEach(type => {
- let cache = this._layerCache[type]
- Object.keys(cache).forEach(layerId => {
- method.call(context, cache[layerId])
- })
- })
- return this
- }
-
- /**
- * @param target
- * @param duration
- * @returns {Viewer}
- */
- flyTo(target, duration) {
- this._delegate.flyTo(target?.delegate || target, {
- duration
- })
- return this
- }
-
- /**
- * @param target
- * @returns {Viewer}
- */
- zoomTo(target) {
- this._delegate.zoomTo(target?.delegate || target)
- return this
- }
-
- /**
- * Camera fly to a position
- * @param position
- * @param completeCallback
- * @param duration
- * @returns {Viewer}
- */
- flyToPosition(position, completeCallback, duration) {
- position = Parse.parsePosition(position)
- this.camera.flyTo({
- destination: Transform.transformWGS84ToCartesian(position),
- orientation: {
- heading: Cesium.Math.toRadians(position.heading),
- pitch: Cesium.Math.toRadians(position.pitch),
- roll: Cesium.Math.toRadians(position.roll)
- },
- complete: completeCallback,
- duration: duration
- })
- return this
- }
-
- /**
- * Camera zoom to a position
- * @param position
- * @param completeCallback
- * @returns {Viewer}
- */
- zoomToPosition(position, completeCallback) {
- this.flyToPosition(position, completeCallback, 0)
- return this
- }
-
- /**
- * Camera fly to bounds
- * @param bounds
- * @param heading
- * @param pitch
- * @param roll
- * @param completeCallback
- * @param duration
- * @return {Viewer}
- */
- flyToBounds(
- bounds,
- { heading = 0, pitch = 0, roll = 0 },
- completeCallback,
- duration
- ) {
- if (!bounds) {
- return this
- }
- if (!Array.isArray(bounds)) {
- bounds = bounds.split(',')
- }
- this.camera.flyTo({
- destination: Cesium.Rectangle.fromDegrees(
- bounds[0],
- bounds[1],
- bounds[2],
- bounds[3]
- ),
- orientation: {
- heading: Cesium.Math.toRadians(heading),
- pitch: Cesium.Math.toRadians(pitch),
- roll: Cesium.Math.toRadians(roll)
- },
- complete: completeCallback,
- duration: duration
- })
- return this
- }
-
- /**
- *
- * @param bounds
- * @param heading
- * @param pitch
- * @param roll
- * @param completeCallback
- * @return {Viewer}
- */
- zoomToBounds(bounds, { heading = 0, pitch = 0, roll = 0 }, completeCallback) {
- this.flyToBounds(bounds, { heading, pitch, roll }, completeCallback)
- return this
- }
-
- /**
- *
- * @param type
- * @param callback
- * @param context
- * @returns {Viewer}
- */
- on(type, callback, context) {
- this._viewerEvent.on(type, callback, context || this)
- this._sceneEvent.on(type, callback, context || this)
- return this
- }
-
- /**
- *
- * @param type
- * @param callback
- * @param context
- * @returns {Viewer}
- */
- once(type, callback, context) {
- this._viewerEvent.once(type, callback, context || this)
- return this
- }
-
- /**
- *
- * @param type
- * @param callback
- * @param context
- * @returns {Viewer}
- */
- off(type, callback, context) {
- this._viewerEvent.off(type, callback, context || this)
- this._sceneEvent.off(type, callback, context || this)
- return this
- }
-
- /**
- * Destroys the viewer.
- */
- destroy() {
- Object.keys(this._layerCache).forEach(type => {
- let cache = this._layerCache[type]
- Object.keys(cache).forEach(layerId => {
- this._removeLayer(cache[layerId])
- })
- })
- this._delegate.destroy()
- this._delegate = undefined
- this._baseLayerPicker = undefined
- this._layerCache = {}
- this._dcContainer.parentNode.removeChild(this._dcContainer)
- this._dcContainer = undefined
- return this
- }
-
- /**
- * Export scene to image
- * @param name
- * @returns {Viewer}
- */
- exportScene(name) {
- let canvas = this.canvas
- let image = canvas
- .toDataURL('image/png')
- .replace('image/png', 'image/octet-stream')
- let link = document.createElement('a')
- let blob = Util.dataURLtoBlob(image)
- let objUrl = URL.createObjectURL(blob)
- link.download = `${name || 'scene'}.png`
- link.href = objUrl
- link.click()
- return this
- }
-
- /**
- * Adds a plugin
- * @param plugin
- * @returns {Viewer}
- */
- use(plugin) {
- if (plugin && plugin.install) {
- plugin.install(this)
- }
- return this
- }
- }
-
- export default Viewer
|