| | |
| | | <a-input v-model:value="currentWayLine.name" placeholder="请输入航线名称" /> |
| | | </a-modal> |
| | | </div> |
| | | <!-- 航线编辑 --> |
| | | <ul class="targt-point scrollbar" :style="{ height: height + 'px' }" v-else> |
| | | <div class="back-btn" @click="isPointListOpen = !isPointListOpen"> |
| | | <div class="back-btn" @click="backPage"> |
| | | <ArrowLeftOutlined /> |
| | | <span>返回上一页</span> |
| | | </div> |
| | | <div class="wayline-info"> |
| | | <div class="info-box" v-for="(item, index) in waylineDetails" :key="index"> |
| | | <div class="title">{{ item.title }}</div> |
| | | <div class="info">{{ item.value }}</div> |
| | | </div> |
| | | </div> |
| | | <li v-for="(item, index) in tragetPointArr" :key="index" :class="{ selectedColor: index === selectedPoint }" |
| | | @click="tragetPointClick(item.position, index)"> |
| | |
| | | import { message } from 'ant-design-vue' |
| | | import { onMounted, onUpdated, ref } from 'vue' |
| | | import ImageTrailMaterial from '/@/utils/cesium/ImageTrailMaterial' |
| | | import { getPolylineLength } from '/@/utils/cesium/mapUtils' |
| | | import { |
| | | deleteWaylineFile, |
| | | downloadWaylineFile, |
| | |
| | | |
| | | const getResource = (name: string) => { |
| | | return new URL(`/src/assets/icons/${name}`, import.meta.url).href |
| | | } |
| | | const getResourceSvg = (name: string) => { |
| | | return new URL(`/src/assets/svg/${name}`, import.meta.url).href |
| | | } |
| | | |
| | | const projectWayLine = ref<HTMLDivElement>() |
| | |
| | | ) |
| | | const editVisible = ref<boolean>(false) |
| | | const height = ref() |
| | | const { removeById, addClickEvent, getEntityById, addPolyline } = cesiumOperation() |
| | | const { removeById, addClickEvent, getEntityById, addPolyline, removeAllPoint } = cesiumOperation() |
| | | |
| | | const isPointListOpen = ref<boolean>(false) |
| | | const tragetPointArr = ref< |
| | |
| | | if (kmlDataSource) { |
| | | global.$viewer.dataSources.remove(kmlDataSource) |
| | | } |
| | | removeById('entityLine') |
| | | removeById('bottomLine') |
| | | // removeById('entityLine') |
| | | removeAllPoint() |
| | | removeById('clickBox') |
| | | store.commit('SET_WAYLINE_INFO', { |
| | | isShow: false, |
| | |
| | | * @param file |
| | | */ |
| | | function initKmlFile (file: string) { |
| | | // const [, address] = file.split('cloud-bucket') |
| | | // file = import.meta.env.VITE_MEDIAPANEL_API_URL + address |
| | | removeById('entityLine') |
| | | removeById('bottomLine') |
| | | // removeById('entityLine') |
| | | removeAllPoint() |
| | | const options = { |
| | | camera: global.$viewer.scene.camera, |
| | | canvas: global.$viewer.scene.canvas, |
| | |
| | | .add(Cesium.KmlDataSource.load(file, options)) |
| | | .then((res: any) => { |
| | | kmlDataSource = res |
| | | kmlEntity.value = kmlDataSource.entities.values |
| | | kmlDataSource.show = true |
| | | const kmlEntityArr = kmlDataSource.entities.values[0]._children |
| | | const cartesianArr: any[] = [] |
| | | for (let i = 0; i < kmlEntityArr.length; i++) { |
| | | const entity = kmlEntityArr[i] |
| | | const billboard = createBillboard(`${i + 1}`, '#2D8CF0') |
| | | entity._id = 'tragetPoint' + i |
| | | entity.billboard = new Cesium.BillboardGraphics({ |
| | | image: billboard, |
| | | pixelOffset: new Cesium.Cartesian2(0, -20), |
| | | }) |
| | | entity.point = new Cesium.PointGraphics({ |
| | | pixelSize: 20, |
| | | color: Cesium.Color.GHOSTWHITE, |
| | | outlineColor: Cesium.Color.BLACK, |
| | | }) |
| | | cartesianArr.push(entity.position._value) |
| | | tragetPointArr.value[i] = { |
| | | position: entity.position._value, |
| | | eventList: [], |
| | | } |
| | | } |
| | | // tragetPointArr.value = cartesianArr |
| | | // const stripe = createStripe() |
| | | // 绘制静态线 |
| | | addPolyline({ |
| | | id: 'entityLine', |
| | | polyline: { |
| | | positions: cartesianArr, |
| | | width: 10, |
| | | material: new Cesium.ImageMaterialProperty({ |
| | | image: getResource('arrow-right.png'), |
| | | color: Cesium.Color.WHITE, |
| | | repeat: new Cesium.Cartesian2(30, 1), |
| | | }), |
| | | zIndex: 2, |
| | | clampToGround: true, // 关闭贴地效果,保留高度 |
| | | }, |
| | | }) |
| | | addPolyline({ |
| | | id: 'bottomLine', |
| | | polyline: { |
| | | positions: cartesianArr, |
| | | width: 7, |
| | | material: Cesium.Color.fromBytes(96, 210, 149), |
| | | zIndex: 1, |
| | | clampToGround: true, // 关闭贴地效果,保留高度 |
| | | }, |
| | | }) |
| | | |
| | | const lineEntity = getEntityById('entityLine') |
| | | global.$viewer.flyTo(lineEntity, { |
| | | offset: new Cesium.HeadingPitchRange(0, -90, 200), |
| | | }) |
| | | |
| | | createPointMarker(kmlDataSource) |
| | | // 解析kmz文件 |
| | | readKmzFile(file) |
| | | }) |
| | | } |
| | | |
| | | const waylineDetails = reactive([ |
| | | { |
| | | title: '航线长度', |
| | | value: '0' |
| | | }, |
| | | { |
| | | title: '预计执行时间', |
| | | value: '0' |
| | | }, |
| | | { |
| | | title: '航点', |
| | | value: 0 |
| | | }, |
| | | { |
| | | title: '照片', |
| | | value: 0 |
| | | }, |
| | | ]) |
| | | function createPointMarker (dataSource: { entities: { values: { _children: any }[] }; show: boolean }) { |
| | | const ellipsoid = global.$viewer.scene.globe.ellipsoid |
| | | kmlEntity.value = dataSource.entities.values |
| | | dataSource.show = true |
| | | const kmlEntityArr = dataSource.entities.values[0]._children |
| | | const cartesianArr: any[] = [] |
| | | let btmStartPoint = null |
| | | for (let i = 0; i < kmlEntityArr.length; i++) { |
| | | const entity = kmlEntityArr[i] |
| | | // 将cartographic3D坐标转换为正常坐标 |
| | | const c3Position = entity.position._value |
| | | const c2Postion = ellipsoid.cartesianToCartographic(c3Position) |
| | | const longitude = Cesium.Math.toDegrees(c2Postion.longitude) |
| | | const latitude = Cesium.Math.toDegrees(c2Postion.latitude) |
| | | const height = 100 |
| | | entity.position = Cesium.Cartesian3.fromDegrees(longitude, latitude, height) |
| | | if (i === 0) { |
| | | btmStartPoint = Cesium.Cartesian3.fromDegrees(longitude, latitude, 0) |
| | | } |
| | | // 创建广告牌信息 |
| | | const billboard = createBillboard(`${i + 1}`, '#61d396') |
| | | // 修改id |
| | | entity._id = 'tragetPoint' + i |
| | | // 修改广告牌样式 |
| | | entity.billboard = new Cesium.BillboardGraphics({ |
| | | image: billboard, |
| | | pixelOffset: new Cesium.Cartesian2(0, -20), |
| | | }) |
| | | // 修改点的信息 |
| | | entity.point = new Cesium.PointGraphics({ |
| | | pixelSize: 20, |
| | | color: Cesium.Color.GHOSTWHITE, |
| | | outlineColor: Cesium.Color.BLACK, |
| | | }) |
| | | // 创建虚线 |
| | | addPolyline({ |
| | | id: 'dashLine' + i, |
| | | polyline: { |
| | | positions: Cesium.Cartesian3.fromDegreesArrayHeights([ |
| | | longitude, |
| | | latitude, |
| | | height, |
| | | longitude, |
| | | latitude, |
| | | 0 |
| | | ]), |
| | | width: 1, |
| | | material: new Cesium.PolylineDashMaterialProperty({ |
| | | color: Cesium.Color.WHITE |
| | | }) |
| | | } |
| | | }) |
| | | cartesianArr.push(entity.position._value) |
| | | tragetPointArr.value[i] = { |
| | | position: entity.position._value, |
| | | eventList: [], |
| | | } |
| | | } |
| | | // 创建起飞位置 |
| | | global.$viewer.entities.add({ |
| | | id: 'dronePosition', |
| | | position: btmStartPoint, |
| | | billboard: { |
| | | image: getResource('dock.png'), |
| | | width: 36, |
| | | height: 36, |
| | | } |
| | | }) |
| | | // 绘制链接线 |
| | | addPolyline({ |
| | | id: 'entityLine', |
| | | polyline: { |
| | | positions: [btmStartPoint, ...cartesianArr], |
| | | width: 7, |
| | | material: new ImageTrailMaterial({ |
| | | backgroundColor: Cesium.Color.fromBytes(96, 210, 149), |
| | | image: getResource('arrow-right.png'), |
| | | imageW: 7, |
| | | duration: 0, |
| | | animation: false |
| | | }), |
| | | clampToGround: false, // 关闭贴地效果,保留高度 |
| | | }, |
| | | }) |
| | | const lineEntity = getEntityById('entityLine') |
| | | const polylineLength = getPolylineLength(lineEntity).toFixed(1) || 0 |
| | | waylineDetails[0].value = polylineLength + 'm' |
| | | waylineDetails[2].value = cartesianArr.length |
| | | global.$viewer.flyTo(lineEntity, { |
| | | offset: new Cesium.HeadingPitchRange(0, -90, 300), |
| | | }) |
| | | } |
| | | |
| | | // 返回上一页 |
| | | function backPage () { |
| | | isPointListOpen.value = false |
| | | store.commit('SET_WAYLINE_INFO', { |
| | | isShow: false, |
| | | wayline: {}, |
| | | position: 0, |
| | | }) |
| | | } |
| | | |
| | | // 点击目标点 |
| | |
| | | selectedPoint.value = index |
| | | store.commit('SET_WAYLINE_INFO', { |
| | | isShow: true, |
| | | wayline: currentWayLine, |
| | | wayline: currentWayLine.value, |
| | | position: index, |
| | | }) |
| | | if (getEntityById('clickBox')) { |
| | |
| | | }) |
| | | } |
| | | ) |
| | | // 创建盒子 |
| | | const entity = { |
| | | id: 'clickBox', |
| | | position, |
| | | box: { |
| | | dimensions: new Cesium.Cartesian3(10.0, 10.0, 120), |
| | | material: Cesium.Color.MEDIUMSPRINGGREEN.withAlpha(0.1), |
| | | // outline: true, |
| | | // outlineColor: Cesium.Color.MEDIUMSPRINGGREEN.withAlpha(0.8), |
| | | heightReference: true, |
| | | }, |
| | | } |
| | | |
| | | const boxEntity = global.$viewer.entities.add(entity) |
| | | global.$viewer.flyTo(boxEntity, { |
| | | duration: 3, |
| | | }) |
| | | } |
| | | |
| | | function onScroll (e: any) { |
| | |
| | | } |
| | | |
| | | // 创建广告牌 |
| | | const createBillboard = (title: string, color: string) => { |
| | | const createBillboard = (title: string | number, color: string) => { |
| | | // 创建canvas绘制广告牌 |
| | | const billboard = document.createElement('canvas') |
| | | billboard.width = 30 |
| | |
| | | ctx.fill() |
| | | ctx.font = '18px serif' |
| | | ctx.fillStyle = '#ffffff' |
| | | ctx.fillText(title, 10, 15) |
| | | ctx.fillText(Number(title) === 1 ? 'S' : title, 10, 15) |
| | | ctx.closePath() |
| | | return billboard |
| | | } |
| | | |
| | | // 创建条纹 |
| | | const createStripe = () => { |
| | | // 创建canvas绘制广告牌 |
| | | const stripe = document.createElement('canvas') |
| | | stripe.width = 40 |
| | | stripe.height = 40 |
| | | const ctx: HTMLCanvasElement | any = stripe.getContext('2d') |
| | | ctx.beginPath() |
| | | ctx.moveTo(0, 20) |
| | | ctx.lineTo(0, 40) |
| | | ctx.lineTo(20, 20) |
| | | ctx.lineTo(20, 0) |
| | | ctx.fillStyle = '#fff' |
| | | ctx.fill() |
| | | ctx.closePath() |
| | | ctx.beginPath() |
| | | ctx.moveTo(20, 0) |
| | | ctx.lineTo(20, 20) |
| | | ctx.lineTo(40, 40) |
| | | ctx.lineTo(40, 20) |
| | | ctx.fillStyle = '#fff' |
| | | ctx.fill() |
| | | ctx.closePath() |
| | | return stripe |
| | | } |
| | | |
| | | /** |
| | |
| | | color: #2d8cf0; |
| | | } |
| | | } |
| | | .wayline-info { |
| | | display: flex; |
| | | height: 50px; |
| | | margin: 10px 0; |
| | | text-align: center; |
| | | align-items: center; |
| | | .info-box { |
| | | flex: 1; |
| | | border-right: 1px solid hsla(0,0%,100%,.1); |
| | | .title { |
| | | color: hsla(0,0%,100%,.65); |
| | | font-size: 12px; |
| | | font-weight: bold; |
| | | } |
| | | .info { |
| | | font-weight: bold; |
| | | } |
| | | &:last-child { |
| | | border: 0; |
| | | } |
| | | } |
| | | } |
| | | |
| | | li { |
| | | cursor: pointer; |
| | |
| | | background-color: #3c3c3c; |
| | | } |
| | | </style> |
| | | ../../../utils/cesium/polylineImageTrailMaterial |