Newer
Older
KaiFengPC / src / utils / gis / NewFiberMapUtils.js
@zhangdeliang zhangdeliang on 23 May 28 KB 初始化项目
import request from 'axios';
import { useRouter } from 'vue-router';

// wms 通用参数
const WMS_PARAMS = {
  SERVICE: "WMS",
  VERSION: "1.1.0",
  REQUEST: "GetMap",
  FORMAT: "image/png",
  TRANSPARENT: true,
  srs: "EPSG:3857",
  width: 256,
  height: 256,
  bbox: "bboxx",
};

const WFS_PARAMS = {
  SERVICE: "WFS",
  request: "GetFeature",
  typeName: "typename",
  VERSION: "1.1.0",
  outputFormat: "application/json",
  bbox: "",
};

const VECTOR_TYPE = {
  POINT: "POINT",
  LINESTRING: "LINESTRING",
  POLYGON: "POLYGON",
};

const mapConfig = {
  NAN_PING: {
    center: [118.09335687862085, 27.36991075178898],
  },
  WU_HU: {
    center: [118.43303301141083, 31.350763350582454],
  },
  HONG_SHAN: {
    // center: [116.348081212490996, 39.883840939490099],
    center: [114.3395742820067, 30.505834716825838],
  },
  YUE_YANG: {
    center: [113.11514893344838,29.35451519155447],
  },
  XIAO_GAN: {
    center: [113.899, 30.915],
  }
}[import.meta.env.VITE_PROJECT_NAME];

export default class NewFiberMapLKUtils {
  //地图实例
  map = null;

  //三维场景对象
  virtualSpaceObj = null;

  //搜索对象
  search = null;

  features = [];

  //相机动画对象
  animation = null;

  //点聚合对象
  markerCluster = null;

  isOpenLabel = true;

  callbacks = {
    mapClick: undefined,
    featureClick: undefined,
  };

  imageLayers = [];

  canvasLayers = [];

  timer = null;

  static defaultParams = {
    keys: { temporary: "temporary", primaryKey: "primary_key" },
    url: {
      // icon: img,
        icon: "https://lkimgyt.luokuang.com/1592966522911.png",
    },
    size: { icon: [32, 32] },
    flyTo: { duration: 3000, zoom: 15, center: mapConfig.center },
  };

  static mapConfig = {
    adcode: 411600,
    container: "map",
    zoom: 11.6,
    pitch: 0,
    bearing: 0,
    fog: false,
    antialias: true, // 是否开启抗锯齿
    cursor: "default",
    center: new LKMap.LngLat(...mapConfig.center),
    minZoom: 3,
    maxZoom: 22,
    isHotspot: false,
    isHotspotActive: false,
  };

  static _layers = {
    terrain: {
      url: "https://api.luokuang.com/data3d/terrain_png/440100/20220901/{z}/{x}/{y}.png",
    },
    baseMap: [
      {
        id: "baseMap_vector",
        name: "矢量图",
        icon:
            import.meta.env.VITE_APP_MAP_SRC + "static/images/ylz/dengjired.png",
        type: 0,
        url: import.meta.env.VITE_APP_MAP_SRC + "static/libs/map/nightblue.json",
        check: true,
      },
      {
        id: "baseMap_imagery",
        name: "影像图",
        icon:
            import.meta.env.VITE_APP_MAP_SRC +
            "static/images/ylz/dengjigreen.png",
        type: 1,
        url: "https://gac-geo.googlecnapps.cn/maps/vt?lyrs=s&hl=zh-CN&gl=CN&x={x}&y={y}&z={z}&src=app&scale=2",
      },
    ],
    wms: {
    },
    features: [],
  };

  constructor(container, options) {
    this.initMap(container, options);
  }

