Openlayers实例-加载天地图

<template>
  <div>
    <MapIndex v-on:getSelected="getSelected" ></MapIndex>
    <div id="popup" class="ol-popup">
      <div  id="popup-closer" class="ol-popup-closer"></div>
      <div id="popup-content">
      </div>
    </div>

    <div id="map" style="width: 100vw; height: 100vh">
      <div id="mouse-position"></div>

      <div id="layerControl" class="layerControl" v-show="showLayer">
        <!-- <button type="button" aria-label="Close" class="el-message-box__headerbtn" @click="showLayerControl"><i class="el-dialog__close el-icon el-icon-close"></i></button> -->
        <!-- <div class="title"><label>图层列表</label></div> -->
        <ul id="layerTree" class="layerTree">

        </ul>
      </div>
      <div class="layerSwitch" @click="showLayerControl">
         <span class="iconfont icon-diqiu" style="font-size: 20px;color: #0075FF"></span>
      </div>
    </div>
  </div>
</template>
<script>
import "ol/ol.css";
import TileLayer from "ol/layer/Tile";
import XYZ from "ol/source/XYZ";
import { Map, View, Feature } from "ol";
import OverviewMap from "ol/control/OverviewMap";
import addControl from "ol/Map";
import { Style } from "ol/style";
import Point from 'ol/geom/Point';
import addOverLay from "@/views/map/display/map_overLay.js";
import MapIndex from "@/views/map2";
import AddLayer from "@/views/map/display/add_geojson_layer";
import icon from "@/views/map/display/default_icon";
import text from "@/views/map/display/default_text";
import markLayer from "@/views/map/display/add_mark_layer";
import getIconByName, {getIconMapper} from "@/views/map/display/icon_mapper";
import getPoint from "@/views/map/display/load_point_location";
import {getGeoJson,getLocationAndZoom} from "@/views/map/display/load";
import layers_img_1 from "@/assets/images/vec.jpg";
import layers_img_2 from "@/assets/images/img.jpg";

