| | |
| | | import { fieldRules, geomAnalysis, getDictLabel } from '@ztzf/utils' |
| | | import CommonCesiumMap from '@/components/map-container/common-cesium-map.vue' |
| | | import { DrawManager, EditManager, buildEllipsePositions } from '@/utils/cesium/shapeTools' |
| | | import { cartesian3Convert, getPointPositionsHeight } from '@/utils/cesium/mapUtil' |
| | | import { cartesian3Convert } from '@/utils/cesium/mapUtil' |
| | | import { |
| | | createDeviceRangePrimitive, |
| | | getDeviceLngLat, |
| | | normalizeDeviceRange, |
| | | resolveDeviceTerrainHeight, |
| | | } from '@/utils/cesium/deviceRange' |
| | | import * as Cesium from 'cesium' |
| | | import { AREA_TYPE_STYLE_MAP, BUFFER_LEVEL_STYLES, DEFAULT_AREA_STYLE } from '@ztzf/constants' |
| | | import { fwPoliceStationListApi } from '@/views/areaManage/precinctInfo/precinctInfoApi' |
| | |
| | | let viewEntity |
| | | let shapeDisplaySource |
| | | const deviceRangePrimitiveMap = new Map() |
| | | let deviceRangeMaterialRegistered = false |
| | | const activeToolMode = ref('') |
| | | |
| | | const rules = { |
| | |
| | | return shapeDisplaySource |
| | | } |
| | | |
| | | function registerDeviceRangeMaterial () { |
| | | if (deviceRangeMaterialRegistered || !Cesium?.Material) return |
| | | deviceRangeMaterialRegistered = true |
| | | Cesium.Material._materialCache.addMaterial('DeviceRangeEllipsoid', { |
| | | fabric: { |
| | | type: 'DeviceRangeEllipsoid', |
| | | uniforms: { |
| | | color: new Cesium.Color(1.0, 0.0, 0.0, 0.7), |
| | | speed: 3.0, |
| | | }, |
| | | source: ` |
| | | uniform vec4 color; |
| | | uniform float speed; |
| | | czm_material czm_getMaterial(czm_materialInput materialInput){ |
| | | czm_material material = czm_getDefaultMaterial(materialInput); |
| | | vec2 st = materialInput.st; |
| | | float time = fract(czm_frameNumber * speed / 1000.0); |
| | | float alpha = abs(smoothstep(0.5,1.,fract( -st.t - time))); |
| | | alpha += .1; |
| | | material.alpha = alpha; |
| | | material.diffuse = color.rgb; |
| | | return material; |
| | | } |
| | | `, |
| | | }, |
| | | translucent: () => true, |
| | | }) |
| | | } |
| | | |
| | | function createDeviceRangeMaterial () { |
| | | registerDeviceRangeMaterial() |
| | | return Cesium.Material.fromType('DeviceRangeEllipsoid', { |
| | | color: Cesium.Color.fromBytes(0, 255, 255, 155), |
| | | }) |
| | | } |
| | | |
| | | function clearDeviceRangePrimitives () { |
| | | if (!viewer || !deviceRangePrimitiveMap.size) return |
| | | for (const primitive of deviceRangePrimitiveMap.values()) { |
| | |
| | | deviceRangePrimitiveMap.clear() |
| | | } |
| | | |
| | | function normalizeDeviceRange (value) { |
| | | const range = Number(value) |
| | | if (!Number.isFinite(range) || range <= 0) return 2000 |
| | | return range |
| | | } |
| | | |
| | | function getDeviceLngLat (device) { |
| | | const lngRaw = device?.longitude ?? device?.lng ?? device?.lon |
| | | const latRaw = device?.latitude ?? device?.lat |
| | | const lng = Number(lngRaw) |
| | | const lat = Number(latRaw) |
| | | if (!Number.isFinite(lng) || !Number.isFinite(lat)) return null |
| | | return { lng, lat } |
| | | } |
| | | |
| | | async function resolveDeviceTerrainHeight (position) { |
| | | if (!viewer) return 0 |
| | | try { |
| | | const results = await getPointPositionsHeight([{ lng: position.lng, lat: position.lat }], viewer) |
| | | const height = Number(results?.[0]?.ASL) |
| | | return Number.isFinite(height) ? height : 0 |
| | | } catch (error) { |
| | | return 0 |
| | | } |
| | | } |
| | | |
| | | async function createDeviceRangePrimitive (device) { |
| | | if (!viewer) return null |
| | | if (!device) return null |
| | | const position = getDeviceLngLat(device) |
| | | if (!position) return null |
| | | const rangeMeters = normalizeDeviceRange(device.effectiveRangeKm) |
| | | const centerHeight = await resolveDeviceTerrainHeight(position) |
| | | const center = Cesium.Cartesian3.fromDegrees(position.lng, position.lat, centerHeight) |
| | | const radii = new Cesium.Cartesian3(rangeMeters, rangeMeters, rangeMeters) |
| | | const geometry = new Cesium.EllipsoidGeometry({ |
| | | radii, |
| | | vertexFormat: Cesium.MaterialAppearance.MaterialSupport.TEXTURED?.vertexFormat |
| | | || Cesium.VertexFormat.POSITION_AND_NORMAL, |
| | | }) |
| | | const instance = new Cesium.GeometryInstance({ |
| | | geometry, |
| | | modelMatrix: Cesium.Transforms.eastNorthUpToFixedFrame(center), |
| | | }) |
| | | return new Cesium.Primitive({ |
| | | geometryInstances: instance, |
| | | appearance: new Cesium.MaterialAppearance({ |
| | | material: createDeviceRangeMaterial(), |
| | | closed: true, |
| | | translucent: true, |
| | | flat: true, |
| | | faceForward: true, |
| | | }), |
| | | asynchronous: false |
| | | }) |
| | | } |
| | | |
| | | async function renderDeviceRangeSingle (device) { |
| | | if (!viewer) return |
| | | clearDeviceRangePrimitives() |
| | | const primitive = await createDeviceRangePrimitive(device) |
| | | const position = getDeviceLngLat(device) |
| | | if (!position) return |
| | | const rangeMeters = normalizeDeviceRange(device.effectiveRangeKm) |
| | | const primitive = await createDeviceRangePrimitive(viewer, position, rangeMeters) |
| | | if (!primitive) return |
| | | deviceRangePrimitiveMap.set(String(device?.id ?? Date.now()), primitive) |
| | | viewer.scene.primitives.add(primitive) |
| | |
| | | if (!pendingRows.length) return |
| | | const primitives = await Promise.all( |
| | | pendingRows.map(async row => { |
| | | const primitive = await createDeviceRangePrimitive(row) |
| | | const position = getDeviceLngLat(row) |
| | | if (!position) return { row, primitive: null } |
| | | const rangeMeters = normalizeDeviceRange(row.effectiveRangeKm) |
| | | const primitive = await createDeviceRangePrimitive(viewer, position, rangeMeters) |
| | | return { row, primitive } |
| | | }) |
| | | ) |
| | |
| | | if (!viewer) return |
| | | const position = getDeviceLngLat(device) |
| | | if (!position) return |
| | | const height = await resolveDeviceTerrainHeight(position) |
| | | const destination = Cesium.Cartesian3.fromDegrees(position.lng, position.lat, height + device.effectiveRangeKm * 3) |
| | | const height = await resolveDeviceTerrainHeight(viewer, position) |
| | | const rangeMeters = normalizeDeviceRange(device?.effectiveRangeKm) |
| | | const destination = Cesium.Cartesian3.fromDegrees(position.lng, position.lat, height + rangeMeters * 3) |
| | | viewer.camera.flyTo({ |
| | | destination, |
| | | orientation: { |