UNPKG

vue-cesium

Version:
1 lines 117 kB
{"version":3,"file":"useViewer.mjs","sources":["../../../../../../packages/components/viewer/src/useViewer.ts"],"sourcesContent":["import { watch, ref, onMounted, onUnmounted, nextTick, reactive, VNode } from 'vue'\nimport mitt, { Emitter } from 'mitt'\nimport { useLocale } from '@vue-cesium/composables'\nimport defaultProps from './defaultProps'\nimport { mergeDescriptors } from '@vue-cesium/utils/merge-descriptors'\nimport { dirname, isEmptyObj, hasOwn } from '@vue-cesium/utils/util'\nimport { getInstanceListener, $ } from '@vue-cesium/utils/private/vm'\nimport type {\n VcComponentInternalInstance,\n VcCamera,\n VcReadyObject,\n VcComponentPublicInstance,\n AnyObject,\n VcMittEvents,\n VcTerrainProvider,\n VcDatasource,\n ViewerWidgetResizedEvent,\n VcContextOptions,\n VcViewerProvider,\n Mars3dConfig,\n DCConfig\n} from '@vue-cesium/utils/types'\nimport { compareCesiumVersion, setViewerCamera } from '@vue-cesium/utils/cesium-helpers'\nimport useLog from '@vue-cesium/composables/private/use-log'\nimport { useEvents } from '@vue-cesium/composables'\nimport { getMars3dConfig as getDefaultMars3dConfig } from './loadUtil'\nimport { useGlobalConfig } from '@vue-cesium/composables/use-global-config'\nimport { VcSkeletonProps } from '../../ui/skeleton'\nimport useVcExtension from '@vue-cesium/composables/private/use-vc-extension'\n\nexport const viewerProps = defaultProps\n\nexport default function (props: VcViewerProps, ctx, vcInstance: VcComponentInternalInstance) {\n // state\n let createResolve, reject\n const creatingPromise = new Promise<VcReadyObject>((_resolve, _reject) => {\n createResolve = _resolve\n reject = _reject\n })\n\n const viewerRef = ref<HTMLElement>()\n const isReady = ref(false)\n const vcMitt: Emitter<VcMittEvents> = mitt()\n const { emit } = ctx\n\n const globalConfig = useGlobalConfig()\n\n const logger = useLog(vcInstance)\n\n vcInstance.mounted = false\n vcInstance.vcMitt = vcMitt\n vcInstance.cesiumClass = 'Viewer'\n vcInstance.children = []\n const eventsState = useEvents(props, vcInstance, logger)\n\n const layout = reactive({\n toolbarContainerRC: undefined,\n timelineContainerRC: undefined,\n animationContainerRC: undefined,\n bottomContainerRC: undefined\n })\n\n let loadLibs: Array<string> = []\n\n logger.debug('viewer creating')\n\n const { t } = useLocale()\n\n const { invokeExtensions, revokeExtensions } = useVcExtension()\n\n // watch\n watch(\n () => props.selectionIndicator,\n val => {\n const { viewer, viewerElement } = vcInstance\n const { defined, SelectionIndicator } = Cesium\n let selectionIndicatorContainer\n if (defined(viewer.selectionIndicator) && !viewer.selectionIndicator.isDestroyed() && !val) {\n selectionIndicatorContainer = viewer.selectionIndicator.container\n viewerElement?.removeChild(selectionIndicatorContainer)\n viewer.selectionIndicator.destroy()\n viewer._selectionIndicator = undefined\n } else if (!defined(viewer.selectionIndicator) || viewer.selectionIndicator.isDestroyed()) {\n selectionIndicatorContainer = document.createElement('div')\n selectionIndicatorContainer.className = 'cesium-viewer-selectionIndicatorContainer'\n viewerElement?.appendChild(selectionIndicatorContainer)\n const selectionIndicator = new SelectionIndicator(selectionIndicatorContainer, viewer.scene)\n viewer._selectionIndicator = selectionIndicator\n }\n\n viewer.viewerWidgetResized.raiseEvent({\n type: 'selectionIndicator',\n status: val ? 'added' : 'removed',\n target: selectionIndicatorContainer\n })\n }\n )\n\n watch(\n () => props.infoBox,\n val => {\n const { viewer, viewerElement } = vcInstance\n const { defined, InfoBox } = Cesium\n const events = ['cameraClicked', 'closeClicked']\n let infoBoxContainer\n if (defined(viewer.infoBox) && !viewer.infoBox.isDestroyed() && !val) {\n const infoBoxViewModel = viewer.infoBox.viewModel\n infoBoxViewModel && eventsState.bindEvents(infoBoxViewModel, events, false)\n infoBoxContainer = viewer.infoBox.container\n viewerElement?.removeChild(infoBoxContainer)\n viewer.infoBox.destroy()\n viewer._infoBox = undefined\n } else if (!defined(viewer.infoBox) || viewer.infoBox.isDestroyed()) {\n infoBoxContainer = document.createElement('div')\n infoBoxContainer.className = 'cesium-viewer-infoBoxContainer'\n viewerElement?.appendChild(infoBoxContainer)\n const infoBox = new InfoBox(infoBoxContainer)\n const infoBoxViewModel = infoBox.viewModel\n viewer._onInfoBoxCameraClicked && viewer._eventHelper?.add(infoBoxViewModel.cameraClicked, viewer._onInfoBoxCameraClicked, viewer)\n viewer._onInfoBoxClockClicked && viewer._eventHelper?.add(infoBoxViewModel.closeClicked, viewer._onInfoBoxClockClicked, viewer)\n infoBoxViewModel && eventsState.bindEvents(infoBoxViewModel, events, true)\n viewer._infoBox = infoBox\n }\n viewer.forceResize()\n viewer.viewerWidgetResized.raiseEvent({\n type: 'infoBox',\n status: val ? 'added' : 'removed',\n target: infoBoxContainer\n })\n }\n )\n\n watch(\n () => props.geocoder,\n val => {\n const { viewer } = vcInstance\n const toolbar = viewer._toolbar\n const { defined, Geocoder } = Cesium\n let geocoderContainer\n if (defined(viewer.geocoder) && !viewer.geocoder.isDestroyed() && !val) {\n geocoderContainer = viewer.geocoder.container\n toolbar?.removeChild(geocoderContainer)\n viewer.geocoder.destroy()\n viewer._geocoder = undefined\n } else if (!defined(viewer.geocoder) || viewer.geocoder.isDestroyed()) {\n geocoderContainer = document.createElement('div')\n geocoderContainer.className = 'cesium-viewer-geocoderContainer'\n toolbar?.appendChild(geocoderContainer)\n const geocoder = new Geocoder({\n container: geocoderContainer,\n geocoderServices:\n defined(props.geocoder) && typeof props.geocoder !== 'boolean'\n ? Array.isArray(props.geocoder)\n ? props.geocoder\n : [props.geocoder]\n : undefined,\n scene: viewer.scene\n })\n viewer._clearObjects && viewer._eventHelper?.add(geocoder.viewModel.search.beforeExecute, viewer._clearObjects, viewer)\n viewer._geocoder = geocoder\n resizeToolbar(toolbar, geocoderContainer)\n }\n viewer.viewerWidgetResized.raiseEvent({\n type: 'geocoder',\n status: val ? 'added' : 'removed',\n target: geocoderContainer\n })\n }\n )\n\n watch(\n () => props.homeButton,\n val => {\n const { viewer } = vcInstance\n const toolbar = viewer._toolbar\n const { defined, HomeButton } = Cesium\n if (defined(viewer.homeButton) && !viewer.homeButton.isDestroyed() && !val) {\n viewer.homeButton.destroy()\n viewer._homeButton = undefined\n } else if (!defined(viewer.homeButton) || viewer.homeButton.isDestroyed()) {\n const homeButton = new HomeButton(toolbar!, viewer.scene)\n if (defined(viewer.geocoder)) {\n viewer._eventHelper?.add(homeButton.viewModel.command.afterExecute, function () {\n const viewModel = viewer.geocoder.viewModel\n viewModel.searchText = ''\n viewModel.isSearchInProgress && (viewModel as any).search()\n })\n }\n viewer._clearTrackedObject && viewer._eventHelper?.add(homeButton.viewModel.command.beforeExecute, viewer._clearTrackedObject, viewer)\n viewer._homeButton = homeButton\n resizeToolbar(toolbar, homeButton)\n }\n viewer.viewerWidgetResized.raiseEvent({\n type: 'homeButton',\n status: val ? 'added' : 'removed',\n target: toolbar\n })\n }\n )\n\n watch(\n () => props.sceneModePicker,\n val => {\n const { viewer } = vcInstance\n const toolbar = viewer._toolbar\n const { defined, DeveloperError, SceneModePicker } = Cesium\n if (defined(viewer.sceneModePicker) && !viewer.sceneModePicker.isDestroyed() && !val) {\n viewer.sceneModePicker.destroy()\n viewer._sceneModePicker = undefined\n } else if (!defined(viewer.sceneModePicker) || viewer.sceneModePicker.isDestroyed()) {\n if (props.sceneModePicker && props.scene3DOnly) {\n throw new DeveloperError('options.sceneModePicker is not available when options.scene3DOnly is set to true.')\n }\n if (!props.scene3DOnly && props.sceneModePicker) {\n const sceneModePicker = new SceneModePicker(toolbar!, viewer.scene)\n viewer._sceneModePicker = sceneModePicker\n resizeToolbar(toolbar, sceneModePicker)\n }\n }\n viewer.viewerWidgetResized.raiseEvent({\n type: 'sceneModePicker',\n status: val ? 'added' : 'removed',\n target: toolbar\n })\n }\n )\n\n watch(\n () => props.projectionPicker,\n val => {\n const { viewer } = vcInstance\n const toolbar = viewer._toolbar\n const { defined, ProjectionPicker } = Cesium\n if (defined(viewer.projectionPicker) && !viewer.projectionPicker.isDestroyed() && !val) {\n viewer.projectionPicker.destroy()\n viewer._projectionPicker = undefined\n } else if (!defined(viewer.projectionPicker) || viewer.projectionPicker.isDestroyed()) {\n const projectionPicker = new ProjectionPicker(toolbar!, viewer.scene)\n viewer._projectionPicker = projectionPicker\n resizeToolbar(toolbar, projectionPicker)\n }\n viewer.viewerWidgetResized.raiseEvent({\n type: 'projectionPicker',\n status: val ? 'added' : 'removed',\n target: toolbar\n })\n }\n )\n\n watch(\n () => props.baseLayerPicker,\n async val => {\n const { viewer } = vcInstance\n const toolbar = viewer._toolbar\n const {\n defined,\n buildModuleUrl,\n DeveloperError,\n defaultValue,\n createDefaultImageryProviderViewModels,\n createDefaultTerrainProviderViewModels,\n BaseLayerPicker\n } = Cesium\n if (defined(viewer.baseLayerPicker) && !viewer.baseLayerPicker.isDestroyed() && !val) {\n viewer.baseLayerPicker.destroy()\n viewer._baseLayerPicker = undefined\n viewer.imageryLayers.remove(viewer.imageryLayers.get(viewer.imageryLayers.length - 1))\n const url = buildModuleUrl('Assets/Textures/NaturalEarthII')\n const baseLayer = viewer.imageryLayers.addImageryProvider(\n compareCesiumVersion(Cesium.VERSION, '1.104')\n ? await Cesium.TileMapServiceImageryProvider.fromUrl(url)\n : new Cesium.TileMapServiceImageryProvider({\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n url\n })\n )\n viewer.imageryLayers.lowerToBottom(baseLayer)\n } else if (!defined(viewer.baseLayerPicker) || viewer.baseLayerPicker.isDestroyed()) {\n const createBaseLayerPicker =\n (!Cesium.defined(viewer.scene.globe) || props.globe !== false) &&\n (!Cesium.defined(viewer.baseLayerPicker) || props.baseLayerPicker !== false)\n\n if (createBaseLayerPicker && defined(props.imageryProvider)) {\n throw new DeveloperError(`options.imageryProvider is not available when using the BaseLayerPicker widget.\n Either specify options.selectedImageryProviderViewModel instead or set options.baseLayerPicker to false.`)\n }\n if (!createBaseLayerPicker && defined(props.selectedImageryProviderViewModel)) {\n throw new DeveloperError(`options.selectedImageryProviderViewModel is not available when not using the BaseLayerPicker widget.\n Either specify options.imageryProvider instead or set options.baseLayerPicker to true.`)\n }\n if (createBaseLayerPicker && defined(props.terrainProvider)) {\n throw new DeveloperError(`options.terrainProvider is not available when using the BaseLayerPicker widget.\n Either specify options.selectedTerrainProviderViewModel instead or set options.baseLayerPicker to false.`)\n }\n if (!createBaseLayerPicker && defined(props.selectedTerrainProviderViewModel)) {\n throw new DeveloperError(`options.selectedTerrainProviderViewModel is not available when not using the BaseLayerPicker widget.\n Either specify options.terrainProvider instead or set options.baseLayerPicker to true.`)\n }\n if (createBaseLayerPicker) {\n const imageryProviderViewModels = defaultValue(props.imageryProviderViewModels, createDefaultImageryProviderViewModels())\n const terrainProviderViewModels = defaultValue(props.terrainProviderViewModels, createDefaultTerrainProviderViewModels())\n const baseLayerPicker = new BaseLayerPicker(toolbar!, {\n globe: viewer.scene.globe,\n imageryProviderViewModels: imageryProviderViewModels,\n selectedImageryProviderViewModel: imageryProviderViewModels[0],\n terrainProviderViewModels: terrainProviderViewModels,\n selectedTerrainProviderViewModel: terrainProviderViewModels[0]\n })\n\n const elements = toolbar?.getElementsByClassName('cesium-baseLayerPicker-dropDown')\n\n const baseLayerPickerDropDown = elements?.[0]\n viewer._baseLayerPickerDropDown = baseLayerPickerDropDown\n viewer._baseLayerPicker = baseLayerPicker\n viewer.imageryLayers.raiseToTop(viewer.imageryLayers.get(0))\n resizeToolbar(toolbar, baseLayerPicker)\n }\n }\n viewer.viewerWidgetResized.raiseEvent({\n type: 'baseLayerPicker',\n status: val ? 'added' : 'removed',\n target: toolbar\n })\n }\n )\n\n watch(\n () => props.navigationHelpButton,\n val => {\n const { viewer } = vcInstance\n const toolbar = viewer._toolbar\n const { defined, defaultValue, NavigationHelpButton } = Cesium\n if (defined(viewer.navigationHelpButton) && !viewer.navigationHelpButton.isDestroyed() && !val) {\n viewer.navigationHelpButton.destroy()\n viewer._navigationHelpButton = undefined\n } else if (!defined(viewer.navigationHelpButton) || viewer.navigationHelpButton.isDestroyed()) {\n let showNavHelp = true\n try {\n if (defined(window.localStorage)) {\n const hasSeenNavHelp = window.localStorage.getItem('cesium-hasSeenNavHelp')\n if (defined(hasSeenNavHelp) && Boolean(hasSeenNavHelp)) {\n showNavHelp = false\n } else {\n window.localStorage.setItem('cesium-hasSeenNavHelp', 'true')\n }\n }\n } catch (e) {\n //\n }\n const navigationHelpButton = new NavigationHelpButton({\n container: toolbar!,\n instructionsInitiallyVisible: defaultValue(props.navigationInstructionsInitiallyVisible, showNavHelp)\n })\n viewer._navigationHelpButton = navigationHelpButton\n resizeToolbar(toolbar, navigationHelpButton)\n }\n viewer.viewerWidgetResized.raiseEvent({\n type: 'navigationHelpButton',\n status: val ? 'added' : 'removed',\n target: toolbar\n })\n }\n )\n\n watch(\n () => props.animation,\n val => {\n const { viewer, viewerElement } = vcInstance\n const { defined, Animation, AnimationViewModel } = Cesium\n let animationContainer\n if (defined(viewer.animation) && !viewer.animation.isDestroyed() && !val) {\n animationContainer = viewer.animation.container\n viewerElement?.removeChild(animationContainer)\n viewer.animation.destroy()\n viewer._animation = undefined\n } else if (!defined(viewer.animation) || viewer.animation.isDestroyed()) {\n animationContainer = document.createElement('div')\n animationContainer.className = 'cesium-viewer-animationContainer'\n viewerElement?.appendChild(animationContainer)\n const animation = new Animation(animationContainer, new AnimationViewModel(viewer.clockViewModel))\n animation.viewModel.dateFormatter = localeDateTimeFormatter\n animation.viewModel.timeFormatter = localeTimeFormatter\n viewer._animation = animation\n }\n viewer.forceResize()\n viewer.viewerWidgetResized.raiseEvent({\n type: 'animation',\n status: val ? 'added' : 'removed',\n target: animationContainer\n })\n }\n )\n\n watch(\n () => props.timeline,\n val => {\n const { viewer, viewerElement } = vcInstance\n const { defined, Timeline } = Cesium\n let timelineContainer\n if (defined(viewer.timeline) && !viewer.timeline.isDestroyed() && !val) {\n timelineContainer = viewer.timeline.container\n viewerElement?.removeChild(timelineContainer)\n viewer.timeline.destroy()\n viewer._timeline = undefined\n } else if (!defined(viewer.timeline) || viewer.timeline.isDestroyed()) {\n timelineContainer = document.createElement('div')\n timelineContainer.className = 'cesium-viewer-timelineContainer'\n viewerElement?.appendChild(timelineContainer)\n const timeline = new Timeline(timelineContainer, viewer.clock)\n timeline.makeLabel = time => {\n return localeDateTimeFormatter(time)\n }\n timeline.addEventListener?.('settime', onTimelineScrubfunction, false)\n timeline.zoomTo(viewer.clock.startTime, viewer.clock.stopTime)\n viewer._timeline = timeline\n }\n viewer.forceResize()\n viewer.viewerWidgetResized.raiseEvent({\n type: 'timeline',\n status: val ? 'added' : 'removed',\n target: timelineContainer\n })\n }\n )\n\n watch(\n () => props.fullscreenButton,\n val => {\n const { viewer, viewerElement } = vcInstance\n const { defined, FullscreenButton } = Cesium\n let fullscreenContainer\n if (defined(viewer.fullscreenButton) && !viewer.fullscreenButton.isDestroyed() && !val) {\n fullscreenContainer = viewer.fullscreenButton.container\n viewerElement?.removeChild(fullscreenContainer)\n viewer.fullscreenButton.destroy()\n viewer._fullscreenButton = undefined\n } else if (!defined(viewer.fullscreenButton) || viewer.fullscreenButton.isDestroyed()) {\n fullscreenContainer = document.createElement('div')\n fullscreenContainer.className = 'cesium-viewer-fullscreenContainer'\n viewerElement?.appendChild(fullscreenContainer)\n const fullscreenButton = new FullscreenButton(fullscreenContainer, viewerElement)\n viewer._fullscreenButton = fullscreenButton\n }\n viewer.forceResize()\n viewer.viewerWidgetResized.raiseEvent({\n type: 'fullscreenButton',\n status: val ? 'added' : 'removed',\n target: fullscreenContainer\n })\n }\n )\n\n watch(\n () => props.fullscreenElement,\n val => {\n const { viewer } = vcInstance\n const { defined } = Cesium\n if (!defined(viewer.fullscreenButton)) {\n return\n }\n if (defined(val)) {\n viewer.fullscreenButton.viewModel.fullscreenElement = val as Element\n }\n }\n )\n\n watch(\n () => props.vrButton,\n val => {\n const { viewer, viewerElement } = vcInstance\n const { defined, VRButton } = Cesium\n let vrContainer\n if (defined(viewer.vrButton) && !viewer.vrButton.isDestroyed() && !val) {\n vrContainer = viewer.vrButton.container\n viewerElement?.removeChild(vrContainer)\n viewer.vrButton.destroy()\n viewer._vrButton = undefined\n } else if (!defined(viewer.vrButton) || viewer.vrButton.isDestroyed()) {\n vrContainer = document.createElement('div')\n vrContainer.className = 'cesium-viewer-vrContainer'\n viewerElement?.appendChild(vrContainer)\n const vrButton = new VRButton(vrContainer, viewer.scene, viewerElement)\n const viewModelCommand = vrButton.viewModel.command as any\n ;(vrButton.viewModel as any)._command = function (VRButtonViewModel) {\n viewModelCommand()\n enableVRUI(viewer, VRButtonViewModel.isVRMode)\n }\n viewer._vrButton = vrButton\n }\n viewer.forceResize()\n viewer.viewerWidgetResized.raiseEvent({\n type: 'fullscreenButton',\n status: val ? 'added' : 'removed',\n target: vrContainer\n })\n }\n )\n\n watch(\n () => props.useDefaultRenderLoop,\n val => {\n vcInstance.viewer.useDefaultRenderLoop = val\n }\n )\n\n watch(\n () => props.sceneMode,\n val => {\n const { SceneMode } = Cesium\n if (SceneMode.COLUMBUS_VIEW === val || SceneMode.MORPHING === val || SceneMode.SCENE2D === val || SceneMode.SCENE3D === val) {\n vcInstance.viewer.scene.mode = val\n }\n }\n )\n\n watch(\n () => props.shouldAnimate,\n val => {\n vcInstance.viewer.clock.shouldAnimate = val\n }\n )\n\n watch(\n () => props.terrainExaggeration,\n val => {\n vcInstance.viewer._terrainExaggeration = val\n }\n )\n\n watch(\n () => props.shadows,\n val => {\n vcInstance.viewer.scene.shadowMap.enabled = val\n }\n )\n\n watch(\n () => props.terrainProvider,\n val => {\n val && (vcInstance.viewer.terrainProvider = val)\n }\n )\n\n watch(\n () => props.camera,\n val => {\n setViewerCamera(vcInstance.viewer, val)\n },\n { deep: true }\n )\n\n watch(\n () => props.imageryProvider,\n (val, oldVal) => {\n const { viewer } = vcInstance\n const { defined } = Cesium\n if (defined(val)) {\n for (let i = 0; i < viewer.imageryLayers.length; i++) {\n viewer.imageryLayers.get(i).imageryProvider === oldVal && viewer.imageryLayers.remove(viewer.imageryLayers[i])\n }\n val && viewer.imageryLayers.addImageryProvider(val)\n }\n }\n )\n\n watch(\n () => props.showCredit,\n val => {\n const { viewer } = vcInstance\n ;(viewer.cesiumWidget.creditContainer as HTMLElement).style.display = val ? 'inline' : 'none'\n viewer.viewerWidgetResized.raiseEvent({\n type: 'credit',\n status: val ? 'added' : 'removed',\n target: viewer.cesiumWidget.creditContainer\n })\n }\n )\n\n watch(\n () => props.debugShowFramesPerSecond,\n val => {\n const { viewer } = vcInstance\n viewer.scene.debugShowFramesPerSecond = val\n }\n )\n\n // methods\n\n /**\n * 检测是否引入 CesiumJS\n */\n const beforeLoad = async function (): Promise<void> {\n logger.debug('beforeLoad - viewer')\n const listener = getInstanceListener(vcInstance, 'beforeLoad')\n listener && emit('beforeLoad', vcInstance)\n globalConfig.value.__scriptPromise = globalConfig.value.__scriptPromise || getCesiumScript()\n await globalConfig.value.__scriptPromise\n }\n /**\n * 初始化 Viewer,成功返回 {Cesium, viewer, instance}, 失败返回false。\n * @returns VcReadyObject\n */\n const load = async function (): Promise<boolean | VcReadyObject> {\n logger.debug('loading-viewer')\n if (vcInstance.mounted) {\n return false\n }\n\n await beforeLoad()\n\n if (typeof Cesium === 'undefined') {\n return false\n }\n\n const { Ion, buildModuleUrl, ImageryLayer, TileMapServiceImageryProvider, Viewer, defined, Math: CesiumMath, Event } = Cesium\n const accessToken = props.accessToken ? props.accessToken : globalConfig.value.accessToken\n Ion.defaultAccessToken = accessToken\n\n const url = buildModuleUrl('Assets/Textures/NaturalEarthII')\n const options: AnyObject = {}\n props &&\n Object.keys(props).forEach(vueProp => {\n if (props[vueProp] === undefined || props[vueProp] === null) {\n return\n }\n options[vueProp] = props[vueProp]\n })\n\n options.fullscreenElement = isEmptyObj(options.fullscreenElement) ? $(viewerRef) : options.fullscreenElement\n\n if (compareCesiumVersion(Cesium.VERSION, '1.104')) {\n options.baseLayer =\n isEmptyObj(options.baseLayer) && options.baseLayer !== false\n ? ImageryLayer.fromProviderAsync(TileMapServiceImageryProvider.fromUrl(url), {})\n : options.baseLayer\n } else {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n options.imageryProvider = isEmptyObj(options.imageryProvider) ? new TileMapServiceImageryProvider({ url }) : options.imageryProvider\n }\n\n let viewer: Cesium.Viewer\n\n if (props.viewerCreator) {\n viewer = props.viewerCreator(vcInstance, $(viewerRef), options)\n } else {\n if (globalThis.mars3d) {\n vcInstance.map = new mars3d.Map($(viewerRef).id, {\n scene: options,\n control: options\n })\n viewer = vcInstance.map?._viewer\n } else if (globalThis.DC) {\n vcInstance.dcViewer = new DC.Viewer($(viewerRef).id, options)\n viewer = vcInstance.dcViewer?.delegate\n } else if (globalThis.XE) {\n vcInstance.earth = new globalThis.XE.Earth($(viewerRef), options)\n viewer = vcInstance.earth?.czm.viewer\n } else {\n viewer = new Viewer($(viewerRef) as HTMLElement, options)\n }\n }\n\n // 扩展\n invokeExtensions(viewer)\n\n vcInstance.Cesium = Cesium\n vcInstance.viewer = viewer\n vcInstance.viewerElement = (viewer as any)._element\n vcInstance.mounted = true\n\n if (compareCesiumVersion(Cesium.VERSION, '1.83')) {\n if (compareCesiumVersion(Cesium.VERSION, '1.116')) {\n viewer.scene.verticalExaggeration = options.verticalExaggeration || options.terrainExaggeration\n } else {\n viewer.scene.globe['terrainExaggeration'] = options.verticalExaggeration || options.terrainExaggeration\n }\n }\n\n // vue-cesium 扩展补充\n // vue-cesium extension\n defined(options.camera) && setViewerCamera(viewer, options.camera)\n\n const listener = getInstanceListener(vcInstance, 'update:camera')\n listener &&\n viewer.camera.changed.addEventListener(() => {\n const cartographic = viewer.camera.positionCartographic\n let cameraNew: VcCamera\n if (hasOwn(options.camera.position, 'lng')) {\n cameraNew = {\n position: {\n lng: CesiumMath.toDegrees(cartographic.longitude),\n lat: CesiumMath.toDegrees(cartographic.latitude),\n height: cartographic.height\n },\n heading: CesiumMath.toDegrees(viewer.camera.heading || 360),\n pitch: CesiumMath.toDegrees(viewer.camera.pitch || -90),\n roll: CesiumMath.toDegrees(viewer.camera.roll || 0)\n }\n } else {\n cameraNew = {\n position: {\n x: viewer.camera.position.x,\n y: viewer.camera.position.y,\n z: viewer.camera.position.z\n },\n heading: viewer.camera.heading || 2 * Math.PI,\n pitch: viewer.camera.pitch || -Math.PI / 2,\n roll: viewer.camera.roll || 0\n }\n }\n\n emit('update:camera', cameraNew)\n })\n\n if (defined(viewer.animation)) {\n viewer.animation.viewModel.dateFormatter = localeDateTimeFormatter as Cesium.AnimationViewModel.DateFormatter\n viewer.animation.viewModel.timeFormatter = localeTimeFormatter as Cesium.AnimationViewModel.TimeFormatter\n }\n\n if (defined(viewer.timeline)) {\n viewer.timeline.makeLabel = time => {\n return localeDateTimeFormatter(time)\n }\n viewer.timeline.zoomTo(viewer.clock.startTime, viewer.clock.stopTime)\n }\n\n if (process.env.NODE_ENV !== 'production') {\n if ((props as any).logo) {\n logger.warn(\"'logo' is deprecated. Use `showCredit` prop instead. \")\n }\n }\n\n !props.showCredit && ((viewer.cesiumWidget.creditContainer as HTMLElement).style.display = 'none')\n\n props.debugShowFramesPerSecond && (viewer.scene.debugShowFramesPerSecond = true)\n\n viewer.viewerWidgetResized = viewer.viewerWidgetResized || new Event()\n viewer.viewerWidgetResized.addEventListener(onViewerWidgetResized)\n viewer.imageryLayers.layerAdded.addEventListener(onImageryLayerAdded)\n eventsState.registerEvents(true)\n const readyObj: VcReadyObject = {\n Cesium,\n viewer,\n vm: vcInstance\n }\n if (globalThis.XE) {\n Object.assign(readyObj, {\n earth: vcInstance.earth\n })\n } else if (globalThis.mars3d) {\n Object.assign(readyObj, {\n map: vcInstance.map\n })\n } else if (globalThis.DC) {\n Object.assign(readyObj, {\n dcViewer: vcInstance.dcViewer\n })\n }\n\n const listenerReady = getInstanceListener(vcInstance, 'ready')\n listenerReady && emit('ready', readyObj)\n vcMitt?.emit('ready', readyObj)\n nextTick(() => {\n viewer.resize()\n onViewerWidgetResized({\n type: 'viewer',\n status: 'added',\n target: viewer.container as HTMLElement\n })\n isReady.value = true\n })\n\n logger.debug('loaded-viewer')\n\n Object.assign(vcInstance.proxy, {\n cesiumObject: viewer\n })\n return readyObj\n }\n\n /**\n * Viewer 销毁方法。\n */\n const unload = async function () {\n if (!vcInstance.mounted) {\n return false\n }\n\n logger.debug('viewer---unloading')\n let unloadingResolve\n globalConfig.value.__viewerUnloadingPromise = new Promise((resolve, reject) => {\n unloadingResolve = resolve\n })\n\n // If the component has subcomponents, you need to remove the subcomponents first. 如果该组件带有子组件,需要先移除子组件。\n for (let i = 0; i < vcInstance.children.length; i++) {\n const vcChildCmp = vcInstance.children[i].proxy as VcComponentPublicInstance\n await vcChildCmp.unload()\n }\n\n vcInstance.children.length = 0\n\n const { viewer, earth, map, dcViewer } = vcInstance\n if (globalThis.Cesium) {\n viewer.imageryLayers.layerAdded.removeEventListener(onImageryLayerAdded)\n eventsState.registerEvents(false)\n }\n\n const { removeCesiumScript } = props\n\n viewer._vcPickScreenSpaceEventHandler && viewer._vcPickScreenSpaceEventHandler.destroy()\n viewer._vcViewerScreenSpaceEventHandler && viewer._vcViewerScreenSpaceEventHandler.destroy()\n viewer._vcPickScreenSpaceEventHandler = undefined\n viewer._vcViewerScreenSpaceEventHandler = undefined\n\n removeCesiumScript && revokeExtensions(viewer)\n\n delete vcInstance.appContext.config.globalProperties.$VueCesium[viewer.container.id]\n\n if (globalThis.XE) {\n earth && earth.destroy()\n } else if (globalThis.mars3d) {\n map && map.destroy()\n } else if (globalThis.DC) {\n dcViewer && dcViewer.destroy()\n } else {\n viewer && viewer.destroy()\n }\n\n vcInstance.viewer = undefined\n vcInstance.mounted = false\n if (removeCesiumScript && globalThis.Cesium) {\n const scripts = document.getElementsByTagName('script')\n const removeScripts: Array<HTMLScriptElement | HTMLLinkElement> = []\n for (const script of scripts) {\n script.src.indexOf('/Cesium.js') > -1 && removeScripts.push(script)\n script.src.indexOf('/Workers/zlib.min.js') > -1 && removeScripts.push(script)\n if (globalThis.XE) {\n script.src.indexOf('/rxjs.umd.min.js') > -1 && removeScripts.push(script)\n script.src.indexOf('/XbsjCesium.js') > -1 && removeScripts.push(script)\n script.src.indexOf('/viewerCesiumNavigationMixin.js') > -1 && removeScripts.push(script)\n script.src.indexOf('/XbsjEarth.js') > -1 && removeScripts.push(script)\n }\n\n loadLibs.includes(script.src) && !removeScripts.includes(script) && removeScripts.push(script)\n }\n\n const links = document.getElementsByTagName('link')\n for (const link of links) {\n link.href.includes('Widgets/widgets.css') && !removeScripts.includes(link) && removeScripts.push(link)\n loadLibs.includes(link.href) && !removeScripts.includes(link) && removeScripts.push(link)\n }\n removeScripts.forEach(script => {\n script.parentNode && script.parentNode.removeChild(script)\n })\n globalThis.Cesium && (globalThis.Cesium = undefined!)\n globalThis.XbsjCesium && (globalThis.XbsjCesium = undefined)\n globalThis.XbsjEarth && (globalThis.XbsjEarth = undefined)\n globalThis.XE && (globalThis.XE = undefined)\n globalThis.mars3d && (globalThis.mars3d = undefined)\n globalThis.DC && (globalThis.DC = undefined)\n globalThis.DcCore && (globalThis.DcCore = undefined)\n globalConfig.value.__scriptPromise = undefined\n loadLibs = []\n }\n // ensure custom events can be emitted after unmount. 不推荐\n // https://github.com/vuejs/core/issues/5674\n vcInstance.isUnmounted = false\n\n const listener = getInstanceListener(vcInstance, 'destroyed')\n listener && emit('destroyed', vcInstance)\n vcMitt.emit('destroyed', vcInstance)\n logger.debug('viewer---unloaded')\n unloadingResolve(true)\n globalConfig.value.__viewerUnloadingPromise = undefined\n isReady.value = false\n return true\n }\n\n const reload = function () {\n return unload().then(() => {\n return load()\n })\n }\n\n /**\n * 动态引入 CesiumJS\n */\n const getCesiumScript = async function (): Promise<typeof Cesium> {\n logger.debug('getCesiumScript')\n if (!globalThis.Cesium) {\n const cesiumPath = props.cesiumPath ? props.cesiumPath : globalConfig.value.cesiumPath\n const dirName = dirname(cesiumPath)\n const mars3dConfig = globalConfig.value.mars3dConfig || props.mars3dConfig\n const dcConfig = globalConfig.value.dcConfig || props.dcConfig\n if (mars3dConfig) {\n // 引入 mars3d\n const libsConfig = mars3dConfig.libs || getDefaultMars3dConfig()\n const include = mars3dConfig.include || 'mars3d'\n const arrInclude = include.trim().split(',')\n const keys = {}\n for (let i = 0, len = arrInclude.length; i < len; i++) {\n const key = arrInclude[i]\n if (keys[key]) {\n //规避重复引入lib\n continue\n }\n keys[key] = true\n loadLibs.push(...libsConfig[key])\n }\n } else if (dcConfig) {\n loadLibs.push(cesiumPath)\n loadLibs.push(cesiumPath.replace('dc.min.js', 'dc.min.css'))\n\n loadLibs.push(dcConfig.Cesium)\n const dirName = dirname(dcConfig.Cesium)\n loadLibs.push(`${dirName}/Widgets/widgets.css`)\n\n if (dcConfig.turf) {\n loadLibs.push(dcConfig.turf)\n }\n\n if (dcConfig.echarts) {\n loadLibs.push(dcConfig.echarts)\n }\n } else if (cesiumPath.includes('/dc.base.min.js')) {\n loadLibs.push(cesiumPath)\n loadLibs.push(cesiumPath.replace('/dc.base.min.js', '/dc.core.min.js'))\n loadLibs.push(cesiumPath.replace('/dc.base.min.js', '/dc.core.min.js').replace('/dc.core.min.js', '/dc.core.min.css'))\n } else if (cesiumPath.includes('/XbsjEarth.js')) {\n loadLibs.push(cesiumPath)\n } else {\n loadLibs.push(cesiumPath)\n loadLibs.push(`${dirName}/Widgets/widgets.css`)\n }\n\n const secondaryLibs = loadLibs\n if (mars3dConfig || dcConfig) {\n // mars3d 必须要等 Cesium 先初始化\n const primaryLib = loadLibs.find(v => v.includes('Cesium.js'))\n await loadScript(primaryLib)\n secondaryLibs.splice(secondaryLibs.indexOf(primaryLib), 1)\n }\n\n const scriptLoadPromises: Array<Promise<unknown>> = []\n secondaryLibs.forEach(url => {\n const cssExpr = new RegExp('\\\\.css')\n if (cssExpr.test(url)) {\n scriptLoadPromises.push(loadLink(url))\n } else {\n scriptLoadPromises.push(loadScript(url))\n }\n })\n\n return Promise.all(scriptLoadPromises).then(() => {\n if (globalThis.Cesium) {\n if (globalThis.DC) {\n const config: any = {\n ...dcConfig,\n Cesium: globalThis.Cesium\n }\n if (dcConfig.echarts) {\n config.echarts = globalThis.echarts\n }\n\n if (dcConfig.turf) {\n config.turf = globalThis.turf\n }\n\n return globalThis.DC.ready(config).then(() => {\n globalThis.Cesium = DC.getLib('Cesium')\n const listener = getInstanceListener(vcInstance, 'cesiumReady')\n listener && emit('cesiumReady', globalThis.DC)\n return globalThis.Cesium\n })\n } else {\n const listener = getInstanceListener(vcInstance, 'cesiumReady')\n listener && emit('cesiumReady', globalThis.Cesium)\n return globalThis.Cesium\n }\n } else if (globalThis.XE) {\n // 兼容 cesiumlab earthsdk\n return globalThis.XE.ready().then(() => {\n // resolve(globalThis.Cesium)\n const listener = getInstanceListener(vcInstance, 'cesiumReady')\n listener && emit('cesiumReady', globalThis.Cesium)\n return globalThis.Cesium\n })\n } else if (globalThis.DC) {\n // 兼容 dc-sdk\n if (compareCesiumVersion(globalThis.DC.VERSION, '3.0.0')) {\n return globalThis.DC.ready({\n ...dcConfig,\n Cesium: globalThis.Cesium\n }).then(() => {\n globalThis.Cesium = DC.getLib('Cesium')\n const listener = getInstanceListener(vcInstance, 'cesiumReady')\n listener && emit('cesiumReady', globalThis.DC)\n return globalThis.Cesium\n })\n } else {\n globalThis.DC.use(globalThis.DcCore.default || globalThis.DcCore)\n globalThis.DC.baseUrl = `${dirName}/resources/`\n globalThis.DC.ready(() => {\n globalThis.Cesium = DC.Namespace.Cesium\n\n const listener = getInstanceListener(vcInstance, 'cesiumReady')\n listener && emit('cesiumReady', globalThis.DC)\n return globalThis.Cesium\n })\n return globalThis.Cesium\n }\n } else {\n reject(new Error('VueCesium ERROR: ' + 'Error loading CesiumJS!'))\n }\n })\n } else {\n return Promise.resolve(globalThis.Cesium)\n }\n }\n\n const loadScript = src => {\n const $script = document.createElement('script')\n $script.async = false\n $script.src = src\n document.body.appendChild($script)\n return new Promise((resolve, reject) => {\n $script.onload = () => {\n resolve(true)\n }\n })\n }\n\n const loadLink = src => {\n const $link = document.createElement('link')\n $link.rel = 'stylesheet'\n $link.href = src\n document.head.appendChild($link)\n return new Promise((resolve, reject) => {\n $link.onload = () => {\n resolve(true)\n }\n })\n }\n\n const onViewerWidgetResized = e => {\n const { viewer } = vcInstance\n const toolbarElement = viewer._toolbar as HTMLElement\n if (\n toolbarElement !== void 0 &&\n getComputedStyle(toolbarElement).visibility !== 'hidden' &&\n getComputedStyle(toolbarElement).display !== 'none'\n ) {\n layout.toolbarContainerRC = toolbarElement.getBoundingClientRect()\n } else {\n layout.toolbarContainerRC = undefined\n }\n\n const bottomContainer = viewer.bottomContainer as HTMLElement\n if (\n bottomContainer !== void 0 &&\n getComputedStyle(bottomContainer).visibility !== 'hidden' &&\n getComputedStyle(bottomContainer).display !== 'none'\n ) {\n layout.bottomContainerRC = bottomContainer.getBoundingClientRect()\n } else {\n layout.bottomContainerRC = undefined\n }\n\n const timelineContainer = viewer.timeline?.container as HTMLElement\n if (\n timelineContainer !== void 0 &&\n getComputedStyle(timelineContainer).visibility !== 'hidden' &&\n getComputedStyle(timelineContainer).display !== 'none'\n ) {\n layout.timelineContainerRC = timelineContainer.getBoundingClientRect()\n } else {\n layout.timelineContainerRC = undefined\n }\n\n const animationContainer = viewer.animation?.container as HTMLElement\n if (\n animationContainer !== void 0 &&\n getComputedStyle(animationContainer).visibility !== 'hidden' &&\n getComputedStyle(animationContainer).display !== 'none'\n ) {\n layout.animationContainerRC = animationContainer.getBoundingClientRect()\n } else {\n layout.animationContainerRC = undefined\n }\n\n viewer.resize()\n const listener = getInstanceListener(vcInstance, 'viewerWidgetResized')\n listener && emit('viewerWidgetResized', e)\n }\n\n /**\n * 添加影像图层事件回调方法,在此维护影像图层相对顺序。\n * @param layer 添加的图层。\n */\n const onImageryLayerAdded = (layer: Cesium.ImageryLayer) => {\n const viewer = vcInstance.viewer as Cesium.Viewer\n const { autoSortImageryLayers } = props\n\n if (viewer.baseLayerPicker) {\n viewer.imageryLayers.raiseToTop(layer)\n }\n const { defined } = Cesium\n if (autoSortImageryLayers) {\n layer.sortOrder = defined(layer.sortOrder) ? layer.sortOrder : 9999\n viewer.imageryLayers._layers.sort((a: Cesium.ImageryLayer, b: Cesium.ImageryLayer) => a.sortOrder! - b.sortOrder!)\n viewer.imageryLayers._update()\n }\n }\n /**\n * 本地日期和时间格式化函数。\n * @param date\n * @param viewModel\n * @param ignoredate\n */\n const localeDateTimeFormatter = function (date: Cesium.JulianDate, viewModel?: Cesium.AnimationViewModel, ignoredate?: boolean): string {\n const { JulianDate } = Cesium\n let TZCode\n\n if (props.UTCOffset) {\n date = JulianDate.addMinutes(date, props.UTCOffset, new JulianDate())\n const offset = new Date().getTimezoneOffset() - props.UTCOffset\n TZCode = offset === 0 ? 'UTC' : 'UTC' + '+' + -(offset / 60)\n } else {\n TZCode = new Date().getTimezoneOffset() === 0 ? 'UTC' : 'UTC' + '+' + -(new Date().getTimezoneOffset() / 60)\n }\n const jsDate = JulianDate.toDate(date)\n const timeString: string = jsDate\n .toLocaleString(t('name'), {\n hour: 'numeric',\n minute: 'numeric',\n second: 'numeric',\n hour12: false\n })\n .replace(/,/g, '')\n const dateString: string = jsDate\n .toLocaleString(t('name'), {\n year: 'numeric',\n month: 'short',\n day: 'numeric'\n })\n .replace(/,/g, '')\n\n if (!ignoredate && (viewModel || jsDate.getHours() + jsDate.getMinutes() === 0)) {\n return dateString\n }\n\n props.TZCode && (TZCode = props.TZCode)\n return ignoredate ? `${timeString} ${TZCode}` : `${dateString} ${timeString} ${TZCode}`\n }\n\n /**\n * 本地时间格式化函数。\n * @param time\n * @param viewModel\n */\n const localeTimeFormatter = function (time: Cesium.JulianDate, viewModel: Cesium.AnimationViewModel): string {\n return localeDateTimeFormatter(time, viewModel, true)\n }\n\n const onTimelineScrubfunction = function (e) {\n const clock = e.clock\n clock.currentTime = e.timeJulian\n clock.shouldAnimate = false\n }\n\n const enableVRUI = function (viewer, enabled) {\n const geocoder = viewer._geocoder\n const homeButton = viewer._homeButton\n const sceneModePicker = viewer._sceneModePicker\n const projectionPicker = viewer._projectionPicker\n const baseLayerPicker = viewer._baseLayerPicker\n const animation = viewer._animation\n const timeline = viewer._timeline\n const fullscreenButton = viewer._fullscreenButton\n const infoBox = viewer._infoBox\n const selectionIndicator = viewer._selectionIndicator\n const visibility = enabled ? 'hidden' : 'visible'\n const { defined } = Cesium\n if (defined(geocoder)) {\n geocoder.container.style.visibility = visibility\n }\n if (defined(homeButton)) {\n homeButton.container.style.visibility = visibility\n }\n if (defined(sceneModePicker)) {\n sceneModePicker.container.style.visibility = visibility\n }\n if (defined(projectionPicker)) {\n projectionPicker.container.style.visibility = visibility\n }\n if (defined(baseLayerPicker)) {\n baseLayerPicker.container.style.visibility = visibility\n }\n if (defined(animation)) {\n animation.container.style.visibility = visibility\n }\n if (defined(timeline)) {\n timeline.container.style.visibility = visibility\n }\n if (defined(fullscreenButton) && fullscreenButton.viewModel.isFullscreenEnabled) {\n fullscreenButton.container.style.visibility = visibility\n }\n if (defined(infoBox)) {\n infoBox.container.style.visibility = visibility\n }\n if (defined(selectionIndicator)) {\n selectionIndicator.container.style.visibility = visibility\n }\n if (viewer._container) {\n const right = enabled || !defined(fullscreenButton) ? 0 : fullscreenButton.container.clientWidth\n viewer._vrButton.container.style.right = right + 'px'\n viewer.forceResize()\n }\n }\n\n const resizeToolbar = function (parent, child) {\n Array.prototype.slice.call(parent.children).forEach(element => {\n switch (element.className) {\n case 'cesium-viewer-geocoderContainer':\n element.customIndex = 1\n break\n case 'cesium-button cesium-toolbar-button cesium-home-button':\n element.customIndex = 2\n break\n case 'cesium-sceneModePicker-wrapper cesium-toolbar-button':\n element.customIndex = 3\n break\n case 'cesium-projectionPicker-wrapper cesium-toolbar-button':\n element.customIndex = 4\n break\n case 'cesium-button cesium-toolbar-button':\n case 'cesium-baseLayerPicker-dropDown':\n element.customIndex = 5\n break\n case 'cesium-navigationHelpButton-wrapper':\n element.customIndex = 6\n break\n }\n })\n const arr: any[] = []\n Array.prototype.slice.call(parent.children).forEach(element => {\n arr.push(element)\n })\n arr.sort(function (a, b) {\n return a.customIndex - b.customIndex\n })\n for (let i = 0; i < arr.length; i++) {\n parent.appendChild(arr[i])\n }\n }\n\n const getServices = function (): VcViewerProvider {\n return mergeDescriptors(\n {},\n {\n get layout() {\n return layout\n },\n get vm() {\n return vcInstance\n },\n get Cesium() {\n return vcInstance.Cesium\n },\n get viewer(): Cesium.Viewer {\n return vcInstance.viewer\n },\n get dataSources(): Cesium.DataSourceCollection {\n return vcInstance.viewer?.dataSources\n },\n get entities() {\n return vcInstance.viewer?.entities\n },\n get imageryLayers() {\n return vcInstance.viewer?.imageryLayers\n },\n get primitives() {\n return vcInstance.viewer?.scene.primitives\n },\n get groundPrimitives() {\n return vcInstance.viewer?.scene.groundPrimitives\n },\n get postProcessStages() {\n return vcInstance.viewer?.postProcessStages\n },\n get creatingPromise() {\n return creatingPromise\n },\n /**\n * for mars3d only\n */\n get mars3dMap() {\n return vcInstance.map\n },\n /**\n * for dc-sdk only\n */\n get dcViewer() {\n return vcInstance.dcViewer\n },\n /**\n * for earth-sdk only\n */\n get earth() {\n return vcInstance.earth\n }\n }\n )\n }\n\n Object.defineProperties(vcInstance, {\n cesiumObject: {\n enumerable: true,\n get: () => vcInstance.viewer\n }\n })\n\n // lifecycle\n onMounted(async () => {\n try {\n logger.debug('viewer - onMounted')\n await globalConfig.value?.__viewerUnloadingPromise\n load()\n .then(e => {\n createResolve(e)\n })\n .catch(e => {\n emit('unready', e)\n reject(e)\n })\n } catch (e) {\n emit('unready', e)\n reject(e)\n }\n })\n\n onUnmounted(() => {\n logger.debug('viewer - onUnmounted')\n unload().then(() => {\n vcMitt.all.clear()\n })\n })\n\n return {\n isReady,\n load,\n unload,\n reload,\n getServices,\n viewerRef,\n creatingPromise\n }\n}\n\nexport interface VcViewerProps {\n /**\n * If set to false, the Animation widget will not be created.\n * Default value: false\n */\n animation?: boolean\n /**\n * If set to false, the BaseLayerPicker widget will not be created.\n * Default value: false\n */\n baseLayerPicker?: boolean\n /**\n * \tIf set to false, the FullscreenButton widget will not be created.\n * Default value: false\n */\n fullscreenButton?: boolean\n /**\n * If set to true, the VRButton widget will be created.\n * Default value: false\n */\n vrButton?: boolean\n /**\n * If set to false, the Geocoder widget will not be created.\n * Default value: false\n */\n geocoder?: boolean | Array<Cesium.GeocoderService>\n /**\n * If set to false, the HomeButton widget will not be created.\n * Default value: