import billboardImage from "./h.png";

export default class CesiumMap {
  viewer;
  currentMarkPointId;
  init = () => {
    const tianDiTuKey = "06494bcf2d4b66df7f3c586cc65af0cb";
    const subdomains = ["0", "1", "2", "3", "4", "5", "6", "7"];
    this.viewer = new window.Cesium.Viewer("map_container", {
      // terrainProvider: window.Cesium.createWorldTerrain()
      animation: false, // 动画
      homeButton: true, // home键
      geocoder: true, // 地址编码
      baseLayerPicker: false, // 图层选择控件
      timeline: false, // 时间轴
      fullscreenButton: true, // 全屏显示
      infoBox: true, // 点击要素之后浮窗
      sceneModePicker: true, // 投影方式  三维/二维
      navigationInstructionsInitiallyVisible: false, // 导航指令
      navigationHelpButton: false, // 帮助信息
      selectionIndicator: false, // 选择
      imageryProvider: new window.Cesium.WebMapTileServiceImageryProvider({
        // 影像底图
        url:
          `https://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=${
            tianDiTuKey}`,
        subdomains,
        layer: "tdtImgLayer",
        style: "default",
        format: "image/jpeg",
        tileMatrixSetID: "GoogleMapsCompatible", // 使用谷歌的瓦片切片方式
        show: true,
      }),
    });
    this.viewer._cesiumWidget._creditContainer.style.display = "none"; // 隐藏cesium ion
    this.viewer.imageryLayers.addImageryProvider(
      new window.Cesium.WebMapTileServiceImageryProvider({
        // 影像注记
        url:
          `https://t{s}.tianditu.gov.cn/cia_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=cia&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default.jpg&tk=${
            tianDiTuKey}`,
        subdomains,
        layer: "tdtCiaLayer",
        style: "default",
        format: "image/jpeg",
        tileMatrixSetID: "GoogleMapsCompatible",
        show: true,
      }),
    );
    this.initObliquePhotography();
    return { viewer: this.viewer };
  };

  initObliquePhotography = () => {
    this.viewer.scene.globe.depthTestAgainstTerrain = true;
    window.Cesium.ExperimentalFeatures.enableModelExperimental = true;
    const mapObliquePhotography = window.mapObliquePhotography || [];
    for (let i = 0; i < mapObliquePhotography.length; i++) {
      this.createObliquePhotography(mapObliquePhotography[i]);
    }
  };

  createObliquePhotography = (url) => {
    const tileset = new window.Cesium.Cesium3DTileset({
      url,
      skipLevelOfDetail: true,
      baseScreenSpaceError: 1024,
      maximumScreenSpaceError: 128, // 数值加大，能让最终成像变模糊
      skipScreenSpaceErrorFactor: 16,
      skipLevels: 1,
      immediatelyLoadDesiredLevelOfDetail: false,
      loadSiblings: true, // 如果为true则不会在已加载完概况房屋后，自动从中心开始超清化房屋
      cullWithChildrenBounds: true,
      cullRequestsWhileMoving: true,
      cullRequestsWhileMovingMultiplier: 10, // 值越小能够更快的剔除
      preloadWhenHidden: true,
      preferLeaves: true,
      maximumMemoryUsage: 128, // 内存分配变小有利于倾斜摄影数据回收，提升性能体验
      progressiveResolutionHeightFraction: 0.5, // 数值偏于0能够让初始加载变得模糊
      dynamicScreenSpaceErrorDensity: 0.5, // 数值加大，能让周边加载变快
      dynamicScreenSpaceErrorFactor: 1, // 不知道起了什么作用没，反正放着吧先
      dynamicScreenSpaceError: true, // 有了这个后，会在真正的全屏加载完之后才清晰化房屋
    });

    tileset.readyPromise.then((tileset) => {
      // 笛卡尔转换为弧度

      const cartographic = window.Cesium.Cartographic.fromCartesian(
        tileset.boundingSphere.center,
      );
      const lng = window.Cesium.Math.toDegrees(cartographic.longitude); // 使用经纬度和弧度的转换，将WGS84弧度坐标系转换到目标值，弧度转度
      const lat = window.Cesium.Math.toDegrees(cartographic.latitude);
      // 计算中心点位置的地表坐标
      const surface = window.Cesium.Cartesian3.fromDegrees(lng, lat, 0);
      // 偏移后的坐标
      const offset = window.Cesium.Cartesian3.fromDegrees(lng, lat, 5);
      const translation = window.Cesium.Cartesian3.subtract(
        offset,
        surface,
        new window.Cesium.Cartesian3(),
      );
      tileset.modelMatrix = window.Cesium.Matrix4.fromTranslation(translation);
    });
    this.viewer.scene.primitives.add(tileset);
  };

  flyTo = ({ longitude, latitude, height }) => {
    this.viewer.camera.flyTo({
      destination: this.getPosition(longitude, latitude, height),
      duration: 2,
    });
  };

  getPosition = (x, y, z = 0.0) => {
    return window.Cesium.Cartesian3.fromDegrees(x, y, z);
  };

  clearMarkPoint = () => {
    if (this.currentMarkPointId) {
      this.viewer.entities.removeById(this.currentMarkPointId);
      this.currentMarkPointId = null;
    }
  };

  getLongitudeAndLatitude = (callback) => {
    const handler = new window.Cesium.ScreenSpaceEventHandler(
      this.viewer.scene.canvas,
    );
    handler.setInputAction((click) => {
      this.clearMarkPoint();
      const cartesian = this.viewer.camera.pickEllipsoid(
        click.position,
        this.viewer.scene.globe.ellipsoid,
      );
      if (cartesian) {
        const cartographic = window.Cesium.Cartographic.fromCartesian(cartesian);
        const longitude = window.Cesium.Math.toDegrees(cartographic.longitude);
        const latitude = window.Cesium.Math.toDegrees(cartographic.latitude);
        this.currentMarkPointId = window.Cesium.createGuid();
        this.viewer.entities.add(
          new window.Cesium.Entity({
            id: this.currentMarkPointId,
            position: cartesian,
            billboard: {
              image: billboardImage,
              width: 23,
              height: 25,
              verticalOrigin: window.Cesium.VerticalOrigin.BOTTOM,
              horizontalOrigin: window.Cesium.HorizontalOrigin.CENTER,
              heightReference: window.Cesium.HeightReference.CLAMP_TO_GROUND,
              disableDepthTestDistance: Number.POSITIVE_INFINITY,
              clampToGround: true,
            },
          }),
        );
        if (callback && typeof callback === "function")
          callback(null, { longitude, latitude });
      }
      else {
        if (callback && typeof callback === "function")
          callback(new Error("【Map】 无法获取坐标"), null);
      }
    }, window.Cesium.ScreenSpaceEventType.LEFT_CLICK);
  };

  addMarkPoint = ({ longitude, latitude }) => {
    const cartesian = window.Cesium.Cartesian3.fromDegrees(longitude, latitude);
    this.currentMarkPointId = window.Cesium.createGuid();
    this.viewer.entities.add(
      new window.Cesium.Entity({
        id: this.currentMarkPointId,
        position: cartesian,
        billboard: {
          image: billboardImage,
          width: 23,
          height: 25,
          verticalOrigin: window.Cesium.VerticalOrigin.BOTTOM,
          horizontalOrigin: window.Cesium.HorizontalOrigin.CENTER,
          heightReference: window.Cesium.HeightReference.CLAMP_TO_GROUND,
          disableDepthTestDistance: Number.POSITIVE_INFINITY,
          clampToGround: true,
        },
      }),
    );
  };
}
