Search code examples
javascriptdom-eventsopenlayers-3markers

Multiple Event on a map Marker


html, body {
  height: 100%;
  padding: 0;
  margin: 0;
  font-family: sans-serif;
  font-size: small;
}

#map {
  width: 100%;
  height: 60%;
}


#selection-map {
    height: 40%;
    width: 100%;
    background-color: whitesmoke;
}

.selection-title {
    height: 15%;
    width: 15%;
    margin: auto;
    position: relative;
    border-bottom: 3px solid #DA1A21;
    font-size: 30px;
    top: 30px;
    color: #DA1A21;
}

.selection-form {
    height: 20%;
    width: 100%;
    text-align: center;
    top: 100px;
    position: relative;
}

.selection-form input {
    height: 20px;
    width: 300px;
}
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>SouthWest Airport Map</title>
     <link rel="stylesheet" href="lib/ol3/ol.css" />
     <link rel="stylesheet" href="ol3.css" />
  </head>
  <body>
    <div id="map" class="map"></div>
    <div id="selection-map" class="map">
      <h2 class="selection-title">Airports Selected</h2>
      <form class="selection-form" method="post" action="traitement.php">
        <p><input type="text" id="input-airports" placeholder="Click a marker" /></p>
        <p>For Selecting Multiple Airpots, please press Shift and select all the markers that you need</p>
      </form>
    </div>
    <script src="../common/lib/reqwest.min.js"></script>
    <script src="lib/proj4.js"></script>
    <script src="lib/ol3/ol.js"></script>
    <script src="ol3.js"></script>

  </body>
</html>

I implemented a map with markers pointing to airports, and when I click on a marker the name of the airport appears in a field. (All data included in a GEOJson external file). I just have a last problem that I can't resolve :

I can only select one marker at a time, and i want to be able to select multiples Markers, and make all the name appears in the field. I think that my problem are that I need to change the calling my features, but i don't know what to write instead. I already tried to change my function from "forEachFeatureAtPixel" to "forFeatureAtPixel" or things like that, but every time I break my map.

I'm a beginner in Javascript :/ Here is my JS code

var vectorLayer = new ol.layer.Vector({
  source: new ol.source.Vector({
    format: new ol.format.GeoJSON(),
    url: '//localhost/osgis-ol3-leaflet-master/ol3/data.geojson'
  }),
  style: new ol.style.Style({
    image: new ol.style.Circle({
      radius: 10,
      fill: new ol.style.Fill({
        color: 'green'
      })
    })
  })
});
var rasterLayer = new ol.layer.Tile({
  source: new ol.source.TileJSON({
    url: 'http://api.tiles.mapbox.com/v3/mapbox.geography-class.json',
    crossOrigin: ''
  })
});
var map = new ol.Map({
  layers: [rasterLayer, vectorLayer],
  target: document.getElementById('map'),
 view: new ol.View({
        center: [0, 0],
          zoom: 3
    })
});

var input = document.getElementById('id-airports');

var select_interaction = new ol.interaction.Select();
map.addInteraction(select_interaction);

select_interaction.on('select', function(evt) {
  var features = select_interaction.getFeatures();
  var value = '';
  features.forEach(function(feature){
    // change this to your own needs
    value += feature.get('name') + ', ';
  });
  
  input.value = value;
});

map.on('pointermove', function(e) {
  if (e.dragging) return;
  var hit = map.hasFeatureAtPixel(map.getEventPixel(e.originalEvent));
  map.getTarget().style.cursor = hit ? 'pointer' : '';
});


Solution

  • UPDATE:

    (fiddle) — To select multiple use Shift + Click

    You will remove that another approach:

    map.on('click', function(evt) {
      var feature = map.forEachFeatureAtPixel(
            evt.pixel, function(ft, l) { return ft; });
      if (feature) ...
    });
    

    And use ol.interaction.Select, see bellow.


    There's a select interaction that you can add to your map with a lot of options, see ol.interaction.Select. You can set, for instance some conditions:

    // only select with Mouse Hover
    var select_interaction = new ol.interaction.Select({
       condition: ol.events.condition.pointerMove
    });
    

    Another condition:

    // only select with Alt key + Click
    var select_interaction = new ol.interaction.Select({
      condition: function(mapBrowserEvent) {
        return ol.events.condition.click(mapBrowserEvent) &&
          ol.events.condition.altKeyOnly(mapBrowserEvent);
        }
    });
    

    In your case, putting all together would be something like:

    var select_interaction = new ol.interaction.Select();
    map.addInteraction(select_interaction);
    
    // add a listener to know when features are selected
    select_interaction.on('select', function(evt) {
      var features = select_interaction.getFeatures();
      features.forEach(function(feature){
        // change this to your own needs
        input.value += feature.get('name') + ', ';
      });
    });