1

I am trying to modify the Openlayers 3 box selection example here so I can draw a polygon onto the map to select features.

Below is my code - I have added a vector source which will contain the polygon, changed the interaction from 'DragBox' to 'Draw' and changed the box methods to draw methods.

I do not get any errors in the js console so I am not too sure where I might be going wrong with this? Should this produce a result?

<!DOCTYPE html>
<html>
  <head>
    <title>Box Selection</title>
    <link rel="stylesheet" href="http://openlayers.org/en/v3.14.1/css/ol.css" type="text/css">
    <script src="http://openlayers.org/en/v3.14.1/build/ol.js"></script>
    <style>
      .ol-dragbox {
        background-color: rgba(255,255,255,0.4);
        border-color: rgba(100,150,0,1);
      }
    </style>
  </head>
  <body>
    <div id="map" class="map"></div>
    <div id="info">No countries selected</div>
    <script>
      var vectorSource = new ol.source.Vector({
        url: 'countries.geojson',
        format: new ol.format.GeoJSON()
      });

      var source = new ol.source.Vector();

      var map = new ol.Map({
        layers: [
          new ol.layer.Tile({
            source: new ol.source.OSM()
          }),
          new ol.layer.Vector({
            source: vectorSource
          })
        ],
        renderer: 'canvas',
        target: 'map',
        view: new ol.View({
          center: [0, 0],
          zoom: 2
        })
      });

      // a normal select interaction to handle click
      var select = new ol.interaction.Select();
      map.addInteraction(select);

      var selectedFeatures = select.getFeatures();

      // a DragBox interaction used to select features by drawing boxes
      var dragBox = new ol.interaction.Draw({
        source: source,
        type: 'Polygon'
      });

      map.addInteraction(dragBox);

      var infoBox = document.getElementById('info');

      dragBox.on('drawend', function() {
        // features that intersect the box are added to the collection of
        // selected features, and their names are displayed in the "info"
        // div
        var info = [];
        var extent = source.getExtent();
        vectorSource.forEachFeatureIntersectingExtent(extent, function(feature) {
          selectedFeatures.push(feature);
          info.push(feature.get('name'));
        });
        if (info.length > 0) {
          infoBox.innerHTML = info.join(', ');
        }
      });

      // clear selection when drawing a new box and when clicking on the map
      dragBox.on('drawstart', function() {
        selectedFeatures.clear();
        infoBox.innerHTML = '&nbsp;';
      });
      map.on('click', function() {
        selectedFeatures.clear();
        infoBox.innerHTML = '&nbsp;';
      });
    </script>
  </body>
</html>
Chris
  • 647
  • 1
  • 8
  • 32
  • You didn't say what you are trying to achieve. – Jonatas Walker Mar 02 '16 at 13:21
  • I want to select features by drawing a polygon onto the map which selects all features that intersect that polygon, the names of the features are then to be populated in the div with the 'info' id. – Chris Mar 02 '16 at 14:00

2 Answers2

1

UPDATE:

Note the difference between ol.source.Vector#forEachFeatureInExtent and ol.source.Vector#forEachFeatureIntersectingExtent.


http://jsfiddle.net/jonataswalker/sum62szv/

First, get the drawn polygon extent, then check with ol.source.Vector#forEachFeatureIntersectingExtent like:

draw.on('drawend', function(evt){
  var polygon_extent = evt.feature.getGeometry().getExtent();
  vectorSource.forEachFeatureIntersectingExtent(polygon_extent, function(feature) {
    selectedFeatures.push(feature);
    info.push(feature.get('name'));
  });

});
Jonatas Walker
  • 13,583
  • 5
  • 53
  • 82
  • Thanks for your response Jonatas. Unfortunately that didn't seem to work - I believe I am retrieving the extent ok from my polygon with source.getExtent(); as the coordinates show up in the console, it appears it must be a problem with forEachFeatureIntersectingExtent as it fails to add the name to the array. – Chris Mar 02 '16 at 14:17
  • `source.getExtent()` is not the extent you're looking for. You want to check the features inside the polygon extent, don't you? – Jonatas Walker Mar 02 '16 at 14:36
  • Ah yes that is correct - my thinking though is that there will only be one feature associated to the source at a time, so it would be ok to get the polygon extent? Although this would just return the rectangular extent i.e the bounding box for the polygon would it not? Sorry just trying to learn and understand :) – Chris Mar 02 '16 at 14:42
  • On reflection this would only get the bounding box extent wouldn't it? I would need to return the drawn polygon's geometry to get the shape? – Chris Mar 02 '16 at 14:52
  • That's it, go with polygon extent. See http://jsfiddle.net/jonataswalker/sum62szv/ – Jonatas Walker Mar 02 '16 at 15:09
  • Thank you Jonas I am starting to understand :) - the results are a bit strange though as I tried to draw a polygon between the polygon and line on the map and both seemed to appear in the console when they do not intersect? – Chris Mar 02 '16 at 15:52
  • I think this might be because it is searching the bounding box extent rather than the geometry though, which would make sense. – Chris Mar 02 '16 at 16:09
  • I'm afraid I'm not able to explain better than the API docs. Give them a read and tell me if there's anything missing to your question. – Jonatas Walker Mar 02 '16 at 18:15
1

this is possible a duplicate. check it here

For such action you need to use JSTS lib. Check the link above, it has a fiddle as well, to see it in action

Community
  • 1
  • 1
pavlos
  • 3,001
  • 18
  • 23