| | |
| | | <template> |
| | | <div class="command-cesium map-container" :id="props.containerId"></div> |
| | | <CommonCesiumMap |
| | | ref="mapRef" |
| | | class="command-cesium map-container" |
| | | :dom-id="props.containerId" |
| | | :active="true" |
| | | :flat-mode="false" |
| | | :terrain="false" |
| | | :layer-mode="4" |
| | | :contour="false" |
| | | :boundary="false" |
| | | :show-admin-boundary="true" |
| | | :zoom-to-boundary="true" |
| | | @ready="handleMapReady" |
| | | /> |
| | | <div v-if="props.showLayerControl" class="layer-control-root" :class="{ collapsed: props.leftCollapsed }"> |
| | | <div class="layer-control-wrap" ref="layerWrapRef"> |
| | | <div class="layer-control" @click="toggleLayerPanel"> |
| | |
| | | |
| | | <script setup> |
| | | import * as Cesium from 'cesium' |
| | | import { PublicCesium } from '@/utils/cesium/publicCesium' |
| | | import CommonCesiumMap from '@/components/map-container/common-cesium-map.vue' |
| | | import { geomAnalysis } from '@ztzf/utils' |
| | | import { fwDefenseZonePageApi } from '@/views/areaManage/defenseZone/defenseZoneApi' |
| | | import { fwAreaDividePageApi } from '@/views/areaManage/partition/partitionApi' |
| | | import jaGeojsonRaw from '@/assets/geojson/ja.geojson?raw' |
| | | import layerControlIcon from '@/assets/images/dataCockpit/layerControl.png' |
| | | import equipmentIcon from '@/assets/images/dataCockpit/map/equipment.png' |
| | | |
| | |
| | | |
| | | const DEFAULT_ZONE_PAGE_SIZE = 999 |
| | | |
| | | let viewInstance = null |
| | | const mapRef = ref(null) |
| | | let viewer = null |
| | | const deviceEntityIds = new Set() |
| | | let defenseZoneSource = null |
| | | let partitionSource = null |
| | | let adminBoundarySource = null |
| | | let adminBoundaryLabelSource = null |
| | | let adminBoundaryLineSource = null |
| | | let adminBoundaryFlyDone = false |
| | | const showLayerPanel = ref(false) |
| | | const layerWrapRef = ref(null) |
| | | const layerTreeProps = { |
| | |
| | | partitionSource.entities.removeAll() |
| | | } |
| | | |
| | | const clearAdminBoundaryEntities = () => { |
| | | if (!adminBoundarySource) return |
| | | adminBoundarySource.entities.removeAll() |
| | | } |
| | | |
| | | const clearAdminBoundaryLabels = () => { |
| | | if (!adminBoundaryLabelSource) return |
| | | adminBoundaryLabelSource.entities.removeAll() |
| | | } |
| | | |
| | | const clearAdminBoundaryLines = () => { |
| | | if (!adminBoundaryLineSource) return |
| | | adminBoundaryLineSource.entities.removeAll() |
| | | } |
| | | |
| | | const RING_STYLES = [ |
| | | { inner: 0, outer: 2000, gradient: ['#FF361C', '#360B00'] } |
| | |
| | | position: Cesium.Cartesian3.fromDegrees(position.longitude, position.latitude, 0), |
| | | billboard: { |
| | | image: equipmentIcon, |
| | | width: 40.34, |
| | | height: 40.34, |
| | | width: 40, |
| | | height: 56, |
| | | verticalOrigin: Cesium.VerticalOrigin.BOTTOM, |
| | | }, |
| | | }) |
| | | }) |
| | |
| | | } |
| | | } |
| | | |
| | | const loadAdminBoundary = async () => { |
| | | if (!viewer) return |
| | | try { |
| | | if (adminBoundarySource) { |
| | | viewer.dataSources.remove(adminBoundarySource) |
| | | adminBoundarySource = null |
| | | } |
| | | if (adminBoundaryLabelSource) { |
| | | viewer.dataSources.remove(adminBoundaryLabelSource) |
| | | adminBoundaryLabelSource = null |
| | | } |
| | | if (adminBoundaryLineSource) { |
| | | viewer.dataSources.remove(adminBoundaryLineSource) |
| | | adminBoundaryLineSource = null |
| | | } |
| | | const geojson = JSON.parse(jaGeojsonRaw) |
| | | adminBoundarySource = await Cesium.GeoJsonDataSource.load(geojson, { |
| | | stroke: Cesium.Color.fromCssColorString('#FFFFFF'), |
| | | strokeWidth: 2, |
| | | fill: Cesium.Color.fromCssColorString('#FFFFFF').withAlpha(0.05), |
| | | clampToGround: true, |
| | | }) |
| | | viewer.dataSources.add(adminBoundarySource) |
| | | if (!adminBoundaryFlyDone) { |
| | | adminBoundaryFlyDone = true |
| | | viewer.flyTo(adminBoundarySource, { |
| | | duration: 0, |
| | | offset: new Cesium.HeadingPitchRange(0, Cesium.Math.toRadians(-75), 0), |
| | | }) |
| | | } |
| | | |
| | | adminBoundaryLineSource = new Cesium.CustomDataSource('adminBoundaryLineSource') |
| | | adminBoundarySource.entities.values.forEach(entity => { |
| | | const polygon = entity.polygon |
| | | if (!polygon) return |
| | | const hierarchy = polygon.hierarchy?.getValue?.(viewer.clock.currentTime) |
| | | const positions = hierarchy?.positions |
| | | if (!positions?.length) return |
| | | adminBoundaryLineSource.entities.add({ |
| | | polyline: { |
| | | positions, |
| | | clampToGround: true, |
| | | width: 2, |
| | | material: Cesium.Color.WHITE, |
| | | }, |
| | | }) |
| | | }) |
| | | viewer.dataSources.add(adminBoundaryLineSource) |
| | | |
| | | adminBoundaryLabelSource = new Cesium.CustomDataSource('adminBoundaryLabelSource') |
| | | geojson.features?.forEach(feature => { |
| | | const name = feature?.properties?.name |
| | | const point = feature?.properties?.centroid || feature?.properties?.center |
| | | if (!name || !Array.isArray(point) || point.length < 2) return |
| | | adminBoundaryLabelSource.entities.add({ |
| | | position: Cesium.Cartesian3.fromDegrees(point[0], point[1]), |
| | | label: { |
| | | text: name, |
| | | font: '14px Source Han Sans CN', |
| | | fillColor: Cesium.Color.WHITE, |
| | | outlineColor: Cesium.Color.BLACK.withAlpha(0.6), |
| | | outlineWidth: 2, |
| | | style: Cesium.LabelStyle.FILL_AND_OUTLINE, |
| | | heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, |
| | | verticalOrigin: Cesium.VerticalOrigin.CENTER, |
| | | horizontalOrigin: Cesium.HorizontalOrigin.CENTER, |
| | | disableDepthTestDistance: Number.POSITIVE_INFINITY, |
| | | }, |
| | | }) |
| | | }) |
| | | viewer.dataSources.add(adminBoundaryLabelSource) |
| | | } catch (error) { |
| | | clearAdminBoundaryEntities() |
| | | clearAdminBoundaryLabels() |
| | | clearAdminBoundaryLines() |
| | | } |
| | | } |
| | | |
| | | watch( |
| | | () => props.onlineDevices, |
| | |
| | | showLayerPanel.value = !showLayerPanel.value |
| | | } |
| | | |
| | | const handleMapReady = ({ viewer: mapViewer }) => { |
| | | viewer = mapViewer |
| | | renderDeviceEntities(props.onlineDevices) |
| | | loadDefenseZones() |
| | | loadPartitions() |
| | | } |
| | | |
| | | const handleClickOutside = event => { |
| | | if (!showLayerPanel.value) return |
| | | const target = event.target |
| | |
| | | |
| | | onMounted(() => { |
| | | document.addEventListener('click', handleClickOutside) |
| | | viewInstance = new PublicCesium({ |
| | | dom: props.containerId, |
| | | flatMode: false, |
| | | terrain: false, |
| | | layerMode: 4, |
| | | contour: false, |
| | | }) |
| | | |
| | | viewer = viewInstance.getViewer() |
| | | renderDeviceEntities(props.onlineDevices) |
| | | loadDefenseZones() |
| | | loadPartitions() |
| | | loadAdminBoundary() |
| | | const map = mapRef.value?.getMap() |
| | | if (map?.viewer) handleMapReady(map) |
| | | }) |
| | | |
| | | onBeforeUnmount(() => { |
| | |
| | | clearDeviceEntities() |
| | | clearDefenseZoneEntities() |
| | | clearPartitionEntities() |
| | | clearAdminBoundaryEntities() |
| | | clearAdminBoundaryLabels() |
| | | clearAdminBoundaryLines() |
| | | if (viewInstance) { |
| | | viewInstance?.viewerDestroy() |
| | | viewInstance = null |
| | | } |
| | | |
| | | viewer = null |
| | | }) |
| | | </script> |