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);
  }
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值