OpenLayers地圖

  1. 搭建本地環境,配置瓦片數據,下載文件並找到相應路徑
    鏈接: https://pan.baidu.com/s/1c6nfZodGBzUxyG2PhmFzPA
    提取碼: p3qi

  2. 開啓本地服務器
    在這裏插入圖片描述

  3. 導入本地包
    鏈接: https://pan.baidu.com/s/1qhe4kxwpmez5-7dBVA1S1g
    提取碼: w6hp
    將文件解壓放到asset文件夾
    在這裏插入圖片描述

  4. 在index.html中引入
    在這裏插入圖片描述

  5. 配置全局變量,初始化地圖

declare var ol: any //配置全局變量

protected map;
protected initMap(): void {
    //對應源代碼中的全圖範圍信息
    let fullExtent = [106.55377197265625, 29.634521484751, 106.57006656576985, 29.646849848303482];
    //對應源代碼中的切片方案信息
    let resolutions = [3.8071376093284481e-005, 1.903568804664224e-005, 9.5178440233211202e-006, 4.7589220116605601e-006, 2.3794610058302801e-006, 1.18973050291514e-006];
    this.baseLayers = [
      new ol.layer.Tile({
        source: new ol.source.TileWMS({
          url: environment.openlayerPath, //http://localhost:98/geowebcache/service/wms 本地服務地址
          params: {
            'LAYERS': 'chongqing1', //對應源代碼中的名稱
            'FORMAT': 'image/png',
            'SRS': 'EPSG:4326', //對應源代碼中的標識
            'VERSION': '1.1.3'
          },
          tileGrid: new ol.tilegrid.TileGrid({
            //resolution和conf.xml中保持一致
            extent: fullExtent,
            resolutions: resolutions,
            tileSize: [256, 256],
            origin: [-400, 399.99999999999977]
          })
        })
      })
    ];
    this.map = new ol.Map({
      controls: [],
      layers: this.baseLayers,
      target: 'map',
      view: new ol.View({
        projection: 'EPSG:4326',
        center: [106.56010, 29.64105],
        resolution: 2.1794610058302801e-006,
        zoom: 10
      })
    });
  }

顯示效果:
在這裏插入圖片描述
6. 在地圖上添加標註

數據格式如下
在這裏插入圖片描述

  protected markerList = [];
  public baseLayers; // 基礎圖層
  public vectorLayerPerson; //標記圖層
  
  protected showMarkers(result: Array<any>, name = 'name'): void {
	    this.markerList.forEach(marker => this.map.remove(marker));
	    this.markerList = [];
	    this.initMark(result)
	}
	  
  /**
   * 加載標記方法
   * */
  public initMark(data) {
    let vectorSourceNetPerson = new ol.source.Vector({});
    data.forEach(item => {
      if (item.longitude == null || item.latitude == null) {
        return
      }
      //創建圖標特性
      let iconFeature = new ol.Feature({
        geometry: new ol.geom.Point([item.longitude, item.latitude]),
        title: "eventLayer",
        Id: item.id,
        type: 'event'
      });

	//因瓦片數據有限,所以可能標註不會顯示在地圖上,這裏使用假數據,保證標註能夠正確顯示在地圖中
      /*let iconFeature = new ol.Feature({
        geometry: new ol.geom.Point([106.56063002597645, 29.641131347586256]),
        name: "personLayer",
      })*/
      
      //將圖標特性添加進矢量中
      vectorSourceNetPerson.addFeature(iconFeature);
    })

    //創建圖標樣式
    let iconStyle = new ol.style.Style({
      image: new ol.style.Icon({
        anchor: [0.5, 46],
        anchorXUnits: 'fraction',
        anchorYUnits: 'pixels',
        opacity: 0.75,
        src: "../assets/img/alarm.png" //標註點的圖片
      }),
    });


    //創建矢量層
    this.vectorLayerPerson = new ol.layer.Vector({
      source: vectorSourceNetPerson,
      style: iconStyle
    });

    //添加進map層
    this.map.addLayer(this.vectorLayerPerson);
  }

顯示效果:
在這裏插入圖片描述

7.在初始化地圖的時候, 爲標誌添加事件交互

