使用Angular 8和OpenLayers 3可以从地图上绘制和删除临时矢量图层

时间:2020-04-08 10:21:33

标签: angular openlayers polygon

我有一个使用Angular 8和OpenLayers 3构建的项目。我希望能够在地图上绘制和删除多边形。我试图将此工作example移植到我的项目中。

这些是相互作用的组件。

  • sidebar.html :包含要单击的按钮
  • sidebar.component :调用可观察对象的 next()
  • sidebar.service :包含可观察对象的实现。
  • map.component :在其中 subscribe()到可观察对象并添加(临时)矢量层。

使用以下代码,我可以在地图上绘制多边形,但是无法删除它们。

在sidebar.html中,设置了一个按钮来调用 addInteraction()

sidebar.html

  ...
  <mat-button-toggle value="Polygon" (change)="addInteraction()">Draw Polygon
    <mat-icon>crop_original</mat-icon></mat-button-toggle>
  <br><br/>
  ...

在侧边栏组件中,我们称为 next()

sidebar.component

  ...
  addInteraction() {
    this._sidebarService.nextDrawAOI('Polygon');
  }
  ...

在侧边栏服务中实现了 next()

sidebar.service

  private drawAOI = new Subject<string>();

  ...
  getDrawAOI() {
    return this.drawAOI.asObservable();
  }
   ...
  nextDrawAOI(x) {
    this.drawAOI.next(x);
  }

在地图组件中,调用了subscription()和。

  1. 创建了Vector层。
  2. 添加了“绘制,捕捉和修改”交互。
  3. 使用 setMap(this.map)将地图添加到矢量层。该图层不会被地图处理,但会暂时添加到其中。

map.component

    ...
private polygonLayer: VectorLayer;
private polygonSource: VectorSource;
private modify: Modify;
private draw: Draw;
private snap: Snap;
    ...
ngAfterViewInit() {

..

// Layers
let source = new OlXYZ({
  ..
});

let layer = new OlTileLayer({
  ..
});

// View
let view = new OlView({
  ..
});

const mousePositionControl = new MousePosition({
   ...
});

// Map
this._map = new OlMap({
  controls: defaultControls().extend([
    scaleLineControl, mousePositionControl
  ]),
  interactions: OlXYZ.interactions,
  target: 'map',
  layers: [layer],
  view: view
});


this._sidebarService.getDrawAOI().pipe(map((x) => {
  this.polygonSource = new VectorSource({
    wrapX: false,
    dataProjection: 'EPSG:4326',
    featureProjection: 'EPSG:3857'
  });
  this.polygonLayer = new VectorLayer({
    source: this.polygonSource
  });

  this.modify = new Modify({source: this.polygonSource});
  this._map.addInteraction(this.modify);

  this._map.removeInteraction(this.draw);
  this._map.removeInteraction(this.snap);
  this.polygonLayer.setMap(null);

  this.draw = new Draw({
    source: this.polygonSource,
    type: x
  });
  this._map.addInteraction(this.draw);
  this.snap = new Snap({source: this.polygonSource});
  this._map.addInteraction(this.snap);

  this.polygonLayer.setMap(this._map);
  return x;
})).subscribe((x) => {
  console.log(x);
});


this._map.on('click', function(evt) {

在触发事件的下一行中, this.polygonLayer 未定义

  var features = this.polygonLayer.getSource().getFeatures();
  features.forEach((feature) => {
    this.polygonLayer.getSource().removeFeature(feature);
  });
});

}

问题出在这里。

map.component 中,我放置了事件的处理程序。触发事件后,矢量层(即 polygonLayer )是未定义的。看来向量不会绑定到 this 。这是一个有约束力的问题吗?如果是这样,为什么会发生?

1 个答案:

答案 0 :(得分:0)

是的,这是您的this的一个绑定(范围)问题。将功能更改为arrow function

this._map.on('click', (evt) => {
  var features = this.polygonLayer.getSource().getFeatures();
  features.forEach((feature) => {
    this.polygonLayer.getSource().removeFeature(feature);
  });
});

因为:

箭头功能没有自己的this。的this值 使用封闭的词汇范围;箭头功能遵循正常 可变查找规则。因此,在搜索this时, 当前范围内的箭头功能最终会找到this 从其封闭范围。

然后您的this具有正确的范围(您的组件)。