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 objetsol.interaction.Translate
pour déplacer un objetol.interaction.Draw
pour dessiner des objetsol.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 retournetrue
(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;
});