diff options
Diffstat (limited to 'platform/macos/app/MapDocument.m')
-rw-r--r-- | platform/macos/app/MapDocument.m | 158 |
1 files changed, 139 insertions, 19 deletions
diff --git a/platform/macos/app/MapDocument.m b/platform/macos/app/MapDocument.m index f494c91c18..36ca4ad228 100644 --- a/platform/macos/app/MapDocument.m +++ b/platform/macos/app/MapDocument.m @@ -3,6 +3,7 @@ #import "AppDelegate.h" #import "LimeGreenStyleLayer.h" #import "DroppedPinAnnotation.h" +#import "MGLMapsnapshotter.h" #import "MGLStyle+MBXAdditions.h" #import "MGLVectorSource+MGLAdditions.h" @@ -73,6 +74,9 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio BOOL _isTouringWorld; BOOL _isShowingPolygonAndPolylineAnnotations; BOOL _isShowingAnimatedAnnotation; + + // Snapshotter + MGLMapSnapshotter* snapshotter; } #pragma mark Lifecycle @@ -153,6 +157,67 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio camera.heading, camera.pitch]]; } +#pragma mark File methods + +- (IBAction)takeSnapshot:(id)sender { + MGLMapCamera *camera = self.mapView.camera; + + MGLMapSnapshotOptions* options = [[MGLMapSnapshotOptions alloc] initWithStyleURL:self.mapView.styleURL camera:camera size:self.mapView.bounds.size]; + options.zoom = self.mapView.zoomLevel; + + // Create and start the snapshotter + snapshotter = [[MGLMapSnapshotter alloc] initWithOptions:options]; + [snapshotter startWithCompletionHandler: ^(NSImage *image, NSError *error) { + if (error) { + NSLog(@"Could not load snapshot: %@", [error localizedDescription]); + } else { + NSWindow* window = [[[self windowControllers] objectAtIndex:0] window]; + + NSString* newName = [[@"snapshot" stringByDeletingPathExtension] stringByAppendingPathExtension:@"png"]; + + // Set the default name for the file and show the panel. + NSSavePanel* panel = [NSSavePanel savePanel]; + [panel setNameFieldStringValue:newName]; + [panel beginSheetModalForWindow:window completionHandler:^(NSInteger result){ + if (result == NSFileHandlingPanelOKButton) { + // Write the contents in the new format. + NSURL* fileURL = [panel URL]; + + NSBitmapImageRep *bitmapRep = nil; + for (NSImageRep *imageRep in [image representations]) { + if ([imageRep isKindOfClass:[NSBitmapImageRep class]]){ + bitmapRep = (NSBitmapImageRep *)imageRep; + break; // stop on first bitmap rep we find + } + } + + if (!bitmapRep) { + bitmapRep = [NSBitmapImageRep imageRepWithData:[image TIFFRepresentation]]; + + } + + NSString *extension = [[fileURL pathExtension] lowercaseString]; + NSBitmapImageFileType fileType; + if ([extension isEqualToString:@"png"]) { + fileType = NSPNGFileType; + } else if ([extension isEqualToString:@"gif"]) { + fileType = NSGIFFileType; + } else if ([extension isEqualToString:@"jpg"] || [extension isEqualToString:@"jpeg"]) { + fileType = NSJPEGFileType; + } else { + fileType = NSTIFFFileType; + } + + NSData *imageData = [bitmapRep representationUsingType:fileType properties:@{}]; + [imageData writeToURL:fileURL atomically:NO]; + } + }]; + + } + snapshotter = nil; + }]; +} + #pragma mark View methods - (IBAction)showStyle:(id)sender { @@ -572,6 +637,37 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio cos(angle) * 20); } +- (IBAction) addAnimatedImageSource:(id)sender { + + MGLImage *image = [[NSBundle bundleForClass:[self class]] imageForResource:@"southeast_0"]; + + MGLCoordinateBounds bounds = { {22.551103322318994, -90.24006072802854}, {36.928147474567794, -75.1441643681673} }; + MGLImageSource *imageSource = [[MGLImageSource alloc] initWithIdentifier:@"animated-radar-source" coordinateQuad:MGLCoordinateQuadFromCoordinateBounds(bounds) image:image]; + [self.mapView.style addSource:imageSource]; + + MGLRasterStyleLayer * imageLayer = [[MGLRasterStyleLayer alloc] initWithIdentifier:@"animated-radar-layer" source:imageSource]; + [self.mapView.style addLayer:imageLayer]; + + [NSTimer scheduledTimerWithTimeInterval:1.0 + target:self + selector:@selector(updateAnimatedImageSource:) + userInfo:imageSource + repeats:YES]; +} + + +- (void)updateAnimatedImageSource:(NSTimer *)timer { + static int radarSuffix = 0; + MGLImageSource *imageSource = (MGLImageSource *)timer.userInfo; + + MGLImage *image = [[NSBundle bundleForClass:[self class]] imageForResource:[NSString stringWithFormat:@"southeast_%d", radarSuffix++]]; + [imageSource setValue:image forKey:@"image"]; + + if(radarSuffix > 3) { + radarSuffix = 0 ; + } +} + - (IBAction)insertCustomStyleLayer:(id)sender { [self.undoManager registerUndoWithTarget:self handler:^(id _Nonnull target) { [self removeCustomStyleLayer:sender]; @@ -650,40 +746,58 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio MGLTransition transition = { .duration = 5, .delay = 1 }; self.mapView.style.transition = transition; - MGLFillStyleLayer *fillStyleLayer = (MGLFillStyleLayer *)[self.mapView.style layerWithIdentifier:@"water"]; - + MGLStyleLayer *waterLayer = [self.mapView.style layerWithIdentifier:@"water"]; MGLStyleValue *colorFunction = [MGLStyleValue<NSColor *> valueWithInterpolationMode:MGLInterpolationModeExponential cameraStops:@{ @0.0: [MGLStyleValue<NSColor *> valueWithRawValue:[NSColor redColor]], @10.0: [MGLStyleValue<NSColor *> valueWithRawValue:[NSColor yellowColor]], @20.0: [MGLStyleValue<NSColor *> valueWithRawValue:[NSColor blackColor]], } options:nil]; - fillStyleLayer.fillColor = colorFunction; + + if ([waterLayer respondsToSelector:@selector(fillColor)]) { + [waterLayer setValue:colorFunction forKey:@"fillColor"]; + } else if ([waterLayer respondsToSelector:@selector(lineColor)]) { + [waterLayer setValue:colorFunction forKey:@"lineColor"]; + } NSString *filePath = [[NSBundle bundleForClass:self.class] pathForResource:@"amsterdam" ofType:@"geojson"]; NSURL *geoJSONURL = [NSURL fileURLWithPath:filePath]; MGLShapeSource *source = [[MGLShapeSource alloc] initWithIdentifier:@"ams" URL:geoJSONURL options:nil]; [self.mapView.style addSource:source]; - MGLFillStyleLayer *fillLayer = [[MGLFillStyleLayer alloc] initWithIdentifier:@"test" source:source]; - fillLayer.fillColor = [MGLStyleValue<NSColor *> valueWithRawValue:[NSColor greenColor]]; - fillLayer.predicate = [NSPredicate predicateWithFormat:@"%K == %@", @"type", @"park"]; - [self.mapView.style addLayer:fillLayer]; + MGLCircleStyleLayer *circleLayer = [[MGLCircleStyleLayer alloc] initWithIdentifier:@"test" source:source]; + circleLayer.circleColor = [MGLStyleValue<NSColor *> valueWithRawValue:[NSColor greenColor]]; + circleLayer.circleRadius = [MGLStyleValue<NSNumber *> valueWithRawValue:[NSNumber numberWithInteger:40]]; +// fillLayer.predicate = [NSPredicate predicateWithFormat:@"%K == %@", @"type", @"park"]; + [self.mapView.style addLayer:circleLayer]; + MGLSource *streetsSource = [self.mapView.style sourceWithIdentifier:@"composite"]; + if (streetsSource) { NSImage *image = [NSImage imageNamed:NSImageNameIChatTheaterTemplate]; [self.mapView.style setImage:image forName:NSImageNameIChatTheaterTemplate]; - MGLSource *streetsSource = [self.mapView.style sourceWithIdentifier:@"composite"]; - MGLSymbolStyleLayer *theaterLayer = [[MGLSymbolStyleLayer alloc] initWithIdentifier:@"theaters" source:streetsSource]; - theaterLayer.sourceLayerIdentifier = @"poi_label"; - theaterLayer.predicate = [NSPredicate predicateWithFormat:@"maki == 'theatre'"]; - theaterLayer.iconImageName = [MGLStyleValue valueWithRawValue:NSImageNameIChatTheaterTemplate]; - theaterLayer.iconScale = [MGLStyleValue valueWithRawValue:@2]; - theaterLayer.iconColor = [MGLStyleValue valueWithInterpolationMode:MGLInterpolationModeExponential cameraStops:@{ - @16.0: [MGLStyleValue valueWithRawValue:[NSColor redColor]], - @18.0: [MGLStyleValue valueWithRawValue:[NSColor yellowColor]], - @20.0: [MGLStyleValue valueWithRawValue:[NSColor blackColor]], - } options:nil]; - [self.mapView.style addLayer:theaterLayer]; + MGLSymbolStyleLayer *theaterLayer = [[MGLSymbolStyleLayer alloc] initWithIdentifier:@"theaters" source:streetsSource]; + theaterLayer.sourceLayerIdentifier = @"poi_label"; + theaterLayer.predicate = [NSPredicate predicateWithFormat:@"maki == 'theatre'"]; + theaterLayer.iconImageName = [MGLStyleValue valueWithRawValue:NSImageNameIChatTheaterTemplate]; + theaterLayer.iconScale = [MGLStyleValue valueWithRawValue:@2]; + theaterLayer.iconColor = [MGLStyleValue valueWithInterpolationMode:MGLInterpolationModeExponential cameraStops:@{ + @16.0: [MGLStyleValue valueWithRawValue:[NSColor redColor]], + @18.0: [MGLStyleValue valueWithRawValue:[NSColor yellowColor]], + @20.0: [MGLStyleValue valueWithRawValue:[NSColor blackColor]], + } options:nil]; + [self.mapView.style addLayer:theaterLayer]; + } + + NSURL *imageURL = [NSURL URLWithString:@"https://www.mapbox.com/mapbox-gl-js/assets/radar.gif"]; + MGLCoordinateQuad quad = { {46.437, -80.425}, + {37.936, -80.425}, + {37.936, -71.516}, + {46.437, -71.516} }; + MGLImageSource *imageSource = [[MGLImageSource alloc] initWithIdentifier:@"radar-source" coordinateQuad:quad URL:imageURL]; + [self.mapView.style addSource:imageSource]; + + MGLRasterStyleLayer * imageLayer = [[MGLRasterStyleLayer alloc] initWithIdentifier:@"radar-layer" source:imageSource]; + [self.mapView.style addLayer:imageLayer]; } - (IBAction)dropPin:(NSMenuItem *)sender { @@ -892,6 +1006,9 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio if (menuItem.action == @selector(drawAnimatedAnnotation:)) { return !_isShowingAnimatedAnnotation; } + if (menuItem.action == @selector(addAnimatedImageSource:)) { + return YES; + } if (menuItem.action == @selector(insertCustomStyleLayer:)) { return ![self.mapView.style layerWithIdentifier:@"mbx-custom"]; } @@ -911,6 +1028,9 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio if (menuItem.action == @selector(giveFeedback:)) { return YES; } + if (menuItem.action == @selector(takeSnapshot:)) { + return !(snapshotter && [snapshotter isLoading]); + } return NO; } |