<template>
  <div id="cesiumContainer"></div>
</template>

<script>
import api from "@/api/data";
import FireHydrant from "@/assets/Images/MapSymbol/FireHydrant.png";
import Flowmeter from "@/assets/Images/MapSymbol/Flowmeter.png";
import LeakageTester from "@/assets/Images/MapSymbol/LeakageTester.png";
import WaterQuality from "@/assets/Images/MapSymbol/WaterQuality.png";
// import guanxianGeojson from "../../public/static/data/guanxian.json";

export default {
  data() {
    return {
      waterClass: null,
    };
  },
  created() {
    proj4.defs(
      "EPSG:0986",
      "+proj=tmerc +lat_0=0 +lon_0=120.666666666667 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs +type=crs"
    );
    // $.getJSON("./static/data/guanxian.json", function (result) {
    //   globalVariable.guanxianGeojson = result
    // });
  },
  mounted() {
    this.waterClass = new Cesium.Water();
    this.initViewer().then(() => {
      this.setViewDefaultlocation().then(() => {
        this.mainFunc();
      });
    });
  },
  methods: {
    initViewer() {
      return new Promise((resolve, reject) => {
        globalVariable.viewer = new Cesium.Viewer("cesiumContainer", {
          // useDefaultRenderLoop: false,  //关闭自动渲染
          animation: false, //动画控制不显示
          timeline: false, //时间线不显示
          fullscreenButton: false, //全屏按钮不显示
          infoBox: false,
          baseLayerPicker: false, //地图切换不显示
          // terrainProvider: Cesium.createWorldTerrain(), // 地形
          imageryProvider: new Cesium.SingleTileImageryProvider({
            url: (function createColorCanvas(color) {
              var width = 1,
                height = 1;
              var canvas = document.createElement("canvas");
              canvas.width = width;
              canvas.height = height;
              var ctx = canvas.getContext("2d");
              ctx.fillStyle = color;
              ctx.fillRect(0, 0, width, height);
              return canvas.toDataURL();
            })("#ffffff00"),
            rectangle: Cesium.Rectangle.fromDegrees(-180.0, -90.0, 180.0, 90.0),
          }),
          geocoder: false,
          homeButton: false,
          selectionIndicator: false, // 去除绿色选择框
          sceneModePicker: false,
          navigationHelpButton: false,
          scene3DOnly: true, // 仅以3D渲染以节省GPU内存
          useBrowserRecommendedResolution: true, // 以浏览器建议的分辨率渲染
        });
        //去除版权标记
        globalVariable.viewer._cesiumWidget._creditContainer.style.display =
          "none";
        resolve();
      });
    },

    // 默认定位
    setViewDefaultlocation(time) {
      return new Promise((resolve, reject) => {
        globalVariable.viewer.camera.flyTo({
          destination: Cesium.Cartesian3.fromDegrees(
            systemConfig.mapDefault.center.lon,
            systemConfig.mapDefault.center.lat,
            systemConfig.mapDefault.height
          ),
          orientation: {
            heading: Cesium.Math.toRadians(systemConfig.mapDefault.heading), // 方向
            pitch: Cesium.Math.toRadians(systemConfig.mapDefault.pitch), // 倾斜角度
            roll: Cesium.Math.toRadians(systemConfig.mapDefault.roll),
          },
          duration: isNaN(time) ? 3 : time,
          pitchAdjustHeight: 1000,
          complete: function () {
            resolve();
          },
        });
      });
    },

    mainFunc() {
      this.mapConfig();

      // 加载地图瓦片
      this.addMapTiles("arcgis");

      // this.getPointPosition()
      //   .then((result) => {
      //     that.bindPopup();
      //   })
      //   .catch((err) => {});

      this.tilesetAdd();

      this.addWater("./static/data/ojk_water_v3.json", {
        // this.addWater("./static/data/ojksb.json", {
        // normalMap: "img/textures/waterNormals.jpg", // 水正常扰动的法线图
        frequency: 8000.0, // 控制波数的数字。
        animationSpeed: 0.02, // 控制水的动画速度的数字。
        amplitude: 5.0, // 控制水波振幅的数字。
        specularIntensity: 0.8, // 控制镜面反射强度的数字。
        baseWaterColor: "#006ab4", // rgba颜色对象基础颜色的水。#00ffff,#00baff,#006ab4
        blendColor: "#006ab4", // 从水中混合到非水域时使用的rgba颜色对象。
        height: -1, //水面高度
        clampToGround: true, //是否贴地
        opacity: 0.8, //透明度
      });

      // this.singleClick();

      // this.addGWDataPrimitive();

      // this.loadBigDataGltf();
    },

    // cesium 球体配置
    mapConfig() {
      // 基础球体颜色
      globalVariable.viewer.scene.globe.baseColor = Cesium.Color.BLUE;
      // 取消大气效果（发光）
      globalVariable.viewer.scene.globe.showGroundAtmosphere = true;

      globalVariable.viewer.scene.globe.translucency.enabled = true;

      // // 地底颜色
      // globalVariable.viewer.scene.globe.undergroundColor = undefined;

      // 地形遮盖
      globalVariable.viewer.scene.globe.depthTestAgainstTerrain = false;

      // globalVariable.viewer.scene.globe.translucency.frontFaceAlpha = 1.0;
      // globalVariable.viewer.scene.globe.translucency.rectangle = Cesium.Rectangle.fromDegrees(
      //   120.87373270003363,
      //   27.913116219448348,
      //   120.98856425530658,
      //   27.97741914289562
      // );

      // // 地下模式
      // globalVariable.viewer.scene.screenSpaceCameraController.enableCollisionDetection = true ;
      // globalVariable.viewer.scene.undergroundMode = true;
      // // 设置地表透明度
      // globalVariable.viewer.scene.globe.translucency.frontFaceAlpha=0

      // // 天空盒隐藏
      // globalVariable.viewer.scene.skyBox.show = false;
      // // 解决抗锯齿问题
      // if (Cesium.FeatureDetection.supportsImageRenderingPixelated()) {
      //   //判断是否支持图像渲染像素化处理
      //   globalVariable.viewer.resolutionScale = window.devicePixelRatio;
      // }
      // // //是否开启抗锯齿
      // globalVariable.viewer.scene.fxaa = true;
      // globalVariable.viewer.scene.postProcessStages.fxaa.enabled = true;
      // globalVariable.viewer.scene.globe.depthTestAgainstTerrain = true;
      // globalVariable.viewer.scene.debugShowFramesPerSecond = true;
      // globalVariable.viewer.scene.globe.enableLighting = true;
      // globalVariable.viewer.shadows = true;
      // //globalVariable.viewer.shadowMap.softShadows  = true
      // globalVariable.viewer.shadowMap.darkness = 0.7; //阴影透明度--越大越透明
      // // 改变时间设置光照效果
      // var utc = Cesium.JulianDate.fromDate(new Date("2021/07/04 08:00:00"));
      // //北京时间=UTC+8=GMT+8
      // globalVariable.viewer.clockViewModel.currentTime = Cesium.JulianDate.addHours(
      //   utc,
      //   8,
      //   new Cesium.JulianDate()
      // );
      // globalVariable.viewer.scene.light = new Cesium.DirectionalLight({
      //   //去除时间原因影响模型颜色
      //   direction: new Cesium.Cartesian3(
      //     0.35492591601301104,
      //     -0.8909182691839401,
      //     -0.2833588392420772
      //   ),
      // });
    },

    // 添加地图底图瓦片
    addMapTiles(key) {
      switch (key) {
        case "tdt":
          // 加载天地图影像
          globalVariable.viewer.imageryLayers.addImageryProvider(
            new Cesium.WebMapTileServiceImageryProvider({
              url:
                "http://t{s}.tianditu.gov.cn/img_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=img&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default&format=tiles&tk=" +
                systemConfig.tdt_tk,
              // url: "/proxy_tdt/proxy{s}/img_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=img&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default&format=tiles&tk="+systemConfig.tdt_tk,
              layer: "img",
              style: "default",
              tileMatrixSetID: "w",
              format: "image/jpeg",
              subdomains: ["0", "1", "2", "3", "4", "5", "6", "7"],
              tileMatrixSetID: "GoogleMapsCompatible",
              show: true,
              minimumLevel: 1,
              maximumLevel: 18,
              // rectangle: Cesium.Rectangle.fromDegrees(90, -90, 180, -180),
            })
          );
          // 加载影像注记
          globalVariable.viewer.imageryLayers.addImageryProvider(
            new Cesium.WebMapTileServiceImageryProvider({
              url:
                "http://t{s}.tianditu.gov.cn/cia_w/wmts?tk=" +
                systemConfig.tdt_tk,
              layer: "cia",
              style: "default",
              tileMatrixSetID: "w",
              format: "tiles",
              subdomains: ["0", "1", "2", "3", "4", "5", "6", "7"],
              maximumLevel: 20,
            })
          );
          break;
        case "xq":
          viewer.imageryLayers.addImageryProvider(
            new Cesium.UrlTemplateImageryProvider({
              url: "http://119.3.233.75/tile/v1.0/gr?l={z}&x={x}&y={y}",
              minimumLevel: 1,
              maximumLevel: 19,
              format: "png",
            })
          );

          break;
        case "arcgis":
          // 加载ArcGIS在线地图
          globalVariable.viewer.imageryLayers.addImageryProvider(
            new Cesium.ArcGisMapServerImageryProvider({
              url: "https://server.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer",
            })
          );
          break;

        default:
          break;
      }
    },

    // 模型加载
    tilesetAdd() {
      // 水坝
      // this.add3DTilesData(
      //   systemConfig.modelTilesObj.ojk_shuiba_dm,
      //   undefined,
      //   true
      // );
      // this.add3DTilesData(
      //   systemConfig.modelTilesObj.ojk_shuiba_snjz,
      //   undefined,
      //   true
      // );
      // this.add3DTilesData(
      //   systemConfig.modelTilesObj.ojk_shuiba_swjz,
      //   undefined,
      //   true
      // );
      // this.add3DTilesData(
      //   systemConfig.modelTilesObj.ojk_shuiba_xp,
      //   undefined,
      //   true
      // );
      // globalVariable.ojk_shuiba_zm = this.add3DTilesData(
      //   systemConfig.modelTilesObj.ojk_shuiba_zm,
      //   undefined,
      //   true
      // );

      // 模型加载;
      if (systemConfig.modelTilesObj.plan) {
        // 地面
        // let pianyi = this.createMatrix4(systemConfig.modelTilesMatrixObj.plan);
        globalVariable.plan = this.add3DTilesData(
          systemConfig.modelTilesObj.plan,
          undefined,
          true
        );
      }
      if (systemConfig.modelTilesObj.plan_nowater) {
        // 无水地面
        // let pianyi = this.createMatrix4(systemConfig.modelTilesMatrixObj.plan);
        globalVariable.plan = this.add3DTilesData(
          systemConfig.modelTilesObj.plan_nowater,
          undefined,
          true
        );
      }
      // 建筑
      if (systemConfig.modelTilesObj.build) {
        globalVariable.build = this.add3DTilesData(
          systemConfig.modelTilesObj.build,
          undefined,
          true
        );
      }
      // 其他建筑（厂房）
      if (systemConfig.modelTilesObj.other_build) {
        globalVariable.other_build = this.add3DTilesData(
          systemConfig.modelTilesObj.other_build,
          undefined,
          true
        );
      }
      // 管网
      if (systemConfig.modelTilesObj.pipe) {
        globalVariable.pipe = this.add3DTilesData(
          systemConfig.modelTilesObj.pipe,
          undefined,
          false
        );
      }
      // globalVariable.tileset = [globalVariable.plan, globalVariable.build]
    },

    addWater(url, style) {
      this.waterClass.create(url, style).then((waterPrimitiveArr) => {
        this.waterPrimitiveArr = waterPrimitiveArr;
        window.waterPrimitiveArr = this.waterPrimitiveArr;
        waterPrimitiveArr.map(function (waterPrimitive) {
          return globalVariable.viewer.scene.primitives.add(waterPrimitive);
        });
      });
      // setTimeout(() => {
      // Cesium.upraiseModel(waterPrimitiveArr, {
      //   time: 3,
      //   height: 2,
      //   defaultHeight: 2,
      // });
      // Cesium.upraiseModel([globalVariable.ojk_shuiba_zm], {
      //   time: 3,
      //   height: 2,
      //   defaultHeight: 0,
      // });
    },

    // 点位数据
    // 1 流量计  2 消火栓  3 漏失监测仪  4 水质检测设备
    getPointPosition() {
      let that = this;
      return new Promise((resolve, reject) => {
        if (Object.keys(globalVariable.point_positions).length != 0) {
          Object.keys(globalVariable.point_positions).map(function (key) {
            globalVariable.viewer.entities.remove(
              globalVariable.point_positions[key]
            );
          });
          globalVariable.point_positions = {};
        }
        api
          .getAllPointPosition()
          .then((result) => {
            if (result.code == 0) {
              let data = result.data;
              // primitives可加载大量数据，性能方面比entities要好一些
              // let billboards = globalVariable.viewer.scene.primitives.add(
              //   new Cesium.BillboardCollection()
              // );
              data.map(function (item, index) {
                let arr = that.wenzhou2000ToWGS84([item.x, item.y]);
                let img = null;
                switch (item.equipmentType) {
                  case 1:
                    img = Flowmeter;
                    break;
                  case 2:
                    img = FireHydrant;
                    break;
                  case 3:
                    img = LeakageTester;
                    break;
                  case 4:
                    img = WaterQuality;
                    break;
                }
                let entity = globalVariable.viewer.entities.add({
                  id: item.equipmentId,
                  position: Cesium.Cartesian3.fromDegrees(arr[0], arr[1], 7),
                  billboard: {
                    image: img,
                    width: 34.5,
                    height: 35.5,
                    scale: 1.0,
                    horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
                    verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
                    pixelOffset: new Cesium.Cartesian2(0, 0),
                  },
                  // description: '<table><tr><td>事件描述：</td><td>' + item.id + '</td></tr>'+'<tr><td>中心点坐标：'+item.palce+'',
                });
                item.lon = arr[0];
                item.lat = arr[1];
                entity.info = item;
                entity.callback = that.searchPointInfo;
                globalVariable.point_positions[item.equipmentId] = entity;
                return;
                // billboards.add({
                //   image: img, // 图片地址
                //   width: 138,
                //   height: 142,
                //   scale: 1.0,
                //   sizeInMeters: true, //图像的尺寸被指定成图像实际的尺寸
                //   // Use a bottom, left origin
                //   horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
                //   verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
                //   position: Cesium.Cartesian3.fromDegrees(arr[0], arr[1], 80), // 点图标的位置
                //   id: "",
                // });
                // return item;
              });
              resolve();
            }
          })
          .catch((err) => {
            reject();
          });
      });
    },
    // 点位popup窗口事件
    bindPopup() {
      let that = this;
      var handler = new Cesium.ScreenSpaceEventHandler(
        globalVariable.viewer.scene.canvas
      );
      handler.setInputAction(function (event) {
        popup({
          type: "LEFT_CLICK",
          infos: event,
        });
      }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
      function popup(options) {
        if (options.type == "LEFT_CLICK") {
          if ($("#markerPopup")) {
            $("#markerPopup").remove();
          }
          clearInterval(that.ponitInterVal);
          var evt = options.infos;
          var pickedObject = globalVariable.viewer.scene.pick(evt.position);
          if (pickedObject && pickedObject.id) {
            var clickMarkerId = pickedObject.id._id;
            if (globalVariable.point_positions[clickMarkerId]) {
              var data = globalVariable.point_positions[clickMarkerId];
              if (data.callback) {
                data.callback(data.info);
              }
            }
          } else {
            return false;
          }
        }
      }
    },

    // 查询点位坐标
    searchPointInfo(data) {
      let that = this;
      return new Promise((resolve, reject) => {
        api
          .getSinglePointInfo({ id: data.equipmentId })
          .then((result) => {
            if (result.code == 0) {
              let param = Object.assign({}, data, result.data);
              that.setHtml(param);
              resolve();
            }
          })
          .catch((err) => {
            reject();
          });
      });
    },

    // 设置 popup 弹窗
    setHtml(data) {
      jumpPopup("popup", data);
    },

    // // 地图左击事件
    // singleClick(viewer) {
    //   var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
    //   handler.setInputAction(function (event) {
    //     var earthPosition = viewer.camera.pickEllipsoid(
    //       event.position,
    //       viewer.scene.globe.ellipsoid
    //     );
    //     var cartographic = Cesium.Cartographic.fromCartesian(
    //       earthPosition,
    //       viewer.scene.globe.ellipsoid,
    //       new Cesium.Cartographic()
    //     );
    //     var lat = Cesium.Math.toDegrees(cartographic.latitude);
    //     var lng = Cesium.Math.toDegrees(cartographic.longitude);
    //     var height = cartographic.height;
    //     console.log(lng + "," + lat);
    //   }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
    // },

    // 加载3DTiles数据
    add3DTilesData(url, matrix, show) {
      let tileset = new Cesium.Cesium3DTileset({
        url: url + "/tileset.json",
        skipLevelOfDetail: true, //开启跳级加载
        // preferLeaves: true,
        maximumScreenSpaceError: 16,
        maximumNumberOfLoadedTiles: 2000,
        maximumMemoryUsage: 512, //tileset可以使用的最大内存
        show: show,
        immediatelyLoadDesiredLevelOfDetail: true,
      });
      globalVariable.viewer.scene.primitives.add(tileset);
      tileset.readyPromise.then(function () {
        if (matrix) tileset.root.transform = matrix;
      });
      return tileset;
    },

    // 创建偏移矩阵
    createMatrix4(matrixParam) {
      var mx = Cesium.Matrix3.fromRotationX(
        Cesium.Math.toRadians(matrixParam.rx)
      );
      var my = Cesium.Matrix3.fromRotationY(
        Cesium.Math.toRadians(matrixParam.ry)
      );
      var mz = Cesium.Matrix3.fromRotationZ(
        Cesium.Math.toRadians(matrixParam.rz)
      );
      var rotationX = Cesium.Matrix4.fromRotationTranslation(mx);
      var rotationY = Cesium.Matrix4.fromRotationTranslation(my);
      var rotationZ = Cesium.Matrix4.fromRotationTranslation(mz);
      //平移 修改经纬度
      var position = Cesium.Cartesian3.fromDegrees(
        matrixParam.longitude,
        matrixParam.latitude,
        matrixParam.height
      );
      var m = Cesium.Transforms.eastNorthUpToFixedFrame(position);
      //旋转、平移矩阵相乘
      Cesium.Matrix4.multiply(m, rotationX, m);
      Cesium.Matrix4.multiply(m, rotationY, m);
      Cesium.Matrix4.multiply(m, rotationZ, m);
      //缩放 修改缩放比例
      var scale = Cesium.Matrix4.fromUniformScale(matrixParam.scale);
      Cesium.Matrix4.multiply(m, scale, m);
      return m;
    },

    // 加载大批量gltf文件
    loadBigDataGltf() {
      let that = this;
      globalVariable.treeArr = [];
      return new Promise((resolve, reject) => {
        $.getJSON("./static/data/GLTF/tree_path.json", function (array) {
          //array.length
          let instances = [];
          for (let i = 0; i < array.length; i += 2) {
            const item = array[i];
            let lonlat = that.wenzhou2000ToWGS84([
              Number(item.x),
              Number(item.y),
            ]);
            globalVariable.treeArr.push(lonlat);
            let modelMatrix = Cesium.Transforms.headingPitchRollToFixedFrame(
              new Cesium.Cartesian3.fromDegrees(
                lonlat[0] + 0.0007,
                lonlat[1] - 0.0004,
                5
              ),
              new Cesium.HeadingPitchRoll(0, 0, 0)
            );
            Cesium.Matrix4.multiplyByUniformScale(modelMatrix, 2, modelMatrix); // 缩放
            instances.push({
              modelMatrix: modelMatrix,
            });
          }
          // // for (let i = 0; i < newPositions.length; i++) {
          // for (let i = 0; i < 5000; i++) {
          //   let cartesian = newPositions[i];
          //   //批量加载
          //   let modelMatrix = Cesium.Transforms.headingPitchRollToFixedFrame(
          //     cartesian,
          //     new Cesium.HeadingPitchRoll(0, 0, 0)
          //   ); // 旋转
          // }
          let primitive = new Cesium.ModelInstanceCollection({
            url: "./static/data/GLTF/SEWQ01.gltf",
            instances: instances,
          });
          globalVariable.viewer.scene.primitives.add(primitive);
          // globalVariable.viewer.camera.setView({
          //   // 4.730190106068796,26.731048740120254
          //   destination: newPositions[0], // 设置位置
          //   orientation: {
          //     heading: Cesium.Math.toRadians(0), // 方向
          //     pitch: Cesium.Math.toRadians(-90.0), // 倾斜角度
          //     roll: 0,
          //   },
          // });
          resolve(primitive);
        });
      });
    },

    // 加载 GW 数据 primitive
    addGWDataPrimitive() {
      let data = globalVariable.guanxianGeojson;
      // console.log(data);
      let collection = new Cesium.PrimitiveCollection();
      data.features.forEach((item, index) => {
        let coor = item.geometry.coordinates[0].map(function (arr) {
          return [arr[0], arr[1], 100];
        });
        coor = JSON.parse("[" + coor.join(",") + "]");
        let line = Cesium.Cartesian3.fromDegreesArrayHeights(coor);
        let radius = Number(item.properties.DIAMETER) / 100;
        let shape = computeCircle(radius);

        let polylineVolumeGeometry = new Cesium.PolylineVolumeGeometry({
          polylinePositions: line,
          shapePositions: shape,
          cornerType: Cesium.CornerType.ROUNDED,
        });
        let GeometryInstance = new Cesium.GeometryInstance({
          geometry: polylineVolumeGeometry,
          // attributes: item.properties,
          attributes: {
            color: Cesium.ColorGeometryInstanceAttribute.fromColor(
              new Cesium.Color(1.0, 0.0, 0.0, 1.0)
            ),
          },
        });
        let primitive = new Cesium.Primitive({
          geometryInstances: GeometryInstance,
          appearance: new Cesium.PolylineColorAppearance({
            translucent: false,
          }),
        });
        // collection.add(primitive);
        // if (index < 2000)
        collection.add(primitive);
      });

      globalVariable.viewer.scene.primitives.add(collection);

      function computeCircle(radius) {
        let radiusd = 6;
        let beishu = 60;
        var positions = [];
        for (var i = 0; i < radiusd; i++) {
          var radians = Cesium.Math.toRadians(i * beishu);
          positions.push(
            new Cesium.Cartesian2(
              radius * Math.cos(radians),
              radius * Math.sin(radians)
            )
          );
        }
        return positions;
      }
    },

    wenzhou2000ToWGS84(coordinate) {
      return proj4("EPSG:0986", "EPSG:4326", coordinate);
    },

    // 经纬度转墨卡托
    lonlattoWebMercator(lon, lat) {
      var xy = [];
      var x = (lon * 20037508.34) / 180;
      var y =
        Math.log(Math.tan(((90 + lat) * Math.PI) / 360)) / (Math.PI / 180);
      y = (y * 20037508.34) / 180;
      xy[0] = x;
      xy[1] = y;
      return xy;
    },

    // 墨卡托转经纬度
    webMercator2lonlat(x, y) {
      var lonlat = [];
      var lon = (x / 20037508.34) * 180;
      var lat = (y / 20037508.34) * 180;
      lat =
        (180 / Math.PI) *
        (2 * Math.atan(Math.exp((lat * Math.PI) / 180)) - Math.PI / 2);
      lonlat[0] = lon;
      lonlat[1] = lat;
      return lonlat;
    },
  },
};
</script>

<style lang="less" scoped>
#cesiumContainer {
  width: 100%;
  height: 100%;
}
</style>