<template>
    <div class="kMapBox">
        <div id="kMap" class="kMapss"></div>
        <div class="tipBox" v-if="cameraHeight">
            <span class="tipItem">视角高度≈{{ cameraHeight.toFixed(2) }}</span>
            <span class="tipItem">视角经度≈{{ cameraLongitude.toFixed(2) }}</span>
            <span class="tipItem">视角纬度≈{{ cameraLatitude.toFixed(2) }}</span>
        </div>
        <RightMenu :rightMenuPosition="rightMenuPosition" :rightMenuShow="rightMenuShow" :clickModel="clickModel"
            @cliclMenu="clickMenuItem" @closeRightmenu="() => { rightMenuShow = false; }" />
    </div>
</template>

<script>
    import * as Cesium from "cesium";
    import axios from "axios";
    import httpRequest from '@/utils/request.js'
    import RightMenu from "./rightMenu.vue";
    export default {
        props: {
            ids: {
                type: Array,
                default: () => [],
            },
            parentId: {
                type: String,
                default: () => "",
            },
        },

        components: {
            RightMenu,
        },

        data() {
            return {
                mapViewer: null,
                tilsUrl: "./static/kMapTiles/{z}/{x}/{y}.jpg",
                labelEntities: [],
                // 本地化语言配置
                localSet: {
                    // 地址搜索栏
                    ".cesium-viewer-geocoderContainer form>.cesium-geocoder-input": {
                        placeholder: "在此输入地址或坐标...",
                    },
                    ".cesium-sceneModePicker-wrapper.cesium-toolbar-button button:nth-child(3)": {
                        title: "2D化平面",
                    },
                    ".cesium-sceneModePicker-wrapper.cesium-toolbar-button button:last-child": {
                        title: "哥伦布视图",
                    },
                },
                showEntities: true,
                isFirstLoad: true,
                cameraHeight: 0,
                cameraLatitude: 0,
                cameraLongitude: 0,
                wpList: [],
                wtList: [],
                mapModelType: "3d",
                substationId: "",
                searchId: [],
                rightMenuShow: false,
                rightMenuPosition: {
                    x: 0,
                    y: 0,
                },
                clickModel: {},
            };
        },

        created() {
            console.log('cesium====>>>', Cesium)
            this.substationId = this.parentId;
            Cesium.Ion.defaultAccessToken =
                "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIwNGVhZmJlNi03Mzg2LTRhZDQtYTBjYi1hNDk0MjM1NWYzZGEiLCJpZCI6MTcyNDQ1LCJpYXQiOjE2OTc1OTg3Nzd9.tJdKhFXx4JXjcKxUDvJffwwo2tMvIDIGEuwsYXbeeW0";
        },

        mounted() {
            this.initKMap();
            // axios({
            //         method: "get",
            //         baseURL: "ping",
            //         url: "",
            //     })
            //     .then(() => {})
            //     .catch(() => {
            this.initGetLocalTiles();
            //     })
            //     .finally(() => {

            //     });
            this.$nextTick(() => {
                this.initCurrentOptions();
                this.getGeoJson();
                this.getWpList();
                this.$emit("mapDone", true);
            });
        },

        methods: {
            // 手动将地球工具栏英文内容本地化
            localToZhCn() {
                for (let className in this.localSet) {
                    const dom = document.querySelector(className);
                    if (dom) {
                        for (let domOption in this.localSet[className]) {
                            dom.setAttribute(domOption, this.localSet[className][domOption]);
                        }
                    }
                }
            },

            initKMap() {
                this.mapViewer = new Cesium.Viewer("kMap", {
                    infoBox: false,
                    animation: false, // 是否显示动画控件
                    homeButton: false, // 是否显示 home 键
                    geocoder: false, // 是否显示地名查找控件
                    baseLayerPicker: false, // 是否显示图层选择控件
                    timeline: false, // 是否显示时间线控件
                    fullscreenButton: false, // 是否全屏显示
                    infoBox: false, // 是否显示点击要素之后显示的信息
                    sceneModePicker: true, // 是否显示投影方式控件  三维/二维
                    navigationInstructionsInitiallyVisible: false,
                    navigationHelpButton: false, // 是否显示帮助信息控件
                    orderIndependentTranslucency: false,
                    shouldAnimate: true,
                    scene3DOnly: false, // 每个几何实例将只能以3D渲染以节省GPU内存
                    selectionIndicator: false, // 取消点击有绿框
                    baseLayerPicker: false, //是否显示图层选择控件
                });

                // 视角移动结束钩子
                this.mapViewer.scene.camera.moveEnd.addEventListener(() => {
                    this.getCameraInfo();
                });

                // 视角发生改变钩子
                this.mapViewer.scene.camera.changed.addEventListener(() => {
                    this.rightMenuShow = false;
                    this.getCameraInfo();
                });

                // 注册场景点击事件
                const handler = new Cesium.ScreenSpaceEventHandler(
                    this.mapViewer.scene.canvas
                );

                // 左键事件
                handler.setInputAction(() => {
                    this.rightMenuShow = false;
                    return false;
                }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

                // 右键事件
                handler.setInputAction((e) => {
                    const pick = this.mapViewer.scene.pick(e.position);
                    if (pick && pick.id) {
                        const clickModel = this.mapViewer.entities.getById(pick.id.id) || {};
                        if (clickModel.modelType === "wt") {
                            this.clickModel = clickModel;
                            this.rightMenuPosition = e.position;
                            this.rightMenuShow = true;
                        }
                    }
                    return false;
                }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);

                // 滚轮事件监听
                handler.setInputAction(() => {
                    this.rightMenuShow = false;
                    this.getCameraInfo();
                }, Cesium.ScreenSpaceEventType.WHEEL);
            },

            initGetLocalTiles() {
                const imageryProvider = new Cesium.TileMapServiceImageryProvider({
                    url: this.tilsUrl, // 本地瓦片的路径
                    maximumLevel: 18, // 最大级别
                    minimumLevel: 0, // 最小级别
                    fileExtension: "jpg", // 图像文件扩展名
                    flipXY: true, // 如果你的瓦片Y轴方向与通常的瓦片格式相反，设置为true
                });
                this.mapViewer.imageryLayers.addImageryProvider(imageryProvider);
            },

            initCurrentOptions() {
                // document.querySelector(".cesium-viewer-bottom").remove();
                this.mapViewer._cesiumWidget._creditContainer.style.display = "none";

                // 创建自定义还原按钮
                var homeButton = document.createElement("button");
                homeButton.textContent = "复位";
                homeButton.className = "cesium-button";
                homeButton.style.height = "36px";

                // 将按钮添加到Cesium Viewer的界面中
                var toolbar = document.querySelector(".cesium-viewer-toolbar");
                toolbar.appendChild(homeButton);

                // 在按钮点击时执行自定义还原视图操作
                homeButton.addEventListener("click", () => {
                    // 这里可以编写代码以实现自定义的还原视图操作
                    // 例如，重置摄像机位置和缩放级别
                    this.mapViewer.camera.flyTo({
                        destination: Cesium.Cartesian3.fromDegrees(
                            112.48699,
                            37.94036,
                            1100000
                        ),
                    });
                });

                var entitiesButton = document.createElement("button");
                entitiesButton.textContent = `${
        this.showEntities ? "隐藏" : "显示"
      }区域标记`;
                entitiesButton.className = "cesium-button cesiumResetBtn";
                entitiesButton.style.height = "36px";

                toolbar.appendChild(entitiesButton);

                // 在按钮点击时执行自定义还原视图操作
                entitiesButton.addEventListener("click", () => {
                    this.showEntities = !this.showEntities;
                    entitiesButton.textContent = `${
          this.showEntities ? "隐藏" : "显示"
        }区域标记`;
                    this.getGeoJson();
                    this.showEntities && this.getWpList();
                });

                const select = document.createElement("select");

                const optionsArray = [{
                        innerHTML: "3D模型",
                        value: "3d"
                    },
                    {
                        innerHTML: "2D平面",
                        value: "2d"
                    },
                    {
                        innerHTML: "2D图标",
                        value: "icon"
                    },
                ];

                optionsArray.forEach((ele) => {
                    const optionsItem = document.createElement("option");
                    optionsItem.innerHTML = ele.innerHTML;
                    optionsItem.setAttribute("value", ele.value);
                    select.appendChild(optionsItem);
                });

                toolbar.appendChild(select);

                select.addEventListener("change", (select) => {
                    this.mapModelType = select.target.value;
                    this.showEntities && this.getWpList();
                });

                this.localToZhCn();
            },

            getGeoJson() {
                if (this.showEntities) {
                    const strokeColor = new Cesium.Color.fromCssColorString("yellow");
                    const fillColor = new Cesium.Color.fromCssColorString(
                        "rgba(228,141,43,0.3)"
                    );
                    Cesium.Math.setRandomNumberSeed(0);
                    var promise = this.mapViewer.dataSources.add(
                        Cesium.GeoJsonDataSource.load("./static/geoJson/sx.json", {
                            stroke: strokeColor,
                            // fill: Cesium.Color.TRANSPARENT,
                            fill: fillColor,
                            clampToGround: false,
                            strokeWidth: 5.0,
                            markerSymbol: "?",
                        })
                    );
                    promise.then((dataSource) => {
                        const entities = dataSource.entities.values;
                        if (this.labelEntities.length === 0) {
                            for (let i = 0; i < entities.length; i++) {
                                const entity = entities[i];
                                const name = entity.name;
                                const location = entity.properties._centroid._value;
                                const labelEntity = this.mapViewer.entities.add({
                                    modelType: "geo",
                                    position: Cesium.Cartesian3.fromDegrees(
                                        location[0],
                                        location[1]
                                    ),
                                    label: {
                                        text: name,
                                        font: "14px Helvetica",
                                        fillColor: Cesium.Color.WHITE,
                                        showBackground: false,
                                        backgroundColor: Cesium.Color.fromCssColorString(
                                            "rgba(52,79,209,1.0)"
                                        ),
                                        backgroundPadding: new Cesium.Cartesian2(3, 3),
                                        scale: 0.9,
                                        style: Cesium.LabelStyle.FILL_AND_OUTLINE,
                                        outlineColor: Cesium.Color.BLACK,
                                        outlineWidth: 2,
                                        verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
                                    },
                                });
                                this.labelEntities.push(labelEntity);
                            }
                        }
                    });
                    if (this.isFirstLoad) {
                        this.isFirstLoad = false;
                        this.mapViewer.flyTo(promise);
                    }
                } else {
                    this.mapViewer.entities.removeAll();
                    this.mapViewer.dataSources.removeAll();
                    this.labelEntities = [];
                }
            },

            getCameraInfo() {
                const camera = this.mapViewer.camera;
                this.cameraHeight = camera.positionCartographic.height;
                this.cameraLatitude = camera.positionCartographic.latitude;
                this.cameraLongitude = camera.positionCartographic.longitude;
            },

            async getWpList() {
                if (this.ids.length) {
                    this.wtList.forEach((ele) => {
                        this.addWt(ele, "wt");
                    });
                    this.switchEntities(["wt"], this.substationId);
                } else {
                    if (!this.wpList.length) {
                        const {
                            data
                        } = await httpRequest.get("/base/station");
                        this.wpList = data || [];
                        data.forEach((ele) => {
                            this.addWt(ele, "wp");
                        });
                    } else {
                        this.wpList.forEach((ele) => {
                            this.addWt(ele, "wp");
                        });
                    }
                    this.switchEntities(["wp"], this.substationId);
                }
            },

            addWt(resItem, modelType = "wp") {
                const hpRoll = new Cesium.HeadingPitchRoll(
                    modelType === "wt" ? 45 : 20,
                    0.0,
                    0.0
                );
                const origin = Cesium.Cartesian3.fromDegrees(106.0231304, 37.73323706, 0);
                const position = Cesium.Cartesian3.fromDegrees(
                    Number(resItem.longitude),
                    Number(resItem.latitude),
                    0
                );
                const orientation = Cesium.Transforms.headingPitchRollQuaternion(
                    position,
                    hpRoll
                );

                const modelMatrix = Cesium.Transforms.headingPitchRollToFixedFrame(
                    origin,
                    hpRoll
                );

                // const id = `${modelType}_${resItem.id}`;
                const minimumPixelSize = modelType === "wt" ? 50 : 40;
                const maximumSize = modelType === "wt" ? 40 : 40;
                const maximumScale = modelType === "wt" ? 80 : 70;
                const substationId = this.substationId || "";
                const fittingId = resItem.fittingId;
                const processId = resItem.processId;
                const currentName = resItem.name;
                const mapModelType = this.mapModelType;

                const modelItem = {
                    // 模型id
                    // id,
                    modelType,
                    substationId,
                    fittingId,
                    processId,
                    currentName,
                    mapModelType,
                    // 模型位置
                    position,
                    // 模型方向
                    orientation,
                    // 添加描述
                    description: resItem.name,
                    label: {
                        // 文字内容
                        text: resItem.aname,
                        // 文本大小与字体
                        font: "14px Helvetica",
                        // 文字填充颜色
                        fillColor: Cesium.Color.WHITE,
                        // 是否显示背景
                        showBackground: false,
                        //背景墙的颜色
                        backgroundColor: Cesium.Color.fromCssColorString(
                            "rgba(52,79,209,1.0)"
                        ),
                        // 背景宽度
                        backgroundPadding: new Cesium.Cartesian2(3, 3),
                        // 文字与背景墙的总大小
                        scale: 1.2,
                        // 文本轮廓
                        style: Cesium.LabelStyle.FILL_AND_OUTLINE,
                        // 外边界颜色
                        outlineColor: Cesium.Color.fromCssColorString("#000"),
                        // 外边界宽度
                        outlineWidth: 4,
                        // 文本出现的位置
                        verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
                        // 文本的偏移方向
                        pixelOffset: new Cesium.Cartesian2(0, 25),
                        eyeOffset: new Cesium.Cartesian3(0, 0, -250),
                    },
                };

                if (mapModelType === "3d") {
                    // 模型资源
                    modelItem.model = {
                        // 模型路径
                        uri: `./static/glb/${modelType}.glb`,
                        // 模型最小刻度
                        minimumPixelSize,
                        // 模型最大刻度
                        maximumSize,
                        // 设置模型最大放大大小
                        maximumScale,
                        // 模型是否可见
                        show: true,
                        // 模型轮廓颜色
                        silhouetteColor: Cesium.Color.WHITE,
                        // 模型颜色  ，这里可以设置颜色的变化
                        color: Cesium.Color.WHITE,
                        // 仅用于调试，显示魔仙绘制时的线框
                        debugWireframe: false,
                        // 仅用于调试。显示模型绘制时的边界球。
                        debugShowBoundingVolume: false,
                        scale: 1,
                        // 是否运行模型中的动画效果
                        runAnimations: true,
                        clampAnimations: true, // 是否保持最后一针的动画
                        // 模型贴地
                        // heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
                    };
                } else if (mapModelType === "2d") {
                    const semiMinorAxis = modelType === "wt" ? 350 : 1200;
                    const semiMajorAxis = modelType === "wt" ? 350 : 1200;
                    const extrudedHeight = modelType === "wt" ? 5.0 : 200;
                    const materialColor = modelType === "wt" ? "#f25656" : "#1890ff";
                    modelItem.ellipse = {
                        semiMinorAxis, // 椭圆的短半轴
                        semiMajorAxis, // 椭圆的长半轴
                        extrudedHeight, // 拉伸高度
                        material: Cesium.Color.fromCssColorString(materialColor), // 椭圆颜色
                        outline: true, //是否显示边框
                        outlineColor: Cesium.Color.fromCssColorString("#000"), //边框颜色
                        rotation: Cesium.Math.toRadians(45), //旋转角度,从正北方向开始顺时针旋转
                    };
                } else if (mapModelType === "icon") {
                    modelItem.billboard = {
                        image: "./static/img/markIcon.png",
                        width: 19,
                        height: 31,
                    };
                }

                this.mapViewer.entities.add(modelItem);
            },

            switchEntities(modelTypeList = [], substationId = "") {
                let entities = [];
                modelTypeList.forEach((type) => {
                    this.mapViewer.entities.values.forEach((ele, index) => {
                        if (
                            ele.modelType === type &&
                            ele.mapModelType === this.mapModelType &&
                            (substationId ? substationId === ele.substationId : true)
                        ) {
                            if (this.searchId.length) {
                                const someRes = this.searchId.some((fittingId) => {
                                    return ele.fittingId === fittingId;
                                });
                                someRes && entities.push(ele);
                            } else {
                                entities.push(ele);
                            }
                        }

                        if (ele.modelType === "geo") {
                            entities.push(ele);
                        }
                    });
                });

                this.mapViewer.entities.removeAll();
                entities.forEach((ele) => {
                    this.mapViewer.entities.add(ele);
                });
            },

            clickMenuItem(params) {
                this.$emit("rightClick", params);
            },
        },

        watch: {
            ids(value) {
                httpRequest
                    .get("/base/location", {
                        params: {
                            ids: value.join(","),
                        },
                    })
                    .then((res) => {
                        this.searchId = value || [];
                        this.wtList = res.data || [];
                        this.getWpList();
                    });
            },
            parentId(value) {
                this.substationId = value || "";
            },
        },
    };
</script>
<style lang="less" scoped>
    .kMapBox,
    .kMapBox #kMap {
        width: 100%;
        height: 100%;



    }

    .kMapss {
        .cesium-viewer {
            height: 100%;

            .cesium-viewer-cesiumWidgetContainer {
                height: 100%;

                .cesium-widget {
                    height: 500px !important;

                    canvas {
                        height: 500px;
                    }
                }
            }
        }
    }

    .kMapBox {
        position: relative;

        .tipBox {
            position: absolute;
            left: 0;
            bottom: 0;
            font-size: 12px;
            padding: 4px;
            background: rgba(0, 0, 0, 0.5);
            color: #fff;
            width: 100%;

            .tipItem {
                margin-left: 4px;

                &:first-child {
                    margin-left: 1px;
                }
            }
        }
    }
</style>