mapbox / mapbox-gl-js

Interactive, thoroughly customizable maps in the browser, powered by vector tiles and WebGL
https://docs.mapbox.com/mapbox-gl-js/
Other
11.2k stars 2.22k forks source link

Evaluate pixel color for pixel perfect picking of symbols in queryRenderedFeatures #10555

Open iJoris opened 3 years ago

iJoris commented 3 years ago

mapbox-gl-js version: V.2.2.1

browser: Chrome 89

Steps to Trigger Behavior

  1. Create a map with a custom marker-image, this can be SVG or PNG
  2. Click around the marker events will go off without being on the marker

This results in click events on the wrong markers because if markers are close to each other they stack on top of each other. A more basic example of the problem is this image: image

Example with SVG + map.showCollisionBoxes = true; & 'icon-padding': 0, image

I've tested this with both PNG images as markers as SVG.

Link to Demonstration

https://output.jsbin.com/fudemut/

Expected Behavior

When the mouse is not on the marker I don't want the click event to fire.

Actual Behavior

Even if I'm not on the marker the marker catches a click event. It seems that mapbox renders a square around each marker with a big offset. Even if the marker is transparent (PNG/svg)

arindam1993 commented 3 years ago

Thanks for the report @iJoris , yes, this is a known limitation.

We evaluate all features as primitive boxes for queryRenderedFeatures . We could potentially implement this by evaluating the pixel color for the icon/text. Tagging this as a feature request and updating the title so we cant find it easily later

iJoris commented 3 years ago

Hi @arindam1993, Thanks for your quick response.

Isn't there any other way at the moment to make the markers only click-able by their marker instead of a click-box? Could custom-HTML markers be a solution?

arindam1993 commented 3 years ago

Yes HTML markers ware a valid solution if

  1. The data for your layer does not come from vector tiles
  2. There aren't too many of them
Jukurrpa commented 3 years ago

Hijacking this comment section as I would have a similar need that could fall under the same feature request.

I was wondering if there was any way to ignore the icon padding in queryRenderedFeatures. While iJoris' request would be the ideal solution, having this as a first step would already be a good start for symbol layers with a fair amount of icon padding to avoid hovering/selecting icons that aren't actually under the cursor.

While this can be achieved with extra logic after queryRenderedFeatures, it requires keeping a list of the shape and size of every symbol used on the map which isn't great for maintainability. I tried to get help on stackoverflow to have a generic way of doing this but to no avail.

manafire commented 2 years ago

I was able to get better precision with HTML Markers using SVG images and the pointer-events css property to get better precision, but they suffer from jiggle when moving the map (due to pixel snapping issues I think).