Closed Helium314 closed 3 weeks ago
It's not really important to be done immediately on start, we could e.g. delay it by 30 seconds.
I'll do this, and also upgrade to pre-6
maybe https://github.com/maplibre/maplibre-native/issues/2217 is fixed
I guess so, looks good now.
preset icons in shop overlay do not appear
Look like it's related to text. All overlays work, except places and addresses. Found 2 places in places overlay, a clothing shop and a vacant shop, both without a name. However, when I create a vacant or clothing shop it's not displayed in the overlay.
There is some other issue related to text. There are no addresses displayed at all, there are very few road names, and road names are hidden by quest dots (but not by the pins).
Is this caused by pre6? I hope so, otherwise it is might be some weird device-specific issue that is more difficult to find :-/
Also happens on pre-5. I'll try and go back to older versions to maybe find where it stopped working.
btw not loading any icons at all results in the map being displayed ~5 seconds after tapping the icon, instead of 6. So I get the impression there is limited gain from making everything run in parallel. For fast phones it's much faster anyway (as you reported), and slow phones probably don't have any unused of their 2-4 cores anyway (during startup).
[edit: nope, need to re-check it... actually it's working with de7bd79e8f87a9c278c05761655c5b8c9383b936. I'm confused, but ok.]
Weird thing. Apparently got fixed by going back to an older state... Everything working now on a fresh install.
Btw iconAllowOverlap
for overlays is true only at z19, while the +
button is already enabled at z18. I think the zoom levels should be aligned to avoid users not seeing mapped things and adding duplicates.
The overlay weirdness I sometimes noticed (see first post) is reproducible, at least for me:
Oh dear, I surely hope that the issue is on our end, because that sounds like a hell of a bug, difficult to debug / prove/reproduce to maplibre maintainers.
Two ideas:
The screenshot from https://github.com/Helium314/SCEE/pull/516#issuecomment-2067581158 is from current HEAD of this branch?
The screenshot from https://github.com/Helium314/SCEE/pull/516#issuecomment-2067581158 is from current HEAD of this branch?
Yes, I think you were asking for this in the SDF branch.
It is the only overlay that hides another layer when it is activated and un-hides when it is turned off. You could try commenting out this behavior to find if the issue is somehow caused by that.
Thanks! I guess that's a good place to start checking.
It is the only overlay that hides another layer when it is activated and un-hides when it is turned off. You could try commenting out this behavior to find if the issue is somehow caused by that.
Commenting override val hidesLayers = listOf("labels-housenumbers")
didn't help.
I even did a fresh install to make sure eveything is working / using only fresh data, only to stumble across the missing place overlay icons again... arrrgh
So, it can be reproduced without the address overlay?
So, it can be reproduced without the address overlay?
No, it only happens with the address overlay. But it happens even when I remove the hidesLayers
val that makes the address overlay unique in some sense.
No, it only happens with the address overlay. But it happens even when I remove the
hidesLayers
val that makes the address overlay unique in some sense.
But interestingly when I comment the code in MainMapFragment.onSelectedOverlayChanged
it works. Even though as far as I understand this should have the same effect as previouslyHiddenLayers
is always an empty list.
At this point (also considering my place overlay icons not showing bug) I'm not sure whether I want to trust the phone...
[edit: or possibly I shouldn't trust launching the app from Android Studio without a clean build?]
I would really like to understand this.
I added a short delay
between setting layer visibilities in MainMapFragment.onSelectedOverlayChanged
, and it worked, Then I removed the delay (reverted all my changes), uninstalled the app, and did a clean build and it still worked. I don't understand it at all.
It looks like a Heisenbug, then. I have to admit, I noticed this bug on my phone, also. I disregarded it then, because I was busy looking into other stuff and - one issue at a time. I think I remember that there was even an issue with quest pins, i.e. the circles were displayed but not the icons. Maybe I changed addImagesAsync
to addImages
or maybe I didn't do anything, then, don't quite remember. In any case, I disregarded it then because it looked like rather an issue with the *Manager class(es) which you were working on making superfluous at that time.
So, it seems worthwhile to me to prove that the *Manager classes cannot be the source of the bug before diving deeper into this. I.e. is the area that ought to be displayed retrieved by the manager? Is there anything we can say for sure about when or when the bug is reproducible? Doing clean Android build sounds like a good idea. Also, the thing with the manager,
Is there anything we can say for sure about when or when the bug is reproducible?
Not at all... Maybe it's still ok to put a small delay between setting layers visible and invisible? But currently I think this cannot actually have had any effect, because all overlays either hide nothing, or the housenumbers layer. In both cases, either nothing is set visible or nothing is set invisible, and thus the delay in between cannot make things suddenly work.
Do you have any idea where logging could be added that might help finding a pattern? I'm pretty certain the data is retrieved by the manager, but will add some test logging there.
quest pins: try replacing quest dots with clustering
I played a little with clustering, but without any results other than seeing fewer pins...
My guess is that a key is withClusterProperty
, but I don't understand it and couldn't find any example to copy from.
Maybe this is helpful? https://maplibre.org/maplibre-gl-js/docs/examples/cluster/
After all, all this Java typesafe API just wraps the JS/JSON-based api on maplibre-gl-js.
Is there anything we can say for sure about when or when the bug is reproducible?
Not at all...
Well. If we can't know the shape of the bug, maybe we can first ascertain what shape it isn't. It's not spherical, right? (I can very much recommend the short stories in the Antimemetics Division hub if you like this kind of literature, the stories by qntm have even been published as a book)
So, that's why I suggested to first check if the error could lie in the Managers, because if it doesn't, we can already exclude that as the source and move on.
Does it also affect quest pins? If not, we can check what are the differences between quest pins and icons in overlays. The halo? The fact that they are SDFs? The fact that they have (sometimes) text? Etc., and so you can cross off one possible cause after another after the number of suspects becomes smaller and smaller.
This video shows the bug you (and I) are seeing, right?
https://github.com/Helium314/SCEE/assets/4661658/090a86ca-f636-4adc-b97f-c3de82a1dc32
This video shows the bug you (and I) are seeing, right?
Not really. For you, there are just a few icons missing. The issue I had was no icons and no text, except for very few icons. Both of them had no name, thus no text to be expected. But other place icons without name were not shown, so it's not only connected to this.
Does it also affect quest pins?
No, pins have always been ok for me. It also happened before the SDF PR, and I think I had tried playing with halos as well. But since when it works I never know whether a change I made is responsible, I only can write down what I had when it didn't work.I'm ready for this, but now waiting for the bug to show up again...
To clarify, what I can very well reproduce in the emulator is the following:
I played around with it, disabled one feature after another until only simple icons+text for these icons was displayed. I.e. the following things can not be the cause of this because when disabling, the bug as shown in the above video persists:
.withProperties(iconImage(get("icon")), textField(get("label")))
Furthermore, I added a log whenever a StyleableOverlayManager::onNewTilesRect
is called, and as it turns out, the bug appearing (or disappearing again), i.e. icons not showing or suddenly showing after all coincides with calls to this function.
So, it is very likely that the issue is in StyleableOverlayManager
, or otherwise in MapLibre, but very unlikely in the style or how certain properties of the style are handled by MapLibre. The manager does have a lot of concurrency, maybe some assumptions that were true with tangram-es don't hold true for MapLibre anymore. Or maybe, it is even a race condition in MapLibre - e.g. the geojson is still being built when a new geojson should be pushed or something.
All I can say for almost certain at the moment is that the issue is definitely triggered by StyleableOverlayManager::onNewTilesRect
, whether the root issue lies in the manager, too, is something to be found out.
The manager does have a lot of concurrency, maybe some assumptions that were true with tangram-es don't hold true for MapLibre anymore. Or maybe, it is even a race condition in MapLibre - e.g. the geojson is still being built when a new geojson should be pushed or something.
That's a good point. I vaguely remember when I added the updateJob
that you said something like you only accept it because tangram is really slow when updating. This doesn't hold for MapLibre (well, maybe it does, but MapLibre internal stuff is happening on a different thread).
So we could try getting rid of the updateJob
and see how it goes.
Btw in case we get bored by the lack of hard to reproduce bugs: I just had a case when after a theme switch the quest pins were gone in some tiles, but not others. Circles were still there. Not sure what triggers it, so here what I know:
I see, well, it is a *Manager
, too. Maybe same root problem (that for some reason surfaces much more infrequently on the pins layer)
I am looking into the *Manager now to see if I find the cause of this.
Well, I didn't really find anything conclusive today. I found and fixed a few other things, as well as added performance improvements:
synchronized
within the suspending function on an IO thread (onNewTilesRect
) with a mutex. synchronized
blocks the IO thread, this could (have been) the source of a big performance bottleneckI noticed another possible performance improvement, but I am not sure how big it would be, if it will have a measurable effect. I didn't notice anything on my phone, but then again I have no performance issues at all. Currently, the sorting of quests plus creation of a GeoJson data structure is done on the UI thread. Same with overlays: The styled elements are mapped to GeoJson data structure on the UI thread. (StyledElement.toFeatures()
, Pin.toFeature()
)
Maybe you could try if this makes any difference on an older phone? I committed the change that puts the load on a background thread in the maplibre-suspend-component
s branch (in your repo).
Maybe you could try if this makes any difference on an older phone?
I'll give it a try tomorrow at best. Currently I'm in the process of switching to a different PC, and now I'm blocked by an extremely tightened screw holding the SSD in place...
Currently I'm in the process of switching to a different PC, and now I'm blocked by an extremely tightened screw holding the SSD in place...
😅
I created an issue for what I found regarding the vanishing icons:
I am not sure if this is the same issue you have been encountering. But on my phone, I cannot reproduce it, while on the emulator, I very reliably can.
The only thing I once or twice observed on my phone is that after install and launch of the app, some quest pins were missing while the quest dots were still visible. Not all quest pins were missing, only some. So, this sounds very much like exactly https://github.com/maplibre/maplibre-native/issues/2372 , with the difference that by zooming in, the quest pins didn't eventually appear at all (I didn't try zooming out). On the other hand, there seems to be no issue with quest pins on the emulator - which is weird, because they are just as much simple icons as the preset icons...
I also spent most of the day researching cause for issues that make it pretty impossible to test MapLibre on emulators, hmm 😕:
I also encountered this crash right now when I reentered the app after having it lying around long. Didn't investigate much further, something with Offline Regions. That's by now almost the only area I didn't get acquainted with.
Process: de.westnordost.streetcomplete.debug, PID: 5230 java.lang.IllegalStateException: Already resumed at kotlin.coroutines.SafeContinuation.resumeWith(SafeContinuationJvm.kt:44) at de.westnordost.streetcomplete.screens.main.map.maplibre.OfflineManagerKt$awaitDownload$2$1.onStatusChanged(OfflineManager.kt:81) at org.maplibre.android.offline.OfflineRegion$setObserver$1.onStatusChanged$lambda$0(OfflineRegion.kt:249) at org.maplibre.android.offline.OfflineRegion$setObserver$1.$r8$lambda$rUt7TfKIBCanK55ACsV3Si7sCqg(OfflineRegion.kt:0) at org.maplibre.android.offline.OfflineRegion$setObserver$1$$ExternalSyntheticLambda0.run(R8$$SyntheticClass:0) at android.os.Handler.handleCallback(Handler.java:958) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loopOnce(Looper.java:205) at android.os.Looper.loop(Looper.java:294) at android.app.ActivityThread.main(ActivityThread.java:8177) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)
I also encountered this crash right now when I reentered the app after having it lying around long. Didn't investigate much further, something with Offline Regions. That's by now almost the only area I didn't get acquainted with.
I never had this, but looks like onStatusChanged
may be called with status.isComplete
more than once for some reason.
Maybe you could try if this makes any difference on an older phone?
On the A3 there is no noticeable difference.
Creating mapLibreFeatures
for ~1000 pins usually takes between 5 and 15 ms, for ~1000 overlay features it's between 15 and 25 ms. [edit: measured time is about the same with and without suspend-component
changes]
Thanks! So I'll not pursue this further. I didn't commit it to the maplibre branch because I was not sure if it would be clean to have all these functions suspend. (Measured time is not meaningful here though, as it doesn't take less time, only less things are done on the UI thread. It's more about whether map updates look smooth or not.)
I also encountered this crash right now when I reentered the app after having it lying around long. Didn't investigate much further, something with Offline Regions. That's by now almost the only area I didn't get acquainted with.
The crash can be reproduced by starting a dowload where you don't already have map tiles, and disabling network connection right after start.
Then both onError
and onStatusChanged
with status complete are called, which triggers the crash.
The only solution I currently see is using a var resumed: Boolean
to avoid resuming twice.
Cool, thank you for investigating this! I guess this is expected behavior of MapLibre, because the status when an error is encountered does change - the download state becomes inactive.
I think awaitDownload
is also wrong for other reasons: It adds an observer to the OfflineRegion, but never removes the observer. So, I figure that this could/should also be solved by removing the observer once the first callback has been received.
(The API is a little odd here, all other methods accept an observer within the startDoingSomething
method itself)
if quest pin size has considerable impact on performance with MapLibre, a SCEE setting to half the size of quest pins would be conceivable (maybe some sort of ancient-phone-mode)
I'd like to try this on my S4 Mini, but even on much faster A3 there is a noticeably difference. Shrinking the bitmaps to 25%, and increasing the symbol scale and offsets accordingly, results in clearly smoother zooming, especially when zooming out at low zoom levels when pins start disappearing.
Oh, so the performance issue scales with the size of the source bitmap, rather than the actually displayed size of the bitmap?
By the way, we may need to downgrade maplibre to v10 again because of the two critical issues. Specificall, I don't expect the (for us) more critical issue of some icons sometimes not being displayed to get any love soon, as it has been flagged as a simulator
(only) issue.
Is there anything that we absolutely need from v11?
Oh, so the performance issue scales with the size of the source bitmap, rather than the actually displayed size of the bitmap?
Yes, definitely. You can probably trigger performance issues on your phone by increasing scale
in MapIcons
, and dividing iconSize
and multiplying iconOffset
in PinsMapComponent
by the same factor.
Is there anything that we absolutely need from v11?
I don't think so. I really hope the icon issue is not also present in v10 and we just overlooked it...
Actually, when I set the scale to anything above 3f, I get an OOM exception. I compared 3f with 1f and I am not sure, maybe there is a little difference.
I set the pin icon scale to 1 now. Better?
(missed the comment button)
Hmm, if we indeed only show clusters below a certain zoom level, e.g. 16, and above that use dots for pins that don't fit (I guess the dots could also be clickable and zoom in), we'd win back that the total amount of quests is shown for the clusters, not just the number of pins. Also, we save copying all to-be-displayed pins into a Set
and then also to a new List
(that's what distinctBy
does).
This has a few minor advantages too:
Arguably, the clusters at zoom 16 are also not all that interesting. For me, it mostly displays numbers between 2 and 4. Could just as well go with dots here.
We could also make the pin layer visible one or two zoom levels earlier (and fetch the data also at lower zoom levels). I tried it out, the performance is fine on my phone, but it should only be done if it is also smooth on yours.
Also, we save copying all to-be-displayed pins into a
Set
and then also to a newList
(that's whatdistinctBy
does).
I already had a look at this when I did the change, and found that it's ok even for many pins. Probably also for slower phones.
Arguably, the clusters at zoom 16 are also not all that interesting. For me, it mostly displays numbers between 2 and 4. Could just as well go with dots here.
Agree.
We could also make the pin layer visible one or two zoom levels earlier (and fetch the data also at lower zoom levels). I tried it out, the performance is fine on my phone, but it should only be done if it is also smooth on yours.
With one level earlier it's a noticeable difference, but could still be fine.
Btw for the same map area, with MapLibre much less detail is shown than with Tangram, especially fewer low priority roads:
Possibly this is intended, but it might be bad for using SC in rural areas, forests or mountains.
That's probably kind of intended and is likely due to the fade-in I added. I.e. many roads do not become visible immediately but fade in from 0% alpha to 100% alpha from e.g. zoom 12 to 13 (etc.)
clear cache directory after upgrade to MapLibre (aka clean old tiles folder)
I remember having issues with tile cache not being cleared (fully?) when it contained a lot of files. Maybe to be safe we should clear the folder more often than just on upgrade? There should not be any side effects when it's empty anyway.
For simple comparison with master, and for discussions.
to do
CustomGeometrySource
(draft started by @Helium314)~ blocked by at least maplibre-native#2262 and not strictly necessaryto do SCEE
upstream blockers
old observations below
Performance regarding icons (symbol layers, mostly about quest pins):
Other things:
This request was cancelled (https://api.jawg.io/glyphs/Roboto%20Regular%2cNoto%20Regular/0-255.pbf). This is expected for tiles that were being prefetched but are no longer needed for the map to render.
. It's not horrible, but downloading the same thing on every start seems like a waste of bandwidth and resources.