cesium 弹框2

引入这几个数据
在这里插入图片描述
//按照需求在这里添加cesuim点击事件,回去点击的位置信息,将弹框信息传进去

    clickentity() {
      window.viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(
        Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK
      );
      if (this.handler) {
        this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK); //移除事件
      }
      this.handler = new Cesium.ScreenSpaceEventHandler(
        window.viewer.scene.canvas
      );
      var timer = null;
      this.handler.setInputAction(movement => {
        let _this = this;
        clearTimeout(timer);
        var pick = window.viewer.scene.pick(movement.position);
        if (Cesium.defined(pick) && pick.id.id && pick.id.uuidobj) {
          if (!infoPanel) {
            infoPanel = new InfoTool(window.viewer);
          }
          timer = window.setTimeout(function() {
            _this.setcontent = pick.id.content;
            _this.setname = pick.id.name;
            let obj = { position: movement.position };
            var picked = window.viewer.scene.pick(obj.position);
            if (Cesium.defined(picked)) {
              viewer.camera.flyTo({
                destination: Cesium.Cartesian3.fromDegrees(
                  pick.id.longitude,
                  pick.id.latitude,
                  10000
                ),
                orientation: {
                  heading: Cesium.Math.toRadians(0.0),
                  pitch: Cesium.Math.toRadians(-90.0),
                  roll: Cesium.Math.toRadians(0.0)
                }
              });
              var id = Cesium.defaultValue(picked.id, picked.primitive.id);
              if (id) {
                let parent = document.createElement("div");
                let component = createApp(infoBox);
                let instance = component.mount(parent);
                instance.$data.title = pick.id.name;
                instance.$data.shotFlag = _this.shotFlag.label;
                instance.$data.setcontent = pick.id.content;
                let el = instance.$el;
                infoPanel.add({
                  content: el,
                  isHtml: true,
                  position: Cesium.Cartesian3.fromDegrees(
                    pick.id.longitude,
                    pick.id.latitude
                  )//获取到的id会不准,应该使用点击点图标,如果有点图标,那么就取这个点击的位置信息
                });
                instance.close = () => {//需要关闭弹框就执行这个
                  infoPanel.remove();
                };
              }
            }
          }, 800);
        }
      }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
    },

