IconSelector设置军标,Cesium添加军标

This commit is contained in:
liaoboping 2025-09-10 16:17:41 +08:00
parent 5f68826986
commit 8f2f953a14
4 changed files with 188 additions and 10 deletions

View File

@ -2,6 +2,28 @@ import * as Cesium from 'cesium'
import CesiumNavigation from 'cesium-navigation-es6' import CesiumNavigation from 'cesium-navigation-es6'
import 'cesium/Build/Cesium/Widgets/widgets.css' import 'cesium/Build/Cesium/Widgets/widgets.css'
const getCatesian3FromPX = (viewer, px) => {
const picks = viewer.scene.drillPick(px)
viewer.scene.render()
let cartesian
let isOn3dtiles = false
for (var i = 0; i < picks.length; i++) {
if (picks[i] && picks[i].primitive && picks[i].primitive instanceof Cesium.Cesium3DTileset) {
//模型上拾取
isOn3dtiles = true
break
}
}
if (isOn3dtiles) {
cartesian = viewer.scene.pickPosition(px)
} else {
var ray = viewer.camera.getPickRay(px)
if (!ray) return null
cartesian = viewer.scene.globe.pick(ray, viewer.scene)
}
return cartesian
}
export default class MyCesium { export default class MyCesium {
static ImageryProviderUrl = '/map/mapWX/{z}/{x}/{y}.jpg' static ImageryProviderUrl = '/map/mapWX/{z}/{x}/{y}.jpg'
static RoadProviderUrl = '' static RoadProviderUrl = ''
@ -299,4 +321,49 @@ export default class MyCesium {
}, },
}) })
} }
/**
* 添加军标(base64图片)
* @param base64
* @param x
* @param y
*/
addPlot(base64, { x, y }) {
this.cancelPreviousOperation()
const id = Cesium.createGuid()
const position = getCatesian3FromPX(this.viewer, { x, y })
if (!position) return
const isEnemy = false
const color = 'red'
const radius = 150000
this.viewer.entities.add({
id,
position,
billboard: {
image: base64,
width: 50,
height: 50,
eyeOffset: new Cesium.Cartesian3(0.0, 0.0, -100000.0), // 使标记在远处看起来更大
},
ellipse: {
semiMajorAxis: radius,
semiMinorAxis: radius,
material: Cesium.Color.fromCssColorString('transparent'),
outline: true,
outlineWidth: 1,
outlineColor: Cesium.Color.fromCssColorString(color),
height: 0,
},
properties: {
type: MyCesium.ENTITY_TYPES.IMAGE,
color,
isEnemy,
radius,
collisions: new Set(),
},
})
}
} }

View File

@ -1,13 +1,106 @@
<template> <template>
<div class="icon-selector"></div> <div class="icon-selector">
<a-dropdown
:trigger="['click']"
:getPopupContainer="() => $el"
overlayClassName="a"
:overlayStyle="{
width: '100%',
borderRadius: '4px',
backgroundColor: '#fefefe',
overflow: 'hidden',
padding: '10px',
boxShadow: '0 0 2px 2px #00000033',
}"
>
<Flex ai="c" style="height: 40px; padding: 0 10px; border-radius: 4px; box-shadow: 0 0 1px 1px #00000022">
<div class="flex-1" style="line-height: 1">
<span v-if="!value" class="text-placeholder">请选择军标</span>
<span v-else-if="!iconSrc" class="text-placeholder">未找到军标</span>
<img
v-else
:src="iconSrc"
alt=""
class="icon-preview"
style="height: 32px; width: 32px; object-fit: contain"
/>
</div>
<a-icon type="down" style="font-size: 16px; margin-left: 10px" />
</Flex>
<div slot="overlay" class="icons-wrapper scroller-y">
<Flex fw="w" class="icon-list">
<div
v-for="item in iconList"
:key="item.id"
:class="{ 'icon-item': true, 'icon-selected': item.id === value }"
@click="handleSelect(item)"
>
<img class="icon-image" :src="item.iconBase64" alt="" />
</div>
</Flex>
</div>
</a-dropdown>
</div>
</template> </template>
<script> <script>
import { getAction } from '@/api/manage'
export default { export default {
props: { props: {
value: { validator: () => true, required: true }, value: { validator: () => true, required: true },
}, },
data() {
return {
iconList: [],
}
},
computed: {
iconSrc() {
return this.iconList.find((item) => item.id === this.value)?.iconBase64
},
},
created() {
this.getIconList()
},
methods: {
async getIconList() {
try {
const res = await getAction('/icon/list', { pageSize: 9999 })
this.iconList = res.data.data
} catch (error) {
console.log(error)
}
},
handleSelect(item) {
if (item.id === this.value) return
this.$emit('input', item.id)
this.$emit('change', item.id)
},
},
} }
</script> </script>
<style lang="less" scoped></style> <style lang="less" scoped>
.icons-wrapper {
max-height: 200px;
}
.icon-item {
width: 50px;
height: 50px;
padding: 9px;
border-radius: 4px;
cursor: pointer;
.icon-image {
width: 32px;
height: 32px;
object-fit: contain;
}
}
.icon-selected {
background-color: #bae7ff;
}
.icon-item:not(.icon-selected):hover {
background-color: #cecece;
}
</style>

