Добавление обработчика событий в функцию OpenLayers 3?

Я использую следующий код для добавления объекта в векторный слой в 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);

маркер отображается, как ожидалось, но событие click никогда не срабатывает. Что я делаю не так?

Я должен отметить, что уже есть обработчик, связанный с "щелчком" на уровне карты, т. е.

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

3 ответов


во-первых: особенности не стрелять кликов! Для получения информации о событиях функции Do fire, проверьте http://openlayers.org/en/master/apidoc/ol.Feature.html.

проверка, если функция была нажата, работает с .forEachFeatureAtPixel(pixel, callback) функция ol.Карта. (http://openlayers.org/en/master/apidoc/ol.Map.html#forEachFeatureAtPixel) обратный вызов выполняется на каждом объекте в пикселе ;). Обратный вызов получает переданный объект как первый, а слой - feature является вторым аргументом.

хорошо знать это .getEventPixel(event) функция, если вы не работаете с обработчиками событий openlayers, но с обработчиками в окне просмотра. Если вы используете openlayers eventhandler, событие имеет свойство .pixel. (http://openlayers.org/en/master/apidoc/ol.Map.html#getEventPixel) Методы .getEventCoordinate(event) и .getCoordinateFromPixels(pixels) может быть полезно, тоже.

таким образом, вы добавите его вот так на свою карту.on ("click",... :

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

то же самое с jQuery:

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

то же самое с pure JS:

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

вы также можете проверить это пример, существует два использования этой функции, во-первых, с событиями openlayers, во-вторых, с событиями jQuery: http://openlayers.org/en/master/examples/icon.js

Примечание

существует также возможность сделать это с помощью ol.взаимодействие.Выбирать (http://openlayers.org/en/master/apidoc/ol.interaction.Select.html?unstable=true), но это немного пересилило для этого случая.

в любом случае это работает, добавляя прослушиватель в коллекцию, принадлежащую взаимодействию. Коллекция может быть получена с помощью .getFeatures().

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

Если вы просто хотите щелкнуть по карте,это будет работать для вас.

  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);
});

Если вам просто нужно добавить маркер на карту, которая является кликабельной, вы можете использовать оверлеи. В заголовке HTML определите стиль маркера:

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

затем в скрипте часть вашего файла, после создания карты:

    // 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);