Home » Javascript » Angular & OpenLayers – Problems with forEachFeatureAtPixel and onclick property

Angular & OpenLayers – Problems with forEachFeatureAtPixel and onclick property

Posted by: admin August 19, 2018 Leave a comment

Questions:

I’m programming a map with OpenLayers (4.6.5) in Angular (6). I have a mat-button containing a map-menu containing two checkboxes. I want to show or hide some specific markers by checking the checkboxes. Each checkboxes is making appear a certain type of markers. When I click on a marker I want to make appear a popup with informations (in GeoJSON files, one for each type of markers).

I have a fully functionnal code in a simple HTML file and now I want to do the same thing with Angular, checkboxes are funtionnal but when I click on a marker I have a forEachFeatureAtPixel error (if I click anywhere on the map I have a onclick error (from the closer.onclick function))

app.component.ts :

import { Component, OnInit } from '@angular/core';

import OlMap from 'ol/map';
import OlWMS from 'ol/source/tilewms';
import OlTileLayer from 'ol/layer/tile';
import OlView from 'ol/view';
import VectorLayer from 'ol/layer/vector';
import VectorSource from 'ol/source/vector';
import Point from 'ol/geom/point';
import Style from 'ol/style/style';
import IconStyle from 'ol/style/icon';
import WFS from 'ol/format/wfs';
import GeoJSON from 'ol/format/geojson';
import Overlay from 'ol/overlay';
import feature from 'ol/feature';
import OlSwitch from 'ol-layerswitcher';
import Group from 'ol/layer/group';
import $ from 'jquery';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent implements OnInit {

  map: OlMap;
  gny_bright: OlWMS;
  gny_bright_mobile: OlWMS;
  wms_gnybrightl93: OlWMS;
  wms_gnybrightl93mobile: OlWMS;
  wms_gnybrightgrey: OlWMS;
  wms_gnybrightgreyl93: OlWMS;
  wms_gnyorthol93: OlWMS;
  wms_gnyorthol93_mobile: OlWMS;
  wms_pistes_c: OlWMS;
  layer: OlTileLayer;
  view: OlView;
  layerSwitcher: OlSwitch;
  WFS: WFS;
  vectorLayer_parking: VectorLayer;
  vectorLayer_piscine: VectorLayer;
  parkingLayer: VectorSource;
  piscineLayer: VectorSource;
  piscine: Style;
  markers: feature;
  popup: Overlay;

  constructor() {
  }

  handleSelected1($event) {
    if($event.target.checked === true) {
      this.map.addControl(this.vectorLayer_piscine);
      this.vectorLayer_piscine.setStyle(this.piscine);
      this.map.addOverlay(this.popup);
    } else {
      this.map.removeControl(this.vectorLayer_piscine);
      this.map.removeOverlay(this.popup);
    }
  }

  handleSelected2($event) {
    if($event.target.checked === true) {
      this.map.addControl(this.vectorLayer_parking);
      this.vectorLayer_parking.setStyle(this.markers);
      this.map.addOverlay(this.popup);
    } else {
      this.map.removeControl(this.vectorLayer_parking);
      this.map.removeOverlay(this.popup);
    }
  }

  ngOnInit() {

    {...}

    //popup

    var element = document.getElementById('popup');

    this.popup = new Overlay({
      element: element,
      autoPan: true,
      offset: [0, -30]
    });

    //Fonction d'affichage des popups

    var content_element = document.getElementById('popup-content');

    this.map.on('click', function(evt){
    var closer = document.getElementById('popup-closer');

    closer.onclick = () => {
      this.popup.setPosition(undefined);
      closer.blur();
      return false;
    };

    console.log(this.popup);

    var feature = this.map.forEachFeatureAtPixel(evt.pixel,
      function(feature) {
        return feature;
      });
    if (feature) {
      var geometry = feature.getGeometry();
      var coord = geometry.getCoordinates();

      if(feature.get('name') != null) {
        var content = '<center><h2>' + feature.get('name') + '</h2></center>' + '<br>';
      } else {
        var content = '<center><h2>' + feature.get('NOM') + '</h2></center>' + '<br>';
      }

      if(feature.get('addr:street') != null) {
        content += '<h5>' + '<i>Adresse : </i>' + feature.get('addr:street') + '</h5>';
      } else if(feature.get('ADRESSE') != null) {
        content += '<h5>' + '<i>Adresse : </i>' + feature.get('ADRESSE') + '</h5>';
      } else {
        null;
      }

      if(feature.get('phone') != null) {
        content += '<h5>' + '<i>Numéro de téléphone : </i>' + feature.get('phone') + '</h5>';
      }

      if(feature.get('website') != null) {
        content += '<h5>' + '<i>Site internet : </i>' + '</h5>' + '<p>' + feature.get('website') + '</p>';
      }

      if(feature.get('CAPACITE')!=null) {
        content += '<h5>' + '<i>Capacité : </i>' + feature.get('CAPACITE') + '</h5>';
      }

      if(feature.get('PLACES')!=null) {
        content += '<h5>' + '<i>Places disponibles : </i>' + feature.get('PLACES') + '<h5>';
      }

      content_element = document.getElementById('popup-content');
      content_element.innerHTML = content;
      this.popup.setPosition(coord);
    }
  });

    this.map.on('pointermove', (e) => {
    if (e.dragging) {
      return;
    };
    var pixel = this.map.getEventPixel(e.originalEvent);
    var hit = this.map.hasFeatureAtPixel(pixel);

    this.map.getViewport().style.cursor = hit ? 'pointer' : '';
    });
  }
}

I put a console.log on ‘this.popup’ in order to know where the problem is because I receive a ‘undefined’ …
I have created a current object of popup in order to have access to popup in my handleSelected functions but that doesn’t work anymore …

Do you have any idea ?

Answers: