I'm using a WFS SelectFeature from OpenLayers 2 to show a Popup containing the features' attributes from line layers and point layers (from GeoServer). This works fine, but I would like to create a buffer (similar to the clickTolerance in the WFS GetFeature) around the point/line, so that I wouldn't have to click exactly on the center of the feature to select it. As i've searched through the Q&A, I found related questions, but no answer worked for me so far.
My code is here:
<script defer="defer" type="text/javascript">
var map;
// pink tile avoidance
OpenLayers.IMAGE_RELOAD_ATTEMPTS = 5;
// make OL compute scale according to WMS spec
OpenLayers.DOTS_PER_INCH = 25.4 / 0.28;
function init(){
// Save-strategy
var saveStrategy = new OpenLayers.Strategy.Save();
// Controls
var controls = [
new OpenLayers.Control.ArgParser(),
new OpenLayers.Control.Attribution(),
new OpenLayers.Control.Navigation(),
new OpenLayers.Control.PanZoomBar({position: new OpenLayers.Pixel(2, 15)}),
new OpenLayers.Control.LayerSwitcher(),
new OpenLayers.Control.ScaleLine(),
new OpenLayers.Control.Scale(document.getElementById('scale')),
new OpenLayers.Control.MousePosition({element: document.getElementById('location')})
];
/////
var options = {
scales: [500000, 100000, 50000, 25000, 10000, 5000],
projection: "EPSG:4326",
displayProjection: "EPSG:4326",
units: 'm'
}
/////
map = new OpenLayers.Map('map', /*{controls: controls}*/ options);
//Basemaps
var osm = new OpenLayers.Layer.OSM("Simple OSM Map");
var gsat = new OpenLayers.Layer.Google("Google Satellite",
{type: google.maps.MapTypeId.SATELLITE, numZoomLevels: 22}
);
var gter = new OpenLayers.Layer.Google("Google Terrain",
{type: google.maps.MapTypeId.TERRAIN, numZoomLevels: 22}
);
//Add Basemaps
map.addLayers([gter, osm, gsat]);
//Layer
var test = new OpenLayers.Layer.Vector("xName", {
strategies: [new OpenLayers.Strategy.Fixed(), saveStrategy],
protocol: new OpenLayers.Protocol.WFS({
url: SETTINGS.BASE_URL,
featurePrefix: 'xNS',
featureNS: "xNS",
//extractAttributes: true,
featureType: "xName",
}),
styleMap: new OpenLayers.StyleMap({
"default": new OpenLayers.Style({
"pointRadius": 2,
fill: true,
fillColor: "#8d006a",
strokeColor: "#000000",
strokeWidth: 0.2
})
})
});
//Add Layer
map.addLayer(test);
//add Popup
var select = new OpenLayers.Control.SelectFeature(test, {
hover: false,
toggle: true,
box: false,
});
map.addControl(select);
select.activate();
function onPopupClose(evt) {
selectControl.unselect(selectedFeature);
}
test.events.on({
featureselected: function(event) {
var feature = event.feature;
console.log(feature);
feature.popup = new OpenLayers.Popup.FramedCloud
("pop",
feature.geometry.getBounds().getCenterLonLat(),
null, feature.attributes["xx"] + " " + feature.attributes["xx"],
null,
true //Boolean indicating if the close buttons must be shown
);
map.addPopup(feature.popup);
},
// destroy popup when feature is no longer selected. Prevents showing 2 Popups at the same time
featureunselected: function(event) {
var feature = event.feature;
map.removePopup(feature.popup);
feature.popup.destroy();
feature.popup = null;
}
});
//Set Map Center
map.setCenter(
new OpenLayers.LonLat(27.1, 47.55).transform(
new OpenLayers.Projection("EPSG:4326"),
map.getProjectionObject()
), 9
);
}
I have also tried WFS GetFeature with clickTolerance, but it doesn't seem to work, nothing is selected on the map.
Code:
var select = new OpenLayers.Layer.Vector("Selection", {styleMap: new OpenLayers.Style(OpenLayers.Feature.Vector.style["select"])});
map.addLayer(select);
getfeature = new OpenLayers.Control.GetFeature({
protocol: new OpenLayers.Protocol.WFS({
url: SETTINGS.BASE_URL,
featurePrefix: 'xNS',
featureNS: "xNS",
//extractAttributes: true,
featureType: "xName"
}),
box: true,
hover: true,
multipleKey: "shiftKey",
toggleKey: "ctrlKey",
clickTolerance: 1000
});
getfeature.events.register("featureselected", this, function {
select.addFeatures([feature]);
});
getfeature.events.register("featureunselected", this, function {
select.removeFeatures([feature]);
});
map.addControl(getfeature);
getfeature.activate();
Cloning the features with bigger invisible ones wouldn't help, due to the large number of features and layers I already have.
Best Answer
quick+dirty workaround:
If you don't need a visible stroke around your symbols you could just use a thicker stroke and make it invisible:
http://jsfiddle.net/expedio/et4c43gp/