How to select a feature programmatically on a vector layer in OpenLayers?

Patrick Hillert picture Patrick Hillert · Jan 12, 2012 · Viewed 22.2k times · Source

I'm currently searching for a solution to select (or highlight) a vector in a OpenLayers.Layer.Vector.

I've build a simple gridtable where a user can pick a vector (given as WKT formatted string) which should highlight the corresponding vector on the layer. All the vectors in the gridtable are drawn to the vector layer on the map when the user visits the the site.

I found out that I either need the OpenLayers.Control.ModifyFeature's selectFeature(feature) function or the OpenLayers.Control.SelectFeature (see dev.openlayers.org/apidocs/files/OpenLayers/Control/SelectFeature-js.html's select(feature) function (which probably does not exists or doesn't exists any longer?). See a post from a Mailinglist: osgeo-org.1803224.n2.nabble.com/Programatically-Select-a-Feature-tt2192485.html#a2193928 for more infos.

I tried the following with no success, so I hope someone could grab this code lines and could show me a working code snippet ;-)

// ... some initializing code
this.vlayer = new OpenLayers.Layer.Vector("VectorLayer");  // VectorLayer

// some controls
this.openLayerControlPoint = new OpenLayers.Control.DrawFeature(this.vlayer, OpenLayers.Handler.Point);
this.openLayerControlPolygon = new OpenLayers.Control.DrawFeature(this.vlayer, OpenLayers.Handler.Polygon);
this.openLayerControlModify = new OpenLayers.Control.ModifyFeature(this.vlayer, {
  mode: OpenLayers.Control.ModifyFeature.RESHAPE | OpenLayers.Control.ModifyFeature.DRAG,
  standalone: false
});

// just deactivate to make sure everything is really deactivated
this.openLayerControlPoint.deactivate();
this.openLayerControlPolygon.deactivate();
this.openLayerControlModify.deactivate();

// add the just created layer to the map
this.map.addLayer(this.vlayer);

// add all (deactivated) controls to the map
this.map.addControl(this.openLayerControlPoint);
this.map.addControl(this.openLayerControlPolygon);
this.map.addControl(this.openLayerControlModify);

Later in code:

// ... another function doing the action
selectVector: function(wktVector) {
  this.openLayerControlModify.activate();

  // this is no elegant solution, this should only show how I would 
  // test the functionallity.
  for (var i = 0; i < this.vlayer.features.length; ++i) {
    // returns a WKT formatted string: 
    // 'POLYGON((xxxx.xxx xxxx.xxx), (xxxx.xxx xxxx.xxx))'
    var wktVectorCurrent = this.vlayer.features[i].geometry.toString(); 
    if (wktVector == wktVectorCurrent) {
      // \/ doesn't work :-(
      this.openLayerControlModify.selectFeature(this.vlayer.features[i]);
      break;
    }
  }
}

Answer

igorti picture igorti · Jan 12, 2012

I don't understand why you are using ModifyFeature to select a feature. OpenLayers.Control.SelectFeature is done specifically to select features so I suggest that you use this control instead.

So, create SelectFeature control:

var selectFeature = new OpenLayers.Control.SelectFeature(this.vlayer);
selectFeature.activate();

Then in you if-statement(I guess it works to find a feature you want to select by comparing geometries?) use select method:

if (wktVector == wktVectorCurrent) {
   selectFeature.select(this.vlayer.features[i]);
}

According to documentation this method should mark feature as selected and raise appropriate events:

 * Method: select
 * Add feature to the layer's selectedFeature array, render the feature as
 * selected, and call the onSelect function.

If you want to do something on the map when feature gets selected(like showing a popup), you should subscribe vector layer to select-event when you create it:

this.vlayer.events.on({'featureselected': function(){
   //Handle select event
}});