//点击的经纬度应该获取的是

 handler.setInputAction(function (movement) {
        //捕获椭球体,将笛卡尔 二维平面坐标  转为  椭球体的笛卡尔三维坐标,返回球体表面的点
        var cartesian = viewer.camera.pickEllipsoid(
          movement.endPosition, //移动终点的位置是
          ellipsoid
        );
        if (cartesian) {//这个值
        

把这个值传进去

 position: Cesium.Cartesian3.fromDegrees(
                 cartesian
                  )//获取到的id会不准,应该使用点

会用到这几个文件代码
在这里插入图片描述
util.js


export function getCss(srcNodeRef, property) {
    if (srcNodeRef) {
        let element;
        if (typeof srcNodeRef === "string") {
            if (srcNodeRef.indexOf("#") < 0 && srcNodeRef.indexOf(".") < 0 && srcNodeRef.indexOf(" ") < 0) {
                element = document.getElementById(srcNodeRef);
            } else {
                element = document.querySelector(srcNodeRef);
            }
        } else {
            element = srcNodeRef;
        }
        if (element.hasOwnProperty("currentStyle")) { // 旧版IE
            return element.currentStyle[property];
        } else {
            return window.getComputedStyle(element, null)[property];
        }
    }
}

export function setCss(srcNodeRef, property, value) {
    if (srcNodeRef) {
        if (srcNodeRef instanceof Array && srcNodeRef.length > 0) {
            for (let i = 0; i < srcNodeRef.length; i++) {
                srcNodeRef[i].style.setProperty(property, value);
            }
        } else if (typeof (srcNodeRef) === "string") {
            if (srcNodeRef.indexOf("#") < 0 && srcNodeRef.indexOf(".") < 0 && srcNodeRef.indexOf(" ") < 0) {
                const element = document.getElementById(srcNodeRef);
                element && (element.style.setProperty(property, value));
            } else {
                const elements = document.querySelectorAll(srcNodeRef);
                for (let i = 0; i < elements.length; i++) {
                    elements[i].style.setProperty(property, value);
                }
            }
        } else if (srcNodeRef instanceof HTMLElement) {
            srcNodeRef.style.setProperty(property, value);
        }
    }
}


export function setInnerText(srcNodeRef, value) {
    if (srcNodeRef) {
        if (srcNodeRef instanceof Array && srcNodeRef.length > 0) {
            const that = this;
            for (let i = 0; i < srcNodeRef.length; i++) {
                let element = srcNodeRef[i];
                if (that.isElement(element)) {
                    element.innerText = value;
                }
            }
        } else if (typeof (srcNodeRef) === "string") {
            if (srcNodeRef.indexOf("#") < 0 && srcNodeRef.indexOf(".") < 0 && srcNodeRef.indexOf(" ") < 0) {
                let element = document.getElementById(srcNodeRef);
                element && (element.innerText = value);
            } else {
                const elements = document.querySelectorAll(srcNodeRef);
                for (let i = 0; i < elements.length; i++) {
                    elements[i].innerText = value;
                }
            }
        } else {
            if (this.isElement(srcNodeRef)) {
                srcNodeRef.innerText = value;
            }
        }
    }
}

export function setInnerHtml(srcNodeRef, value) {
    if (srcNodeRef) {
        if (srcNodeRef instanceof Array && srcNodeRef.length > 0) {
            const that = this;
            for (let i = 0; i < srcNodeRef.length; i++) {
                let element = srcNodeRef[i];
                if (element.childNodes.length > 0) {
                    element.removeChild(element.childNodes[0])
                }
                if (that.isElement(element)) {
                    element.appendChild(value);
                }
            }
        } else if (typeof (srcNodeRef) === "string") {
            if (srcNodeRef.indexOf("#") < 0 && srcNodeRef.indexOf(".") < 0 && srcNodeRef.indexOf(" ") < 0) {
                let element = document.getElementById(srcNodeRef);
                if (element.childNodes.length > 0) {
                    element.removeChild(element.childNodes[0])
                }
                element && (element.appendChild(value));
            } else {
                const elements = document.querySelectorAll(srcNodeRef);
                if (elements.childNodes.length > 0) {
                    elements.removeChild(elements.childNodes[0])
                }
                for (let i = 0; i < elements.length; i++) {
                    elements[i].appendChild(value);
                }
            }
        } else {
            if (this.isElement(srcNodeRef)) {
                if (srcNodeRef.childNodes.length > 0) {
                    srcNodeRef.removeChild(srcNodeRef.childNodes[0])
                }
                srcNodeRef.appendChild(value);
            }
        }
    }
}
export function isElement(obj) {
    return (typeof HTMLElement === 'object')
        ? (obj instanceof HTMLElement)
        : !!(obj && typeof obj === 'object' && (obj.nodeType === 1 || obj.nodeType === 9) && typeof obj.nodeName === 'string');
}

export function getGuid(removeMinus) {
    let d = new Date().getTime();
    let uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
        const r = (d + Math.random() * 16) % 16 | 0;
        d = Math.floor(d / 16);
        return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
    });
    if (removeMinus) {
        uuid = uuid.replace(/-/g, "");
    }
    return uuid;
}

infoTool.js

import './info.css'
import * as util from "./util"


export class InfoTool {

    constructor(viewer) {
        this.viewer = viewer;

        // 在Cesium容器中添加元素
        this.element = document.createElement("div");
        this.element.id = "infoTool_" + util.getGuid(true);
        this.element.name = "infoTool";
        this.element.classList.add("helsing-three-plugins-infotool");
        this.element.appendChild(document.createElement("div"));
        this.element.appendChild(document.createElement("div"));
        viewer.container.appendChild(this.element);
    }
    /**
     * 创建一个动态实体弹窗。
     *
     * @param {Viewer} viewer Cesium视窗。
     * @param {Number} options 选项。
     * @param {Cartesian3} options.position 弹出位置。
     * @param {HTMLElement} options.element 弹出窗元素容器。
     * @param {Function} callback 回调函数。
     * @ignore
     */
    createInfoTool(viewer, options, callback = undefined) {
        let _this = this
        const cartographic = Cesium.Cartographic.fromCartesian(options.position);
        const lon = Cesium.Math.toDegrees(cartographic.longitude); //.toFixed(5);
        const lat = Cesium.Math.toDegrees(cartographic.latitude); //.toFixed(5);

        // 注意,这里不能使用hide()或者display,会导致元素一直重绘。
        util.setCss(options.element, "opacity", "0");
        util.setCss(options.element.querySelector("div:nth-child(1)"), "height", "0");
        util.setCss(options.element.querySelector("div:nth-child(2)"), "opacity", "0");

        // 回调
        callback();

        // 添加div弹窗
        setTimeout(function () {
            _this.popup(viewer, options.element, lon, lat, cartographic.height)
        }, 100);
    }
    /**
     * 弹出HTML元素弹窗。
     * @param {Viewer} viewer Cesium视窗。
     * @param {Element|HTMLElement} element 弹窗元素。
     * @param {Number} lon 经度。
     * @param {Number} lat 纬度。
     * @param {Number} height 高度。
     * @ignore
     */
    popup(viewer, element, lon, lat, height) {
        setTimeout(function () {
            // 设置元素效果
            util.setCss(element, "opacity", "1");
            util.setCss(element.querySelector("div:nth-child(1)"), "transition", "ease 1s");
            util.setCss(element.querySelector("div:nth-child(2)"), "transition", "opacity 1s");
            util.setCss(element.querySelector("div:nth-child(1)"), "height", "80px");
            util.setCss(element.querySelector("div:nth-child(2)"), "pointer-events", "auto");
            window.setTimeout(function () {
                util.setCss(element.querySelector("div:nth-child(2)"), "opacity", "1");
            }, 500);
        }, 100);
        const divPosition = Cesium.Cartesian3.fromDegrees(lon, lat, height);
        this.hookToGlobe(viewer, element, divPosition, [10, -(parseInt(util.getCss(element, "height")))], true);
        viewer.scene.requestRender();
    }
    /**
     * 将HTML弹窗挂接到地球上。
     * @param {Viewer} viewer Cesium视窗。
     * @param {Element} element 弹窗元素。
     * @param {Cartesian3} position 地图坐标点。
     * @param {Array} offset 偏移。
     * @param {Boolean} hideOnBehindGlobe 当元素在地球背面会自动隐藏,以减轻判断计算压力。
     * @ignore
     */
    hookToGlobe(viewer, element, position, offset, hideOnBehindGlobe) {
        const scene = viewer.scene, camera = viewer.camera;
        const cartesian2 = new Cesium.Cartesian2();
        scene.preRender.addEventListener(function () {
            const canvasPosition = scene.cartesianToCanvasCoordinates(position, cartesian2); // 笛卡尔坐标到画布坐标
            if (Cesium.defined(canvasPosition)) {
                util.setCss(element, "left", parseInt(canvasPosition.x + offset[0]) + "px");
                util.setCss(element, "top", parseInt(canvasPosition.y + offset[1]) + "px");

                // 是否在地球背面隐藏
                if (hideOnBehindGlobe) {
                    const cameraPosition = camera.position;
                    let height = scene.globe.ellipsoid.cartesianToCartographic(cameraPosition).height;
                    height += scene.globe.ellipsoid.maximumRadius;
                    if (!(Cesium.Cartesian3.distance(cameraPosition, position) > height)) {
                        util.setCss(element, "display", "flex");
                    } else {
                        util.setCss(element, "display", "none");
                    }
                }
            }
        });
    }

    /**
     * 添加。
     * @param {{position: Cartesian3, content: string}} options 选项。
     * @param {Element} options.element 弹窗元素。
     * @param {Cartesian2|Cartesian3} options.position 点击位置。
     * @param {Cesium3DTileFeature} [options.inputFeature] 模型要素。
     * @param {String} options.type 类型(默认值为default,即任意点击模式;如果设置为info,即信息模式,只有点击Feature才会响应)。
     * @param {String} options.content 内容(只有类型为default时才起作用)。
     * @param {Boolean} options.isHtml 内容加载方式。
     * @param {Function} callback 回调函数。
     */
    add(options, callback = undefined) {
        // 判断参数为空返回
        if (!options) {
            return;
        }
        // 点
        let position, cartesian2d, cartesian3d, inputFeature;
        if (options instanceof Cesium.Cesium3DTileFeature) {
            inputFeature = options;
            options = {};
        } else {
            if (options instanceof Cesium.Cartesian2 || options instanceof Cesium.Cartesian3) {
                position = options;
                options = {};
            } else {
                position = options.position;
                inputFeature = options.inputFeature;
            }
            // 判断点位为空返回
            if (!position) {
                return;
            }
            if (position instanceof Cesium.Cartesian2) { // 二维转三维
                // 如果支持拾取模型则取模型值
                cartesian3d = (this.viewer.scene.pickPositionSupported && Cesium.defined(this.viewer.scene.pick(options.position))) ?
                    this.viewer.scene.pickPosition(position) : this.viewer.camera.pickEllipsoid(position, this.viewer.scene.globe.ellipsoid);
                cartesian2d = position;
            } else {
                cartesian3d = position;
                cartesian2d = Cesium.SceneTransforms.wgs84ToWindowCoordinates(this.viewer.scene, cartesian3d);
            }
            // 判断点位为空返回
            if (!cartesian3d) {
                return;
            }
        }

        const that = this;

        // 1.组织信息
        let info = '';
        if (options.type === "info") {
            // 拾取要素
            const feature = inputFeature || this.viewer.scene.pick(cartesian2d);
            // 判断拾取要素为空返回
            if (!Cesium.defined(feature)) {
                this.remove();
                return;
            }

            if (feature instanceof Cesium.Cesium3DTileFeature) { // 3dtiles
                let propertyNames = feature.getPropertyNames();
                let length = propertyNames.length;
                for (let i = 0; i < length; ++i) {
                    let propertyName = propertyNames[i];
                    info += '"' + (propertyName + '": "' + feature.getProperty(propertyName)) + '",\n';
                }
            } else if (feature.id) { // Entity
                const properties = feature.id.properties;
                if (properties) {
                    let propertyNames = properties._propertyNames;
                    let length = propertyNames.length;
                    for (let i = 0; i < length; ++i) {
                        let propertyName = propertyNames[i];
                        //console.log(propertyName + ': ' + properties[propertyName]._value);
                        info += '"' + (propertyName + '": "' + properties[propertyName]._value) + '",\n';
                    }
                }
            }
        } else {
            options.content && (info = options.content);
        }

        // 2.生成特效
        // 添加之前先移除
        this.remove();

        if (!info) {
            return;
        }

        options.position = cartesian3d;
        options.element = options.element || this.element;

        this.createInfoTool(this.viewer, options, function () {
            if (options.isHtml){
                util.setInnerHtml(that.element.querySelector("div:nth-child(2)"), info);
            } else {
                util.setInnerText(that.element.querySelector("div:nth-child(2)"), info);
            }

            typeof callback === "function" && callback();
        });
    }

    remove(entityId = undefined) {
        util.setCss(this.element, "opacity", "0");
        util.setCss(this.element.querySelector("div:nth-child(1)"), "transition", "");
        util.setCss(this.element.querySelector("div:nth-child(2)"), "transition", "");
        util.setCss(this.element.querySelector("div:nth-child(1)"), "height", "0");
        util.setCss(this.element.querySelector("div:nth-child(2)"), "pointer-events", "none");
    };
}

export default InfoTool;

inforbox.vue传值到弹框,样子自定义

<template>
    <panel :title="title" @close="closeBox">
        <div style="width: 600px">
            <el-descriptions border size="mini" :column="3">
                <el-descriptions-item v-for="field in fields" :key="field.id"  :label="field.fieldname">
                    <span :title="formatValue(detail,field)">{{formatValue(detail,field)}}</span>
                </el-descriptions-item>
            </el-descriptions>
        </div>

    </panel>
</template>

<script>
    import panel from "../panel/panel-widget"
    export default {
        name: "infoBox",
        components:{
          panel
        },
        data(){
            return {
                title: "",
                detail:{},
                fields:[],
                close: () => {

                }
            }
        },
        methods:{
            closeBox(){
                this.close()
            },
            formatValue(item, field){
                let value = item[field.field]
                if (field.dictionary) {
                    //县界内:1,跨县:2,跨省:3,跨国并跨省:4
                    if (!field.filtercondition) {
                        return value
                    }
                    let filtercondition = field.filtercondition.split(",")
                    let arr = filtercondition.filter( condition => {
                        return condition.split(":")[1] == value;
                    })
                    if (arr.length>0){
                        value = arr[0].split(":")[0]
                    }
                }
                return value + (field.unit?field.unit:'')
            }
        }
    }
</script>

<style>
    .el-descriptions .is-bordered{
        table-layout: fixed;
    }
    .el-descriptions--mini.is-bordered .el-descriptions-item__cell {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        padding: 4px;
    }
</style>

info.css

.helsing-three-plugins-infotool {
    display: none;
    flex-direction: column-reverse;
    position: fixed;
    top: 0;
    left: 0;
    min-width: 100px;
    height: 250px;
    user-select: none;
    pointer-events: none;
}

.helsing-three-plugins-infotool > div:nth-child(1) {
    left: 0;
    width: 40px;
    height: 0;
    bottom: 0;
    background: url("../../../../assets/images/map/line.png") no-repeat center 100%;
}

.helsing-three-plugins-infotool > div:nth-child(2) {
    opacity: 0;
    box-shadow: 0 0 8px 0 rgba(0, 170, 255, .6) inset;
    user-select: text;
    pointer-events: auto;
    color: #4db3ff;
    background: rgba(0, 170, 255, .2);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值