/**
   * 初始地圖化點擊事件
   * */
  initMapClickEvent() {
    let $this = this;
    /**
     * 爲map添加點擊事件監聽,渲染彈出popup
     */
    this.map.on('click', function (evt) {
      //在點擊時獲取像素區域
      let pixel = $this.map.getEventPixel(evt.originalEvent);
      $this.map.forEachFeatureAtPixel(pixel, function (feature) {
        //evt.coodinate 存放了點擊時的座標信息
        //feature.values_.Id 存放了當前標註的id
      });
    });

    /**
     * 爲map添加鼠標移動事件監聽,當指向標註時改變鼠標光標狀態
     */
    this.map.on('pointermove', function (e) {
      let pixel = $this.map.getEventPixel(e.originalEvent);
      let hit = $this.map.hasFeatureAtPixel(pixel);
      $this.map.getTargetElement().style.cursor = hit ? 'pointer' : '';
    });

  }
  1. 移除某標註圖層
this.map.removeLayer(this.vectorLayerPerson);
  1. 在地圖上繪製並顯示熱區

顯示熱區
數據格式如下:
在這裏插入圖片描述

 //在地圖上加載熱區方法
  createPolygon(longitude, latitude, pathList) { // pathList:熱區的各個點數據
    let newPathlist = [];
    pathList.forEach(item => {
      let a = [];
      a.push(item.lng);
      a.push(item.lat);
      newPathlist.push(a);
    });
    
    let polygon = new ol.Feature({
      geometry: new ol.geom.Polygon([
        newPathlist,
      ]),
    });
    //設置熱區樣式信息
    polygon.setStyle(
      new ol.style.Style({
        //填充色
        fill: new ol.style.Fill({
          color: 'rgba(255, 255, 255, 0.5)',
        }),
        //邊線顏色
        stroke: new ol.style.Stroke({
          color: '#018fd3',
          width: 1,
        }),
      }),
    );
    //實例化一個矢量圖層Vector作爲繪製層
    let source = new  ol.source.Vector({
      features: [polygon],
    });
    //創建一個圖層
    this.hotAreaLayer = new  ol.layer.Vector({
      source: source,
    });
    this.map.addLayer(this.hotAreaLayer);

  }

顯示效果:
在這裏插入圖片描述

繪製熱區

public addHotArea() {
    let $this = this;
    let source = new ol.source.Vector({wrapX: false})
    this.hotAreaLayer = new ol.layer.Vector({
      source: source
    });

    let drawHot = new ol.interaction.Draw({
      source: source,
      type: 'Polygon'
    });
    drawHot.on('drawend', function (evt) {
      let feature = evt.feature;
      let geometry = feature.getGeometry();
      let coordinate = geometry.getCoordinates();
      //coordinate :熱區每個點的數據
      drawHot.setActive(false);//繪製結束
      $this.map.addLayer($this.hotAreaLayer);
    });
    this.map.addInteraction(drawHot);

  }

顯示效果:
在這裏插入圖片描述

獲取並設置中心點和層級

//獲取地圖中心點
  private getMapCenter() {
    let mapExtent = this.map.getView().calculateExtent(this.map.getSize())
    let map_center = ol.extent.getCenter(mapExtent);
    return map_center;
  }

//設置中心點
this.map.getView().setCenter(['經度','緯度']);

//獲取地圖層級
this.map.getView().getZoom()

//設置層級
this.map.getView().setZoom(gotoZoom);

鼠標移入或點擊時彈出提示信息

html設置
alarmWindowInfo: 存放基本信息的對象
alarmInfoDetails: 查看詳情的函數

 <div id="popup" class="ol-popup" #showPopupDiv>
    <a href="#" id="popup-closer" class="ol-popup-closer"></a>
    <div id="popup-content">
      <!--信息彈窗-->
      <div class="my-security-panel-info">
        <div class="panel-info-content">
          <div class="flex-row">
            <div class="info-content-text">
              <div class="info-content-text-row flex-row">
                <div class="row-label flex-row">
                  <span></span>
                  <span>名:</span>
                </div>
                <div class="row-value">{{alarmWindowInfo?.name}}</div>
              </div>
              <div class="info-content-text-row flex-row">
                <div class="row-label flex-row">
                  <span></span>
                  <span>別:</span>
                </div>
                <div class="row-value" *ngIf="alarmWindowInfo?.sex=='1'">男性</div>
                <div class="row-value" *ngIf="alarmWindowInfo?.sex=='2'">女性</div>
                <div class="row-value" *ngIf="alarmWindowInfo?.sex=='0'">未知性別</div>
              </div>
              <div class="info-content-text-row flex-row">
                <div class="row-label flex-row">
                  <span></span>
                  <span></span>
                  <span>號:</span>
                </div>
                <div class="row-value">{{alarmWindowInfo?.phone}}</div>
              </div>
              <button nz-button nzType="default" nzSize="small"
                      (click)="alarmInfoDetails(alarmWindowInfo)">詳情
              </button>
            </div>
          </div>
          <div class="info-content-closebtn" (click)="closePopup()">
            <img src="https://webapi.amap.com/images/close2.gif" alt="">
          </div>
        </div>
      </div>
    </div>
  </div>

