cesium中显示点位弹框

显示点位图标
/**
 * @param {Viewer} viewer
 * 
 */
export default class DragEntity {
    constructor(val) {
        this.viewer = val.viewer
    }
    addEntity(value) {
        let pinBuilder = new Cesium.PinBuilder();
        // 图片地址
        const url = Cesium.buildModuleUrl(value.text);
        let poin =  Promise.resolve(
            // 设置颜色
            pinBuilder.fromUrl(url, Cesium.Color[value.color]||value.color, 48)
        ).then((canvas) => {
            return this.viewer.entities.add({
                id: value.id,
                name: value.type,
                position: Cesium.Cartesian3.fromDegrees(value.position.x, value.position.y),
                billboard: {
                    image: canvas.toDataURL(),
                    verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
                    heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
                },
                // 这里绑定信息,给弹框使用
                monitoItems: {
                    data: value
                },
            });
        });
        return poin
    }
}
创建用于显示弹框的封装
/**
 * @descripion:
 * @param {Viewer} viewer
 * @param {Cartesian2} position
 * @param {String} title
 * @param {String} id
 * @return {*}
 */

import Vue from "vue";
import Label from "./index.vue";
let WindowVm = Vue.extend(Label);
export default class Bubble {
  constructor(val) {
    this.viewer = val.viewer;
    let lon = val?.longitude
    let lat = val?.latitude
    let position = {lon,lat}
    // 后端数据问题这里处理下
    this.position = val?.position||position;
    this.vmInstance = new WindowVm({
      propsData: {
        // 给创建好的弹框实例传入props数据便于内部渲染
        value: val?._monitoItems?.data || {}
      }
    }).$mount(); //根据模板创建一个面板

    this.vmInstance.closeEvent = e => {
      this.windowClose();
    }

    val.viewer.cesiumWidget.container.appendChild(this.vmInstance.$el); //将字符串模板生成的内容添加到DOM上

    this.addPostRender();
  }

  //添加场景事件
  addPostRender() {
    this.viewer.scene.postRender.addEventListener(this.postRender, this);
  }
  //场景渲染事件 实时更新窗口的位置 使其与笛卡尔坐标一致
  postRender() {
    if (!this.vmInstance.$el || !this.vmInstance.$el.style) return;
    const canvasHeight = this.viewer.scene.canvas.height;
    const windowPosition = new Cesium.Cartesian2();
    Cesium.SceneTransforms.wgs84ToWindowCoordinates(
      this.viewer.scene,
      this.position,
      windowPosition
    );
    // 调整偏移变量
    this.vmInstance.$el.style.bottom =
      canvasHeight - windowPosition.y + 240 + "px";
    const elWidth = this.vmInstance.$el.offsetWidth;
    this.vmInstance.$el.style.left = windowPosition.x - elWidth / 2 + 600 + "px";

    const camerPosition = this.viewer.camera.position;
    let height = this.viewer.scene.globe.ellipsoid.cartesianToCartographic(camerPosition).height;
    height += this.viewer.scene.globe.ellipsoid.maximumRadius;
  }
  //关闭 
  windowClose() {
    if (this.vmInstance) {
      this.vmInstance.$el.remove();
      this.vmInstance.$destroy();
    }
    if (!this.vmInstance.$el || !this.vmInstance.$el.style) {
      return
    }else{
      this.vmInstance.$el.style.display = "none"; //删除dom
      this.viewer.scene.postRender.removeEventListener(this.postRender, this); //移除事件监听

    };
  }
}

创建用于显示弹框的vue文件
<template>
    <div :id="value.id">
        <div class="box-wrap">
            <div class="close" @click="closeClick">X</div>
            <div class="area">
                <el-tooltip class="item" effect="dark" :content="value.name ||'暂无信息'" placement="top">
                    <div class="area-title fontColor text_show" style="padding-left:26px">{{ value.name || "暂无信息" }}</div>
                </el-tooltip>
            </div>
            <!-- 人员轨迹 -->
            <div class="content" v-if="value.type == 'patrol'">
                <div class="data-li" style="width: 120px">
                    <div class="data-label textColor">人员状态:</div>
                    <div class="data-value">
                        <span class="label-num yellowColor">{{ value.state }}</span>
                    </div>
                </div>
                <div class="data-li">
                    <div class="data-label textColor">当前经度:</div>
                    <div class="data-value">
                        <span class="label-num yellowColor">{{ Number(value.position.y).toFixed(3) }}</span>
                    </div>
                </div>
                <div class="data-li">
                    <div class="data-label textColor">当前纬度:</div>
                    <div class="data-value">
                        <span class="label-num yellowColor">{{ Number(value.position.x).toFixed(3) }}</span>
                    </div>
                </div>
            </div>
            <!-- 建筑物位置 -->
            <div class="content" v-if="value.type == 'building'">
                <div class="data-li" :style="{ width: textW }">
                    <div class="data-label textColor">识别类型:</div>
                    <div class="data-value">
                        <span class="label-num yellowColor">{{ value.state || "疑似超障" }}</span>
                    </div>
                </div>
                <div class="data-li">
                    <div class="data-label textColor">当前经度:</div>
                    <div class="data-value">
                        <span class="label-num yellowColor">{{ Number(value.position.y).toFixed(3) }}</span>
                    </div>
                </div>
                <div class="data-li">
                    <div class="data-label textColor">当前纬度:</div>
                    <div class="data-value">
                        <span class="label-num yellowColor">{{ Number(value.position.x).toFixed(3) }}</span>
                    </div>
                </div>
            </div>
    
            <div class="content" v-if="value.buildingType&&value.createTime">
                <div class="data-li">
                    <div class="data-label textColor">录入时间:</div>
                    <div class="data-value">
                        <span class="label-num yellowColor">{{ value.createTime.split('T')[0] || "暂无信息" }}</span>
                    </div>
                </div>
                <div class="data-li">
                    <div class="data-label textColor">建筑高度:</div>
                    <div class="data-value">
                        <span class="label-num yellowColor">{{setModelHeight(value)}}</span>
                    </div>
                </div>
                <div class="data-li">
                    <div class="data-label textColor">当前经度:</div>
                    <div class="data-value">
                        <span class="label-num yellowColor">{{ Number(value.longitude).toFixed(3) }}</span>
                    </div>
                </div>
                <div class="data-li">
                    <div class="data-label textColor">当前纬度:</div>
                    <div class="data-value">
                        <span class="label-num yellowColor">{{ Number(value.latitude).toFixed(3) }}</span>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