  initMap (container, options) {
    let self = this;
    let config = Object.assign(NewFiberMapLKUtils.mapConfig, options);
    config.container = container || config.container;
    if (import.meta.env.VITE_PROJECT_NAME == "NAN_PING")
      config.style = {
        version: 8,
        sources: {
          "raster-tiles": {
            type: "raster",
            tiles: [
              "http://192.168.1.38:8900/OfflineMap/mapabc/satellite/{z}/{x}/{y}.jpg",
            ],
            tileSize: 256,
          },
        },
        // "sources": {"raster-tiles": {"type": "raster", "tiles": ['http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}'], "tileSize": 256}},
        layers: [
          {
            id: "simple-tiles",
            type: "raster",
            source: "raster-tiles",
            minzoom: 0,
            maxzoom: 22,
          },
        ],
      };

    self.callbacks = {
      mapClick: options.mapClick,
      featureClick: options.featureClick,
    };
    this.map = new LKMap.Map(config.container, config);

    this.map.on("load", () => {

      self.loadVectorWall();
      // this.addTerrain();
      // this.addControl();
      self.updateSky();
      self.addBaseMapImagery();
      self.mapZoomEndEvt();

      //地图点击回调
      if (self.callbacks.mapClick) this.mapClick(self.callbacks.mapClick);
      self.animation = new LKMap.CameraAnimation({ map: this.map });
      /*      this.map.plugin(["MarkerClusterer", "AnalysisSearch"], function () {
                      //查询对象
                      self.search = new LKMap.AnalysisSearch({ size: 10, adcode: NewFiberMapLKUtils.mapConfig.adcode, regionLimit: true })

                      //聚合对象
                      self.markerCluster = new LKMap.MarkerClusterer({ map: self.map });
                  });*/

      if (import.meta.env.VITE_PROJECT_NAME == "NAN_PING") {
        let configs = [
          // {id:'tdt_vec',url:'http://t{s}.tianditu.com/DataServer?T=vec_w&X={x}&Y={y}&L={z}&tk=dee46731f7a87187c6507ff35aa9f2ef',params:{subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'], minZoom: 1, maxZoom: 19, tileType: 'xyz'}},
          {
            id: "iserver_basemap_vec",
            url:
                import.meta.env.VITE_PROJECT_ISERVER_URL +
                "/iserver/services/map-arcgis-15/wmts100?layer=图层&style=default&tilematrixset=GlobalCRS84Scale_图层&Service=WMTS&Request=GetTile&Version=1.0.0&Format=image/png&TileMatrix={z}&TileCol={x}&TileRow={y}",
            params: {
              subdomains: [],
              minZoom: 1,
              maxZoom: 19,
              tileType: "xyz",
            },
          },
          {
            id: "iserver_basemap_annotation",
            url:
                import.meta.env.VITE_PROJECT_ISERVER_URL +
                "/iserver/services/map-arcgis-3/wmts100?layer=图层&style=default&tilematrixset=GlobalCRS84Scale_图层&Service=WMTS&Request=GetTile&Version=1.0.0&Format=image/png&TileMatrix={z}&TileCol={x}&TileRow={y}",
            params: {
              subdomains: [],
              minZoom: 1,
              maxZoom: 19,
              tileType: "xyz",
            },
          },
          // {id:'iserver_china_4490',url:'https://iserver.supermap.io/iserver/services/map-china400/rest/maps/China_4490/zxyTileImage.png?z={z}&x={x}&y={y}',params:{subdomains: [], minZoom: 1, maxZoom: 19, tileType: 'xyz'}},
        ];
        configs.forEach((config) => {
          new WMTSLayer({ url: config.url }).addTo(self.map);
        });
        // configs.forEach(config => self.map.addLayer(new customTileLayer(config.id, config.url,config.params)))
      }
      if (config.tools) {
        let tools = new LKMap.MouseTool(self.map, config.tools);
        tools.on("create", config.tools.callback || function () { });
        tools.on("delete", config.tools.callback || function () { });
        tools.on("distance", config.tools.callback || function () { });
        tools.on("measureArea", config.tools.callback || function () { });
        self.map.addControl(tools);
      }

      this.baseMapChange(NewFiberMapLKUtils._layers.baseMap[1]);
    });
    if (!!!(import.meta.env.VITE_PROJECT_NAME == "NAN_PING"))
      self.map.setStyle(NewFiberMapLKUtils._layers.baseMap[0].url);
  }

