-
-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use CustomGeometrySource for quests and overlays #535
Conversation
Not having looked at the code yet, this is hopefully helpful:
|
Getting the |
Also happens when disabling an overlay, and then zooming, which is mildly annoying. I'm now checking whether there are issues with quest pins if a long way has pins in two different tiles. |
For vector tile sources it is possible to define from which to which zoom level they are available. If this is possible for the quest pin source and overlay source too, it could be made so that they are only available at one level. This would at least lead to that at the edges of tiles, it does not flash but stays consistently either rendered, or not rendered. |
There are cases where pins disappear when zooming in (I guess because pin is in same tile as quest (center) on z14, but not on z15. |
Is this what you mean? options = CustomGeometrySourceOptions()
.withMaxZoom(TILES_ZOOM)
.withMinZoom(TILES_ZOOM), That's the case for overlays. |
Yes |
I set the zoom for quest pins to 14 now, so at least pins now don't disappear on zoom in. |
How come you use 14 rather than TILE_ZOOM? |
When I use |
oh, too bad |
I noticed Btw with |
I'm not sure whether the |
I opened maplibre/maplibre-native#2262, maybe the issue in the sreenshot is just a bug. But if not, we should use the If you want I can add it for quests only, but we'll still have the sometimes missing pins for long ways. |
Are you sure that this is a bug in maplibre-native? To me, it looks like Maplibre is just querying the data tile-by-tile and since our CustomGeometrySource will just not return any line for the blue road on the lower-left tile, it is naturally not part of the tile.
|
But data exists in neighboring tiles and is clipped at tile boundaries, which in my understanding it should not. |
No, that's why in the linked issue I wrote "Is this a bug, or am I misunderstanding what withClip is doing?" |
Right, understood, you set |
That's what I was hoping for |
} | ||
).apply { | ||
maxOverscaleFactorForParentTiles = 10 // use data at higher zoom levels | ||
isVolatile = true |
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.
isVolatile=false here and for overlays could potentially improve performance, as documentation reads like other tiles will not be re-fetched when one tile changes. Worth trying it out, at least.
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.
I had planned some performance test possibly using different settings, and comparison with GeoJsonSource
, but if the issue in the screenshot can't be solved I don't need to bother...
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.
Mh, yeah, I mean, it could be solved anyway on our side, by having the bbox call return all the elements whose geometry intersects with the bbox, but that would require a lot of refactoring, especially also in the cache, plus, there were good reasons for why we changed it to the current behavior.
Another thing I noticed is that it is possible to pass null
for the GeometryTileProvider
in a CustomGeometrySource
. Any update would then need to be triggered manually with CustomGeometrySource::setTileData
. This would be pretty close to the solution we have now with the following differences:
- more complex, as we 1. need to calculate the tiles from the bbox in view and 2. slice up the data of that bbox manually into the tiles bboxes (because
withClip
doesn't work the way we thought it would) before repeatedly callingsetTileData
for the different tiles - when data is updated, only the tile(s) in which the changed element(s) is/are contained need to be updated
Whether this is a performance improvement at all hinges on whether re-setting all data vs re-setting it only in one tile (on each edit) does actually make a difference, performance-wise. (Who knows, maybe internally, the whole data is pushed to the GPU anyway).
For this reason, I think it is worthwhile to compare the performance of the current approach with CustomGeometrySource
even if there is this rendering issue from the screenshot right now.
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.
when data is updated, only the tile(s) in which the changed element(s) is/are contained need to be updated
But can't we achieve this by only invalidating the region covered by the update?
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.
Another thing I noticed is that it is possible to pass null for the GeometryTileProvider in a CustomGeometrySource
While technically it's possible, this is useless as it results in an NPE.
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.
I did a very basic performance comparison. Note that this does not include MapLibre internal stuff, this appears to happen on a different thread (was blocking on Tangram).
CustomGeometrySource
- enabling of the overlay (nothing in cache), 4 tiles: 4 updates running in parallel, last one finished after 2.1s. There is a clear tile-by-tile buildup visible.
- disable and enable the overlay: 4 updates in parallel, last one finished after 0.1s
- move to the next tiles: 2 updates in parallel, last one finished after 0.5s. Didn't notice tile-by-tile buildup.
GeoJsonSource
- enabling of the overlay (nothing in cache), 4 tiles: finished after 1.6s
- disable and enable the overlay: finished aftr 0.2s
- move to the next tiles: finished after 0.4s
Fetching the map data for more than a single tile is faster with GeoJsonSource
, but that's expected.
My feeling is that also the visual response (i.e. including MapLibre internal data updates) is faster with GeoJsonSource
. For disabling and enabling the overlay I didn't notice a clear difference.
The tile-by-tile buildup of CustomGeometrySource
doesn't look appealing, but I think it would be acceptable.
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.
What's also relevant is the time for a single edit to one element to go through, as this is the (one) point where CustomGeometrySource should be much faster (as only one tile should be updated, rather than all that is in view and more)
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.
Test with 64 tiles in cache after scrolling around, at lowest possible zoom where overlays are still displayed, in a well mapped city center (probably worst possible case for GeoJsonSource
).
For GeoJsonSource
the update takes 60 ms, updated overlay is visible after estimated 0.2 to 0.4 s.
For CustomGeometrySource
the update (calculating bbox and fetching map date) takes ~100 ms (because styled elements are not cached), updated overlay is visible after estimated 0.1 to 0.2 s (definitely faster than with GeoJsonSource
).
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.
The update after the user edited something is the most important statistic, IMO, because it is done a lot and is part of the user workflow.
In tangram-es, the update of the pins / overlay was quite noticeable because I think something was done on the UI thread, leading to jerky camera-zoom-back animation, and there was a flicker visible.
In MapLibre, I noticed neither, so while up to 300ms (=usual animation time in Android) is in a range of what may be noticed, your measurements and the fact that MapLibre does not flicker when updating the geojson source make me think that we don't really need CustomGeometrySource
. It would only be worthwhile if this method could be deployed without issues and leads to less code on our side.
What's your opinion on this?
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.
I think a CustomGeometrySource
would be really nice to have, mainly because we could kick out a lot of code (also I'd like to do a performance comparison on S4 Mini, but...).
With the current issues with CustomGeometrySource
and with the current code working well with GeoJsonSource
, I think we could just leave it as it is for now. GeoJsonSource
simply works well enough.
Switching to CustomGeometrySource
can still be done at a later point, and I think it's worth trying again (also depending on whether the withClip
thing really is a bug and gets fixed).
I'll close this as it's not necessary for reasonable performance. We can still have a look at it later (definitiely after maplibre/maplibre-native#2262) |
@westnordost I'll try this in a separate branch, so both versions are easier to compare.
Currently I'm not sure how to best arrange
QuestPinsManager
andPinsMapComponent
, but haven't had much time to think it through.Overlays are still missing, but should work very similar to quests.