diff --git a/components.d.ts b/components.d.ts
index 4eeb64745..cdc91ac84 100644
--- a/components.d.ts
+++ b/components.d.ts
@@ -22,6 +22,8 @@ declare module '@vue/runtime-core' {
Modal: typeof import('./src/components/Modal/index.vue')['default']
Nav: typeof import('./src/components/Nav/index.vue')['default']
NButton: typeof import('naive-ui')['NButton']
+ NCheckbox: typeof import('naive-ui')['NCheckbox']
+ NCheckboxGroup: typeof import('naive-ui')['NCheckboxGroup']
NConfigProvider: typeof import('naive-ui')['NConfigProvider']
NDataTable: typeof import('naive-ui')['NDataTable']
NDatePicker: typeof import('naive-ui')['NDatePicker']
diff --git a/package-lock.json b/package-lock.json
index 296a7dcaf..8bddb7d36 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -28,6 +28,7 @@
"satellite.js": "^5.0.0",
"seemly": "^0.3.9",
"v-viewer": "^3.0.21",
+ "vanilla-js-wheel-zoom": "^9.0.4",
"viewerjs": "^1.11.7",
"vue": "^3.2.45",
"vue-draggable-plus": "^0.5.6",
@@ -15120,6 +15121,12 @@
"spdx-expression-parse": "^3.0.0"
}
},
+ "node_modules/vanilla-js-wheel-zoom": {
+ "version": "9.0.4",
+ "resolved": "https://registry.npmmirror.com/vanilla-js-wheel-zoom/-/vanilla-js-wheel-zoom-9.0.4.tgz",
+ "integrity": "sha512-OjmS9ihEKBCRw2OQ7IiIdQGXdC5gTEEmtcAWZcPeNAJaYiS61KCd02Z72YMtIoXLGN5TZP+wliBMylLAsr6wow==",
+ "license": "MIT"
+ },
"node_modules/vdirs": {
"version": "0.1.8",
"resolved": "https://registry.npmmirror.com/vdirs/-/vdirs-0.1.8.tgz",
diff --git a/package.json b/package.json
index 85b7fc7a6..8212ffcf6 100644
--- a/package.json
+++ b/package.json
@@ -31,6 +31,7 @@
"satellite.js": "^5.0.0",
"seemly": "^0.3.9",
"v-viewer": "^3.0.21",
+ "vanilla-js-wheel-zoom": "^9.0.4",
"viewerjs": "^1.11.7",
"vue": "^3.2.45",
"vue-draggable-plus": "^0.5.6",
diff --git a/src/api/Hangjing/index.js b/src/api/Hangjing/index.js
index bec3f5d13..4c549c0af 100644
--- a/src/api/Hangjing/index.js
+++ b/src/api/Hangjing/index.js
@@ -1,8 +1,16 @@
import { defAxios as request } from '@/utils/http'
const baseUrl = window.settings.apis
+// export function getHangjing(data = {}) {
+// return request({
+// url: `${baseUrl}/hangjing/list`,
+// method: 'post',
+// data,
+// })
+// }
+
export function getHangjing(data = {}) {
return request({
- url: `${baseUrl}/hangjing/list`,
+ url: `${baseUrl}/hangjing/shiJianTree`,
method: 'post',
data,
})
diff --git a/src/assets/base.css b/src/assets/base.css
index 3d6ab5bf4..1d345c26c 100644
--- a/src/assets/base.css
+++ b/src/assets/base.css
@@ -56,6 +56,9 @@
);
--color-bg: #1a222966;
+
+ --gradient-bg-title: linear-gradient(to right, #4fd2dd55, #4b877400);
+ --tw-from-opacity: 33%;
}
@media (prefers-color-scheme: dark) {
diff --git a/src/assets/detail.scss b/src/assets/detail.scss
new file mode 100644
index 000000000..0c8d29d91
--- /dev/null
+++ b/src/assets/detail.scss
@@ -0,0 +1,8 @@
+
+.detail-container {
+ @apply flex flex-col gap-4;
+ .detail-item-title{
+ @apply font-bold text-xl w-[120px] h-[30px] leading-[30px];
+ background-image: linear-gradient(to right, #4fd2dd55 0%, transparent 100%);
+ }
+}
\ No newline at end of file
diff --git a/src/assets/main.css b/src/assets/main.css
index 0c8877249..e928b8781 100644
--- a/src/assets/main.css
+++ b/src/assets/main.css
@@ -1,5 +1,6 @@
@import './base.css';
@import './naiveui.css';
+@import './detail.scss';
#app {
width: 100%;
diff --git a/src/assets/naiveui.css b/src/assets/naiveui.css
index d4b58fe0f..4130a1bfb 100644
--- a/src/assets/naiveui.css
+++ b/src/assets/naiveui.css
@@ -1,3 +1,7 @@
+.n-dialog .n-dialog__content {
+ padding-top: 1rem;
+}
+
.n-base-select-option__content {
width: 100%;
}
diff --git a/src/components/Panel/index.vue b/src/components/Panel/index.vue
index e8e076795..3c14dc183 100644
--- a/src/components/Panel/index.vue
+++ b/src/components/Panel/index.vue
@@ -120,7 +120,7 @@ $radius: 2rem;
.content-title {
@apply h-9 px-5 leading-9 tracking-[5px];
border-radius: $radius $radius 0 0;
- background: linear-gradient(to right, #4fd2dd55, #4b877400);
+ background: var(--gradient-bg-title);
.title-text {
@apply font-bold italic;
color: transparent;
diff --git a/src/hooks/entity.ts b/src/hooks/entity.ts
index 6e71de577..ecd762e54 100644
--- a/src/hooks/entity.ts
+++ b/src/hooks/entity.ts
@@ -62,12 +62,12 @@ async function getHisTraj({
function getMBEntityOpt({
id,
- name,
targetType,
+ name,
}: {
id: string
- name?: string
targetType: string
+ name?: string
}) {
const mubiaoDict = window.settings.mbDict[targetType]
@@ -102,6 +102,25 @@ function getMBEntityOpt({
scale: 1000,
minimumPixelSize: 50,
},
+ ellipsoid: {
+ show: true,
+ radii: new Cesium.Cartesian3(100000, 100000, 100000),
+ innerRadii: new Cesium.Cartesian3(1.0, 1.0, 1.0),
+ maximumCone: Cesium.Math.toRadians(90),
+ minimumCone: Cesium.Math.toRadians(40),
+ minimumClock: Cesium.Math.toRadians(20),
+ maximumClock: Cesium.Math.toRadians(90),
+ material: Cesium.Color.fromCssColorString('#00dcff44'),
+ outline: true,
+ outlineColor: Cesium.Color.fromCssColorString('#00dcff'),
+ outlineWidth: 1,
+ distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
+ 0.0,
+ 10.5e8
+ ),
+ slicePartitions: 24,
+ stackPartitions: 36,
+ },
}
}
diff --git a/src/js/Radar.js b/src/js/Radar.js
new file mode 100644
index 000000000..6e4550857
--- /dev/null
+++ b/src/js/Radar.js
@@ -0,0 +1,142 @@
+export default class Radar {
+ // 创建雷达罩
+ constructor(options) {
+ this.radius = options.radius
+ // this.viewer = options.viewer
+ // this.id = options.id
+ // this.entity = null
+ // this.radius = options.radius
+ // ;(this.longitude = options.position[0]),
+ // (this.latitude = options.position[1]),
+ // (this.position = Cesium.Cartesian3.fromDegrees(
+ // options.position[0],
+ // options.position[1]
+ // ))
+ // this.heading = 0
+ // this.positionArr = this.calcPoints(
+ // options.position[0],
+ // options.position[1],
+ // options.radius,
+ // 0
+ // ) //储存脏数据
+ // this.addEntities()
+ }
+ cartesian32LonLat(cartesian3) {
+ const cartographic =
+ this.viewer.scene.globe.ellipsoid.cartesianToCartographic(
+ cartesian3._value
+ )
+ const lat = Cesium.Math.toDegrees(cartographic.latitude)
+ const lon = Cesium.Math.toDegrees(cartographic.longitude)
+ return [lon, lat]
+ }
+ getRadar() {
+ // this.entity = this.viewer.entities.add({
+ // id: this.id,
+ // position: this.position,
+ // wall: {
+ // positions: new Cesium.CallbackProperty(() => {
+ // return Cesium.Cartesian3.fromDegreesArrayHeights(this.positionArr)
+ // }, false),
+ // material: Cesium.Color.fromCssColorString('#00dcff82'),
+ // distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
+ // 0.0,
+ // 10.5e6
+ // ),
+ // },
+ // ellipsoid: {
+ // radii: new Cesium.Cartesian3(
+ // this.radius,
+ // this.radius,
+ // this.radius
+ // ),
+ // maximumCone: Cesium.Math.toRadians(90),
+ // material: Cesium.Color.fromCssColorString('#00dcff82'),
+ // outline: true,
+ // outlineColor: Cesium.Color.fromCssColorString('#00dcff'),
+ // outlineWidth: 1,
+ // distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
+ // 0.0,
+ // 10.5e8
+ // ),
+ // },
+ // })
+ return {
+ // wall: {
+ // positions: new Cesium.CallbackProperty(() => {
+ // return Cesium.Cartesian3.fromDegreesArrayHeights(this.positionArr)
+ // }, false),
+ // material: Cesium.Color.fromCssColorString('#00dcff82'),
+ // distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
+ // 0.0,
+ // 10.5e6
+ // ),
+ // },
+ ellipsoid: {
+ radii: new Cesium.Cartesian3(this.radius, this.radius, this.radius),
+ maximumCone: Cesium.Math.toRadians(90),
+ material: Cesium.Color.fromCssColorString('#00dcff82'),
+ outline: true,
+ outlineColor: Cesium.Color.fromCssColorString('#00dcff'),
+ outlineWidth: 1,
+ distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
+ 0.0,
+ 10.5e8
+ ),
+ },
+ }
+ // this.addPostRender()
+ }
+ addPostRender() {
+ this.viewer.clock.onTick.addEventListener(() => {
+ this.heading += 1.0 //可调节转动速度
+ this.positionArr = this.calcPoints(
+ this.longitude,
+ this.latitude,
+ this.radius,
+ this.heading
+ )
+ })
+ }
+ calcPoints(x1, y1, radius, heading) {
+ let m = Cesium.Transforms.eastNorthUpToFixedFrame(
+ Cesium.Cartesian3.fromDegrees(x1, y1)
+ )
+ let rx = radius * Math.cos((heading * Math.PI) / 180.0)
+ let ry = radius * Math.sin((heading * Math.PI) / 180.0)
+ let translation = Cesium.Cartesian3.fromElements(rx, ry, 0)
+ let d = Cesium.Matrix4.multiplyByPoint(
+ m,
+ translation,
+ new Cesium.Cartesian3()
+ )
+ let c = Cesium.Cartographic.fromCartesian(d)
+ let x2 = Cesium.Math.toDegrees(c.longitude)
+ let y2 = Cesium.Math.toDegrees(c.latitude)
+ return this.computeCirclularFlight(x1, y1, x2, y2, 0, 90)
+ }
+ computeCirclularFlight(x1, y1, x2, y2, fx, angle) {
+ let positionArr = []
+ positionArr.push(x1)
+ positionArr.push(y1)
+ positionArr.push(0)
+ let radius = Cesium.Cartesian3.distance(
+ Cesium.Cartesian3.fromDegrees(x1, y1),
+ Cesium.Cartesian3.fromDegrees(x2, y2)
+ )
+ for (let i = fx; i <= fx + angle; i++) {
+ let h = radius * Math.sin((i * Math.PI) / 180.0)
+ let r = Math.cos((i * Math.PI) / 180.0)
+ let x = (x2 - x1) * r + x1
+ let y = (y2 - y1) * r + y1
+ positionArr.push(x)
+ positionArr.push(y)
+ positionArr.push(h)
+ }
+ return positionArr
+ }
+ removeEntity() {
+ this.entity && this.viewer.entities.remove(this.entity)
+ this.entity = null
+ }
+}
diff --git a/src/js/satelliteEntity.js b/src/js/satelliteEntity.js
index d75549fad..ec3074bd9 100644
--- a/src/js/satelliteEntity.js
+++ b/src/js/satelliteEntity.js
@@ -22,7 +22,7 @@ class SatelliteEntity {
this.entity = null
this._underPoint = false
this.underPointEntity = null
- this._sensorType = 'rectangle'
+ this._sensorType = 'conic'
this._listener = null
}
get sensorType() {
@@ -443,9 +443,8 @@ class SatelliteEntity {
},
polyline: {
positions: points,
-
width: 1,
- material: Cesium.Color.RED,
+ material: color,
},
})
}
diff --git a/src/views/BaseMB/components/HisImages/components/LImage.jsx b/src/views/BaseMB/components/HisImages/components/LImage.jsx
new file mode 100644
index 000000000..77eac536e
--- /dev/null
+++ b/src/views/BaseMB/components/HisImages/components/LImage.jsx
@@ -0,0 +1,70 @@
+import { NImage } from 'naive-ui'
+import WZoom from 'vanilla-js-wheel-zoom/dist/wheel-zoom.min.js'
+
+export default defineComponent({
+ props: {
+ imageList: {
+ type: Array,
+ default: () => [],
+ },
+ },
+ setup(props) {
+ // const { images, activeIndex } = toRefs(props)
+
+ watch(
+ () => props.imageList,
+ () => {
+ if (props.imageList.length > 1) {
+ nextTick(() => {
+ props.imageList.map(image => {
+ const imageElement = document
+ .getElementById(`image-${image.id}`)
+ .querySelector('img')
+
+ const wz = WZoom.create(`#image-${image.id}`, {
+ type: 'html',
+ maxScale: 3,
+ minScale: 0.2,
+ // zoomOnDoubleClick: true,
+ width: imageElement.naturalWidth,
+ height: imageElement.naturalHeight,
+ })
+ })
+ })
+ }
+ }
+ )
+ return () => (
+
+ {props.imageList.map(image => (
+
+
{image.createTime}
+
+ {props.imageList.length > 1 ? (
+
+

+
+ ) : (
+
+ )}
+
+
+
{image.detailContent}
+
+ ))}
+
+ )
+ },
+})
diff --git a/src/views/BaseMB/components/HisImages/index.vue b/src/views/BaseMB/components/HisImages/index.vue
index 9e544f560..15901ca0b 100644
--- a/src/views/BaseMB/components/HisImages/index.vue
+++ b/src/views/BaseMB/components/HisImages/index.vue
@@ -4,6 +4,7 @@
import { ImageOutline } from '@vicons/ionicons5'
import { useHisImage } from './hooks/hisImage'
import Panel from '@/components/Panel/index.vue'
+import LImage from './components/LImage'
const { sheshiData, showOrHideHisImage, getHisImages } = useHisImage()
@@ -61,12 +62,47 @@ const getImage = async () => {
// })
imageList.value = new Array(10).fill(1).map((item, index) => {
return {
+ id: index,
imgPath: `https://picsum.photos/300/200?random=${index}`,
imgId: index,
}
})
// console.log(imageList.value, 'imageList')
}
+
+const checkedImage = ref(null)
+
+const checkValue = e => {
+ e.stopPropagation()
+ if (checkedImage.value && checkedImage.value.length > 2) {
+ checkedImage.value.pop()
+ }
+}
+
+// watch(checkedImage, newCheck => {
+// // console.log(newCheck, 'newCheck')
+// })
+const isCompare = ref(false)
+const compareImages = () => {
+ if (!isCompare.value) {
+ if (checkedImage.value && checkedImage.value.length === 2) {
+ isCompare.value = true
+ }
+ } else {
+ isCompare.value = false
+ checkedImage.value = null
+ }
+}
+
+const largeImageList = computed(() => {
+ if (isCompare.value) {
+ return imageList.value.filter(img => checkedImage.value.includes(img.id))
+ } else {
+ return imageList.value[previewIndex.value - 1]
+ ? [imageList.value[previewIndex.value - 1]]
+ : []
+ }
+})
@@ -79,23 +115,8 @@ const getImage = async () => {
>
-
- {{ previewIndex > 0 ? imageList[previewIndex - 1].createTime : '' }}
-
-
-
-
-
+
-
- {{
- previewIndex > 0 ? imageList[previewIndex - 1].detailContent : ''
- }}
-
@@ -109,12 +130,19 @@ const getImage = async () => {
format="yyyy-MM-dd HH:mm:ss"
/>
搜索
+ {{
+ isCompare ? '取消对比' : '对比'
+ }}
-
+
+
{
index + 1 === previewIndex,
}"
>
+
{
-
+
+
@@ -154,6 +189,7 @@ const getImage = async () => {
+// }
diff --git a/src/views/Hangjing/hooks/hangjing.ts b/src/views/Hangjing/hooks/hangjing.ts
index 381522d32..957d68186 100644
--- a/src/views/Hangjing/hooks/hangjing.ts
+++ b/src/views/Hangjing/hooks/hangjing.ts
@@ -1,4 +1,6 @@
+import { difference } from 'lodash'
import { useWebSocket } from '@vueuse/core'
+import { useTree } from '@/utils/tree'
import { useHjPolygon } from './hangjingPolygon'
interface IPolygonData {
id: string
@@ -6,6 +8,8 @@ interface IPolygonData {
color?: string
}
+const { filterTreeNodeByField } = useTree()
+
const hangjingMap: Map = new Map()
const { addHangjingPolygon, removeHangjingPolygon } = useHjPolygon(hangjingMap)
@@ -13,8 +17,8 @@ export const useHangjing = () => {
onMounted(() => {
initWebSocket()
})
- const addHangjing = (data: Record[]) => {
- addHangjingPolygon(data)
+ const addHangjing = (ids, hangjingData) => {
+ addHangjingPolygon(ids, hangjingData)
}
const removeHangjing = (id: string) => {
diff --git a/src/views/Hangjing/hooks/hangjingDetail.jsx b/src/views/Hangjing/hooks/hangjingDetail.jsx
new file mode 100644
index 000000000..a4f865024
--- /dev/null
+++ b/src/views/Hangjing/hooks/hangjingDetail.jsx
@@ -0,0 +1,34 @@
+import { useModal } from '@/views/Content/hooks/modal'
+const { openDetailsModal } = useModal()
+import { useHangjingStyle } from './hangjingStyle'
+
+const { renderStyleContent } = useHangjingStyle()
+export const useHangjingDetail = () => {
+ return { showDetailsModal }
+}
+
+function renderDetailsContent(data) {
+ return () => (
+
+
基本信息
+
+ {Object.keys(data)
+ .filter(key => key !== 'geom')
+ .map(key => (
+
+ {key}:{data[key]}
+
+ ))}
+
+
样式配置
+ {renderStyleContent(data)}
+
+ )
+}
+
+function showDetailsModal(title, data) {
+ openDetailsModal({
+ titleString: title,
+ contentSlot: renderDetailsContent(data),
+ })
+}
diff --git a/src/views/Hangjing/hooks/hangjingDetail.ts b/src/views/Hangjing/hooks/hangjingDetail.ts
deleted file mode 100644
index e33ae6402..000000000
--- a/src/views/Hangjing/hooks/hangjingDetail.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import { h } from 'vue'
-import { useModal } from '@/views/Content/hooks/modal'
-const { openDetailsModal } = useModal()
-
-export const useHangjingDetail = () => {
- return { showDetailsModal }
-}
-
-function renderDetailsContent(data: Record) {
- return h(
- 'div',
- {},
- Object.keys(data).map(key => h('div', {}, `${key}:${data[key]}`))
- )
-}
-
-function showDetailsModal(title: string, data: Record) {
- openDetailsModal({
- titleString: title,
- contentSlot: renderDetailsContent(data),
- })
-}
diff --git a/src/views/Hangjing/hooks/hangjingPolygon.ts b/src/views/Hangjing/hooks/hangjingPolygon.ts
index 97bc427e5..7fd70adbe 100644
--- a/src/views/Hangjing/hooks/hangjingPolygon.ts
+++ b/src/views/Hangjing/hooks/hangjingPolygon.ts
@@ -5,37 +5,44 @@ import { difference } from 'lodash'
import { polygonGradient } from '@/js/polygonGradient'
import { polygonMaterial } from '@/js/polygon'
import { centerOfMass } from '@turf/turf'
+import { useTree } from '@/utils/tree'
import { useHangjingPopup } from './hangjingPopup'
const { createPopup } = useHangjingPopup()
+const { filterTreeNodeByField } = useTree()
export const useHjPolygon = (polygonMap: Map) => {
let subscriber: Subscriber | null = null
const colors = new Map()
- function addHangjingPolygon(data: Record[]) {
+ function addHangjingPolygon(ids, data) {
subscriber = new Subscriber(viewer, {
pickResult: {
enable: true,
},
})
- const ids = data.map(item => item.id)
+ // const ids = data.map(item => item.id)
const addIds = difference(ids, [...polygonMap.keys()])
const removeIds = difference([...polygonMap.keys()], ids)
// 添加
if (addIds.length > 0) {
- addIds.forEach(id => {
- const item = data.find(item => item.id === id)
- if (item) {
- if (item.zoneList.length > 0) {
- item.zoneList.forEach(zone => {
+ const nodes = filterTreeNodeByField({
+ treeData: data.value,
+ params: addIds,
+ paramName: 'dataId',
+ })
+ nodes.forEach(({ data: hjData, dataId: id }) => {
+ // const item = data.find(item => item.id === id)
+ if (hjData) {
+ if (hjData.zoneList.length > 0) {
+ hjData.zoneList.forEach(zone => {
addPolygon(zone, id)
})
} else {
- addPolygon(item)
+ addPolygon(hjData)
}
}
})
@@ -51,12 +58,14 @@ export const useHjPolygon = (polygonMap: Map) => {
}
function addPolygon(item, parentId: number | null = null) {
- const { id, geom } = item
+ const { id, geom, title } = item
const feature = parseWKT(geom)
const position = feature.coordinates[0].map(pos => {
return Cesium.Cartesian3.fromDegrees(...pos)
})
+ const labels = addTextAlongCurve('Cesium中文垂直排列测试', position)
+
// console.log(item, id, position, 'id, position, color')
// const randomColor =
// '#' + Math.random().toString(16).substring(2, 8).padEnd(6, '0')
@@ -68,6 +77,7 @@ export const useHjPolygon = (polygonMap: Map) => {
// if (zoneId) {
// if()
// }
+
const curId = parentId || id
if (!colors.has(curId)) {
@@ -214,3 +224,121 @@ export const useHjPolygon = (polygonMap: Map) => {
removeHangjingPolygon,
}
}
+
+function addTextAlongCurve(text, polygonPoints) {
+ // 创建 Billboard 集合
+ const billboardCollection = viewer.scene.primitives.add(
+ new Cesium.BillboardCollection()
+ )
+
+ // 创建文字绘制的辅助函数
+ function createTextTexture(text, angle) {
+ const canvas = document.createElement('canvas')
+ const context = canvas.getContext('2d')
+
+ // 设置 Canvas 大小
+ canvas.width = 20
+ canvas.height = 20
+
+ // 设置文字样式
+ context.font = '20px sans-serif' // 支持中文
+ context.fillStyle = 'blue'
+ context.textAlign = 'center'
+ context.textBaseline = 'middle'
+
+ // 将文字绘制到 Canvas,并进行旋转
+ context.clearRect(0, 0, canvas.width, canvas.height)
+ context.save()
+
+ // 旋转文字
+ context.translate(canvas.width / 2, canvas.height / 2)
+ context.rotate(angle)
+ context.fillText(text, 0, 0)
+
+ context.restore()
+
+ return canvas
+ }
+
+ // 动态生成字符标注
+ function generateLabels(cameraHeight) {
+ billboardCollection.removeAll() // 清除之前的标注
+
+ let charIndex = 0 // 当前字符索引
+ for (let i = 0; i < polygonPoints.length - 1; i++) {
+ const start = polygonPoints[i] // 当前边的起点
+ const end = polygonPoints[i + 1] // 当前边的终点
+
+ // 计算线段的方向向量
+ const direction = Cesium.Cartesian3.subtract(
+ end,
+ start,
+ new Cesium.Cartesian3()
+ )
+ Cesium.Cartesian3.normalize(direction, direction)
+
+ // 计算垂直于线段的方向向量
+ const perpendicular = Cesium.Cartesian3.cross(
+ direction,
+ Cesium.Cartesian3.UNIT_Z, // 使用 Z 轴(垂直地球表面)计算垂直方向
+ new Cesium.Cartesian3()
+ )
+ Cesium.Cartesian3.normalize(perpendicular, perpendicular)
+
+ // 计算线段的长度
+ const length = Cesium.Cartesian3.distance(start, end)
+
+ // 动态调整字符间隔,基于相机高度
+ const baseSpacing = 50 // 基础字符间隔
+ const charSpacing = Math.max((baseSpacing * cameraHeight) / 5000000, 30)
+
+ // 按字符间隔放置文字
+ let distance = 0
+ while (distance < length && charIndex < text.length) {
+ // 计算字符的位置
+ const fraction = distance / length // 当前字符在边上的位置比例
+ const position = Cesium.Cartesian3.lerp(
+ start,
+ end,
+ fraction,
+ new Cesium.Cartesian3()
+ )
+
+ // 计算旋转角度,使文字垂直于线段
+ const angle = Math.atan2(perpendicular.y, perpendicular.x)
+
+ // 创建带旋转的文字纹理
+ const canvas = createTextTexture(text[charIndex], angle)
+
+ // 添加 Billboard 显示文字
+ billboardCollection.add({
+ position: position,
+ image: canvas, // 使用生成的文字纹理
+ // pixelOffset: new Cesium.Cartesian2(10, 0),
+ verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
+ })
+
+ // 更新字符索引和距离
+ charIndex++
+ console.log(charSpacing)
+ distance += charSpacing * 2000
+ // distance *= 2
+ console.log(distance)
+ }
+
+ // 如果字符已用完,跳出循环
+ if (charIndex >= text.length) {
+ break
+ }
+ }
+ }
+
+ // 初始化标注(根据初始相机高度)
+ generateLabels(viewer.camera.positionCartographic.height)
+
+ // 监听相机变化事件,动态更新字符间隔
+ viewer.camera.changed.addEventListener(() => {
+ const cameraHeight = viewer.camera.positionCartographic.height
+ generateLabels(cameraHeight)
+ })
+}
diff --git a/src/views/Hangjing/hooks/hangjingStyle.ts b/src/views/Hangjing/hooks/hangjingStyle 1.ts
similarity index 100%
rename from src/views/Hangjing/hooks/hangjingStyle.ts
rename to src/views/Hangjing/hooks/hangjingStyle 1.ts
diff --git a/src/views/Hangjing/hooks/hangjingStyle.jsx b/src/views/Hangjing/hooks/hangjingStyle.jsx
new file mode 100644
index 000000000..cfea8ed8b
--- /dev/null
+++ b/src/views/Hangjing/hooks/hangjingStyle.jsx
@@ -0,0 +1,115 @@
+import {
+ NForm,
+ NFormItem,
+ NInput,
+ NColorPicker,
+ NSelect,
+ NInputNumber,
+ NButton,
+} from 'naive-ui'
+import { useModal } from '@/views/Content/hooks/modal'
+const { openDetailsModal } = useModal()
+
+const styleForm = ref({
+ fontFamily: '微软雅黑',
+ fontSize: 14,
+ textColor: 'rgba(255,255,0,1)',
+ polygonColor: 'rgba(255,0,0,0.3)',
+ lineColor: 'rgba(255,0,0,1)',
+ lineWidth: 1,
+ lineType: 'solid',
+})
+export const useHangjingStyle = () => {
+ return { renderStyleContent, showStyleModal }
+}
+
+function renderStyleContent(data) {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 确定
+
+ 取消
+
+
+ )
+}
+
+function showStyleModal(title, data) {
+ openDetailsModal({
+ titleString: title,
+ contentSlot: renderStyleContent(data),
+ })
+}
+
+function updateStyle() {
+ // TODO: 更新样式
+}
diff --git a/src/views/Hangjing/index.vue b/src/views/Hangjing/index.vue
index f77762a26..a323ce557 100644
--- a/src/views/Hangjing/index.vue
+++ b/src/views/Hangjing/index.vue
@@ -9,9 +9,10 @@ import { getHangjing } from '@/api/Hangjing'
import { useHangjing } from './hooks/hangjing'
import { convertToWKT } from '@/utils/parseWKT'
import { useHangjingDetail } from './hooks/hangjingDetail'
-import { useHangjingStyle } from './hooks/hangjingStyle'
+// import { useHangjingStyle } from './hooks/hangjingStyle'
+import Tree from '@/components/Tree/index.vue'
+
-const { addHangjing } = useHangjing()
const timeRange = ref(null)
@@ -101,70 +102,45 @@ const drawArea = () => {
}
const { showDetailsModal } = useHangjingDetail()
-const { showStyleModal } = useHangjingStyle()
-const columns = [
- {
- type: 'selection',
- // disabled(row) {
- // return row.name === 'Edward King 3'
- // },
- },
- {
- title: 'Name',
- key: 'title',
- },
- {
- title: 'Type',
- key: 'hjType',
- },
- {
- title: 'Action',
- key: 'actions',
- render(row) {
- return h('div', { class: 'flex gap-2' }, [
- h(
- NButton,
- {
- strong: true,
- tertiary: true,
- size: 'small',
- onClick: () => showDetailsModal(`${row.title}详情`, row),
- },
- { default: () => '详情' }
- ),
- h(
- NButton,
- {
- strong: true,
- tertiary: true,
- size: 'small',
- onClick: () => showStyleModal(`${row.title}样式配置`, row),
- },
- { default: () => '样式配置' }
- ),
- ])
- },
- },
-]
+// const { showStyleModal } = useHangjingStyle()
const data = ref([])
-const paginationReactive = reactive({
- page: 1,
- pageSize: 50,
- showSizePicker: true,
- pageSizes: [20, 50, 100],
- onChange: page => {
- paginationReactive.page = page
- },
- onUpdatePageSize: pageSize => {
- paginationReactive.pageSize = pageSize
- paginationReactive.page = 1
- },
+const renderSuffix = ({ option }: { option: TreeOption }) => {
+ return option.data ? h('div', { class: 'flex items-center gap-2 pr-2' }, [
+ h(
+ NButton,
+ {
+ text: true,
+ size: 'tiny',
+ type: 'info',
+ onClick: () => showDetailsModal(`${option.data.title}详情`, option.data),
+ },
+ { default: () => '详情' }
+ ),
+ // h(
+ // NButton,
+ // {
+ // text: true,
+ // size: 'tiny',
+ // type: 'info',
+ // onClick: () => showStyleModal(`${option.data.title}样式配置`, option.data),
+ // },
+ // { default: () => '样式配置' }
+ // ),
+ ]) : null
+}
+
+const checkedKeys = ref>([])
+
+const { addHangjing } = useHangjing()
+
+watch(checkedKeys, val => {
+ addHangjing(val, data)
})
+
const handleCheck = (rowKeys: DataTableRowKey[]) => {
const selectedList = data.value.filter(item => rowKeys.includes(item.id))
-
addHangjing(selectedList)
}
@@ -174,7 +150,7 @@ const getHangjingData = async (params = {}) => {
const { code, data: resData } = await getHangjing(params)
if (code === '200') {
- data.value = resData || []
+ data.value = [resData]
}
isLoading.value = false
}
@@ -204,14 +180,8 @@ const clearSelected = () => {
-
+
@@ -239,15 +209,12 @@ const clearSelected = () => {
检索
-
+
+
+
diff --git a/src/views/Mubiao/hooks/mubiao.ts b/src/views/Mubiao/hooks/mubiao.ts
index 55923cc0a..56c5bb7b8 100644
--- a/src/views/Mubiao/hooks/mubiao.ts
+++ b/src/views/Mubiao/hooks/mubiao.ts
@@ -60,7 +60,7 @@ export const useMubiao = () => {
// 获取目标坐标
const mbPos = await getMubiaoCurPos(targetIdList)
- console.log('mbPos', mbPos)
+ // console.log('mbPos', mbPos)
nodes.forEach(({ data, dataId: id }: IMubiao) => {
const { target_time, target_geom } =
@@ -105,6 +105,7 @@ export const useMubiao = () => {
id,
targetType,
})
+
const mubiaoEntity = viewer.entities.add({
name: id,
position: Cesium.Cartesian3.fromDegrees(...(position as number[])),
diff --git a/src/views/Mubiao/hooks/mubiaoDetail.jsx b/src/views/Mubiao/hooks/mubiaoDetail.jsx
new file mode 100644
index 000000000..507b1edb5
--- /dev/null
+++ b/src/views/Mubiao/hooks/mubiaoDetail.jsx
@@ -0,0 +1,127 @@
+// import { h } from 'vue'
+import { NDataTable, NInputNumber, NSwitch } from 'naive-ui'
+import { useModal } from '@/views/Content/hooks/modal'
+const { openDetailsModal } = useModal()
+export const useMubiaoDetail = () => {
+ return { showDetailsMubiao }
+}
+
+const detectingLoadColumns = [
+ {
+ title: '垂直起始角',
+ key: 'minimumClock',
+ width: 180,
+ render(row) {
+ return (
+
+ )
+ },
+ },
+ // {
+ // title: '垂直终止角',
+ // key: 'maximumClock',
+ // width: 180,
+ // render(row) {
+ // return (
+ //
+ // )
+ // },
+ // },
+ {
+ title: '水平起始角',
+ key: 'minimumCone',
+ width: 180,
+ render(row) {
+ return (
+
+ )
+ },
+ },
+ {
+ title: '水平终止角',
+ key: 'maximumCone',
+ width: 180,
+ render(row) {
+ return (
+
+ )
+ },
+ },
+ {
+ title: '半径',
+ key: 'radius',
+ width: 180,
+ render(row) {
+ return (
+
+ )
+ },
+ },
+ {
+ title: '是否开启',
+ key: 'status',
+ render(row) {
+ return
+ },
+ },
+]
+
+const data = ref([
+ {
+ id: 3,
+ radius: 5000,
+ minimumClock: 20.0,
+ maximumClock: 110.0,
+ minimumCone: 20.0,
+ maximumCone: 90.0,
+ height: 100,
+ status: true,
+ },
+])
+
+function renderMubiaoDetailsContent(mbData) {
+ // return h(
+ // 'div',
+ // {},
+ // Object.keys(mbData).map(key => h('div', {}, `${key}:${mbData[key]}`))
+ // )
+ return () => (
+
+
基本信息
+
+ {Object.keys(mbData).map(key => (
+
+ {key}:{mbData[key]}
+
+ ))}
+
+
探测载荷
+
row.id}
+ columns={detectingLoadColumns}
+ data={data.value}
+ />
+
+ )
+}
+function showDetailsMubiao(mbData) {
+ openDetailsModal({
+ titleString: 'zb详情',
+ contentSlot: renderMubiaoDetailsContent(mbData),
+ })
+}
diff --git a/src/views/Mubiao/hooks/mubiaoDetail.ts b/src/views/Mubiao/hooks/mubiaoDetail.ts
deleted file mode 100644
index 9bdca764f..000000000
--- a/src/views/Mubiao/hooks/mubiaoDetail.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import { h } from 'vue'
-import { useModal } from '@/views/Content/hooks/modal'
-const { openDetailsModal } = useModal()
-export const useMubiaoDetail = () => {
- return { showDetailsMubiao }
-}
-function renderMubiaoDetailsContent(mbData: Record) {
- return h(
- 'div',
- {},
- Object.keys(mbData).map(key => h('div', {}, `${key}:${mbData[key]}`))
- )
-}
-function showDetailsMubiao(mbData: Record) {
- openDetailsModal({
- titleString: 'zb详情',
- contentSlot: renderMubiaoDetailsContent(mbData),
- })
-}
diff --git a/src/views/Mubiao/hooks/mubiaoLoad.jsx b/src/views/Mubiao/hooks/mubiaoLoad.jsx
new file mode 100644
index 000000000..118fc995f
--- /dev/null
+++ b/src/views/Mubiao/hooks/mubiaoLoad.jsx
@@ -0,0 +1,18 @@
+import { useModal } from '@/views/Content/hooks/modal'
+const { openDetailsModal } = useModal()
+export const useMubiaoDetail = () => {
+ return { showDetailsMubiao }
+}
+function renderMubiaoDetailsContent(mbData) {
+ return (
+ <>
+
+ >
+ )
+}
+function showDetailsMubiao(mbData) {
+ openDetailsModal({
+ titleString: '载荷',
+ contentSlot: renderMubiaoDetailsContent(mbData),
+ })
+}
diff --git a/src/views/Mubiao/index.vue b/src/views/Mubiao/index.vue
index 0432d01d3..78e927054 100644
--- a/src/views/Mubiao/index.vue
+++ b/src/views/Mubiao/index.vue
@@ -51,6 +51,16 @@ const renderSuffix = ({ option }: { option: TreeOption }) => {
},
{ default: () => '详情' }
),
+ // h(
+ // NButton,
+ // {
+ // text: true,
+ // size: 'tiny',
+ // type: 'info',
+ // onClick: () => showDetailsMubiao(option.data),
+ // },
+ // { default: () => '载荷' }
+ // ),
h(
NButton,
{
@@ -89,14 +99,8 @@ const renderSuffix = ({ option }: { option: TreeOption }) => {
@update:checked-row-keys="handleCheck"
/> -->
-
+
diff --git a/src/views/Satellite/components/SatDetail.jsx b/src/views/Satellite/components/SatDetail.jsx
new file mode 100644
index 000000000..1590ff0db
--- /dev/null
+++ b/src/views/Satellite/components/SatDetail.jsx
@@ -0,0 +1,127 @@
+import { useModal } from '@/views/Content/hooks/modal'
+import { NDataTable, NSelect, NInputNumber, NSwitch } from 'naive-ui'
+
+const { openDetailsModal } = useModal()
+
+const detectingLoadColumns = [
+ // {
+ // title: '载荷类型',
+ // key: 'type',
+ // render(row) {
+ // return (
+ //
+ // )
+ // },
+ // },
+ {
+ title: '开合角',
+ key: 'angle',
+ width: 120,
+ render(row) {
+ return (
+
+ )
+ },
+ },
+ // {
+ // title: '水平半角',
+ // key: 'xHalfAngle',
+ // width: 120,
+ // render(row) {
+ // return (
+ //
+ // )
+ // },
+ // },
+ // {
+ // title: '垂直半角',
+ // key: 'yHalfAngle',
+ // width: 120,
+ // render(row) {
+ // return (
+ //
+ // )
+ // },
+ // },
+ {
+ title: '是否开启',
+ key: 'status',
+ render(row) {
+ return
+ },
+ },
+]
+
+const data = ref([
+ {
+ id: 3,
+ angle: 30,
+ // xHalfAngle: 20,
+ // yHalfAngle: 25,
+ // type: '电子',
+ status: true,
+ },
+])
+
+export function showDetailsSatellite(option) {
+ openDetailsModal({
+ titleString: '' + option.name + ' 详情',
+ contentSlot: () => (
+
+
基本信息
+
+
卫星编号:{option.name}
+
+
两行根数:
+
+
{option.tle.split('\n')[0]}
+
{option.tle.split('\n')[1]}
+
{option.tle.split('\n')[2]}
+
+
+
+
探测载荷
+
row.id}
+ columns={detectingLoadColumns}
+ data={data.value}
+ />
+ 通信载荷
+ {/* row.id}
+ columns={detectingLoadColumns}
+ data={data.value}
+ /> */}
+
+ ),
+ })
+}
+
+// export default defineComponent({
+// name: 'SatDetail',
+// setup(props) {
+// return () => <>>
+// },
+// })
diff --git a/src/views/Satellite/hooks/satellite.ts b/src/views/Satellite/hooks/satellite.ts
index 2df366b1f..4704be407 100644
--- a/src/views/Satellite/hooks/satellite.ts
+++ b/src/views/Satellite/hooks/satellite.ts
@@ -2,11 +2,10 @@ import SatelliteEntity from '@/js/SatelliteEntity'
import { difference } from 'lodash'
import { useEntity } from '@/hooks/entity'
// import CreateFrustum from '@/js/Sensor'
-import * as CesiumSensorVolumes from 'cesium-sensors-es6'
interface ISatellite {
name: string
- id: number | string
+ id: string
tle: string
}
@@ -18,6 +17,17 @@ interface IBaseFilterParam {
const satelliteList = ref([])
const { satelliteMap } = useEntity()
+
+const showPoint = ref(true)
+function showPointUnderSat(id?: string) {
+ if (id) {
+ satelliteMap.get(id).underPoint = true
+ } else {
+ ;[...satelliteMap.values()].forEach(satellite => {
+ satellite.underPoint = showPoint.value
+ })
+ }
+}
export function useSatellite() {
function addSatellites(ids: Array) {
const addIds = difference(ids, [...satelliteMap.keys()])
@@ -33,6 +43,9 @@ export function useSatellite() {
nodes.forEach(node => {
const entity = addSatellite(node)
satelliteMap.set(node.id, entity)
+ if (showPoint.value) {
+ showPointUnderSat(node.id)
+ }
})
}
@@ -47,9 +60,10 @@ export function useSatellite() {
// const result = viewer.entities.add(cesiumSateEntity)
setTimeout(() => {
- satellite.sensorType = Math.random() > 0.5 ? 'conic' : 'rectangle'
+ // satellite.sensorType = Math.random() > 0.5 ? 'conic' : 'rectangle'
satellite.sensor = true
}, 1000)
+
// viewer.clock.multiplier = 100
return satellite
@@ -85,7 +99,7 @@ export function useSatellite() {
}
}
- return { satelliteList, addSatellites }
+ return { satelliteList, addSatellites, showPoint, showPointUnderSat }
}
function filterTreeNodeByField({
diff --git a/src/views/Satellite/index.vue b/src/views/Satellite/index.vue
index 6533c7577..b8d0edbca 100644
--- a/src/views/Satellite/index.vue
+++ b/src/views/Satellite/index.vue
@@ -4,6 +4,7 @@ import { NButton } from 'naive-ui'
import Tree from '@/components/Tree/index.vue'
import { getSatellite } from '@/api/Satellite'
import { useSatellite } from './hooks/satellite'
+import { showDetailsSatellite } from './components/SatDetail'
const { satelliteList, addSatellites } = useSatellite()
@@ -35,7 +36,7 @@ const renderSuffix = ({ option }: { option: TreeOption }) => {
text: true,
size: 'tiny',
type: 'info',
- // onClick: () => showDetailsSatellite(option),
+ onClick: () => showDetailsSatellite(option),
},
{ default: () => '详情' }
),
@@ -67,5 +68,6 @@ const renderSuffix = ({ option }: { option: TreeOption }) => {
showSearch
:renderSuffix="renderSuffix"
/>
+