import getMinHeight from './getMinHeight.js'
export default {
    name: "DynamicLabel",
    data() {
        return {
            show: true,
            runway:{
                runway1:'跑道RWY04/22', 
            },
            elevationalAll:{},
            elevationalShow:false,
        };
    },
    props: {
        value: {
            type: Object,
            default: {}
        }
    },
    methods: {
        closeClick() {
            if (this.closeEvent) {
                this.closeEvent();
               this.removePoint()
            }
        },
        removePoint() {
            if (window.point.length > 0) {
                window.point.forEach((c) => {
                    viewer.entities.remove(c);
                });
            }
        },
       
    },
    computed: {
        textW() {
            return this.value.name?(this.value.name.split("").length * 22) + "px": 10 *22 +"px"
        }
    }

};
</script>


<style lang="less" scoped>
.detali-text{
    color: #00fcff;
    text-align: center;
    font-size: 17px;
    font-weight: 600;
    animation: fontColor 1s;

}
.detali-text:hover{
    cursor: pointer;
}
.flex{
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-start;
}
.box_1 {
    position: relative;
    bottom: 0;
    left: 0;
}

.close {
    position: absolute;
    color: #fff;
    top: 1px;
    right: 10px;
    text-shadow: 2px 2px 2px #022122;
    cursor: pointer;
    animation: fontColor 1s;
}

.box-wrap {
    position: absolute;
    left: 21%;
    top: 0;
    min-width: 300px;
    border-radius: 50px 0px 50px 0px;
    border: 1px solid #38e1ff;
    background-color: #38e1ff4a;
    box-shadow: 0 0 10px 2px #29baf1;
    animation: slide 2s;
}

.box-wrap .area {
    position: absolute;
    top: 20px;
    right: 0;
    width: 95%;
    height: 30px;
    background-image: linear-gradient(to left, #4cdef9, #4cdef96b);
    border-radius: 30px 0px 0px 0px;
    animation: area 1s;
}

.pine {
    position: absolute;
    left: 0; 
    bottom: -83px; 
    width: 100px;
    height: 100px;
    box-sizing: border-box;
    line-height: 120px;
    text-indent: 5px;
}

/* 线指针 */
/* .pine::before {
    content: "";
        position: absolute;
        left: 0;
        bottom: -86px;
        width: 40%;
        height: 60px;
        box-sizing: border-box;
        border-bottom: 1px solid #38e1ff;
        transform-origin: bottom center;
        transform: rotateZ(135deg) scale(1.5);
        animation: slash 0.5s;
        filter: drop-shadow(1px 0px 2px #03abb4);
        transition: slash 2s;
} */

.area .area-title {
    text-align: center;
    line-height: 30px;
    white-space: nowrap;
}

.textColor {
    font-size: 16px;
    font-weight: 600;
    color: #ffffff;
    text-shadow: 1px 1px 5px #002520d2;
    animation: fontColor 1s;
    letter-spacing: 2px;
    word-spacing: 2px;
}

.yellowColor {
    font-size: 16px;
    font-weight: 600;
    color: #00fcff;
    text-shadow: 1px 1px 5px #002520d2;
    animation: fontColor 1s;
    letter-spacing: 2px;
    word-spacing: 2px;
}

.fontColor {
    font-size: 16px;
    font-weight: 800;
    color: #ffffff;
    text-shadow: 1px 1px 5px #002520d2;
    animation: fontColor 1s;
    letter-spacing: 2px;
    word-spacing: 2px;
}

.content {
    padding: 55px 10px 10px 10px;
}

.content .data-li {
    /* display: flex; */
    /* white-space: nowrap; */

}
.elevational-item{
    /* width: 203px ; */
    padding-right: 8px;
    display: inline-block;
}
.text_show{
    overflow: hidden;
    text-overflow: ellipsis;
}
@keyframes fontColor {
    0% {
        color: #ffffff00;
        text-shadow: 1px 1px 5px #00252000;
    }

    40% {
        color: #ffffff00;
        text-shadow: 1px 1px 5px #00252000;
    }

    100% {
        color: #ffffff;
        text-shadow: 1px 1px 5px #002520d2;
    }
}

@keyframes slide {
    0% {
        border: 1px solid #38e1ff00;
        background-color: #38e1ff00;
        box-shadow: 0 0 10px 2px #29baf100;
    }

    100% {
        border: 1px solid #38e1ff;
        background-color: #38e1ff4a;
        box-shadow: 0 0 10px 2px #29baf1;
    }
}

@keyframes area {
    0% {
        width: 0%;
    }

    25% {
        width: 0%;
    }

    100% {
        width: 95%;
    }
}


@keyframes slash {
    0% {
        transform: rotateZ(135deg) scale(0);
    }

    100% {
        transform: rotateZ(135deg) scale(1.5);
    }
}
</style>
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值