-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Add map snapshot API #1701
Comments
mbgl is already capable of static rendering. Instead of running that same code on the server, we should just expose static rendering mode in the Cocoa later. |
^^ Cool. Yeah, if we can accomplish this on device let's build the MapKit mirroring API that way. 👍 |
AFAICT this will be using one or both of Performance might also be an issue here, but I guess it depends on the use cases for the snapshot (e.g. a simple dummy overlay view for transitions vs. something needing to be more performant like a blur). |
The other interesting bit will be determining if all tiles are loaded to the best of our ability before capturing, so #1804 becomes relevant. |
An interim solution is to do basic snapshotting yourself. This will get you the base map, annotations, and the map view UI. Objective-C: - (UIImage *)snapshot:(UIView *)view {
UIGraphicsBeginImageContextWithOptions(view.bounds.size, YES, 0);
[view drawViewHierarchyInRect:view.bounds afterScreenUpdates:YES];
UIImage *snapshot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return snapshot;
} Swift: func snapshot(view: UIView) -> UIImage {
UIGraphicsBeginImageContextWithOptions(view.bounds.size, true, 0)
view.drawViewHierarchyInRect(view.bounds, afterScreenUpdates: true)
let snapshot = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return snapshot
} (Rehashing my Stack Overflow answer.) |
@friedbunny -(void)viewDidLoad {
MGLMapView *mapView = [[MGLMapView alloc] initWithFrame:self.view.frame];
[self.view addSubview:mapView];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[mapView removeFromSuperview];
UIImageView *snapShotImgView = [[UIImageView alloc]initWithImage:[self snapshot:mapView]];
snapShotImgView.frame = self.view.frame;
[self.view addSubview:snapShotImgView];
});
} |
@TWDdpigram Initiating the manual snapshot in |
@friedbunny does visually ready means all the elements in the map are already rendered on top of it? I've tried taking a snapshot of an MGLMapView using the code suggested inside of its delegate's Here are some examples of what I'm getting: |
@jcarlos-p It appears that [self performSelector:@selector(snapshot:) withObject:mapView afterDelay:0]; |
@friedbunny Can the sample code be safely executed while the app is in the background ? We found a problem where we execute this code but if the App is in the background, the map snapshot would come back completely black. |
@jcarlos-p I wouldn’t expect MGLMapView to render anything if the app is not in the foreground. We’ve had crashes related to instantiating a GL context in the background and currently guard against this happening. As others have touched on on this thread, how to accomplish off-screen rendering is the main hurdle that needs to be addressed for this feature to move forward. |
That's what I thought. Thanks for the clarification. We'll just put a workaround in place then. |
@jcarlos-p just wondering if you could share your workaround for this? We also need to render our map in the background so that it can be included in a UNNotificationAttachment (this, in turn, is a workaround for #6230 – Mapbox doesn't work in a Notification Extension). We're currently using MapboxStatic to accomplish this, but the results are not nearly as pretty and are tied to the old Classic API's/styles. |
@quicklywilliam We had to go the static API way also :( |
Accidentally closed by errant verbiage in mapbox/MapboxStatic.swift#54. |
lol, if only it were so simple! |
iOS prohibits OpenGL operations when the application is in the background: https://developer.apple.com/library/content/documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/ImplementingaMultitasking-awareOpenGLESApplication/ImplementingaMultitasking-awareOpenGLESApplication.html |
Just for a note for someone else trying to achieve the same thing. I have to directly use |
To achieve closer parity with Apple's MapKit, Mapbox GL should have a corresponsding MKMapSnapshotter API for asynchronously loading map imagery. This will likely just mean providing a cleaner API around the Mapbox Static Images API.
The text was updated successfully, but these errors were encountered: