| | |
| | | <template> |
| | | <div :id="mapId" class="common-cesium-map"></div> |
| | | <div :id="mapId" class="common-cesium-map" @contextmenu.prevent></div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { onBeforeUnmount, onMounted, ref, watch } from 'vue' |
| | | import * as Cesium from 'cesium' |
| | | |
| | | import { onBeforeUnmount, onMounted, watch } from 'vue' |
| | | import { PublicCesium } from '@/utils/cesium/publicCesium' |
| | | import { loadJaAdminBoundary, removeJaAdminBoundary } from '@/utils/cesium/adminBoundary' |
| | | |
| | |
| | | |
| | | const emit = defineEmits(['ready', 'height-change', 'stage-change']) |
| | | const mapId = props.domId || `common-cesium-map-${Math.random().toString(36).slice(2, 10)}` |
| | | const viewInstance = ref(null) |
| | | const viewer = ref(null) |
| | | let viewInstance = null |
| | | let viewer = null |
| | | const ADMIN_BOUNDARY_NAMES = { |
| | | boundary: 'jaBoundarySource', |
| | | line: 'jaBoundaryLineSource', |
| | | label: 'jaBoundaryLabelSource', |
| | | } |
| | | let adminBoundarySources = null |
| | | let initialized = false |
| | | let removeCameraListener = null |
| | |
| | | const initMap = async () => { |
| | | if (initialized) return |
| | | initialized = true |
| | | viewInstance.value = new PublicCesium({ |
| | | viewInstance = new PublicCesium({ |
| | | dom: mapId, |
| | | flatMode: props.flatMode, |
| | | terrain: props.terrain, |
| | |
| | | boundary: props.boundary, |
| | | contour: props.contour, |
| | | }) |
| | | viewer.value = viewInstance.value.getViewer() |
| | | viewer = viewInstance.getViewer() |
| | | if (props.showAdminBoundary) { |
| | | adminBoundarySources = await loadJaAdminBoundary(viewer.value, { |
| | | adminBoundarySources = await loadJaAdminBoundary(viewer, { |
| | | zoomTo: props.zoomToBoundary, |
| | | }) |
| | | } |
| | | if (props.enableStageEmit) { |
| | | let lastStage = '' |
| | | const onCameraChanged = () => { |
| | | const height = viewer.value?.camera?.positionCartographic?.height |
| | | const height = viewer?.camera?.positionCartographic?.height |
| | | if (height == null) return |
| | | emit('height-change', height) |
| | | let stage = 'mid' |
| | |
| | | emit('stage-change', stage) |
| | | } |
| | | } |
| | | viewer.value?.camera?.changed?.addEventListener(onCameraChanged) |
| | | removeCameraListener = () => viewer.value?.camera?.changed?.removeEventListener(onCameraChanged) |
| | | viewer?.camera?.changed?.addEventListener(onCameraChanged) |
| | | removeCameraListener = () => viewer?.camera?.changed?.removeEventListener(onCameraChanged) |
| | | } |
| | | emit('ready', { viewer: viewer.value, publicCesium: viewInstance.value }) |
| | | emit('ready', { viewer, publicCesium: viewInstance }) |
| | | } |
| | | |
| | | watch( |
| | |
| | | |
| | | onBeforeUnmount(() => { |
| | | if (removeCameraListener) removeCameraListener() |
| | | removeJaAdminBoundary(viewer.value, adminBoundarySources) |
| | | viewInstance.value?.viewerDestroy?.() |
| | | removeJaAdminBoundary(viewer, adminBoundarySources) |
| | | adminBoundarySources = null |
| | | viewInstance?.viewerDestroy?.() |
| | | }) |
| | | |
| | | const getMap = () => ({ viewer: viewer.value, publicCesium: viewInstance.value }) |
| | | const getViewer = () => viewer.value |
| | | const getPublicCesium = () => viewInstance.value |
| | | const setAdminBoundaryVisible = async visible => { |
| | | if (!viewer) return |
| | | const removeByNames = () => { |
| | | Object.values(ADMIN_BOUNDARY_NAMES).forEach(name => { |
| | | const sources = viewer.dataSources.getByName(name) || [] |
| | | sources.forEach(source => viewer.dataSources.remove(source)) |
| | | }) |
| | | } |
| | | const resolveSources = () => { |
| | | if (adminBoundarySources) return adminBoundarySources |
| | | const boundarySource = viewer.dataSources.getByName(ADMIN_BOUNDARY_NAMES.boundary)?.[0] ?? null |
| | | const lineSource = viewer.dataSources.getByName(ADMIN_BOUNDARY_NAMES.line)?.[0] ?? null |
| | | const labelSource = viewer.dataSources.getByName(ADMIN_BOUNDARY_NAMES.label)?.[0] ?? null |
| | | if (boundarySource || lineSource || labelSource) { |
| | | adminBoundarySources = { boundarySource, lineSource, labelSource } |
| | | } |
| | | return adminBoundarySources |
| | | } |
| | | const setVisible = (source, next) => { |
| | | if (!source) return |
| | | source.show = next |
| | | source.entities?.values?.forEach(entity => { |
| | | entity.show = next |
| | | }) |
| | | } |
| | | const sources = resolveSources() |
| | | if (!visible) { |
| | | if (sources) { |
| | | removeJaAdminBoundary(viewer, sources) |
| | | adminBoundarySources = null |
| | | } |
| | | removeByNames() |
| | | return |
| | | } |
| | | if (sources) { |
| | | const { boundarySource, lineSource, labelSource } = sources |
| | | setVisible(boundarySource, true) |
| | | setVisible(lineSource, true) |
| | | setVisible(labelSource, true) |
| | | return |
| | | } |
| | | adminBoundarySources = await loadJaAdminBoundary(viewer, { |
| | | zoomTo: false, |
| | | }) |
| | | } |
| | | |
| | | defineExpose({ getMap, getViewer, getPublicCesium }) |
| | | const zoomToAdminBoundary = async () => { |
| | | if (!viewer) return |
| | | const resolveSources = () => { |
| | | if (adminBoundarySources) return adminBoundarySources |
| | | const boundarySource = viewer.dataSources.getByName(ADMIN_BOUNDARY_NAMES.boundary)?.[0] ?? null |
| | | const lineSource = viewer.dataSources.getByName(ADMIN_BOUNDARY_NAMES.line)?.[0] ?? null |
| | | const labelSource = viewer.dataSources.getByName(ADMIN_BOUNDARY_NAMES.label)?.[0] ?? null |
| | | if (boundarySource || lineSource || labelSource) { |
| | | adminBoundarySources = { boundarySource, lineSource, labelSource } |
| | | } |
| | | return adminBoundarySources |
| | | } |
| | | let sources = resolveSources() |
| | | if (!sources?.boundarySource) { |
| | | sources = await loadJaAdminBoundary(viewer, { zoomTo: false }) |
| | | adminBoundarySources = sources |
| | | } |
| | | const target = sources?.boundarySource |
| | | if (!target) return |
| | | await viewer.flyTo(target, { |
| | | duration: 0, |
| | | offset: new Cesium.HeadingPitchRange(0, Cesium.Math.toRadians(-75), 0), |
| | | }) |
| | | } |
| | | |
| | | const getMap = () => ({ viewer, publicCesium: viewInstance }) |
| | | const getViewer = () => viewer |
| | | const getPublicCesium = () => viewInstance |
| | | |
| | | defineExpose({ getMap, getViewer, getPublicCesium, setAdminBoundaryVisible, zoomToAdminBoundary }) |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |