Reputation: 2519
quick (and I believe for some of you an easy) question regarding cursor styling while hovering above geojson layer/s.
So, I have one clip layer that I'm using to create a mask around wms layers, and another one that represents some administrative areas.
As you can see in picture below
What I would like is to change style of cursor when I'm hovering above administrative areas but it seems that I'm missing something.
I'm trying to isolate to layer only administrative borders layer using this block of code:
map.on('pointermove', function(e) {
if (e.dragging) return;
var pixel = e.map.getEventPixel(e.originalEvent);
var hit = e.map.forEachFeatureAtPixel(pixel, function(feature, layer) {
return vectorJLS.get('layer_name') === 'jls';
});
e.map.getTargetElement().style.cursor = hit ? 'pointer' : '';
});
UPDATE
While JGH tweak code a bit it still doesn't work. I've detected that problem lies in layer that I'm using for mask clipping, when removed, code that JGH provided, works.
Here is code that I'm using for mask clipping
var clipLayer = new ol.layer.Image({
source: new ol.source.ImageVector({
source: new ol.source.Vector({
url: 'geojson/clip_wgs.geojson',
format: new ol.format.GeoJSON()
}),
style: new ol.style.Style({
fill: new ol.style.Fill({
color: 'black'
})
})
})
});
clipLayer.on('postcompose', function(e) {
e.context.globalCompositeOperation = 'source-over';
});
clipLayer.on('precompose', function(e) {
e.context.globalCompositeOperation = 'destination-in';
});
clipLayer.setMap(map);
Is it possible to somehow ignore clip layer when changing cursor style or should I take another approach?
UPDATE - 2
I've tweaked code a bit, but still without any success while clipedLayer is on.
map.on('pointermove', function(e) {
if (e.dragging) return;
var pixel = e.map.getEventPixel(e.originalEvent);
// initialize the hit variable to false (not found)
var hit = map.hasFeatureAtPixel(e.pixel, {
layerFilter: function(layer) {
return vectorJLS.get('layer_name') === 'jls';
}
});
console.log(hit)
});
Interesting problem if I might add
Upvotes: 1
Views: 3158
Reputation: 2519
Finally, with help from fellow JGH I've found appropriate solution for my problem. Searching release pages and google machine I've stumbled upon some interesting information regarding layer filters and its usage in method hasFeatureAtPixel. This block of code is valid for versions below 3.20.1 but more about that on OpenLayers Git
map.on('pointermove', function(e) {
if (e.dragging) return;
var pixel = e.map.getEventPixel(e.originalEvent);
var hit = map.hasFeatureAtPixel(e.pixel, {
layerFilter: function(layer) {
return layer.get('layer_name') === 'jls';
}
});
e.map.getTargetElement().style.cursor = hit ? 'pointer' : '';
});
For newer versions you should use layer filter like this (I'm using 4.6.5)
map.hasFeatureAtPixel(pixel, {
layerFilter: layerFilterFn.bind(layerFilterThis)
});
Or for my particular problem like this
map.on('pointermove', function(e) {
if (e.dragging) return;
var pixel = e.map.getEventPixel(e.originalEvent);
var hit = map.hasFeatureAtPixel(e.pixel, {
layerFilter: function(layer) {
return layer.get('layer_name') === 'jls';
}
});
e.map.getTargetElement().style.cursor = hit ? 'pointer' : '';
});
Hope it helps :)
Upvotes: 3
Reputation: 17846
In your function, you are basically looping through all the layers at the mouse location. In that loop, if the layer has the proper name you set the pointer, else if it has a different name, you remove the pointer (or set it to something else).
As it is, it is dependent on the layer order:
ex: layer 1 = target -> set custom pointer. Layer 2 = other layer -> remove pointer. ==> final pointer: removed
ex: Layer 1 = other layer -> remove pointer. Layer 2 = target -> set custom pointer. ==> final pointer: custom pointer
The looping occurs when you set the hit
variable, i.e. it corresponds to the last layer only as you are overriding the value for each layer.
map.on('pointermove', function(e) {
if (e.dragging) return;
var pixel = e.map.getEventPixel(e.originalEvent);
// initialize the hit variable to false (not found)
var hit = false;
e.map.forEachFeatureAtPixel(pixel, function(feature, layer) {
if ( vectorJLS.get('layer_name') === 'jls') {
//IF we have found the layer, flag it (but don't return anything!)
hit = true;
}
});
e.map.getTargetElement().style.cursor = hit ? 'pointer' : '';
});
Upvotes: 2