  async loadVectorWall(geojson,id=5) {
    if (!!!geojson) {
      let { VITE_APP_MAP_SRC, VITE_PROJECT_NAME } = import.meta.env;
      let { data } = await request(VITE_APP_MAP_SRC + 'static/json/' + VITE_PROJECT_NAME + '_boundary.json');
      geojson = data;
    }
    if(!!!this.effectLayer) this.effectLayer = new this.virtualSpaceObj.DynamicEffect({ VirtualSpace: this.virtualSpaceObj });
    this.effectLayer.removeModel(NewFiberMapLKUtils.defaultParams.keys.temporary);
    this.effectLayer.createTextureWall({
      id,
      url:'https://lkimgyt.luokuang.com/1655804893047.png',
      // url: import.meta.env.VITE_APP_MAP_SRC + 'static/json/wall.png',
      path: turf.getCoords(geojson.features[0])[0],
      direction: 3,
      height: 3000,
      base: 18,
      isGradient: true,
      repeatY: 4,
    });
  }

  searchByKeyWord (keyword, callback) {
    let self = this;
    self.search.search(keyword, callback);
  }

  featureClick (feature, callback) {
    feature.on("click", (e) => callback(e));
  }

  setAllFeaturesVisible(visible = true) {
    this.features.forEach(feature => feature[['hide', 'show'][Number(visible)]]());
  }

  mapZoomEndEvt () {
    let self = this;
    self.map.on("render", (e) => {
      let zoom = self.map.getZoom();
      self.features
          .filter((i) => !!i.getIcon && i.visible)
          .forEach((i) => {
            let iconScope = i.getIcon().options.scope;
            let labelScope = (i.getLabel() || {}).scope || [0, 25];
            i[
                ["hide", "show"][Number(zoom > iconScope[0] && zoom < iconScope[1])]
                ]();
            if (!!i.getLabel())
              i.setLabelStyle(
                  Object.assign(i.getLabel().style || {}, {
                    opacity: Number(
                        self.isOpenLabel &&
                        zoom > labelScope[0] &&
                        zoom < labelScope[1]
                    ),
                  })
              );
          });
    });
  }

  mapClick (callback) {
    let self = this;
    this.map.on("click", (e) => {
      if (!!!Object.keys(NewFiberMapLKUtils._layers.wms).length) return callback(e);
      const zoom = self.map.getZoom();
      const value = Math.pow(2, 22 - zoom);
      let { lng, lat } = e.lngLat;
      let val = 0.0005;
      let bbox = turf.bbox(turf.buffer(turf.point([lng, lat]), val));
      // let bbox = turf.bbox(turf.buffer(turf.point(CoordTransform.gcj02towgs84(lng,lat)),val));
      const center = wgs84ToMercator(lng, lat);
      // const []
      // const min = [center.x - value, center.y - value];
      // const max = [center.x + value, center.y + value];
      let params = Object.assign(WFS_PARAMS, {});
      // delete params.bbox;
      // params.bbox = bbox.join(',')
      // params.filter = `<Filter xmlns="http://www.opengis.net/ogc" xmlns:gml="http://www.opengis.net/gml"><Intersects><PropertyName>geometrys</PropertyName><gml:Point srsName="http://www.opengis.net/gml/srs/epsg.xml#4326"><gml:coordinates>${CoordTransform.gcj02towgs84(lng,lat).join(',')}</gml:coordinates></gml:Point></Intersects></Filter>`
      // params.bbox = `${lng - val},${lat - val},${lng + val},${lat + val}`
      // params.bbox = [min,max].flat().join(',');
      bbox.push("EPSG:4326");
      params.bbox = bbox.join(",");
      let { linestring, point } = NewFiberMapLKUtils._layers.wms;
      let lineStringChecks = linestring.children.filter((i) => i.check);
      let pointChecks = point.children.filter((i) => i.check);
      let urls = [];
      urls.push(!!lineStringChecks.length && linestring);
      urls.push(!!pointChecks.length && point);
      urls = urls.filter(Boolean).map((item) => {
        let url = item.url;
        params.typeName = item.layers;
        url =
            url +
            "?" +
            Object.keys(params)
                .map((key) => `${key}=${params[key]}`)
                .join("&");
        return request({ url: url.toString() });
      });
      if (!!!urls.length) return Promise.resolve();
      Promise.all(urls).then((results) => callback(results));
    });

    function wgs84ToMercator (lng, lat) {
      lng = parseFloat(lng);
      lat = parseFloat(lat);
      let d = Math.PI / 180,
          max = 90,
          sin = Math.sin(lat * d);
      lat = Math.max(Math.min(max, lat), -max);
      let x = 6378137 * lng * d;
      let y = (6378137 * Math.log((1 + sin) / (1 - sin))) / 2;
      return {
        x,
        y,
      };
    }
  }

