Angular8 и OpenLayers 6: ERROR TypeError: невозможно прочитать свойство forEachFeatureAtPixel из undefined

Я пытаюсь открывать всплывающее окно всякий раз, когда нажимаю на функцию. Мне удалось получить событие onclick на карте, но когда я пытаюсь нажать эту функцию, я получаю указанное ниже. Буду признателен за любую помощь, спасибо.

app.component.html

<div id="map" class="map"></div>
<div id='popup-container'>
    <p id='popup-coordinates'></p>
</div>
<div class="overlay-container">
    <span class='overlay-text' id='feature-name'></span><br>
    <span class='overlay-text' id='feature-additional-info'></span><br>
</div>

app.component.ts

import { ChangeDetectionStrategy, Component, Injector, OnInit } from '@angular/core';
import { MatDialog } from '@angular/material';
import { AppComponentBase } from '../../../shared/app-component-base';
import Map from 'ol/Map';
import View from 'ol/View';
import Feature from 'ol/Feature';
import Point from 'ol/geom/Point';
import { fromLonLat } from 'ol/proj.js';
import { Tile as TileLayer, Vector as VectorLayer } from 'ol/layer';
import VectorSource from 'ol/source/Vector';
import { Icon, Style } from 'ol/style';
import OSM from 'ol/source/OSM';
import Overlay from 'ol/Overlay';
import * as olPixel from 'ol/pixel';

export class app {
    temp;
    map;
    vectorSource;
    vectorLayer;
    rasterLayer;
    pixel;

ngOnInit() {
    this.mapCreator();
// Here I add some features from backend
}

mapCreator() {
    this.vectorSource = new VectorSource({
        features: []
    });

    this.vectorLayer = new VectorLayer({
        source: this.vectorSource
    });

    this.map = new Map({
        target: 'map',
        layers: [new TileLayer({
            source: new OSM()
        })],
        view: new View({
            center: fromLonLat([35.6027698, 38.5946197]),
            zoom: 6.8
        }),
    });
    this.map.addLayer(this.vectorLayer);

    // Vector Feature Popup 
    const overlayContainerElement = document.querySelector('.overlay-container')
    const overlayLayer = new Overlay({
        element: overlayContainerElement
    })
    this.map.addOverlay(overlayLayer);
    const overlayFeatureName = document.getElementById('feature-name');
    const overlayFeatureAdditionInfo = document.getElementById('feature-additional-info');


    // Vector Feature Popup
    this.map.on('click', function (e) {
        overlayLayer.setPosition(undefined);
        this.map.forEachFeatureAtPixel(e.pixel, function (feature, layer) {
            let clickedCoordinate = e.coordinate;
            let clickedFeatureName = feature.get('name');
            let clickedFeatureAdditionInfo = feature.get('additionalinfo');
            if (clickedFeatureName && clickedFeatureAdditionInfo != undefined) {
                overlayLayer.setPosition(clickedCoordinate);
                overlayFeatureName.innerHTML = clickedFeatureName;
                overlayFeatureAdditionInfo.innerHTML = clickedFeatureAdditionInfo;
            }
        })
    })      
}
}

Вот ошибка, которую я получаю, когда нажимаю на карту;

ERROR TypeError: Cannot read property 'forEachFeatureAtPixel' of undefined
at Map.<anonymous> (app.component.ts:94)
at Map.push../node_modules/ol/events/Target.js.Target.dispatchEvent (Target.js:113)
at Map.push../node_modules/ol/PluggableMap.js.PluggableMap.handleMapBrowserEvent (PluggableMap.js:871)
at MapBrowserEventHandler.push../node_modules/ol/events/Target.js.Target.dispatchEvent (Target.js:113)
at MapBrowserEventHandler.push../node_modules/ol/MapBrowserEventHandler.js.MapBrowserEventHandler.emulateClick_ (MapBrowserEventHandler.js:97)
at MapBrowserEventHandler.push../node_modules/ol/MapBrowserEventHandler.js.MapBrowserEventHandler.handlePointerUp_ (MapBrowserEventHandler.js:148)
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:423)
at Object.onInvokeTask (core.js:26247)
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:422)
at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (zone.js:195)
at ZoneTask.push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask [as invoke] (zone.js:498)
at invokeTask (zone.js:1693)
at HTMLDocument.globalZoneAwareCallback (zone.js:1730)

Я использую Angular 8 и Openlayers 6.1.1, как я уже упоминал в заголовке. Я не могу их изменить из-за правил проекта, но я здесь застрял. Я пробовал много разных решений, но всегда сталкивался с одной и той же проблемой.

1 ответ

Решение

В обратном вызове this равно map поскольку это не стрелочная функция, вы можете сделать 2 вещи, во-первых, вы можете изменить свой код на this.forEachFeatureAtPixel нравиться:

    // Vector Feature Popup
    this.map.on('click', function (e) {
        overlayLayer.setPosition(undefined);
        this.forEachFeatureAtPixel(e.pixel, function (feature, layer) {
            let clickedCoordinate = e.coordinate;
            let clickedFeatureName = feature.get('name');
            let clickedFeatureAdditionInfo = feature.get('additionalinfo');
            if (clickedFeatureName && clickedFeatureAdditionInfo != undefined) {
                overlayLayer.setPosition(clickedCoordinate);
                overlayFeatureName.innerHTML = clickedFeatureName;
                overlayFeatureAdditionInfo.innerHTML = clickedFeatureAdditionInfo;
            }
        })
    }) 

или вы можете переключиться на стрелочную функцию, и ваш код будет работать:

    // Vector Feature Popup
    this.map.on('click', (e) => {
        overlayLayer.setPosition(undefined);
        this.map.forEachFeatureAtPixel(e.pixel, function (feature, layer) {
            let clickedCoordinate = e.coordinate;
            let clickedFeatureName = feature.get('name');
            let clickedFeatureAdditionInfo = feature.get('additionalinfo');
            if (clickedFeatureName && clickedFeatureAdditionInfo != undefined) {
                overlayLayer.setPosition(clickedCoordinate);
                overlayFeatureName.innerHTML = clickedFeatureName;
                overlayFeatureAdditionInfo.innerHTML = clickedFeatureAdditionInfo;
            }
        })
    }) 
Другие вопросы по тегам