-
Notifications
You must be signed in to change notification settings - Fork 1.3k
[core] Fix shape annotations disappearing after maxZoom-1 #5418
Conversation
3a524bd
to
0fe4651
Compare
Adding to 4.1 milestone as a potential cherrypick before release. |
👍 |
@brunoabinader Is it possible to explain why it fixes the problem? 1 <<max zoom is equivalent to pow (2, maxzoom)? Was it 32 bit overflow? Is there a compiler option that could have caught this. On java side Android studio shows a warning for code like this. |
It was indeed overflow. Clang's static analyzer should catch issues like this. Unfortunately, we're unable to run the analyzer in CI due to the time it takes, so we have to manually run it periodically to catch these issues. |
@mb12 you are right - there is a certain amount of flakiness when testing zooming in between zoom 19 and 20 that I'm still getting: until z19 it works fine, between z19 and z20 it disappears and exactly on z20 it works again. |
Yes, that same flakiness is in master too. |
Here's a similar case. Can this overflow? |
@jfirebaugh yes - see the example below:
In this case, GCC was able to catch the overflow:
Interestingly, if we switch that value to 31, we get However, concerning our code I believe 1) we shouldn't be using signed types for values like this and 2) |
As discussed with @tobrun, this won't make it to android 4.1.0, removing milestone tag. |
Any idea what release this fix will be publish to? |
we could just use |
I realized that the issue disappears once |
755cc80 did not change the maximum zoom behavior for That said, I'm not aware of any reason why the maximum zoom needs to be 22, though I seem to recall some discussion of the appropriate maximum zoom for GeoJSON sources, which are closely related. Currently they use the default value of 18 from |
0fe4651
to
1bdd801
Compare
Neat and thanks for adding more tests. |
@@ -81,7 +81,7 @@ class TransformState { | |||
|
|||
// Limit the amount of zooming possible on the map. | |||
double min_scale = std::pow(2, 0); | |||
double max_scale = std::pow(2, 20); | |||
double max_scale = std::pow(2, 22); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this not clamped at util::MAX_ZOOM
? (I know it wasn't before, just curious)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that GL JS also uses |
1bdd801
to
15d7611
Compare
32 bit integers should be enough for zoom scale logic. In shape annotation logic, 'maxAmountOfTileFeatures' requires 64 bits because we are multiplying the zoom scale with the extent, which might give a number higher than std::numeric_limits<uint32_t>::max().
15d7611
to
33a8856
Compare
It was initially 14 and this was too low. 18 is probably okayish for most cases but I don't see any reason this couldn't go even further — it doesn't affect performance much, but increases detalization. |
Tested on both iOS and Android test applications @ master. |
@brunoabinader Wouldn't this result in inaccurate placement/positioning of marker at zoom level > 18? The following will not work.
Since the error increases by a power of 2 in both x and y with every zoom level increase, wouldn't this error be unacceptably high at zoom 22? |
This caused a regression in world wrapping: #5648. |
Each tile has a 8192 extent; if a 512px z18 tile is zoomed to z22, this gives exactly Also note that maximum possible error due to rounding of a z18 tile to a 8192 grid is |
Fixes #5138.
👀 @kkaefer @jfirebaugh @1ec5