  addBaseMapImagery () {
    NewFiberMapLKUtils._layers.baseMap[1].instance = new LKMap.TileLayer({
      getTileUrl: NewFiberMapLKUtils._layers.baseMap[1].url,
      opacity: 1,
    });
    NewFiberMapLKUtils._layers.baseMap[1].check = false;
    NewFiberMapLKUtils._layers.baseMap[1].instance.setMap(this.map);
    NewFiberMapLKUtils._layers.baseMap[1].instance.hide();
  }

  wmsLoader(url,key){
    let self = this;
    let urlSearchParams=new URLSearchParams(url);
    let bboxs = urlSearchParams.get('BBOX1').split(',').map(Number);
    let wmsLayer = new LKMap.TileLayer.WMS({
      getTileUrl: bbox => {
        let b = turf.bboxPolygon(bboxs);
        let a = turf.bboxPolygon(bbox.split(',').map(Number));
        a = gcoord.transform(a, gcoord.WebMercator, gcoord.WGS84);
        let i = turf.intersect(b, a);
        if (!!!i) return '';
        return url + `&bbox=${turf.bbox(gcoord.transform(a, gcoord.GCJ02, gcoord.WebMercator)).join(',')}`;
      },
    });
    wmsLayer.setMap(self.map);
    wmsLayer.newfiberId = key;
    self.features.push(wmsLayer);
  }

  wmsLayerChange (cItem, cIndex, item) {
    console.log(cItem, cIndex, item);
    console.log(item.url);
    let self = this;
    cItem.instance
        ? cItem.check
        ? cItem.instance.show()
        : cItem.instance.hide()
        : loadWms();
    function loadWms () {
      let bboxKey = WMS_PARAMS.bbox;
      let url = item.url;
      let params = Object.assign(WMS_PARAMS, {
        LAYERS: item.layers,
        cql_filter: `${item.filterField}='${cItem.id}'`,
      });
      url =
          url +
          "?" +
          Object.keys(params)
              .map((key) => `${key}=${params[key]}`)
              .join("&");
      console.log(url);
      cItem.instance = new LKMap.TileLayer.WMS({
        getTileUrl: (bbox) => url.replaceAll(bboxKey, bbox),
      });
      cItem.instance.setMap(self.map);
    }
  }
  wmsLayerToMap(cItem, item) {
    let self = this;
    cItem.instance ? (cItem.check ? cItem.instance.show() : cItem.instance.hide()) : loadWms();
    function loadWms() {
      let bboxKey = WMS_PARAMS.bbox;
      let url = item.url;
      let params = Object.assign(WMS_PARAMS, { LAYERS: item.layers });
      url =
        url +
        '?' +
        Object.keys(params)
          .map(key => `${key}=${params[key]}`)
          .join('&');
      console.log(url);
      cItem.instance = new LKMap.TileLayer.WMS({
        getTileUrl: bbox => {
          console.log(bbox);
          console.log(url.replaceAll(bboxKey, bbox));
          url.replaceAll(bboxKey, bbox);
        },
      });
      cItem.instance.setMap(self.map);
    }
    return cItem.instance;
  }
  baseMapChange (item) {
    item.instance
        ? item.check
        ? item.instance.show()
        : item.instance.hide()
        : NewFiberMapLKUtils._layers.baseMap[1].instance.hide();
  }