export default {
  components: {MapIndex},
  data() {
    return {
      map: {},
      areaLayer: {},
      vectorSource:{},
      vectorLayerList:[],
      isChecked:[],
      showLayer:false,
      //map中的图层数组
      layer : new Array(),
      //图层名称数组
      layerName : new Array(),
      //图层可见属性数组
      layerVisibility : new Array(),
      //地图样式弹出框
//      showModal: false,
    };
  },
  mounted() {
    this.initMap().then((res)=>{//初始化地图方法
      this.pointMove();
      this.addGeoJsonLayer().then((res)=>{
        this.initLayer();
      }); //添加区域图层方法
      addOverLay(this);
      //加载图层列表数据
      this.loadLayersControl(this.map, "layerTree");
     // this.addEagleViewControl();
    });
  },
  methods: {
    showLayerControl(){
      this.showLayer = !this.showLayer;
      //加载图层列表数据
      // this.loadLayersControl(this.map, "layerTree");
    },
    /**
     * 加载图层列表数据
     * @param {ol.Map} map 地图对象
     * @param {string} id 图层列表容器ID
     */
    loadLayersControl(map, id) {
      //图层目录容器
      var treeContent = document.getElementById(id);
      //获取地图中所有图层
      var layers = map.getLayers();
      // console.log('选择',layers);
      for (var i = 0; i < layers.getLength() ; i++) {
        this.layer[i] = layers.item(i);
        if(this.layer[i].get('pkid')=='t2' || this.layer[i].get('pkid')=='t4'){
          //获取每个图层的名称、是否可见属性
          this.layerName[i] = this.layer[i].get('name');
          this.layerVisibility[i] = this.layer[i].getVisible();
          //新增li元素,用来承载图层项
          var elementLi = document.createElement('li');
          // 添加子节点
          treeContent.appendChild(elementLi);
          //创建复选框元素
          var elementInput = document.createElement('input');
          elementInput.type = "checkbox";
          elementInput.name = "layers";
          elementInput.id = 'layers-'+i;
          elementLi.appendChild(elementInput);
          //创建label元素
          var elementLable = document.createElement('label');
          elementLable.className = "layer";
          elementLable.htmlFor='layers-'+i;
          var elementImg = document.createElement('img');
          if(i<2){
            elementImg.src = layers_img_1;
          }else{
            elementImg.src = layers_img_2;
          }
          elementLable.appendChild(elementImg);
          var elementP = document.createElement('p');
          //设置图层名称
          this.setInnerText(elementP, this.layerName[i]);
          elementLable.appendChild(elementP);
          elementLi.appendChild(elementLable);
          //设置图层默认显示状态
          if (this.layerVisibility[i]) {
            elementInput.checked = true;
            elementLi.className = "active";
          }
          //为checkbox添加变更事件
          this.addChangeEvent(elementInput, this.layer[i],elementLi);
        }

      }
    },

    /**
     * 为checkbox元素绑定变更事件
     * @param {input} element checkbox元素
     * @param {ol.layer.Layer} layer 图层对象
     * @param imgElement checkbox元素绑定的img有无边框
     */
    addChangeEvent(element, layer ,imgElement) {
      var layers = this.map.getLayers();
      var layers1;
      var layers3;
      for (var i = 0; i < layers.getLength() ; i++) {
        if(layers.item(i).get('pkid')=='t1') {
           layers1=layers.item(i);
        }else if(layers.item(i).get('pkid')=='t3'){
          layers3=layers.item(i);
        }
      }
      element.onclick = function () {
        if(layer.get('pkid')=='t2'){
          if (element.checked) {
            //显示图层
            layer.setVisible(true);
            //layers1.setVisible(true);
          } else {
            //不显示图层
            layer.setVisible(false);
           // layers1.setVisible(false);
          }
        }else{
          if (element.checked) {
            //显示图层
            layer.setVisible(true);
            layers3.setVisible(true);
          }
          else {
            //不显示图层
            layer.setVisible(false);
            layers3.setVisible(false);
          }
        }
        if (!imgElement.classList.contains('active')) {
          //显示图层
          imgElement.classList.add('active');
        }
        else {
          //不显示图层
          imgElement.classList.remove('active');
        }

      };
    },
    /**
     * 动态设置元素文本内容(兼容)
     */
    setInnerText(element, text) {
      if (typeof element.textContent == "string") {
        element.textContent = text;
      } else {
        element.innerText = text;
      }
    },

    getSelected(value){
      for (let element of this.vectorLayerList) {
        let e = value.filter(s=>s === element.name);
        if (e && e.length > 0 ) {
          if (!this.isChecked.includes(element.name)) {
            element.vector.setVisible(true);
            this.markByName(element.name);
            this.isChecked.push(element.name);
          }
        } else {
          this.removeVectorByType(element.name);
          this.isChecked = this.isChecked.filter(s=>s !== element.name);
        }

      }

    },

    //-------------------------------------------------------------

    pointMove() {
      // 设置鼠标划过矢量要素的样式
      this.map.on("pointermove", (e) => {
        const isHover = this.map.hasFeatureAtPixel(e.pixel);
        this.map.getTargetElement().style.cursor = isHover ? "pointer" : "";
      });
    },

    //地图打点标记
    markByName(type) {
      getPoint(type).then(point => {
        for (let e of point) {
          this.markPoint(type, e);
        }
      });
    },

    /**
     * 添加geoJson 数据图层
     */
    addGeoJsonLayer() {
      let geoJson = {};
     return  getGeoJson().then(res=>{
        geoJson = res;
        AddLayer(geoJson,this);
        return res;
      });

    },

    removeVectorByType(type) {
      //根据type类型获取相应的vector 对象
      let a = this.vectorLayerList.filter(s=> s.name === type);
      if ( a  && a.length > 0 ) {
        for (let e of a) {
          let vectorLayer = e.vector;
          this.removeVector(vectorLayer);
        }
      }

    },

    removeVector(vectorLayer){
      vectorLayer.setVisible(false);
      let vectorSource = vectorLayer.getSource().getSource();
      let currentFeatures = vectorSource.getFeatures();
      if (currentFeatures.length !== 0) {
        //移除聚合标注数据源中的所有要素
        vectorSource.clear();
        //移除标注图层
        this.map.removeLayer( vectorLayer.getSource());
      }
    },


    /**
     * 初始化点位的图层信息
     */
    initLayer(){
      this.vectorLayerList = [];
      //获取所有的图标映射,并初始化所有类型的图标图层,此时图标图层不可见
      let iconMapper = getIconMapper();
      for (let ele of iconMapper) {
        let vectorLayer =  markLayer(ele.src,this);
        let a = {
          name: ele.name,
          vector:vectorLayer
        }
        this.vectorLayerList.push(a);
      }
    },


    markPoint(type,point) {
      //获取该点位的图层
      let layer ;
      for (let ele of this.vectorLayerList) {
          if (ele.name && ele.name === type ) {
              layer = ele.vector;
              break;
          }
      }

      if (layer === null || layer === undefined) {
        let src = getIconByName(type);
        let vectorLayer = markLayer(src, this);
        let a = {
          name: type,
          vector: vectorLayer
        };
        this.vectorLayerList(a);
        layer = vectorLayer;
      }
      //获取点位图层的数据源
      let vectorSource = layer.getSource().getSource();
      var baidu_point={lat:0,lon:0};
      baidu_point.lat=point.pos[0];
      baidu_point.lon=point.pos[1];
      var ss=this.baiduTomars(baidu_point);  //百度坐标转火星坐标
      var sss=this.transformGCJ2WGS(ss.lat,ss.lon); //火星坐标系GCJ02转地球坐标系WGS84
      point.pos[0]=sss.lat;
      point.pos[1]=sss.lon;
      this.addVectorLabel(vectorSource, point);
      layer.setVisible(true);
    },

//-------------------------------------------------------------


    transformGCJ2WGS(gcjLat, gcjLon) {
      let d = this.delta(gcjLat, gcjLon);
      return {
        'lat': gcjLat - d.lat,
        'lon': gcjLon - d.lon
      }
    },

    delta(lat, lon) {
      var PI = 3.14159265358979324;
      let a = 6378245.0; //  a: 卫星椭球坐标投影到平面地图坐标系的投影因子。
      let ee = 0.00669342162296594323 ;//  ee: 椭球的偏心率。
      let dLat = this.transformLat(lon - 105.0, lat - 35.0);
      let dLon = this.transformLon(lon - 105.0, lat - 35.0);
      let radLat = lat / 180.0 * PI;
      let magic = Math.sin(radLat);
      magic = 1 - ee * magic * magic;
      let sqrtMagic = Math.sqrt(magic);
      dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * PI);
      dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * PI);
      return {
        'lat': dLat,
        'lon': dLon
      }
    },
    transformLat(x, y) {
      var PI = 3.14159265358979324;
      let ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x));
      ret += (20.0 * Math.sin(6.0 * x * PI) + 20.0 * Math.sin(2.0 * x * PI)) * 2.0 / 3.0;
      ret += (20.0 * Math.sin(y * PI) + 40.0 * Math.sin(y / 3.0 * PI)) * 2.0 / 3.0;
      ret += (160.0 * Math.sin(y / 12.0 * PI) + 320 * Math.sin(y * PI / 30.0)) * 2.0 / 3.0;
      return ret
    },
    transformLon(x, y) {
      var PI = 3.14159265358979324;
      let ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x));
      ret += (20.0 * Math.sin(6.0 * x * PI) + 20.0 * Math.sin(2.0 * x * PI)) * 2.0 / 3.0;
      ret += (20.0 * Math.sin(x * PI) + 40.0 * Math.sin(x / 3.0 * PI)) * 2.0 / 3.0;
      ret += (150.0 * Math.sin(x / 12.0 * PI) + 300.0 * Math.sin(x / 30.0 * PI)) * 2.0 / 3.0;
      return ret
    },

