Skip to content

Conversation

@michalgwo
Copy link
Collaborator

Fixes #28

I implemented snapshot functionality for Android and iOS. There is no snapshotter in the MapLibre GL JS library, so I left it empty.

I also created a demo presenting snapshot functionality.

As for iOS, as I already mentioned in my previous PRs, I don't have a Mac, so I couldn't run it, but this time I tried my best to implement it for iOS as well, but as it's not tested, and I don't have any experience with iOS, it may not work 😅 Let me know if you are not interested in fixing it, so I will remove the iOS part, and leave only Android implementation.

A few remarks about the iOS implementation:

  • I wasn't sure what size should I use for CameraPosition.toMLNCamera(), so I took my shot and used the same as the size of the snapshot
  • on Android cameraPosition param for snapshotter options is nullable, but on iOS it's not, I'm not sure if it's the best solution, but I made it nullable in common code and on iOS created a new empty MLNMapCamera() when cameraPosition is null
  • I'm not sure about the error handling, I couldn't find any information in the documentation on what's inside the String returned on Android and NSError returned on iOS. I also failed to make the snapshotter return error, so I have no idea what kind of error is there.
  • the function for converting UIImage to ImageBitmap is not written by me, I took it from this article

@sargunv
Copy link
Collaborator

sargunv commented Feb 2, 2025

Thanks for this! Currently planning on reviewing next week or so.

@sargunv sargunv added this to the v0.7.0 milestone Feb 2, 2025
@michalgwo
Copy link
Collaborator Author

Thank you for your review, I fixed all the things you mentioned.

Copy link
Collaborator

@westnordost westnordost left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Super clean implementation

@michalgwo
Copy link
Collaborator Author

👍

Super clean implementation

Appreciate your review! Did you test it on iOS? As I mentioned, I didn't, because I don't have a Mac right now. I will probably get one in a couple of weeks, so if there is any problem, I can fix it.

@westnordost
Copy link
Collaborator

I didn't test anything, just read the code.

@westnordost
Copy link
Collaborator

westnordost commented May 24, 2025 via email

@michalgwo
Copy link
Collaborator Author

That sounds like a good use case for a sealed interface!

I can imagine a scenario when someone wants to set both cameraPosition and region, for example, when they have a BoundingBox of the region, but want it rotated/tilted, which needs to be set with cameraPosition.

@westnordost
Copy link
Collaborator

westnordost commented May 24, 2025 via email

@michalgwo
Copy link
Collaborator Author

That's... possible? after all, with tilt or camera rotation , the displayed area is not a bbox anymore. I'd presume that if a camera position is specified, at least if it has any rotation or tilt, the camera position takes precedence and the bbox is discarded(?)

According to the documentation, when region and CameraPosition are set in conjunction, the CameraPosition.target is overridden by region. I don't know how it works under the hood, but my understanding is that the other CameraPosition params like tilt, rotation, etc. are applied.

I just tested setting region (BoundingBox) with CameraPosition, which was rotated and tilted, and it works. The snapshot was rotated and tiled area from the BoundingBox. I was also trying zoom and padding, but it seems these don't have any effect on the snapshot.

@sargunv
Copy link
Collaborator

sargunv commented May 25, 2025

I just tested setting region (BoundingBox) with CameraPosition, which was rotated and tilted, and it works. The snapshot was rotated and tiled area from the BoundingBox. I was also trying zoom and padding, but it seems these don't have any effect on the snapshot.

Perhaps our parameters should be bounding box or position/zoom, with optional bearing and tilt?

@sargunv
Copy link
Collaborator

sargunv commented May 25, 2025

This, plus the attribution state stuff, is making me think the style URL and style composition should be something passed into the style state rather than into the map. And then, the user can initialize a camera + style state however they wish, and pass those two into either a map, or a snapshotter, or both

@sargunv sargunv modified the milestones: v0.8.0, v0.9.0 May 26, 2025
@sargunv sargunv modified the milestones: v0.9.0, 0.10.0 Jun 14, 2025
@sargunv sargunv self-assigned this Jun 14, 2025
@sargunv
Copy link
Collaborator

sargunv commented Jun 14, 2025

Relevant comment at #374 (comment)

My suggestion to support StyleState with programmatic styling is possible in Android but not in iOS without upstream MapLibre Native changes. So I think we can merge without that for now, and file issues to request that feature upstream for MapLibre iOS.

I'll take this PR to the finish line and then release v0.9.0 and file the MapLibre Native issues. after that style state refactor.

@sargunv
Copy link
Collaborator

sargunv commented Jun 14, 2025

Ah nope I was wrong; programmatic styling is available in iOS: #374 (comment)

So yeah, back to the original plan to land this after our style state refactor so we can use it here.

@sargunv sargunv added the blocked The issue or PR is blocked by another issue label Jun 14, 2025
@sargunv sargunv marked this pull request as draft June 14, 2025 06:43
@sargunv sargunv modified the milestones: v0.9.0, 0.10.0 Jun 14, 2025
@sargunv sargunv modified the milestones: 0.10.0, v0.11.0 Jul 10, 2025
@sargunv sargunv changed the title Map snapshotter wip: map snapshotter Jul 26, 2025
@sargunv sargunv removed this from the v0.12.0 milestone Sep 2, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

blocked The issue or PR is blocked by another issue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support snapshots

3 participants