Open MosheMalin opened 5 years ago
You will have to getMapRef
, then implement on Layer hover event using Mapbox event listener, and display kepler.gl onLayerHover
action with the hovered feature, mouse pos etc. It would be tricky but doable. Let me know if you were able to get it to work :)
Hey! So i've been having trouble as well and have a work around. Unfortunately mapbox events do not get triggered properly because Deck/kepler block them. I mention deck because this issue existed when I was first experimenting with it before discovering kepler.
Here is my work around, though if there is an easier way I'm definately interested ;)
// building the event data for the interaction, with a flag for whether or not the features at the current mouse position should be retrieved
const buildEventData = (event, map, withFeatures) => {
const { clientX, clientY } = event
const point = [clientX, clientY]
const lngLat = map.unproject({ x: point[0], y: point[1] })
const eventData = {
point,
lngLat,
preventDefault: () => {},
}
if (withFeatures) {
eventData.features = map.queryRenderedFeatures(eventData.point)
}
return eventData
}
// I split the 'click' into mouseDown and mouseUp to prevent clicks being fired on pan
const onMapMouseDown = (event, map) => {
const { clientX, clientY } = event
map.mouseDownPos = {
x: clientX,
y: clientY,
}
}
const onMapMouseUp = (event, map) => {
const { clientX, clientY } = event
const mouseUpPos = {
x: clientX,
y: clientY,
}
// here I check if the pan occurred
if (isEqual(map.mouseDownPos, mouseUpPos)) {
const { click } = map._listeners
if (click) {
const eventData = buildEventData(event, map, true)
click.forEach(c => c(eventData))
}
}
}
// this covers both mouse move, mouse enter, and mouse leave
const onMouseHoverEvent = (event, map, type) => {
const listeners = map._listeners[type]
if (listeners) {
const eventData = buildEventData(event, map)
listeners.forEach(l => l(eventData))
}
}
const [function getting mapbox ref] = (map) => {
// I attached the listener to the '.maps' element, as working with these things
// through keplers hoverInfo caused an unecessary amount of state updates in my container component.
// also worth noting that since kepler's 'clicked' visState prop doesn't change
// if no kepler layer was clicked, it seems it can't be used to detect clicks on non-kepler layers
document
.querySelector('.maps')
.addEventListener('mousemove', e => onMouseHoverEvent(e, map, 'mousemove'))
document
.querySelector('.maps')
.addEventListener('mouseenter', e => onMouseHoverEvent(e, map, 'mouseenter'))
document
.querySelector('.maps')
.addEventListener('mouseleave', e => onMouseHoverEvent(e, map, 'mouseleave'))
document
.querySelector('.maps')
.addEventListener('mousedown', e => onMapMouseDown(e, map))
document
.querySelector('.maps')
.addEventListener('mouseup', e => onMapMouseUp(e, map))
}
I should also note that I've had trouble firing kepler's onLayerClick/onLayerHover
actions myself when this solution was being implemented in my map container component. It's possible I was doing something wrong though
You should be able to take advantage of unfolded vector tiles layer studio
Is there any plan to implement this? It's been over two years for what is a fairly common use case for a geospatial tool and the only 'solution' provided is to use a paid service??
Is there any plan to implement this? It's been over two years for what is a fairly common use case for a geospatial tool
If contributing is not an option for you, note that kepler.gl is under open governance in the linux foundation and it is possible to engage in the community and participate in roadmap discussions. We are always eager to welcome new members to the community.
the only 'solution' provided is to use a paid service??
You need to sign up, however accounts are free and always will be (however it is true that you will need to pay if you want private data / connectors / enterprise sharing / backend powered big data analytics etc features). It is an open core product, that currently funds ~90% of the development of kepler.gl. As more contributors join, the situation may change.
(sort of continuing a previous question - ) I want to get some extra info for the tileserver layers (not Kepler's). Can I use the underlying mapbox events somehow (or anything else), so that hovering or clicking on a tileserver's items will pop-up an info based on the TS info?