In the code snippet, I have added a single Point feature with a text Style (brokenStyle
).
I would like to know when my cursor moves over this feature, but getFeatures
always returns an empty list.
If I use workingStyle
instead, which uses the Circle style, I will see Hit Feature
appear in the console.
Why does the text style not work in this case? If I want to use the text style, will I need to also use a transparent circle or square so getFeatures
will work? What is common practice in this situation?
ol.proj.get("EPSG:4326").setExtent([-180, -85, 180, 85]);
const osm = new ol.source.OSM();
osm.setTileGridForProjection(
"EPSG:4326",
ol.tilegrid.createXYZ({ extent: [-180, -90, 180, 90] })
);
const feature = new ol.Feature({
geometry: new ol.geom.Point([0, 45])
});
const source = new ol.source.Vector();
source.addFeatures([feature]);
const brokenStyle = new ol.style.Style({
text: new ol.style.Text({
text: "X",
scale: 1.0,
textBaseline: "bottom",
fill: new ol.style.Fill({ color: "#000000" }),
stroke: new ol.style.Stroke({ color: "black", width: 1 })
})
});
const workingStyle = new ol.style.Style({
image: new ol.style.Circle({
radius: 5,
stroke: new ol.style.Stroke({
color: "black",
width: 2
}),
fill: new ol.style.Fill({
color: "black"
})
})
});
const vectorLayer = new ol.layer.Vector({
source,
style: (feature) => {
return brokenStyle;
}
});
const map = new ol.Map({
target: "map",
layers: [
new ol.layer.Tile({
source: osm
}),
vectorLayer
],
view: new ol.View({
projection: "EPSG:4326",
center: [0, 0],
zoom: 0
})
});
map.on("pointermove", (e) => {
const pixel = e.pixel;
vectorLayer.getFeatures(e.pixel).then((hitFeatures) => {
if (hitFeatures.length > 0) {
console.log("Hit Feature");
}
});
});
#map {
aspect-ratio: 360/170;
background-color: blue;
margin: 32px;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/openlayers/7.3.0/ol.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/openlayers/7.3.0/dist/ol.min.js"></script>
<div id="map"></div>
"Text is not considered" https://openlayers.org/en/latest/apidoc/module-ol_layer_Vector-VectorLayer.html#getFeatures so you will need to use map.getFeaturesAtPixel()
instead:
map.on("pointermove", (e) => {
const pixel = e.pixel;
const hitFeatures = map.getFeaturesAtPixel(e.pixel, {
layerFilter: (l) => l === vectorLayer
)
if (hitFeatures.length > 0) {
console.log("Hit Feature");
}
});