  updateSky () {
    let self = this;
    // 实例化三维场景类
    self.virtualSpaceObj = new LKMap.VirtualSpace({
      map: self.map,
      /***
       * 天空盒类型:
       * 1. hdr_morning 早上
       * 2. hdr_daylight 白天
       * 3. hdr_sunset 日落
       * 4. hdr_night 晚上
       */
      skyType: "hdr_daylight", // 设置天空盒类型
    });
  }

  addTerrain () {
    this.map.addTerrain({
      url: NewFiberMapLKUtils._layers.terrain.url,
      exaggeration: 1,
      maxDrapeOverZoom: 5,
    });
    this.map.addHillshading({
      illuminationAnchor: "map",
      exaggeration: 0.5,
    });
  }

  // 添加地图控件
  addControl (params) {
    let self = this;
    // 缩放控件
    this.map.plugin(["ToolBar", "Scale", "ControlBar"], function () {
      [
        new LKMap.ToolBar({
          position: "bottom-right",
          showZoom: true,
          liteStyle: true,
        }),
        new LKMap.Scale({ position: "bottom-left" }),
        new LKMap.ControlBar({ position: "bottom-right" }),
      ].forEach((control) => self.map.addControl(control));
    });
  }

  static throttle (fn, delay = 300) {
    let timer = null;
    return function (...args) {
      if (timer == null) {
        timer = setTimeout(() => {
          fn.call(this, ...args);

          clearTimeout(timer);
          timer = null;
        }, delay);
      }
    };
  }

  addMarkers (lngLats, properties, labelScope = [1, 25], iconScope = [0, 25]) {
    let self = this;
    return lngLats.map((lngLat, index) => {
      let id =
          properties[index].mapParams.id ??
          NewFiberMapLKUtils.defaultParams.keys.temporary;
      let icon =
          properties[index].mapParams.icon ??
          NewFiberMapLKUtils.defaultParams.url.icon;
      let size =
          properties[index].mapParams.size ??
          NewFiberMapLKUtils.defaultParams.size.icon;
      let marker = new LKMap.Marker(
          Object.assign(
              {
                map: self.map,
                position: new LKMap.LngLat(...lngLat),
                anchor: "bottom",
                extData: properties[index] ?? {},
                icon: new LKMap.Icon({
                  size: new LKMap.Size(...size),
                  image: icon,
                  scope: iconScope,
                  anchor: "top-center",
                }),
              },
              properties[index].mapParams.name
                  ? {
                    label: {
                      scope: labelScope,
                      content: properties[index].mapParams.name ?? "",
                      direction: "top",
                      offset: new LKMap.Pixel(0, -5),
                      style: {
                        "background-color": "rgba(255,255,255,1)",
                        padding: "5px 10px",
                        "border-radius": "4px",
                        color: "black",
                        "box-shadow":
                            "0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04)",
                      },
                    },
                  }
                  : {}
          )
      );
      marker.newfiberId = id;
      // marker[['hide', 'show'][Number(properties.visible ?? true)]]()
      marker.visible = properties.visible ?? true;
      return marker;
    });
  }

  addPolygon (lngLats, properties, labelScope = [15, 25], iconScope = [0, 25]) {
    let self = this;
    return lngLats.map((lngLat, index) => {
      let id =
          properties[index].mapParams.id ??
          NewFiberMapLKUtils.defaultParams.keys.temporary;
      let { color, strokeColor } = properties[index].mapParams;
      let polygon = new LKMap.Polygon({
        map: self.map,
        path: lngLat,
        strokeWeight: 2.5,
        strokeOpacity: 1,
        strokeStyle: "dashed",
        strokeColor: strokeColor,
        fillColor: color,
        extData: properties[index],
      });
      polygon.newfiberId = id;
      // polygon[['hide', 'show'][Number(properties.visible ?? true)]]()
      polygon.visible = properties.visible ?? true;
      return polygon;
      // this.features.push(marker);
    });
  }

  addPolyline (lngLats, properties) {
    let self = this;
    return lngLats.map((lngLat, index) => {
      let id =
          properties[index].mapParams.id ??
          NewFiberMapLKUtils.defaultParams.keys.temporary;
      let color = properties[index].mapParams.color;
      let polyline = new LKMap.Polyline({
        map: self.map,
        path: lngLat,
        strokeWeight: 1,
        showBorder: true, // 是否显示描边
        borderWeight: 1, // 描边宽度
        borderColor: color,
        extData: properties[index],
      });

      // polyline[['hide', 'show'][Number(properties.visible ?? true)]]()
      polyline.visible = properties.visible ?? true;
      polyline.newfiberId = id;
      return polyline;
      // this.features.push(marker);
    });
  }

  addGeojson (geoJSON) {
    let self = this;
    let features = [];
    geoJSON.features = geoJSON.features.map(feature => gcoord.transform(feature,gcoord.WGS1984,gcoord.AMap));
    let geojson = new LKMap.GeoJSON({
      geoJSON, // GeoJSON对象
      getMarker: function (feature, lnglats) {
        //还可以自定义getMarker和getPolyline
        features.push(self.addMarkers([lnglats], [feature.properties]));
      },
      getPolygon: (feature, lnglats) => {
        let polygon = self.addPolygon([lnglats], [feature.properties]);
        features.push(polygon);
      },
      getPolyline: (feature, lnglats) => {
        features.push(self.addPolyline([lnglats], [feature.properties]));
      },
    });
    if (self.callbacks.featureClick)
      features
          .flat(Infinity)
          .forEach((i) => self.featureClick(i, self.callbacks.featureClick));
    self.features = self.features.concat(features).flat(Infinity);
  }

  beansToGeojson (beans, fields = { id: "id", color: "color", strokeColor: "strokeColor", geometry: "geometry", name: "name", icon: "icon_url", }, isCenter = true) {
    return turf.featureCollection(
        beans.filter((bean) => bean[fields.geometry]).map((bean) => {
              let mapParams = {
                id: bean[fields.id] || NewFiberMapLKUtils.defaultParams.keys.temporary,
                color: bean[fields.color] || NewFiberMapLKUtils.randomRgb(),
                strokeColor: bean[fields.strokeColor] || NewFiberMapLKUtils.randomRgb(),
                icon: bean[fields.icon] || NewFiberMapLKUtils.defaultParams.url.icon,
                name: bean[fields.name] || "",
                size: bean[fields.size] || NewFiberMapLKUtils.defaultParams.size.icon,
              };
              bean = Object.assign({ mapParams }, bean);

              let feature = turf.feature(Terraformer.WKT.parse(bean[fields.geometry]), bean);
              let features = turf.flatten(feature);
              gcoord.transform(features, gcoord.WGS84, gcoord.GCJ02);
              features = features.features;

              let points = features.map((feature, index) => {
                let point = turf.center(feature.geometry);
                point.properties = bean;
                features[index].properties.coorCenter = turf.getCoords(point);
                return point;
              });
              return isCenter ? [...features, ...points] : [...features];
            })
            .flat(Infinity).filter(Boolean)
    );
  }
  addWMSLaters(key) {
    let self = this;
    let bboxs = [113.88115996100544, 30.80362587198562, 114.1592539075588, 31.005052001897184];
    let url = '/geoserver/xiaoganMapServer/wms?';
    let wasParam = {
      SERVICE: 'WMS',
      VERSION: '1.1.0',
      REQUEST: 'GetMap',
      FORMAT: 'image/png',
      TRANSPARENT: true,
      LAYERS: `xiaoganMapServer:${key}`,
      SRS: 'EPSG:3857',
      WIDTH: 256,
      HEIGHT: 256,
    };
    url =
      url +
      Object.keys(wasParam)
        .map(key => `${key}=${wasParam[key]}`)
        .join('&');
    let wmsLayer = new LKMap.TileLayer.WMS({
      getTileUrl: bbox => {
        let b = turf.bboxPolygon(bboxs);
        let a = turf.bboxPolygon(bbox.split(',').map(Number));
        a = gcoord.transform(a, gcoord.WebMercator, gcoord.WGS84);
        let i = turf.intersect(b, a);
        if (!!!i) return '';
        return url + `&bbox=${turf.bbox(gcoord.transform(a, gcoord.GCJ02, gcoord.WebMercator)).join(',')}`;
      },
    });
    wmsLayer.setMap(self.map);
    wmsLayer.newfiberId = key;
    self.features.push(wmsLayer);
  }
  flyTo (params, callback) {
    let defaultFlyParams = NewFiberMapLKUtils.defaultParams.flyTo;
    defaultFlyParams = Object.assign(defaultFlyParams, params);
    this.animation.flyTo(defaultFlyParams, () => callback);
  }

