blob: 5863697d7b9b0c8323d2724531b0ce7a8ae17ab5 [file] [log] [blame]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "FLTGoogleMapTileOverlayController.h"
#import "FLTGoogleMapJSONConversions.h"
@interface FLTGoogleMapTileOverlayController ()
@property(strong, nonatomic) GMSTileLayer *layer;
@property(weak, nonatomic) GMSMapView *mapView;
@end
@implementation FLTGoogleMapTileOverlayController
- (instancetype)initWithTileLayer:(GMSTileLayer *)tileLayer
mapView:(GMSMapView *)mapView
options:(NSDictionary *)optionsData {
self = [super init];
if (self) {
_layer = tileLayer;
_mapView = mapView;
[self interpretTileOverlayOptions:optionsData];
}
return self;
}
- (void)removeTileOverlay {
self.layer.map = nil;
}
- (void)clearTileCache {
[self.layer clearTileCache];
}
- (NSDictionary *)getTileOverlayInfo {
NSMutableDictionary *info = [[NSMutableDictionary alloc] init];
BOOL visible = self.layer.map != nil;
info[@"visible"] = @(visible);
info[@"fadeIn"] = @(self.layer.fadeIn);
float transparency = 1.0 - self.layer.opacity;
info[@"transparency"] = @(transparency);
info[@"zIndex"] = @(self.layer.zIndex);
return info;
}
- (void)setFadeIn:(BOOL)fadeIn {
self.layer.fadeIn = fadeIn;
}
- (void)setTransparency:(float)transparency {
float opacity = 1.0 - transparency;
self.layer.opacity = opacity;
}
- (void)setVisible:(BOOL)visible {
self.layer.map = visible ? self.mapView : nil;
}
- (void)setZIndex:(int)zIndex {
self.layer.zIndex = zIndex;
}
- (void)setTileSize:(NSInteger)tileSize {
self.layer.tileSize = tileSize;
}
- (void)interpretTileOverlayOptions:(NSDictionary *)data {
if (!data) {
return;
}
NSNumber *visible = data[@"visible"];
if (visible != nil && visible != (id)[NSNull null]) {
[self setVisible:visible.boolValue];
}
NSNumber *transparency = data[@"transparency"];
if (transparency != nil && transparency != (id)[NSNull null]) {
[self setTransparency:transparency.floatValue];
}
NSNumber *zIndex = data[@"zIndex"];
if (zIndex != nil && zIndex != (id)[NSNull null]) {
[self setZIndex:zIndex.intValue];
}
NSNumber *fadeIn = data[@"fadeIn"];
if (fadeIn != nil && fadeIn != (id)[NSNull null]) {
[self setFadeIn:fadeIn.boolValue];
}
NSNumber *tileSize = data[@"tileSize"];
if (tileSize != nil && tileSize != (id)[NSNull null]) {
[self setTileSize:tileSize.integerValue];
}
}
@end
@interface FLTTileProviderController ()
@property(strong, nonatomic) FlutterMethodChannel *methodChannel;
@end
@implementation FLTTileProviderController
- (instancetype)init:(FlutterMethodChannel *)methodChannel
withTileOverlayIdentifier:(NSString *)identifier {
self = [super init];
if (self) {
_methodChannel = methodChannel;
_tileOverlayIdentifier = identifier;
}
return self;
}
#pragma mark - GMSTileLayer method
- (void)requestTileForX:(NSUInteger)x
y:(NSUInteger)y
zoom:(NSUInteger)zoom
receiver:(id<GMSTileReceiver>)receiver {
[self.methodChannel
invokeMethod:@"tileOverlay#getTile"
arguments:@{
@"tileOverlayId" : self.tileOverlayIdentifier,
@"x" : @(x),
@"y" : @(y),
@"zoom" : @(zoom)
}
result:^(id _Nullable result) {
UIImage *tileImage;
if ([result isKindOfClass:[NSDictionary class]]) {
FlutterStandardTypedData *typedData = (FlutterStandardTypedData *)result[@"data"];
if (typedData == nil) {
tileImage = kGMSTileLayerNoTile;
} else {
tileImage = [UIImage imageWithData:typedData.data];
}
} else {
if ([result isKindOfClass:[FlutterError class]]) {
FlutterError *error = (FlutterError *)result;
NSLog(@"Can't get tile: errorCode = %@, errorMessage = %@, details = %@",
[error code], [error message], [error details]);
}
if ([result isKindOfClass:[FlutterMethodNotImplemented class]]) {
NSLog(@"Can't get tile: notImplemented");
}
tileImage = kGMSTileLayerNoTile;
}
[receiver receiveTileWithX:x y:y zoom:zoom image:tileImage];
}];
}
@end
@interface FLTTileOverlaysController ()
@property(strong, nonatomic) NSMutableDictionary *tileOverlayIdentifierToController;
@property(strong, nonatomic) FlutterMethodChannel *methodChannel;
@property(weak, nonatomic) GMSMapView *mapView;
@end
@implementation FLTTileOverlaysController
- (instancetype)init:(FlutterMethodChannel *)methodChannel
mapView:(GMSMapView *)mapView
registrar:(NSObject<FlutterPluginRegistrar> *)registrar {
self = [super init];
if (self) {
_methodChannel = methodChannel;
_mapView = mapView;
_tileOverlayIdentifierToController = [[NSMutableDictionary alloc] init];
}
return self;
}
- (void)addTileOverlays:(NSArray *)tileOverlaysToAdd {
for (NSDictionary *tileOverlay in tileOverlaysToAdd) {
NSString *identifier = [FLTTileOverlaysController identifierForTileOverlay:tileOverlay];
FLTTileProviderController *tileProvider =
[[FLTTileProviderController alloc] init:self.methodChannel
withTileOverlayIdentifier:identifier];
FLTGoogleMapTileOverlayController *controller =
[[FLTGoogleMapTileOverlayController alloc] initWithTileLayer:tileProvider
mapView:self.mapView
options:tileOverlay];
self.tileOverlayIdentifierToController[identifier] = controller;
}
}
- (void)changeTileOverlays:(NSArray *)tileOverlaysToChange {
for (NSDictionary *tileOverlay in tileOverlaysToChange) {
NSString *identifier = [FLTTileOverlaysController identifierForTileOverlay:tileOverlay];
FLTGoogleMapTileOverlayController *controller =
self.tileOverlayIdentifierToController[identifier];
if (!controller) {
continue;
}
[controller interpretTileOverlayOptions:tileOverlay];
}
}
- (void)removeTileOverlayWithIdentifiers:(NSArray *)identifiers {
for (NSString *identifier in identifiers) {
FLTGoogleMapTileOverlayController *controller =
self.tileOverlayIdentifierToController[identifier];
if (!controller) {
continue;
}
[controller removeTileOverlay];
[self.tileOverlayIdentifierToController removeObjectForKey:identifier];
}
}
- (void)clearTileCacheWithIdentifier:(NSString *)identifier {
FLTGoogleMapTileOverlayController *controller =
self.tileOverlayIdentifierToController[identifier];
if (!controller) {
return;
}
[controller clearTileCache];
}
- (nullable NSDictionary *)tileOverlayInfoWithIdentifier:(NSString *)identifier {
if (self.tileOverlayIdentifierToController[identifier] == nil) {
return nil;
}
return [self.tileOverlayIdentifierToController[identifier] getTileOverlayInfo];
}
+ (NSString *)identifierForTileOverlay:(NSDictionary *)tileOverlay {
return tileOverlay[@"tileOverlayId"];
}
@end