J'ai réussi à ajouter de l'interactivité à une couche d'entités ajoutée à partir d'une ressource GeoJSON distante. Lorsque je clique sur une entité, je reçois son identifiant, envoie une requête AJAX et affiche des informations pertinentes sur l'entité sur la page située en dehors de la zone de carte.
J'ai utilisé une interaction Select
.
Je tiens à préciser encore plus à l'utilisateur qu'il peut cliquer sur les éléments de la carte. Est-il possible de changer le curseur de la souris en "curseur" de "main" lorsque la souris survole une caractéristique contenue dans un ol.layer.Vector
?
Je n'ai rien trouvé dans la doc, sur ce site ou sur Google.
Grâce au lien d'exemple fourni par Azathoth dans les commentaires, j'ai trouvé une solution:
pointermove
eventVoici le code:
var cursorHoverStyle = "pointer";
var target = map.getTarget();
//target returned might be the DOM element or the ID of this element dependeing on how the map was initialized
//either way get a jQuery object for it
var jTarget = typeof target === "string" ? $("#"+target) : $(target);
map.on("pointermove", function (event) {
var mouseCoordInMapPixels = [event.originalEvent.offsetX, event.originalEvent.offsetY];
//detect feature at mouse coords
var hit = map.forEachFeatureAtPixel(mouseCoordInMapPixels, function (feature, layer) {
return true;
});
if (hit) {
jTarget.css("cursor", cursorHoverStyle);
} else {
jTarget.css("cursor", "");
}
});
Voici le lien vers l'exemple sur le site OpenLayers: http://openlayers.org/en/v3.0.0/examples/icon.html
Si cela ne fonctionne pas, essayez une combinaison des 2, semble fonctionner pour mon vecteur popup ...
var target = map.getTarget();
var jTarget = typeof target === "string" ? $("#" + target) : $(target);
// change mouse cursor when over marker
$(map.getViewport()).on('mousemove', function (e) {
var pixel = map.getEventPixel(e.originalEvent);
var hit = map.forEachFeatureAtPixel(pixel, function (feature, layer) {
return true;
});
if (hit) {
jTarget.css("cursor", "pointer");
} else {
jTarget.css("cursor", "");
}
});
Cela peut être fait aussi bien sans jQuery:
map.on("pointermove", function (evt) {
var hit = this.forEachFeatureAtPixel(evt.pixel, function(feature, layer) {
return true;
});
if (hit) {
this.getTarget().style.cursor = 'pointer';
} else {
this.getTarget().style.cursor = '';
}
});
Voici une autre façon de le faire:
map.on('pointermove', function(e){
var pixel = map.getEventPixel(e.originalEvent);
var hit = map.hasFeatureAtPixel(pixel);
map.getViewport().style.cursor = hit ? 'pointer' : '';
});
Pour moi cela a fonctionné comme ceci:
map.on('pointermove', function(e) {
if (e.dragging) return;
var pixel = e.map.getEventPixel(e.originalEvent);
var hit = e.map.forEachFeatureAtPixel(pixel, function (feature, layer) {
return true;
});
e.map.getTargetElement().style.cursor = hit ? 'pointer' : '';
});
J'ai aussi ajouté un filtre de calque:
map.on('pointermove', function(e) {
if (e.dragging) return;
var pixel = e.map.getEventPixel(e.originalEvent);
var hit = e.map.forEachFeatureAtPixel(pixel, function (feature, layer) {
return layer.get('name') === 'myLayer';
});
e.map.getTargetElement().style.cursor = hit ? 'pointer' : '';
});
Je devais choisir une nouvelle solution car l'ancienne solution que je utilisais auparavant pour le filtre de calque ne fonctionnait plus:
var hit = e.map.hasFeatureAtPixel(e.pixel, function(layer){
return layer.get('name') === 'myLayer';
});
Je l'ai fait avec le code suivant:
var target = $(map.getTargetElement()); //getTargetElement is experimental as of 01.10.2015
map.on('pointermove', function (evt) {
if (map.hasFeatureAtPixel(evt.pixel)) { //hasFeatureAtPixel is experimental as of 01.10.2015
target.css('cursor', 'pointer');
} else {
target.css('cursor', '');
}
});
Un moyen simple d'obtenir un élément cible
var target = map.getTarget();
target = typeof target === "string" ?
document.getElementById(target) : target;
target.style.cursor = features.length > 0) ? 'pointer' : '';
Si vous utilisez Angular 2, vous devez utiliser le code suivant:
this.map.on("pointermove", function (evt) {
var hit = evt.map.hasFeatureAtPixel(evt.pixel);
this.getTargetElement().style.cursor = hit ? 'pointer' : '';
});
Si la variable map est une classe de membre, vous la désignerez sous le nom "this.map". Si elle est déclarée à l'intérieur de la fonction actuelle, elle peut être appelée "map". Mais surtout, vous n'écrivez pas
map.getTargetElement()
mais vous écrivez
this.getTargetElement()
Uncaught TypeError: Cannot set property 'cursor' of undefined.
Corrigé avec: map.getTargetElement()s.style.cursor = hit ? 'pointer' : '';
au lieu de map.getTarget().style.cursor = hit ? 'pointer' : '';
J'ai essayé de minimiser la clôture de pointermove
, en évitant de mettre à jour le style quand ce n'est pas nécessaire, parce qu'il appelle très souvent:
Exemple-1: utilise jQuery :
var cursorStyle = "";
map.on("pointermove", function (e) {
let newStyle = this.hasFeatureAtPixel(e.pixel) ? "pointer" : "";
newStyle !== cursorStyle && $(this.getTargetElement()).css("cursor", cursorStyle = newStyle);
});
Exemple-2: non jQuery:
var cursorStyle = "";
map.on("pointermove", function (e) {
let newStyle = this.hasFeatureAtPixel(e.pixel) ? "pointer" : "";
if (newStyle !== cursorStyle) {
this.getTargetElement().style.cursor = cursorStyle = newStyle;
}
});
Une autre manière (combinée à partir de parties des réponses ci-dessus, mais encore plus simple):
map.on("pointermove", function (evt) {
var hit = map.hasFeatureAtPixel(evt.pixel);
map.getTargetElement().style.cursor = (hit ? 'pointer' : '');
});