//---------------------------------------------------------------------------


    baiduTomars(baidu_point){
      var x_pi=3.14159265358979324 * 3000.0 / 180.0;
      var mars_point={lon:0,lat:0};
      var x=baidu_point.lon-0.0065;
      var y=baidu_point.lat-0.006;
      var z=Math.sqrt(x*x+y*y)- 0.00002 * Math.sin(y * x_pi);
      var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);
      mars_point.lon=z * Math.cos(theta);
      mars_point.lat=z * Math.sin(theta);
      return mars_point;
    },


//------------------------------------------------------------

    /**
     * 添加点位图层的数据源信息
     * @param vectorSource    数据源
     * @paramy point           点位信息
     */
    addVectorLabel(vectorSource,point) {
        //新建一个要素 ol.Feature
        const newFeature = new  Feature({
          //几何信息
          geometry: new Point(point.pos),
          name: point.name,
          desc: point.desc,
          img: point.img
        });
        //设置要素的样式
       /* newFeature.setStyle(this.createLabelStyle(newFeature));*/
        //将新要素添加到数据源中
        vectorSource.addFeature(newFeature);



    },


    /**
     * 创建图标样式
     * @returns {Style}
     */
    createLabelStyle(feature) {
      return new Style({
        image: icon(feature.get("img")),
        text: text( feature.get('name'))
      });
    },


    addEagleViewControl() {
      if (this.map != null) {
        let TiandiMap_img = new TileLayer({
          name: '天地图影像图层',
          visible: true,
          source: new XYZ({
            url:  'http://t0.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=key',
            wrapX: false,
          }),
        });
        let TiandiMap_imgcia = new TileLayer({
          name: '天地图影像注记图层',
          visible: true,
          source: new XYZ({
            url:  'http://t0.tianditu.com/DataServer?T=cia_w&x={x}&y={y}&l={z}&tk=key',
            wrapX: false,
          }),
        });
        //实例化鹰眼控件(OverviewMap),自定义样式的鹰眼控件
        var overviewMapControl = new OverviewMap({
          //鹰眼控件样式(see in overviewmap-custom.html to see the custom CSS used)
          className: 'ol-overviewmap ol-custom-overviewmap',
          //鹰眼中加载同坐标系下不同数据源的图层
          layers: [TiandiMap_img, TiandiMap_imgcia],
          //鹰眼控件展开时功能按钮上的标识(网页的JS的字符编码)
          collapseLabel: '\u00BB',
          //鹰眼控件折叠时功能按钮上的标识(网页的JS的字符编码)
          label: '\u00AB',
          //初始为展开显示方式
          collapsed: false,
        });
        this.map.addControl(overviewMapControl);
      }
    },


    /**
     * 初始化地图
     */
    initMap() {
      let _this = this;
      let location = [116.477464559, 30.523468417];
      let zoomIndex = 9;
      return getLocationAndZoom().then(res=>{
        if (res && res.length > 0 ){
          location[0] = res[0];
          location[1] = res[1];
          zoomIndex = res[2];
        }

        _this.map = new Map({
          target: "map",
          layers: [
            new TileLayer({
              name: "矢量图层",
              pkid:'t1',
              source:new XYZ({
                url:  'http://t'+Math.round(Math.random()*7)+'.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=key',
                wrapX: false
              })
            }),
            new TileLayer({
              name: "矢量",
              pkid:'t2',
              source:new XYZ({
                url:  'http://t'+Math.round(Math.random()*7)+'.tianditu.com/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=key',
                wrapX: false
              })
            }),
            new TileLayer({
              name: "影像图层",
              pkid:'t3',
              source:new XYZ({
                url:  'http://t'+Math.round(Math.random()*7)+'.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=key',
                wrapX: false
              })
            }),
            new TileLayer({
              name: "影像",
              pkid:'t4',
              source:new XYZ({
                url:  'http://t'+Math.round(Math.random()*7)+'.tianditu.com/DataServer?T=cia_w&x={x}&y={y}&l={z}&tk=key',
                wrapX: false
              })
            }),
          ],
          //15°45′—117°44′
          view: new View({
            projection: "EPSG:4326",
            //117.05, 30.53
            center: location,
            zoom: zoomIndex,
          }),
        });
        return res;
      });
    },

