原生cesium 实现 模型单体化(entity)

🚀 个人简介:某大型测绘遥感企业资深Webgis开发工程师,软件设计师(中级)、优快云优质创作者
💟 作 者:柳晓黑胡椒❣️
📝 专 栏:cesium实践(原生)
🌈 若有帮助,还请关注点赞收藏,不行的话我再努努力💪💪💪

需求背景

需要在倾斜模型(3dtiles)的某一层楼栋,做单楼层的单体化
存在3dtiles的元素分的比较细,无法定位到 单楼层级别

解决思路

使用描边的方式,获取 楼栋的四个顶点,通过 entity.polygon 模拟模型单体化

解决效果

index.vue

/**
 * @author: liuk
 * @date: 2024-11-21
 * @describe: 模型单体化(entity)
 */
<template>
  <div class="tilesetOnlyEntity-wrap">
    <Tdt_img_d/>
  </div>
</template>

<script lang="ts" setup>
import {onMounted, onUnmounted, ref} from "vue";
import * as mars3d from "mars3d";
import {usemapStore} from "@/store/modules/cesiumMap";

// Component
import Tdt_img_d from "@/views/cesium/component/controlPanel/layerManagement/basicMap/tdt_img_d.vue"
import {ElMessage} from "element-plus";

const timestamp = ref(null)

const mapStore = usemapStore()
onMounted(() => {
  add3dtileset()
  addEntity()
  viewer.dataSources.add(tilesetOnlyEntityDatasource);
  handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
  handler.setInputAction(onMouseMove, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
  handler.setInputAction(onMouseClick, Cesium.ScreenSpaceEventType.LEFT_CLICK);
})

onUnmounted(() => {
  handler.destroy()
  const primitive = viewer.scene.primitives._primitives.find(primitive => primitive.name === 'tilesetOnlyEntity')
  viewer.scene.primitives.remove(primitive)
  tilesetOnlyEntityDatasource?.entities?.removeAll()
  viewer.dataSources.remove(tilesetOnlyEntityDatasource);
})

// 地图逻辑
const viewer = mapStore.getCesiumViewer();
let tileset, handler, preEntity;
const coordinates = [[114.393023, 30.39233], [114.393113, 30.391984], [114.393573, 30.392082], [114.393588, 30.392045], [114.393712, 30.39207], [114.393623, 30.392423], [114.393023, 30.39233]]
const tilesetOnlyEntityDatasource = new Cesium.CustomDataSource("tilesetOnlyEntity");

const add3dtileset = () => {
  tileset = new mars3d.layer.TilesetLayer({
    name: "tilesetOnlyEntity",
    url: 'https://das-future-map-1301434080.cos.ap-nanjing.myqcloud.com/%E6%B6%88%E9%98%B2%E6%BC%94%E7%BB%83/3dtile/tileset.json', //数据地址
    maximumScreenSpaceError: 25,
    maximumMemoryUsage: 1024,
    enableCollision: true,
    flyTo: true,
  })
  viewer.addLayer(tileset)
}

const addEntity = () => {
  for (let i = 1; i < 5; i++) { // 5层楼
    tilesetOnlyEntityDatasource.entities.add({
      customType: "aaa",
      index: i,
      polygon: {
        hierarchy: Cesium.Cartesian3.fromDegreesArray(coordinates.flat()),
        extrudedHeight: 15 + 4.5 * i, // 初始高度 + 拉伸高度
        height: 15 + 4.5 * (i - 1),
        material: Cesium.Color.fromAlpha(Cesium.Color.BLUE, 0.01),
      },
    });
  }
}

const onMouseMove = (movement) => {
  const pickedObject = viewer.scene.pick(movement.endPosition);
  if (timestamp.value && new Date() - timestamp.value >= 500) {
    preEntity.polygon.material = Cesium.Color.AQUA.withAlpha(0.01)
  }
  if (!Cesium.defined(pickedObject) || !Cesium.defined(pickedObject.id)) return
  const entity = pickedObject.id;
  if (entity instanceof Cesium.Entity && entity.customType === 'aaa') {
    if (preEntity && preEntity !== entity) preEntity.polygon.material = Cesium.Color.AQUA.withAlpha(0.01)
    entity.polygon.material = Cesium.Color.AQUA.withAlpha(0.7);
    timestamp.value = +new Date()
    preEntity = entity
  }
}

const onMouseClick = (movement) => {
  const pickedObject = viewer.scene.pick(movement.position);
  if (!Cesium.defined(pickedObject) || !Cesium.defined(pickedObject.id)) return
  const entity = pickedObject.id;
  if (entity instanceof Cesium.Entity && entity.customType === 'aaa') {
    ElMessage.success('点击' + entity.index)
  }
}

</script>

<style lang="scss" scoped>
.tilesetOnlyEntity-wrap{

}
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柳晓黑胡椒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值