Search code examples
angulartypescriptopenlayers

Angular OpenLayers click event feature


So I made a map displaying parking points as features. Now I would love to add a click function to the features so that when it is clicked I display a popup with the data from that parking.

I have searched online on how to do this but I cannot find any info on how to add a click event to a feature, all I can find is how to add a click event to the whole map. I've also searched the OpenLayers docs but not a lot there either.

export class MapComponent implements OnInit {
  map;
  testp;
  vectorSource;
  vectorLayer;
  rasterLayer;
  //features: Feature[];

  constructor(
    private _pds: ParkingDataService
  ) { }

  ngOnInit(): void {
    let parkingdata = new Array();

    this._pds.allParkings$.subscribe((parkings: Parking[])=>{
      parkings.forEach(parking => {

        let ftre: Feature = new Feature({
          geometry: new Point(fromLonLat([parking.longtitude, parking.latitude]))
        });

        ftre.setStyle(new Style({
          image: new Icon(({
            color: '#8959A8',
            crossOrigin: 'anonymous',
            src: 'assets/park.svg',
            imgSize: [25, 25]
          }))
        }));

        parkingdata.push(ftre)
      });
      this.vectorSource = new VectorSource({
        features: parkingdata
      });

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

    console.log(parkingdata)


  }

  initializeMap(){
    this.map = new Map({
      target: 'map',
      layers: [ new TileLayer({
        source: new OSM()
      }), this.vectorLayer ],
      view: new View({
        center: fromLonLat([3.7219431, 51.048919]),
        zoom: 15,
      })
    });
  }
}

Solution

  • You need the select interaction. The key thing to thinking about how this interaction works is that it does not attach to the feature. Instead it is attached to the entire map. When it is fired by a user clicking something, you get an event object with a list of all the features that were associated with that click (ie, under it).

    The docs for it are here:

    https://openlayers.org/en/latest/apidoc/module-ol_interaction_Select.html

    There's a good example of using it here:

    https://openlayers.org/en/latest/examples/select-features.html?q=select

    That example is a bit complex in that it shows you how to do selection from single clicks, hovers, etc. So there's some extra code to work with all that. I've pulled out the interesting bits here, to give you a more concise overview of what you need:

    // Import the interaction, not sure if this is the correct way to do it in Angular, so maybe adjust this for your setup
    import Select from 'ol/interaction/Select';
    
    // The following code can go in your initialiseMap, after you've created the map:
    
    // Create a select interaction working on "singleclick" (the default)
    let selectSingleClick = new Select();
    
    // Add it to your map
    this.map.addInteraction(select);
    
    // Here's the event handler that will give you the selected features
    select.on('select', function(e) {
        console.log(e.target.getFeatures())
    })