月球大数据地理空间分析展示平台-【前端】-月球2期前端
surprise
2023-11-03 34a81cb796b9a4e862b1598d4dea56c32a68ea07
src/assets/js/Map/olMap.js
@@ -1,27 +1,429 @@
import { Map, View } from "ol";//地图,视图
import { getToken } from "@/utils/auth";
import store from "@/store";
//配置文件地址
// import config from "../../../../public/config/config.js";
import { Map, View } from "ol"; //地图,视图
import OSM from "ol/source/OSM"; //可以理解为数据源,就是一张图片
import TileLayer from "ol/layer/Tile"; //可以理解为图层
import { fromLonLat } from "ol/proj";//将坐标从经度/纬度转换为不同的投影。
import XYZ from "ol/source/XYZ"
import { fromLonLat, transform } from "ol/proj"; //将坐标从经度/纬度转换为不同的投影。
import XYZ from "ol/source/XYZ";
import WMTS from "ol/source/WMTS.js";
import WMTSTileGrid from "ol/tilegrid/WMTS.js";
import { get as getProjection, Projection, addProjection } from "ol/proj.js";
import { register } from "ol/proj/proj4";
import MousePosition from "ol/control/MousePosition.js";
import { getTopLeft, getWidth } from "ol/extent.js";
// import { format } from "ol/coordinate";
// import { nextTick } from "vue";
// import { boundingExtent } from 'ol/extent.js';
// import { createXYZ } from 'ol/tilegrid.js';
// import { defaults as defaultControls } from 'ol/control.js';
const olMap = {
    initMap() {
        //google地图
        var googleMapLayer = new TileLayer({
            source: new XYZ({
                url: 'http://wprd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=6&x={x}&y={y}&z={z}'
            })
        });
  map: null,
  Layer: null,
  proxy: null,
  projectionObj: {
    code: null,
    extent: null,
  },
  initMap() {
    this.proxy = config.proxy
    if (this.map) {
      this.map.setTarget(null);
      this.map.dispose();
      this.map = null;
    }
        var map = new Map({
            target: "mapView",
            layers: [googleMapLayer],//AMapLayer, baiduMapLayer
            view: new View({
                center: [10997148, 4569099],
                zoom: 4
            }),
        });
    // let mousePositionControl = new MousePosition({
    //   coordinateFormat: (coordinate) => {
    //     store.state.olLon = coordinate[0].toFixed(6)
    //     store.state.olLat = coordinate[1].toFixed(6);
    //     if (this.map) {
    //       store.state.olZoom = parseInt(this.map.getView().getZoom())
    //     }
    //   },
    //   projection: this.projectionObj.code,
    //   target: 'mouse',
    // });
    // const projection = new Projection({
    //   code: this.projectionObj.code,
    //   extent: this.projectionObj.extent,
    // });
    // this.map = new Map({
    //   target: "mapView",
    //   layers: [], //AMapLayer, baiduMapLayer
    //   view: new View({
    //     projection: projection,
    //     center: [0, 0],
    //     zoom: 4,
    //   }),
    //   controls: [mousePositionControl]
    // });
  },
  addTreeData(treeNode, obj) {
    // this.delLayerAll();
    this.projectionObj = obj;
    //判断是否为代理
    if (treeNode.proxy) {
      this.addProxyAddress(treeNode); //有代理
    } else {
      this.addUrlAddress(treeNode); //无代理
    }
  },
  //代理地址
  addProxyAddress(res) {
    //判断数据类型
    switch (res.data) {
      case 1: //数字正射影像图
        this.setDataType(res);
        break;
      case 2: //场景地形数据
        this.setTerrainData(res);
        break;
      case 3: //数字高程模型(晕渲图)
        this.setDataType(res);
        break;
      case 4: //单波段栅格数据
        this.setDataType(res);
        break;
      case 5: //多光谱栅格数据
        this.setDataType(res);
        break;
      case 6: //高光谱栅格数据
        this.setDataType(res);
        break;
      case 7: //矢量图层
        this.setVectorData(res);
        break;
      case 8: //三维模型
        this.setModelData(res);
        break;
    }
  },
  //普通地址
  addUrlAddress(res) {
    switch (res.category) {
      case 0: //其他
        break;
      case 1: //GisServer
        this.addProxyAddress(res);
        break;
      case 2: //GeoServer
        this.addGeoServerAddress(res);
        break;
      case 3: //数简
        this.addProxyAddress(res);
        break;
      case 4: //ArgisServer
        this.addProxyAddress(res);
        break;
    }
  },
  setDataType(res) {
    switch (res.type) {
      case 0: //URL
        break;
      case 1: //TMS
        // this.setAddTmsLayer(res);
        break;
      case 2: //WMTS
        this.addWmts(res);
        break;
      case 3: //WMS
        // this.setAddWmsLayer(res);
        break;
    }
  },
  setTerrainData(res) {
    switch (res.type) {
      case 0: //URL
        // this.setAddTearrinLayer(res);
        break;
      case 1: //TMS
        // this.setAddTearrinLayer(res);
        break;
    }
  },
  setVectorData(res) {
    switch (res.type) {
      case 0: //URL
        break;
      case 3: //WMS
        // this.setAddWmsLayer(res);
        break;
      case 4: //WFS
        break;
    }
  },
  //获取服务地址
  getLayrUrl(res) {
    var url;
    if (res.proxy) {
      const token = getToken();
      url = config.proxy + res.proxy.replaceAll("{token}", token);
    } else {
      url = res.url;
    }
    return url;
  },
  deleteLayer() {
    if (this.map && this.Layer) {
      this.map.removeLayer(this.Layer);
      this.Layer = null;
    }
  },
  addWmts(res) {
    this.initMap();
    if (res.category == 4) {//判断是否为Arcgis服务
      addArcGisWmst(res);
    } else {
      addGeoWmst(res);
    }
  },
};
function addGeoWmst(res) {
  var url;
  if (res.proxy) {
    const token = getToken();
    url = config.proxy + res.proxy.replaceAll("{token}", token);
  } else {
    url = res.url;
  }
  const projection = new Projection({
    code: olMap.projectionObj.code,
    extent: olMap.projectionObj.extent,
  });
  var mapCode = olMap.projectionObj.code;
  epsgPolarCoord(mapCode)
  ol.proj.addProjection(projection);
  var projectionExtent = projection.getExtent();
  var size = getWidth(projectionExtent) / 256;
  var resolutions = new Array(18);
  var matrixIds = new Array(18);
  for (var z = 1; z < 19; ++z) {
    resolutions[z] = size / Math.pow(2, z);
    matrixIds[z] = z;
  }
  let mousePositionControl1 = new MousePosition({
    coordinateFormat: (coordinate) => {
      store.state.olLon = coordinate[0].toFixed(6)
      store.state.olLat = coordinate[1].toFixed(6);
      if (olMap.map) {
        store.state.olZoom = parseInt(olMap.map.getView().getZoom())
      }
    },
    projection: mapCode,
    target: 'mouse',
  });
  var wmtsLayer = new TileLayer({
    // opacity: 0.7, //图层透明度
    source: new WMTS({
      url: url, //WMTS服务基地址
      layer: "img", //注意每个图层这里不同
      matrixSet: "GoogleMapsCompatible",
      format: "image/png",
      style: "default",
      projection: projection,
      tileGrid: new WMTSTileGrid({
        origin: getTopLeft(projectionExtent), //原点(左上角)
        resolutions: resolutions, //分辨率数组
        matrixIds: matrixIds, //矩阵标识列表,与地图级数保持一致
      }),
      wrapX: true,
    })
  });
  var val = olMap.projectionObj.extent;
  olMap.map = new Map({
    target: 'mapView',
    layers: [],
    view: new View({
      center: [0, 0],
      zoom: 4,
      projection: projection,
      resolutions: res.resolutions
    }),
    controls: [mousePositionControl1]
  });
  olMap.map.addLayer(wmtsLayer)
  setTimeout(() => {
    if (olMap.map) {
      if (res.bak) {
        var json = JSON.parse(res.bak)
        olMap.map.getView().setCenter([json.center[0], json.center[1]])
        olMap.map.getView().setZoom(json.zoom)
      } else {
        olMap.map.getView().setCenter([0, 0])
        olMap.map.getView().setZoom(5)
      }
    }
  }, 500);
}
export default olMap;
function addArcGisWmst(res) {
  olMap.initMap
  var olMapDate = null;
  if (res.url.indexOf('south') > -1) {//南极
    olMapDate = proDate.south;
  } else if (res.url.indexOf('north') > -1) {//北极
    olMapDate = proDate.north;
  } else if (res.url.indexOf('near') > -1) {//北极
    olMapDate = proDate.near;
  } else if (res.url.indexOf('far') > -1) {//北极
    olMapDate = proDate.far;
  } else if (res.url.indexOf('equid') > -1) {//北极
    olMapDate = proDate.equid;
  }
  var extent = olMapDate.extent;
  var mapCode = olMapDate.epsg;
  initPolarCoord()
  var proj = new ol.proj.Projection({
    code: mapCode,
    extent: extent,
    worldExtent: extent,
    units: "m",
    metersPerUnit: 2 * Math.PI * 1737400 / 360
  });
  proj.getMetersPerUnit = function () {
    return 2 * Math.PI * 1737400 / 360; // 6378137
  };
  ol.proj.addProjection(proj);
  var ResolutionsAndMids = getResolutionsAndMids(12);
  var arcUrl = res.url;
  var arcgisLayer = new ol.layer.Tile({
    source: new ol.source.XYZ({
      tileUrlFunction: function (coords) {
        var l = 'L' + fillZero(coords[0], 2, 10);
        var r = 'R' + fillZero(-coords[2] - 1, 8, 16);
        var c = 'C' + fillZero(coords[1], 8, 16);
        return arcUrl + "/" + l + "/" + r + "/" + c + ".png";
      },
      projection: proj,
      tileGrid: new ol.tilegrid.TileGrid({
        origin: ol.extent.getTopLeft(proj.getExtent()),
        resolutions: ResolutionsAndMids.resolutions,
      })
    })
  });
  let mousePositionControl = new ol.control.MousePosition({
    coordinateFormat: (coordinate) => {
      var sourceProj = mapCode;
      console.log("yuanshi",mapCode)
      var destProj = "ESRI:104903"; // 目标坐标系为墨卡托投影
      var olLon = coordinate[0]
      var olLat = coordinate[1];
      console.log(olLon, olLat)
      var destCoord = ol.proj.transform([olLon, olLat], sourceProj, destProj);
      store.state.olLon = destCoord[0].toFixed(6)
      store.state.olLat = destCoord[1].toFixed(6);
      if (olMap.map) {
        store.state.olZoom = parseInt(olMap.map.getView().getZoom())
      }
    },
    projection: mapCode,
    target: 'mouse',
  });
  olMap.map = new ol.Map({
    target: 'mapView',
    controls: ol.control.defaults({
      attributionOptions: ({
        collapsible: true
      })
    }),
    layers: [],
    view: new ol.View({
      center:  [0,0 ],
      zoom:1,
      minZoom: 1,
      maxZoom: 12,
      controls: [mousePositionControl],
      projection: ol.proj.get(mapCode), // "ESRI:103877", //
      resolutions: res.resolutions
    })
  });
  olMap.map.addControl(mousePositionControl);
  olMap.map.addLayer(arcgisLayer)
  // setTimeout(() => {
  //   if (olMap.map) {
  //     olMap.map.getView().setCenter(olMapDate.centert)
  //     olMap.map.getView().setZoom(olMapDate.zoom)
  //   }
  // },1000);
}
function initPolarCoord() {
  proj4.defs("ESRI:103877","+proj=stere +lat_0=90 +lon_0=0 +k=1 +x_0=0 +y_0=0 +R=1737400 +units=m +no_defs +type=crs");
  ol.proj.proj4.register(proj4);
  proj4.defs("ESRI:103878","+proj=stere +lat_0=-90 +lon_0=0 +k=1 +x_0=0 +y_0=0 +R=1737400 +units=m +no_defs +type=crs");
  ol.proj.proj4.register(proj4);
  // proj4.defs("ESRI:103881", "+proj=eqc +lat_ts=0 +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +R=1737400 +units=m +no_defs +type=crs");
  proj4.defs("ESRI:103881","+proj=eqc +lat_ts=0 +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +R=1737400 +units=m +no_defs +type=crs");
  ol.proj.proj4.register(proj4);
  proj4.defs("ESRI:103880","+proj=laea +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +R=1737400 +units=m +no_defs +type=crs");
  ol.proj.proj4.register(proj4);
  proj4.defs("ESRI:103879","+proj=laea +lat_0=0 +lon_0=180 +x_0=0 +y_0=0 +R=1737400 +units=m +no_defs +type=crs");
  ol.proj.proj4.register(proj4);
  proj4.defs("ESRI:104903", "+proj=longlat +R=1737400 +no_defs +type=crs");
  ol.proj.proj4.register(proj4);
}
function epsgPolarCoord(res) {
  proj4.defs(res, "+proj=longlat +R=1737400 +no_defs +type=crs");
  ol.proj.proj4.register(proj4);
}
function getResolutionsAndMids(maxLevel) {
  var rs = [
    156543.03392800014,
    78271.516963999937,
    39135.758482000092,
    19567.879240999919,
    9783.9396204999593,
    4891.9698102499797,
    2445.9849051249898,
    1222.9924525624949,
    611.49622628137968,
    305.74811314055756,
    152.87405657041106,
    76.437028285073239,
    38.21851414253662,
    19.10925707126831,
    9.5546285356341549,
    4.7773142679493699,
    2.3886571339746849,
    1.1943285668550503,
    0.59716428355981721,
    0.29858214164761665,
    // 0.14929107082380833,
    // 0.074645535411904163,
    // 0.037322767705952081,
    // 0.018661383852976041
  ];
  var matrixIds = [], resolutions = [];
  for (var z = 0; z <= maxLevel; ++z) {
    resolutions[z] = rs[z]; // size / Math.pow(2, z);
    matrixIds[z] = z;
  }
  return { "resolutions": resolutions, "matrixIds": matrixIds };
}
function fillZero(num, len, radix) {
  var str = num.toString(radix || 10);
  while (str.length < len) {
    str = '0' + str;
  }
  return str;
}
export default olMap;