  removeByIds (ids = []) {
    if (!!!ids.length) {
      this.features.forEach((i) => i.remove());
      this.features = [];
    }
    let features = this.getFeaturesByIds(ids);
    features.forEach((i) => i.remove());
    this.features = this.features.filter(
        (feature) => !!!ids.includes(feature.newfiberId)
    );
    // return this.getFeaturesByIds(ids).forEach(feature => feature.remove())
  }

  getFeaturesByIds (ids) {
    return ids
        ? (this.map.getIdLayers(ids) || []).concat(
            this.features.filter((feature) => ids.includes(feature.newfiberId))
        )
        : this.map.getLayers();
  }

  setFeaturesVisibleByIds (ids, visible = true, features = []) {
    this.getFeaturesByIds(ids)
        .concat(features)
        .flat(Infinity)
        .forEach((feature) => {
          feature.visible = visible;
          feature[["hide", "show"][Number(visible)]]();
        });
  }

  setFitViewByFeatures (feature = null, options = null, isDelayed = false) {
    setTimeout(
        () => {
          this.map.setFitView(feature, options);
        },
        isDelayed ? 2000 : 0
    );
  }

  dynamicLine (geojson,url) {
    if (!!!this.runLineLayer) this.runLineLayer = new this.virtualSpaceObj.RunLine({ VirtualSpace: this.virtualSpaceObj });
    this.runLineLayer.remove();
    this.runLineLayer.addLine(
        geojson.features.map((feature, index) => {
          let lngLats = turf.coordAll(feature);
          return {
            id:index,
            image: url || "https://lkimgyt.luokuang.com/1655260316814.png",
            height: 0,
            from: gcoord.transform(lngLats[0], gcoord.WGS1984, gcoord.AMap),
            to: gcoord.transform(lngLats[1], gcoord.WGS1984, gcoord.AMap),
            speed: 2,
            width: 10,
          };
        }),
        (e) => {
          console.log("飞线添加完成", e);
        }
    );
  }

  initImageLayers (urls, bounds) {
    let self = this;
    if (!!!self.imageLayers.length)
      self.imageLayers.forEach((layer) => layer.remove());
    self.imageLayers.length = 0;
    self.imageLayers = urls.map((url) => {
      let imageLayer = new LKMap.ImageLayer({
        url,
        bounds: new LKMap.Bounds(...bounds), // 设置图片覆盖的范围
        opacity: 1, // 设置图层透明度
      });
      imageLayer.setMap(self.map);
      return imageLayer;
    });
  }

