For anyone who might want a solution for this in the future, I managed to create a hook that returns a feature that is hovered on and its pixel coordinates. All one has to do is create a pop-up using this info.
import { useState, useEffect } from "react";
const useMouseTracker = () => {
const [pixelCoordinates, setPixelCoordinates] = useState({ x: 0, y: 0 });
useEffect(() => {
const handleMouseMove = (event) => {
setPixelCoordinates({ x: event.clientX, y: event.clientY });
};
window.addEventListener("mousemove", handleMouseMove);
return () => {
window.removeEventListener("mousemove", handleMouseMove);
};
}, []);
return pixelCoordinates;
};
export default useMouseTracker;
import { useState, useEffect } from "react";
import useMouseTracker from "./useMouseTracker";
import { reproject } from "@mapstore/utils/CoordinatesUtils";
const useHoverOnFeature = (map, geoJson, hoverRadius = 10) => {
const [closestFeature, setClosestFeature] = useState(null);
const [closestFeaturePixel, setClosestFeaturePixel] = useState(null);
const mouseCoords = useMouseTracker(); // Get pixel coordinates of the mouse
useEffect(() => {
if (!map || !geoJson || !geoJson.features || geoJson.features.length === 0) return;
let minDistance = Infinity;
let nearestFeature = null;
let nearestPixelCoords = null;
geoJson.features.forEach((feature) => {
const { coordinates } = feature.geometry;
if (!coordinates || coordinates.length < 2) return;
const projectedCoords = reproject(
[coordinates[0], coordinates[1]],
"EPSG:4326",
"EPSG:900913"
);
const featurePixelCoords = map.getPixelFromCoordinate([
projectedCoords.x,
projectedCoords.y,
]);
if (!featurePixelCoords) return;
const distance = Math.sqrt(
Math.pow(mouseCoords.x - featurePixelCoords[0], 2) +
Math.pow(mouseCoords.y - featurePixelCoords[1], 2)
);
if (distance <= hoverRadius && distance < minDistance) {
minDistance = distance;
nearestFeature = feature;
nearestPixelCoords = featurePixelCoords;
}
});
setClosestFeature(nearestFeature);
setClosestFeaturePixel(nearestPixelCoords);
}, [map, geoJson, mouseCoords, hoverRadius]);
return { closestFeature, closestFeaturePixel };
};
export default useHoverOnFeature;