View File

@ -337,7 +337,7 @@ export default {
}, },
zb: { zb: {
entityType: '', entityType: '',
parentId: '', parentId: 0,
queryConfig: { queryConfig: {
items: [ items: [
{ {
@ -544,10 +544,10 @@ export default {
} }
}, },
handleOpenEditZbjbModal(id, data) { handleOpenEditZbjbModal(id, data) {
this.zbjbModal.title = '修改军标' this.zbjbModal.title = `修改 ${data.entityName} 军标`
this.zbjbModal.formData = {} this.zbjbModal.formData = {}
this.zbjbModal.formData.id = id this.zbjbModal.formData.id = id
this.zbjbModal.formData.iconId = data.iconId this.$set(this.zbjbModal.formData, 'iconId', data.iconId)
this.zbjbModal.visible = true this.zbjbModal.visible = true
}, },
handleSubmitZbjb(formData) { handleSubmitZbjb(formData) {

View File

@ -42,9 +42,15 @@
@change="getZbysListData()" @change="getZbysListData()"
/> />
</Flex> </Flex>
<Flex class="flex-1 scroller-y" fw="w"> <Flex class="flex-1 scroller-y" fw="w" ac="fs">
<Flex v-for="item in model.listData" :key="item.id" class="model-item" fd="co" ai="c"> <Flex v-for="item in model.listData" :key="item.id" class="model-item" fd="co" ai="c">
<img class="model-image" :src="item.imgBase64" :draggable="true" /> <img
class="model-image"
:src="item.imgBase64"
:draggable="true"
@dragstart="dragstart(item, $event)"
@dragend="dragend(item, $event)"
/>
<span class="model-name">{{ item.name }}</span> <span class="model-name">{{ item.name }}</span>
</Flex> </Flex>
</Flex> </Flex>
@ -52,7 +58,12 @@
</Flex> </Flex>
</ModuleWrapper> </ModuleWrapper>
</div> </div>
<div class="cesium-container" id="cesium-container" style="grid-column: 2 / 3; overflow: hidden"></div> <div
ref="cesium-container"
class="cesium-container"
id="cesium-container"
style="grid-column: 2 / 3; overflow: hidden"
></div>
<div> <div>
<ModuleWrapper height="100%"> <ModuleWrapper height="100%">
<template #title> <template #title>
@ -153,11 +164,18 @@ export default {
keyword: this.model.queryParams.keyword, keyword: this.model.queryParams.keyword,
}) })
this.model.listData = res.data this.model.listData = res.data
console.log(this.model.listData)
} catch (error) { } catch (error) {
console.log(error) console.log(error)
} }
}, },
dragstart(item, e) {},
dragend(item, e) {
console.log(e.x, this.$refs['cesium-container'].offsetLeft, e.x - this.$refs['cesium-container'].offsetLeft)
console.log(e.y, this.$refs['cesium-container'].offsetTop, e.y - this.$refs['cesium-container'].offsetTop)
const x = e.x - this.$refs['cesium-container'].offsetLeft
const y = e.y - this.$refs['cesium-container'].offsetTop
this.cesium.addPlot(item.imgBase64, { x, y })
},
}, },
} }
</script> </script>
@ -198,4 +216,4 @@ export default {
overflow: visible; overflow: visible;
} }
} }
</style> </style>