如何通过方法在OpenLayers 4和Angular 4中添加标记

3

我希望在我的地图上添加实时位置标记。
首先,我只想在我的地图上显示一个静态点(lat、lon)或标记,由我的代码中的addMarker方法定义。
以下是我的代码:

import {Component, OnInit, AfterViewInit, ViewEncapsulation, Input, ElementRef, ViewChilds} from '@angular/core';
import { WmslayerService} from './wmslayer.service';
import { MapService} from './map.service';
import {AddwmslayerService} from '../../menue/addlayer/formlayer/addwmslayer.service';


import * as ol from 'openlayers';


@Component({
  selector: 'olmap',
  encapsulation: ViewEncapsulation.None,
  templateUrl: './map.component.html',
  styleUrls: ['./map.component.css']
})
export class MapComponent implements OnInit, AfterViewInit {


  iconFeatures = [];
  layername: string;
  layerurl: string;

  mapId2: string;
  mapIndex: number;
  layerName: string;

  layer = [];
  layers = [];


  constructor(private mapService: MapService, private wmslayerService: WmslayerService,
              private addLayerService: AddwmslayerService, private tempdatagiaService: TempdatagiaService,
              private geomqttService: GeomqttService) {}


ngAfterViewInit() {
    setTimeout (() => {

let map = new ol.Map({
        target: this.mapId2,
        layers: [
          new ol.layer.Tile({
            source: new ol.source.OSM(),
          }),
          //vector
        ],
        view: new ol.View({
          center: ol.proj.fromLonLat([6.661594, 50.433237]),
          zoom: 3,
        })
      });

      //// for loop, to add some layer

      for (let layer of this.wmslayerService.layer) {

        console.log(layer);

        let examplelayer = new ol.layer.Tile({
          source: new ol.source.TileWMS({
            url: layer.layerurl,
            params: {
              'LAYERS': layer.layername,
              'TILED': true
            },
            projection: 'EPSG:4326',
            serverType: 'geoserver'
          })
        });
        this.layers.push(examplelayer);
        map.addLayer(examplelayer);
      }
      this.mapIndex = this.mapService.addMap(map);
      this.layername = this.layerName;
      console.log(this.mapIndex);
    },300)}

// -- addlayer dynamicly--

  addNewLayer(url: string, name: string) {
    console.log(name);
    let addedlayer = new ol.layer.Tile({
      source: new ol.source.TileWMS({
        url: url,
        params: {
          'LAYERS': name,
          'TILED': true
        },
        projection: 'EPSG:4326'
      })
    });
    this.layers.push(addedlayer);
    this.mapService.getMap(this.mapIndex).addLayer(addedlayer);
  }



  addMarker(lon: string, lat: string) {
    console.log(lat);
    console.log(lon);

    var iconFeatures = [];

    var iconFeature = new ol.Feature({
      geometry: new ol.geom.Point(ol.proj.transform([lon, lat], 'EPSG:4326',
        'EPSG:3857')),
      name: 'Null Island',
      population: 4000,
      rainfall: 500
    });

    iconFeatures.push(iconFeature);

    var vectorSource = new ol.source.Vector({
      features: iconFeatures //add an array of features
    });

    var iconStyle = new ol.style.Style({
      image: new ol.style.Icon(/** @type {olx.style.IconOptions} */ ({
        anchor: [0.5, 46],
        anchorXUnits: 'fraction',
        anchorYUnits: 'pixels',
        opacity: 0.75,
        src: 'https://openlayers.org/en/v4.6.4/examples/data/icon.png'
      }))
    });


    var vectorLayer = new ol.layer.Vector({
      source: vectorSource,
      style: iconStyle
    });

    map.addLayer(vectorLayer);

  }
}


最后一行的 map.addLayer(vectorLayer); 没有起作用。
addMarker 方法将会被点击事件触发。
我该如何使这个方法起作用呢?
是否有更好的想法或是稳定的解决方案来在 OpenLayers 4 地图中展示实时数据点呢?

1个回答

8

每次想要显示额外标记时,您无需创建新图层。通常更容易创建单个“标记图层”,并只需将功能添加到其源中。您只需要保留对图层源的引用,并在其上调用addFeature即可。

坐标不是字符串,而是小数:addMarker(lon: decimal, lat: decimal)

const markerSource = new ol.source.Vector();

var markerStyle = new ol.style.Style({
  image: new ol.style.Icon(/** @type {olx.style.IconOptions} */ ({
    anchor: [0.5, 46],
    anchorXUnits: 'fraction',
    anchorYUnits: 'pixels',
    opacity: 0.75,
    src: 'https://openlayers.org/en/v4.6.4/examples/data/icon.png'
  }))
});

let map = new ol.Map({
  target: 'map',
  layers: [
    new ol.layer.Tile({
      source: new ol.source.OSM(),
    }),
    new ol.layer.Vector({
      source: markerSource,
      style: markerStyle,
    }),
  ],
  view: new ol.View({
    center: ol.proj.fromLonLat([6.661594, 50.433237]),
    zoom: 3,
  })
});


function addMarker(lon, lat) {
  console.log('lon:', lon);
  console.log('lat:', lat);

  var iconFeatures = [];

  var iconFeature = new ol.Feature({
    geometry: new ol.geom.Point(ol.proj.transform([lon, lat], 'EPSG:4326',
      'EPSG:3857')),
    name: 'Null Island',
    population: 4000,
    rainfall: 500
  });

  markerSource.addFeature(iconFeature);
}

map.on('singleclick',function(event){
  var lonLat = ol.proj.toLonLat(event.coordinate);
  addMarker(lonLat[0], lonLat[1]);
});
#map {
  /* just for testing purposes */
  width: 100%;
  min-width: 240px;
  max-width: 500px;
  height: 200px;
}
<link href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@main/dist/en/v7.0.0/legacy/ol.css" rel="stylesheet"/>
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@main/dist/en/v7.0.0/legacy/ol.js"></script>

<button onclick="addMarker(8.54, 47.37)">add marker at 8.54, 47.37</button>
<div id="map"></div>


谢谢你的帮助,代码快要运行了!但是我在addMarker函数中总是得到ERR“找不到名称'markerSource'”...和之前的图层一样的ERR。 - Steffn
markerSource 应该是一个类属性 ol.source.Vector,您可以在其中添加所有标记。所以只需在构造函数中创建它。在您的初始代码中,它被称为 vectorSource,我只是将其重命名为不再是本地变量 :) - dube
抱歉...我没有理解你的意思。所以我必须在我的构造函数中定义一个新类(ol.source.vector),并将markerSource作为类属性?这应该是什么样子的? - Steffn
看看我的示例(不使用Angular)。变量markerSourcemarkerStylemap应该是您的MapComponent类的属性,因此您需要在组件的addMarker方法中使用this.来访问它们。例如:this.markerSource - dube
我认为带有 geometry: new ol.geom.Point(ol.proj.transform([lat, lon], 'EPSG:4326' 的那一行经纬度前后颠倒了。我必须在那里交换它们才能正常工作。 - Matthew
1
@Matthew 谢谢你,你说得对。我的解决方案交换了代码两次。已更新答案。 - dube

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接