  startPlayImageLayers () {
    let self = this;
    let step = 0;
    const alphaStep = 0.01;
    let arrTileLayer = self.imageLayers;

    function changeRadarAlpha (time) {
      if (step > arrTileLayer.length - 1) {
        step = 0;
        arrTileLayer[arrTileLayer.length - 1].setOptions({ opacity: 0 });
        // arrTileLayer[arrTileLayer.length - 1].alpha = 0
      }
      const layer1 = arrTileLayer[step];
      const layer2 = arrTileLayer[step + 1];
      if (!layer1 || !layer2) return;
      layer1.setOptions({ opacity: 1 });
      layer2.setOptions({ opacity: 0 });

      clearInterval(self.timer);
      self.timer = window.setInterval(function () {
        let opacity1 = layer1.getOptions().opacity;
        let opacity2 = layer2.getOptions().opacity;
        opacity1 -= alphaStep;
        opacity2 += alphaStep;
        layer2.setOptions({ opacity: opacity1 });
        layer2.setOptions({ opacity: opacity2 });

        if (opacity1 < alphaStep) {
          layer1.alpha = 0;
          layer2.setOptions({ opacity: 0 });
          step++;
          changeRadarAlpha(time);
        }
      }, time * 1000 * alphaStep);
    }
    changeRadarAlpha(1);
  }

  initCanvasLayer (id, bounds) {
    if (!!this.canvasLayers.length)
      this.canvasLayers.forEach((i) => i.remove());
    this.canvasLayers.length = 0;
    let canvasLayerObj = new LKMap.CanvasLayer({
      canvasId: id,
      bounds: new LKMap.Bounds(...bounds),
    });
    canvasLayerObj.setMap(this.map);
    this.canvasLayers.push(canvasLayerObj);
  }

  static randomRgb () {
    //rgb颜色随机
    const r = Math.floor(Math.random() * 256);
    const g = Math.floor(Math.random() * 256);
    const b = Math.floor(Math.random() * 256);
    return `rgba(${r},${g},${b},0.5)`;
  }

  static loadAllImages (imgUrls) {
    var _load = function (imgUrl) {
      //创建img标签
      var img = new Image();
      img.src = imgUrl;
      //跨域选项
      img.setAttribute("crossOrigin", "Anonymous");
      return new Promise((resolve, reject) => {
        //文件加载完毕
        img.onload = function () {
          resolve(img);
        };
      });
    };
    var _loadAll = function (imgUrls) {
      var loadedImageUrls = [];
      for (var i = 0, len = imgUrls.length; i < len; i++) {
        loadedImageUrls.push(_load(imgUrls[i]));
      }
      return loadedImageUrls;
    };
    return Promise.all(_loadAll(imgUrls));
  }

  canvasImageToMap (data) {
    let images = [];
    Object.keys(data).forEach((key) => {
      let canvasLayerObj = new LKMap.CanvasLayer({
        canvasId: `${key}_canvas`,
        bounds: new LKMap.Bounds(...data[key].bounds),
      });
      canvasLayerObj.setMap(AllData.maps[key].map);
      images = images.concat(data[key].urls);
      AllData.maps[key].map.setBounds(new LKMap.Bounds(...data[key].bounds));
    });
    let index = 0;
    NewFiberMapLKUtils.loadAllImages(images).then((res) => {
      let imagess = _.chunk(res, res.length / 2);
      let keys = Object.keys(AllData.remouldData);
      let canvass = keys.map((key, index) => {
        let canvas = document.getElementById(`${key}_canvas`);
        canvas.width = data[key].wh[0];
        canvas.height = data[key].wh[1];
        return canvas;
      });
      let contexts = canvass.map((canvas) => canvas.getContext("2d"));
      if (AllData.interval) clearInterval(AllData.interval);
      AllData.interval = setInterval(() => {
        index++;
        if (index == imagess[0].length) index = 0;
        contexts.forEach((context, idx) => {
          let w = canvass[idx].width;
          let h = canvass[idx].height;
          canvass[idx].width = w;
          canvass[idx].height = h;
          context.drawImage(
              imagess[idx][index],
              0,
              0,
              data[keys[idx]].wh[0],
              data[keys[idx]].wh[1]
          );
        });
      }, 1000);
    });
  }
}