web-dev-qa-db-fra.com

Ajout d'un gestionnaire d'événements à la fonctionnalité d'OpenLayers 3?

J'utilise le code suivant pour ajouter une fonctionnalité à une couche vectorielle dans OpenLayers 3 (OL3):

marker = new ol.Feature({
    geometry: new ol.geom.Point([longitude, latitude]),
    name: "Location Marker"
});
markerStyle = new ol.style.Style({
  image: new ol.style.Icon({
    anchor: [0.5, 1.0],
    anchorXUnits: "fraction",
    anchorYUnits: "fraction",
    src: "Content/Images/OpenLayers/marker_trans.png"
  }),
  zIndex: 100000
});
marker.setStyle(markerStyle);
marker.on("click", function(e) {
  // do something
}, marker);
map.getSource().addFeature(marker);

Le marqueur s'affiche comme prévu, mais l'événement de clic ne se déclenche jamais. Qu'est-ce que je fais mal?

Je dois noter qu'il existe déjà un gestionnaire associé au "clic" au niveau de la carte, c'est-à-dire.

map.on("click", function(e) {
  // do something
}, marker);
15
ProfNimrod

Premièrement: les fonctionnalités ne déclenchent pas de clics! Pour plus d'informations sur les événements déclenchés, consultez http://openlayers.org/en/master/apidoc/ol.Feature.html .

Pour vérifier si une fonction a été cliquée, il existe la fonction .forEachFeatureAtPixel(pixel, callback) de ol.Map. ( http://openlayers.org/en/master/apidoc/ol.Map.html#forEachFeatureAtPixel ) Le rappel est exécuté sur chaque fonctionnalité au pixel. Le rappel reçoit 2 arguments: l'entité et la couche dans laquelle l'entité se trouve.

Bon à savoir est la fonction .getEventPixel(event), si vous ne travaillez pas avec des gestionnaires d'événements openlayers mais avec des gestionnaires dans la fenêtre. Si vous utilisez un gestionnaire d'événements openlayers, l'événement a une propriété .pixel. ( http://openlayers.org/en/master/apidoc/ol.Map.html#getEventPixel ) Les méthodes .getEventCoordinate(event) et .getCoordinateFromPixels(pixels) pourraient être utiles , aussi.

Donc, vous l'ajouteriez comme ceci à votre map.on ("cliquez", ...:

map.on("click", function(e) {
    map.forEachFeatureAtPixel(e.pixel, function (feature, layer) {
        //do something
    })
});

Même chose avec jQuery:

$(map.getViewport()).on("click", function(e) {
    map.forEachFeatureAtPixel(map.getEventPixel(e), function (feature, layer) {
        //do something
    });
});

Même chose avec du JS pur:

map.getViewport().addEventListener("click", function(e) {
    map.forEachFeatureAtPixel(map.getEventPixel(e), function (feature, layer) {
        //do something
    });
});

Vous pouvez également vérifier cet exemple , il existe deux utilisations de cette fonction, d'abord avec les événements openlayers, la seconde avec les événements jQuery: http://openlayers.org/en/master/examples/icon.js

Remarque

Il est également possible de le faire avec un ol.interaction.Select ( http://openlayers.org/en/master/apidoc/ol.interaction.Select.html?unstable=true ), mais c'est un peu trop puissant pour ce cas. Et il a quelques mises en garde non intuitives causées par les couches ouvertes déplaçant en interne les entités sélectionnées vers une autre couche dite non gérée.

Quoi qu'il en soit, cela fonctionne en ajoutant un écouteur à la collection appartenant à l'interaction. La collection peut être récupérée avec .getFeatures().

interaction.getFeatures().on("add", function (e) { 
    // do something. e.element is the feature which was added
});
46
Simon Zyx

Si vous voulez juste un clic sur une carte, cela fonctionnera pour vous.

  var map = new ol.Map({
    target: 'map',
    layers: [
      new ol.layer.Tile({
        source: new ol.source.MapQuest({layer: 'sat'})
      })
    ],
    view: new ol.View({
      center: ol.proj.transform([37.41, 8.82], 'EPSG:4326', 'EPSG:3857'),
      zoom: 4
    })
  });

map.on("click", function(evt) {
    var coord = ol.proj.transform(evt.coordinate, 'EPSG:3857', 'EPSG:4326');
    var lon = coord[0];
    var lat = coord[1];
    alert(lon);
    alert(lat);
});
3
Costales

Si vous avez juste besoin d'ajouter un marqueur cliquable sur votre carte, vous pouvez utiliser des superpositions. Dans votre en-tête HTML, définissez le style de votre marqueur:

<style>
    #marker {
        width: 20px;
        height: 20px;
        border: 1px solid #088;
        border-radius: 10px;
        background-color: #0FF;
        opacity: 0.5;
    }
</style>

puis dans la partie script de votre fichier, une fois la carte créée:

    // add marker
    var pos = ol.proj.fromLonLat([0.01123, 0.00612]);
    var marker = new ol.Overlay({
        position: pos,
        positioning: 'center-center',
        element: $('<div id="marker" title="Marker"></div>')
            .popover({
                'placement': 'top',
                'html': true,
                'content': '<strong>anything...</strong>'
            })
            .on('click', function (e) { $(".location-popover").not(this).popover('hide'); }),
        stopEvent: false
    });
    map.addOverlay(marker);
2
Amir Dashti