css設置

. 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: 12px;
  left: -50px;
}

.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: "✖";
  height:30px;
  padding:12px;
}

#popup-content
{
  font-size: 14px;
  font-family: "微軟雅黑", serif;
  width:100px;
}

.my-security-panel-info {
  width: 320px;
  background-color: #fff;
  border: 1px solid #ccc;
  border-radius: 7px;
  box-shadow: 4px 4px 25px #ccc;
}


js設置,當點擊或鼠標移入標註時,獲取popup節點對象

//地圖交互事件
  private initMapClickEvent() {
    let $this = this;
    /**
     * 爲map添加點擊事件監聽,渲染彈出popup
     */
    this.map.on('singleclick', function (evt) {
      //在js中獲取HTML元素
      $this.popupContainer = document.getElementById("popup");

      let overlay = new ol.Overlay({
        element: $this.popupContainer, //設置彈出框的容器
        autoPan: true, //是否自動平移,即假如標記在屏幕邊緣,彈出時自動平移地圖使彈出框完全可見
        autoPanAnimation: {
          duration: 300   //當Popup超出地圖邊界時,爲了Popup全部可見,地圖移動的速度.
        }
      });
      let coodinate = evt.coordinate; // coodinate存放了點擊時的座標信息
      overlay.setPosition(coodinate);
      let pixel = $this.map.getEventPixel(evt.originalEvent); //在點擊時獲取像素區域
      $this.map.forEachFeatureAtPixel(pixel, function (feature) {  //在點擊時獲取像素區域
        if (feature.values_.type == 'event') { 
        //獲取基本信息
          $this.http.get(`${environment.requestPath}/event/get/${feature.values_.Id}`, {
            success: (data => {
              $this.alarmWindowInfo = data.result;
              $this.showPopupDiv.nativeElement.style.display = 'block';
              $this.map.addOverlay(overlay);
            })
          });
        }
      });
    }); 
  }

框選標註並獲取id


public camerasActive = false; //框選功能激活
public allCameraData = []; //所有攝像頭數據
public isDrow() {
    this.camerasActive = !this.camerasActive;
      if (this.camerasActive) {
        this.drow('camerasActive');
      } else {
        this.map.removeLayer(this.drawVectorLayer);  //刪除框選圖層
      }
  }
//框選
//allCameraData :所有的標註數據
  public drow(name) {
    let $this = this;
    //新建source和layer
    let source = new ol.source.Vector({wrapX: false});
    this.drawVectorLayer = new ol.layer.Vector({source: source});
    //設置geometryFunction
    let geometryFunction = ol.interaction.Draw.createBox();
    //新建繪製正方形interaction
    let drawSquare = new ol.interaction.Draw({
      source: source,
      type: "Circle",
      geometryFunction: geometryFunction,
    });
    //框選結束
    drawSquare.on('drawend', function (evt) {
      let feature = evt.feature;
      let geometry = feature.getGeometry();
      let coordinate = geometry.getCoordinates();
      //獲取到點
      let pointList = [];
      let coordinateOne = coordinate[0][0];
      let coordinateTwo = coordinate[0][2];
      //框選攝像頭
      if (name == 'camerasActive') {
        for (let i = 0; i < $this.allCameraData.length; i++) {
          let List = $this.allCameraData[i];
          //1經度 >= 點經度   
          //2經度 <= 2點經度   
          //1緯度 >= 點緯度   
          //2緯度 <= 2點緯度
          let isTrue = coordinateOne[1] <= List.latitude && List.latitude <= coordinateTwo[1] && coordinateOne[0] <= List.longitude && List.longitude <= coordinateTwo[0];
          if (isTrue) {
          //滿足以上條件及當前標註在框選範圍內
            pointList.push($this.allCameraData[i].id)
          }
        }
     
        if (pointList.length > 0) {
          // pointList:選框內的攝像頭數據
        } else {
          $this.message.error('此框選範圍沒有任何攝像頭');
        }
        $this.camerasActive = false;
        drawSquare.setActive(false);
        $this.map.removeLayer($this.drawVectorLayer)
      }
    });
    //將layer和interaction添加到地圖上
    this.map.addLayer(this.drawVectorLayer);
    this.map.addInteraction(drawSquare);
  }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章