map.vue 11.8 KB
<template>
  <div>
    <div id="map" class="maps"></div>
    <div id="popup" class="ol-popup">
      <a href="#" id="popup-closer" class="ol-popup-closer" @click="closepopup"></a>
      <div id="t-popup-content"></div>
    </div>
  </div>
</template>

<script>
import { inherits } from "ol/util.js";
import Map from "ol/Map";
import View from "ol/View";
import Feature from "ol/Feature"; //元素
import Overlay from "ol/Overlay"; //弹出框
import { toStringHDMS } from "ol/coordinate";
import { fromLonLat, toLonLat } from "ol/proj";
import {
  Tile as TileLayer,
  Vector as VectorLayer,
  VectorTile,
  Heatmap as HeatmapLayer
} from "ol/layer"; //瓦片图层 , 矢量图层等基础图层
import { Cluster, OSM, Vector as VectorSource, XYZ, TileJSON } from "ol/source";
import KML from "ol/format/KML.js";
import {
  defaults,
  Select,
  DragBox,
  Pointer,
  DragAndDrop,
  Draw,
  defaults as defaultInteractions,
  Pointer as PointerInteraction
} from "ol/interaction"; //交互,选择,画框等
import {
  Circle as CircleStyle,
  Fill,
  Stroke,
  Style,
  Text,
  Icon
} from "ol/style"; //添加图层,点,圆等的样式调节
import { Point, Geometry, LineString } from "ol/geom";
import GeoJSON from "ol/format/GeoJSON.js";
import "ol/ol.css"; //地图默认样式
var map = "";
var Views = "";
var container = '';
var content = "";
var closer = "";
var overlay = "";
export default {
  data() {
    return {
      devList:[]
    };
  },
  methods: {
    InitMap() {
      let _this = this;
      //坐标
      //
      var heatData = {
        type: "FeatureCollection",
        features: [
          {
            type: "Feature",
            geometry: {
              type: "Point",
              coordinates: [116.357068, 39.954021, 0]
            },
            properties: {
              name: "M 5 - 2012 Dec 25, PAKISTAN"
            }
          }
        ]
      };

      for (var i = 0; i < 300; i++) {
        let c = Math.random(1) * 1000;
        let e = Math.random(1) * 100;
        let b = (116.357068 * 1000000 + i * c) / 1000000;
        let d = (39.954021 * 1000000 + i * e) / 1000000;
        let a = {
          type: "Feature",
          geometry: {
            type: "Point",
            coordinates: [b, d, 0]
          },
          properties: {
            name: "M 5 - 2012 Dec 25, PAKISTAN" + i
          }
        };
        heatData.features.push(a);
      }

      var vectorSources = new VectorSource({
        features: new GeoJSON().readFeatures(heatData, {
          dataProjection: "EPSG:4326"
        })
      });
      var path =
        "http://192.168.9.62:20080/static/pics/qingdaoMap/roadmap/{z}/{x}/{y}.png";
      var offlineMapLayer = new TileLayer({
        source: new XYZ({
          // 设置本地离线瓦片所在路径,由于例子里面只有一张瓦片,页面显示时就只看得到一张瓦片。
          url: path
        })
      });

      Views = new View({
        projection: "EPSG:4326",
        zoom: 2, // 并且定义地图显示层级为2
        minZoom: 13,
        maxZoom: 18,
        center: [120.324447, 36.064594]
      });
      map = new Map({
        // 设置地图图层
        layers: [
          // 创建一个使用Open Street Map地图源的瓦片图层
          offlineMapLayer
        ],
        loadTilesWhileAnimating: true,

        // 设置显示地图的视图
        view: Views,
        // 让id为map的div作为地图的容器
        target: "map"
      });
      var heatmapvector = new HeatmapLayer({
        source: vectorSources,
        blur: parseInt(20, 6),
        radius: parseInt(3, 5)
      });

      map.addLayer(heatmapvector);

      // 添加一个使用离线瓦片地图的层
      this.devList.map(ele => {
        console.log(ele.longitude)
          var CameraVertorlayer = new VectorLayer({
            source: _this.addCameraLayer([Number(ele.longitude), Number(ele.latitude)], ele)
          });
      map.addLayer(CameraVertorlayer);
    })
    
       let that = this;

      map.on("click", e => {
        var pixel = map.getEventPixel(e.originalEvent);
        console.log(pixel);
        //点击相机标注点
        map.forEachFeatureAtPixel(pixel, function(feature) {
          // var coodinate = e.coordinate;
          // _this.unid = feature.getProperties().unid;
          // Overlay.setPosition(coodinate);
          // map.addOverlay(Overlay);
          //播放视频操作
           let data = feature.getProperties().cameraInfo
          that.$emit('playvideo',data)
          console.log('视频播放地址'+ data)
        });
      });
    },
    movemap(data){
      let pos = [120.324447, 36.074594]
       Views.animate({
        center: pos,
        duration: 400,
        zoom:14
      });
      this.addLayer(data,pos)

      },
    closepopup(){
      overlay.setPosition(undefined);
      closer.blur();
      return false;
    },
    addLayer(pdata,pos) {
      document.getElementById('popup').style.display = 'block';

      console.log(pdata)
      if( pdata.pics) {
         content.innerHTML = '<div class="content-box"><div class="img-box"><img src='+ pdata.pics+'></div></div>'
      } else {
          content.innerHTML = '<div class="content-box"><div class="img-box"><img src=""></div></div>'
      }
       overlay = new Overlay({
          element: container,
          autoPan: true,
          position:pos,
          autoPanAnimation: {
            duration: 500
          }
        });
        map.addOverlay(overlay);
    },
    addCameraLayer(coordinate, data) {
      let vectorSource = new VectorSource({ id: 1 });
      let icon = new Feature({
        geometry: new Point(coordinate),
        unid: "1",
        cameraInfo:data
      });
      let color = "#156BB1"; //设置气泡颜色
      //添加svg图标需注意 width,height要和 new Icon 的imgSize保持一致
      // let svg =
      //   '<svg t="1540524238971"  class="icon" style="text-align:center" x="0px" y="0px" width="28px" height="28px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4126" xmlns:xlink="http://www.w3.org/1999/xlink"  xml:space="preserve"><defs><style type="text/css"></style></defs>' +
      //   '<path fill="' +
      //   color +
      //   '" d="M865.309 291.918c-19.289-45.606-46.897-86.557-82.06-121.719-35.161-35.162-76.114-62.771-121.718-82.06-47.23-19.976-97.385-30.105-149.072-30.105S410.618 68.163 363.388 88.139c-45.605 19.289-86.557 46.898-121.719 82.06-35.162 35.161-62.771 76.114-82.06 121.719-19.976 47.229-30.105 97.384-30.105 149.071 0 51.687 10.129 101.841 30.105 149.07 19.289 45.605 46.898 86.558 82.06 121.72 35.162 35.161 76.114 62.771 121.719 82.06 11.201 4.738 22.569 8.914 34.081 12.541l-58.051 143.991-17.783 0c-14.129 0-25.583 11.454-25.583 25.583s11.454 25.583 25.583 25.583l352.169 0c0.063 0 0.124 0.007 0.187 0.007 0.101 0 0.203-0.006 0.303-0.007l35.985 0c14.13 0 25.583-11.454 25.583-25.583s-11.453-25.583-25.583-25.583l-18.876 0-57.565-146.13c24.322-8.109 47.832-18.654 70.119-31.546 57.156-33.063 105.093-80.61 138.628-137.502 34.561-58.633 52.83-125.787 52.83-194.204C895.414 389.302 885.285 339.148 865.309 291.918zM513.814 146.1c26.472 0 48.01 21.537 48.01 48.01 0 26.472-21.537 48.01-48.01 48.01s-48.011-21.537-48.011-48.01C465.804 167.638 487.342 146.1 513.814 146.1zM512.54 688.835c-111.982 0-203.086-91.104-203.086-203.086 0-111.982 91.104-203.086 203.086-203.086 111.981 0 203.086 91.104 203.086 203.086C715.626 597.731 624.521 688.835 512.54 688.835z" p-id="4127"></path><path d="M512.54 333.829c-83.769 0-151.921 68.152-151.921 151.921 0 83.769 68.15 151.921 151.921 151.921 83.769 0 151.921-68.15 151.921-151.921C664.461 401.98 596.309 333.829 512.54 333.829z" p-id="4128"></path><path d="M513.814 197.265c1.739 0 3.154-1.415 3.154-3.155 0-1.74-1.415-3.155-3.154-3.155-1.74 0-3.155 1.415-3.155 3.155C510.659 195.85 512.074 197.265 513.814 197.265z" p-id="4129"></path><path d="M636.408 950.372 636.408 950.372 636.408 950.373Z" p-id="4130"></path></svg>';
      // let cameraIcon = new Image();
      // cameraIcon.src = "data:image/svg+xml," + escape(svg);
      icon.setStyle(
        new Style({
          //设置样式和大小
          image: new Icon({
            // img: cameraIcon,
            // crossOrigin: "anonymous",
            // imgSize: [38, 38],
            // marginTop: 100
            anchor: [0.5, 36],
            anchorXUnits: 'fraction',
            anchorYUnits: 'pixels',
            src: require('./bioazhu.png')
          }),
            text: new Text({
            text: data.vchan_name,
            textBaseline: "top",
            font: "normal 12px 微软雅黑",
            lineHeight: "0px",
            fill: new Fill({
              color: "red"
            })
          }),
          stroke: new Stroke({
            color: "red",
            width: 21,
            marginTop: 100
          })
        })
      );
      vectorSource.addFeature(icon);
      return vectorSource;
    },

    // addFeature() {
    //   function createStyle(src, img) {
    //     return new Style({
    //       image: new Icon(
    //         /** @type {module:ol/style/Icon~Options} */ ({
    //           anchor: [0.5, 0.96],
    //           crossOrigin: "anonymous",
    //           src: src,
    //           img: img,
    //           imgSize: img ? [img.width, img.height] : undefined
    //         })
    //       )
    //     });
    //   }

    //   var iconFeature = new Feature(new Point([113.338591, 34.50691]));
    //   iconFeature.set(
    //     "style",
    //     createStyle("../../../assets/img/dianli.png", undefined)
    //   );
    //   var CameraVertorlayer = new VectorLayer({
    //     source: iconFeature,
    //     id: 1
    //   });
    //   map.addLayer(this.CameraVertorlayer);
    // },
    getDevList(){
      this.$api.show.getDevList(this.dev_unid).then(res => {
        let devlist = [];
        res.list_data.map(ele => {
          if(ele.vchan_type == 'camera'){
            devlist.push(ele)
          }
        })
        this.devList = devlist
        setTimeout(() => {
          this.InitMap();
        }, 200);
      })
    }
  },
  mounted(){
    setTimeout(()=>{
      this.getDevList()
    },1000)
    container = document.getElementById('popup');
    content = document.getElementById('t-popup-content');
    closer = document.getElementById('popup-closer');
   
  },
};
</script>

<style lang="stylus" scoped>
.ol-control button{
	  display:none!important;
	  background:red!important
	}
  .canvasDiv{
	  height :30px;
	  width :30px;
	  background :red;
	  border-radius :30px;
	  color: #ffffff;
	  font-size :12px;
	  text-align :center;
	  line-height :30px;
	  z-index :10;
	  opacity :0.5;
	}

  .ol-popup {
    display: none;
    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: 12px;
    left: -50px;
    width: 20vw;
    height 25vh;
    overflow hidden
  }
  .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: "✖";
  }
	.pop-img-box {
	  float: left;
	  height: 100px;
	  width :120px;
	  img {
	    height: 100%;
	    width: 100%;
	  }
	}
	.pop-info{
	  float: left;
	  padding-left: 20px;
	  width :100px
	}
	.map-box {
	  position: relative;
	  background :#f8f8f8;
	  border-radius: 10px;
	  .content-info{
	    position :absolute;
	    z-index :1000;
	    color: red
	  }
	}
</style>