2

I have an OpenLayers map that draws features in a vector layer. The features are selectable and have a popup on select. Unfortunately in a lot of cases the features overlap so it can be impossible to select some features. I think that what I need to do to fix this is change my select control so that it uses a click handler and searches the map for features at this point. What sort of function do i need to write? are there any examples of this being implemented before?

This is how the features are drawn:

var vector_Layer = new OpenLayers.Layer.Vector();
function GetFeaturesFromKMLString (strKML) {
 var format = new OpenLayers.Format.KML({
 'internalProjection': new OpenLayers.Projection("EPSG:900913"),
 'extranalProjection': new OpenLayers.Projection("EPSG:4326") 
 });
 return format.read(strKML);
};
vector_Layer.addFeatures(GetFeaturesFromKMLString('$newkml'));

And this is how Layers are currently selected:

var select = new OpenLayers.Control.SelectFeature(vector_Layer, {clickout: true}); 
 vector_Layer.events.on({
 "featureselected": onFeatureSelect,
 "featureunselected": onFeatureUnselect}); 
 map.addControl(select);
 select.activate();
 select.handlers['feature'].stopDown = false; 
 select.handlers['feature'].stopUp = false;

here is the click event listener I was planning on using:

OpenLayers.Control.Click = OpenLayers.Class(OpenLayers.Control, { 
 defaultHandlerOptions: {
 'single': true,
 'double': false,
 'pixelTolerance': 0,
 'stopSingle': false,
 'stopDouble': false
 },
 initialize: function(options) {
 this.handlerOptions = OpenLayers.Util.extend(
 {}, this.defaultHandlerOptions
 );
 OpenLayers.Control.prototype.initialize.apply(
 this, arguments
 ); 
 this.handler = new OpenLayers.Handler.Click(
 this, {
 'click': this.onClick,
 'dblclick': this.onDblclick 
 }, this.handlerOptions
 );
 }, 
 onClick: function(evt) {
 //function that seachers for and selectas features at this point
 },
asked Jul 13, 2013 at 14:34

3 Answers 3

1

I've had this this situation, and came up with a novel solution: use the WMSGetFeatureInfo instead of the SelectFeature control, because it is able to return multiple features associated with a click event. Even though the WMSGetFeatureInfo is not supposed to be used with vector layers, it is possible to trick OpenLayers into thinking it is interacting with a WMS layer by adding WMS properties to the vector layer, and hacking some layer methods.

var lyrJobs = new OpenLayers.Layer.Vector(
"User Jobs",
{
 strategies: [
 new OpenLayers.Strategy.BBOX({ resFactor: 1 }) //Force bb to refresh on every zoom.
 ],
 url: wmsServerAddress + '?',
 protocol: new OpenLayers.Protocol.WFS({
 version: '1.1.0',
 srsName: map.getProjection(),
 url: wfsServerAddress,
 featureType: 'MyLayerName',
 featureNS: 'MyNameSpace', //URI
 geometryName: 'Geom'
 }),
 //Add WMS-style properties to allow WMSGetFeatureInfo protocol to be used.
 params: {
 FORMAT: 'image/png',
 VERSION: '1.1.1',
 STYLES: '',
 LAYERS: 'myNameSpace' + layerName
 }
}
);
lyrJobs.reverseAxisOrder = function ()
{
 return (parseFloat(this.params.VERSION) >= 1.3 &&
 !!this.yx[map.getProjectionObject().getCode()]);
}

It's perhaps a bit weird, but it works extremely well. When you get a response from the control, you can check if it returned a single features or multiple features, and display a popup accordingly.

answered May 25, 2015 at 4:45
0

One observation first: if you have vector features of a same group overlapping on your map, you might want to look into some clustering implementation first. One reason for this is that rendering vector graphics in a browser is expensive. Running into performance issues nowadays is less of a problem, but depending on the number of vector points and the browser-machine rendering them, you could still run into problems, especially on mobile platforms. Let say that it is good practice to keep the vector features (and the DOM elements) in your page as lower as possible. Openlayers has its own clustering strategy implemented in its API, but if you do not like it you could still plugin a third party one or roll your own.

Having pointed this out, one possible route I would suggest is to try having a look at what OpenLayers.Geometry has to offer and especially this example. I have never tried this, but depending on needs, you could even think at creating a temporary circle on click (all within OpenLayers) and then intersect your vector points with this circle...

Hope this can be of some help.

answered Jul 13, 2013 at 19:27
2
  • Do you know if clustering strategies work with polygons? The only one I'm aware of takes everything as a point, or so i thought... Commented Jul 14, 2013 at 15:39
  • I assumed you were talking about points. No, on top of my head I am not aware of obvious clustering strategies with polygons. But, at a certain zoom level these polygons could be clustered and abstracted as points on centroids. Again, having polygons, the openlayers.geometry intersection method should work reasonably well for what you are trying to do. Finally, you could have simplified polygons for certain zoom levels... it all depends obviously from the specific case... Commented Jul 15, 2013 at 20:49
0
answered Aug 13, 2013 at 3:54

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.