Aller au contenu

OpenLayers Les interactions

Pour OpenLayers, tout est dessiné au sein du contexte graphique, les objets de la carte n’existent pas en tant que tels. Heureusement, OpenLayers définit un ensemble de classes (ol.interaction.xxx) pour simplifier certaines interactions. Par exemple, pour sélectionner un objet vectoriel au click, on peut utiliser la classe ol.interaction.Select.

OpenLayers - Sélectionner un objet au click

let layer = new ol.layer.Vector({
    source: new ol.source.Vector({
        features: [
            new ol.Feature(new ol.geom.Point([0, 0])),
        ],
    }),
});
map.addLayer(layer);

let select = new ol.interaction.Select({
    layers: [layer],
    condition: ol.events.condition.click,
});
map.addInteraction(select);

Parmi les autres interactions, on retrouve :

  • ol.interaction.Select pour sélectionner/survoler des objets
  • ol.interaction.Translate pour déplacer un objet
  • ol.interaction.Draw pour dessiner des objets
  • ol.interaction.Modify pour modifier des objets

OpenLayers - Déplacer un marqueur avec ol.interaction.Translate

let translate = new ol.interaction.Translate({
    layers: [layer],
});
map.addInteraction(translate);

OpenLayers - Séléctionner un objet au survol avec la condition ol.events.condition.pointerMove

let hover = new ol.interaction.Select({
    layers: [layer],
    condition: ol.events.condition.pointerMove,
});
map.addInteraction(hover);

Interactions avancées#

Pour des interactions avancées, il faut gérer un événement global sur les pixels du contexte de dessin, pour ensuite effectuer le traitement qui nous intéresse. OpenLayers fournit des fonctions génériques pour interagir avec les objets de la carte, pour un pixel donné :

OpenLayers - Écouter le click

// première méthode
map.on('click', evt => {
    let features = map.getFeaturesAtPixel(evt.pixel);
    if (features.length) {
        console.log(features[0].getGeometry().getCoordinates());
    }
});

// seconde méthode
map.on('click', evt => {
    let feature = map.forEachFeatureAtPixel(evt.pixel, feature => feature);
    if (feature) {
        console.log(feature.getGeometry().getCoordinates());
    }
});

Plusieurs méthodes possibles pour récupérer les objets :

  • map.getFeaturesAtPixel récupère toutes les features qui intersectent le click. Retourne un tableau de features ou un tableau vide.
  • map.forEachFeatureAtPixel exécute une fonction pour chaque feature qui intersectent le click. Si la fonction retourne true (ou retourne la feature), alors les suivantes ne sont pas appelées.

Les 2 méthodes peuvent être filtrées par couche (avec l’option layerFilter).

OpenLayers - Filtrer par couche

let couche = new ol.layer.Vector();

map.on('click', evt => {
    let features = map.getFeaturesAtPixel(evt.pixel, {
        layerFilter: (layer) => {
            return couche == layer;
        },
    });
});

Interactions sur raster#

OpenLayers permet également de réaliser des interactions avec des couches de données pixels (comme un flux WMS), grâce à la méthode getData des couches ol.layer.Tile

OpenLayers - Récupération de la couleur d’un pixel

let pixelColor = layer.getData(evt.pixel);

// retourne
// int8ClampedArray(4) [ 0, 0, 0, 0 ] quand pas de données
// int8ClampedArray(4) [ 255, 0, 0, 255 ] pour un pixel rouge

Les popups#

Ajout d’une popup#

Pour OpenLayers, il faut créer une Overlay (basé sur un objet HTML de la page) et gérer les interactions sur la carte pour ouvrir/fermer cette overlay.

OpenLayers - Ajout d’une popup

// element HTML
let el = document.createElement('div');
el.innerText = 'Une popup';

// création de l’overlay
let popup = new ol.Overlay({
    element: el,
    positioning: 'bottom-center',
    offset: [0, -30],
});
map.addOverlay(popup);

Pour l’ouverture/fermeture de la popup au click, deux méthodes :

// avec `ol.interaction.Select`

let select = new ol.interaction.Select({
    layers: [votreCouche],
    condition: ol.events.condition.click,
    style: null,
});
map.addInteraction(select);

// event
select.on('select', evt => {
    // close
    popup.setPosition();
    // si select ok
    if (evt.selected.length) {
        let feature = evt.selected[0];
        // open
        popup.setPosition(feature.getGeometry().getCoordinates());
    }
});
// sans `ol.interaction.Select`, mais gestion du click sur la map

map.on('click', evt => {
    let feature = map.forEachFeatureAtPixel(evt.pixel, feature => feature);
    // close 
    popup.setPosition();
    if (feature) {
        // open
        popup.setPosition(feature.getGeometry().getCoordinates());
    }
});

Il faut également penser à styler cette popup, qui n’a aucune mise en forme par défaut.

Modification d’une popup#

Pour modifier le contenu de la popup, il faut mettre à jour l’élément HTML

OpenLayers - Modification d’une popup

map.on('click', evt => {
    let [lng, lat] = feature[0].getGeometry().getCoordinates(); // proj de la map
    el.innerText = 'lat: ' + lat + ' / lng: ' + lng;
});