//------------------------------------------------------------
    /**
     * 弹窗2021-12-21
     */
//    layerDetail() {
//      this.showModal = true;
//    },
//    layerClose() {
//      this.showModal = false;
//    }
  },
};
</script>

<style scoped>
  >>>.ol-overviewmap {
    left: 1.5em;
    bottom: 9.5em;
  }
  /*=S 自定义鹰眼样式 */
  .ol-custom-overviewmap, .ol-custom-overviewmap.ol-uncollapsible {
    bottom: auto;
    left: auto;
    /* 右侧显示 */
    right: 0;
    /* 顶部显示 */
    top: 0;
  }
  /* 鹰眼控件展开时控件外框的样式 */
  .ol-custom-overviewmap:not(.ol-collapsed)  {
    border: 1px solid black;
  }
  /* 鹰眼控件中地图容器样式 */
  >>>.ol-custom-overviewmap .ol-overviewmap-map {
    border: none;
    width: 260px;
  }
  /* 鹰眼控件中显示当前窗口中主图区域的边框 */
  >>>.ol-custom-overviewmap .ol-overviewmap-box {
    border: 2px solid red;
  }
  /* 鹰眼控件展开时其控件按钮图标的样式 */
  .ol-custom-overviewmap:not(.ol-collapsed) button{
    bottom: auto;
    left: auto;
    right: 1px;
    top: 1px;
  }

.ol-popup {
  position: absolute;
  background-color: white;
  -webkit-filter: drop-shadow(0 1px 4px rgba(0,0,0,0.2));
  filter: drop-shadow(0 1px 4px rgba(0,0,0,0.2));
  padding: 15px;
  border-radius: 10px;
  border: 1px solid #cccccc;
  bottom: 45px;
  left: -50px;
  width: 200px;
}

.ol-popup:after, .ol-popup:before {
  top: 100%;
  border: solid transparent;
  content: " ";
  height: 0;
  width: 0;
  position: absolute;
  pointer-events: none;
}

.ol-popup:after {
  border-top-color: white;
  border-width: 10px;
  left: 48px;
  margin-left: -10px;
}

.ol-popup:before {
  border-top-color: #cccccc;
  border-width: 11px;
  left: 48px;
  margin-left: -11px;
}

.ol-popup-closer {
  text-decoration: none;
  position: absolute;
  top: 2px;
  right: 8px;
}

.ol-popup-closer:after {
  content: "✖";
}

#popup-content {
  font-size: 14px;
  font-family: "微软雅黑";
}

#popup-content .markerInfo {
  font-weight: bold;
  width: 200px;
}

/* 图层控件层样式设置 */
.layerSwitch{
  position: absolute;
  right: 50px;
  bottom: 80px;
  z-index: 2001;
  padding: 10px;
  background-color: rgba(249, 249, 249, 0.87);
  cursor: pointer;
  -webkit-box-shadow: rgb(0 0 0 / 20%) 0 2px 4px, rgb(0 0 0 / 2%) 0 -1px 0;
  box-shadow: 0 2px 4px rgb(0 0 0 / 20%), 0 -1px 0 rgb(0 0 0 / 2%);
  border-radius: 4px
}

.layerControl {
  position: absolute;
  bottom: 5px;
  min-width: 190px;
  max-height: 75px;
  right: 105px;
  bottom: 60px;
  /*在地图容器中的层,要设置z-index的值让其显示在地图上层*/
  z-index: 2001;
  color: rgba(0,0,0,0.85);
  background-color: rgba(249, 249, 249, 0.87);
  /*边缘的宽度*/
  border-width: 0;
  /*圆角的大小 */
  border-radius: 0;
  /*边框颜色*/
  border-color: #000 #000 #000 #000;
}

.layerControl .title {
  font-weight: bold;
  font-size: 15px;
  margin: 10px;
  line-height: 30px;
  border-bottom: 1px solid #dbdbdb;
  text-align: left;
}
.layerTree{
    display: flex;
    flex-wrap: wrap;
    text-align: center;
    padding: 0 5px;
}
>>>.layerTree li {
  list-style: none;
  margin: 10px 5px;
  border: 2px solid transparent;
}
>>>.layerTree li label{
  display: block;
  cursor: pointer;
  position: relative;
  width: 78px;
  height: 55px;
  overflow:hidden;
}
>>>.layerTree li label p{
  position:  absolute;
  bottom: 0;
  left: 0;
  background-color: rgba(0,0,0,0.5);
  color: #fff;
  padding: 1px 5px;
  border-radius: 0 4px 0 0;
}
>>>.layerTree li input{
  display: none;
}
>>>.layerTree li:hover img{
  transform: scale(1.1);
}
>>>.layerTree li img{
  width: 78px;
  height: 55px;
  position: absolute;
  left: 0;
  bottom: 0;
}
>>>.layerTree li.active{
  border: 2px solid #0075ff;
}
>>>.layerTree li.active p{
  background-color:#0075ff;

}

/* 鼠标位置控件层样式设置 */
#mouse-position {
  float: left;
  position: absolute;
  bottom: 5px;
  width: 330px;
  height: 20px;
  /*在地图容器中的层,要设置z-index的值让其显示在地图上层*/
  z-index: 2000;
}

</style>

 

posted on 2022-02-21 15:01  ALWAYS☆REMIND  阅读(1231)  评论(0编辑  收藏  举报

导航