Skip to content

Conversation

@depau
Copy link

@depau depau commented Sep 14, 2025

Hi!
This is a preliminary PoC implementation that adds handling of Z-index and polyline spans to the MapBox map implementation.

It isn't thoroughly tested, though it should fix some of the annoying glitches reported in #2382. Primarily it fixes my annoyance with Garmin Connect not actually displaying the run stats on the map.

I'm not a huge fan of the implementation, I basically did the least amount of work to get the feature going as a proof of concept to make sure this was even possible with the MapLibre API. If you'd like to integrate it I'm open to guidance and suggestions on how to properly implement it.

I also implemented JointType handling.

Before:
image

After:

image

Website (just as a reference, I currently don't have a device with GApps to test):

image

The reason why the colors are slightly different in this image is that I ran multiple times in the same spots. I'll need to compare with the Google Android implementation since I think their web implementation is a bit messy.

EDIT:

Google Maps vs microG:

image

I think the result is very acceptable.

@depau
Copy link
Author

depau commented Sep 14, 2025

A little explanation is probably necessary to understand some of the main choices:

  • To add multiple line segments I could have either split polylines into multiple polyline objects or, as I did, introduce support for multiple annotations into Markup. I went for the latter since I thought it would be the least effort.
  • I didn't put too much effort into cleaning up the code that performs polyline updates, it's probably not very efficient
  • With the version of MapLibre in use the only way to control the stacking of annotations is to create multiple managers, since each gets signed its layer id and since we can specify above/below which other layers it should go.
  • The routine that fetches the correct Line/Segment/Fill Manager for the given Z index uses a TreeMap to compute the layers stacking. The idea is that the underlying tree's inherent ordering properties make it easy to insert a layer at any position in the layer stack, determining the layer above/below quickly. The situation might get a bit messy when apps insert layers like crazy but my intuition is that the layer ordering should stay visually consistent.

@depau
Copy link
Author

depau commented Sep 15, 2025

I finally implemented geodesic polyline. Disclaimer: for this part I used AI extensively since I don't fully understand the math. If you'd rather exclude this let me know.

image

At this point I don't think there's a lot more functionality we're missing that can be implemented. Tile overlays are basically impossible to add, and respecting the user's requested start/end cap style is very cumbersome with the MapLibre API. So I think I'm done, once somebody gets the change to take a look I can clean it up and get it ready for upstreaming if you'd like to get these changes in.

@mar-v-in mar-v-in requested a review from fynngodau September 16, 2025 09:04
@mar-v-in mar-v-in added this to the 0.3.11 milestone Sep 24, 2025
@depau
Copy link
Author

depau commented Oct 15, 2025

Tile overlays are basically impossible to add,

Someone asked me over email why this is the case. As I was gathering the info to provide an answer I actually found a potential hacky way to implement it. Maybe next month if I have some time I can play with the idea.

This is my response I gave the person, for whoever may be interested:

[...]

I'm not sure whether the docs I'm providing are for the exact corresponding version of MapLibre but they still give an idea of how things work.

The way you add overlays in MapLibre/MapBox is by adding layers; the relevant layer is the RasterLayer, which can load images from various sources. However, the source can either be a bunch of static files you provide ahead of time, or a web server that serves imagery over HTTP.

On the other hand a Google Maps v2 API tile provider is a very simple class that implements a method that must return a tile given x+y+zoom.

A few links:

The reason why I think it might be possible is because I found out you can actually implement your own HTTP transport for HTTP tiles. So it may be possible to implement a custom HTTP transport that, when requesting images from an unlikely domain name, forges a response by calling the GMaps TileProvider locally, while forwarding the request to a proper HTTP client otherwise.

https://github.com/maplibre/maplibre-native/blob/main/platform/android/MapLibreAndroidTestApp/src/main/java/org/maplibre/android/testapp/utils/ExampleHttpRequestImpl.kt

@depau depau force-pushed the feature/mapbox-polyline-spans branch from 4d20102 to 7c6e79c Compare October 15, 2025 18:18
@fynngodau
Copy link
Member

@depau I had come to a similar rough conclusion w.r.t. implementing tile overlays, so overall I agree with this approach. Thanks for giving it further thought! Please do it in a separate PR though 😃

I'm intending on reviewing your changes from this PR but alas, time is short.

@depau
Copy link
Author

depau commented Oct 15, 2025

No rush, it doesn't look like the next CalyxOS release is going to come any time soon so I'll have to make do with black lines on Garmin Connect anyway :)

Sure, I'll do that in another PR, it shouldn't too hard to integrate any layer changes with these changes (assuming the overall design doesn't change too much over here)

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants