diff options
Diffstat (limited to 'platform/darwin/src/MGLStyle.mm')
-rw-r--r-- | platform/darwin/src/MGLStyle.mm | 186 |
1 files changed, 119 insertions, 67 deletions
diff --git a/platform/darwin/src/MGLStyle.mm b/platform/darwin/src/MGLStyle.mm index 79d7d7e0f6..f9f2e03d40 100644 --- a/platform/darwin/src/MGLStyle.mm +++ b/platform/darwin/src/MGLStyle.mm @@ -21,6 +21,7 @@ #import "MGLGeoJSONSource.h" #include <mbgl/util/default_styles.hpp> +#include <mbgl/sprite/sprite_image.hpp> #include <mbgl/style/layers/fill_layer.hpp> #include <mbgl/style/layers/line_layer.hpp> #include <mbgl/style/layers/symbol_layer.hpp> @@ -32,8 +33,15 @@ #include <mbgl/style/sources/raster_source.hpp> #include <mbgl/mbgl.hpp> +#if TARGET_OS_IPHONE + #import "UIImage+MGLAdditions.h" +#else + #import "NSImage+MGLAdditions.h" +#endif + @interface MGLStyle() @property (nonatomic, weak) MGLMapView *mapView; +@property (readonly, copy, nullable) NSURL *URL; @end @implementation MGLStyle @@ -92,107 +100,129 @@ static NSURL *MGLStyleURL_emerald; return @(self.mapView.mbglMap->getStyleName().c_str()); } -- (id <MGLStyleLayer>)layerWithIdentifier:(NSString *)identifier +- (NSURL *)URL { + return [NSURL URLWithString:@(self.mapView.mbglMap->getStyleURL().c_str())]; +} + +- (MGLStyleLayer *)layerWithIdentifier:(NSString *)identifier { - auto layer = self.mapView.mbglMap->getLayer(identifier.UTF8String); + auto mbglLayer = self.mapView.mbglMap->getLayer(identifier.UTF8String); + if (!mbglLayer) { + return nil; + } + + MGLStyleLayer *styleLayer; + if (auto fillLayer = mbglLayer->as<mbgl::style::FillLayer>()) { + MGLSource *source = [self sourceWithIdentifier:@(fillLayer->getSourceID().c_str())]; + styleLayer = [[MGLFillStyleLayer alloc] initWithIdentifier:identifier source:source]; + } else if (auto lineLayer = mbglLayer->as<mbgl::style::LineLayer>()) { + MGLSource *source = [self sourceWithIdentifier:@(lineLayer->getSourceID().c_str())]; + styleLayer = [[MGLLineStyleLayer alloc] initWithIdentifier:identifier source:source]; + } else if (auto symbolLayer = mbglLayer->as<mbgl::style::SymbolLayer>()) { + MGLSource *source = [self sourceWithIdentifier:@(symbolLayer->getSourceID().c_str())]; + styleLayer = [[MGLSymbolStyleLayer alloc] initWithIdentifier:identifier source:source]; + } else if (auto rasterLayer = mbglLayer->as<mbgl::style::RasterLayer>()) { + MGLSource *source = [self sourceWithIdentifier:@(rasterLayer->getSourceID().c_str())]; + styleLayer = [[MGLRasterStyleLayer alloc] initWithIdentifier:identifier source:source]; + } else if (auto circleLayer = mbglLayer->as<mbgl::style::CircleLayer>()) { + MGLSource *source = [self sourceWithIdentifier:@(circleLayer->getSourceID().c_str())]; + styleLayer = [[MGLCircleStyleLayer alloc] initWithIdentifier:identifier source:source]; + } else if (mbglLayer->as<mbgl::style::BackgroundLayer>()) { + styleLayer = [[MGLBackgroundStyleLayer alloc] initWithIdentifier:identifier]; + } else { + NSAssert(NO, @"Unrecognized layer type"); + return nil; + } + + styleLayer.layer = mbglLayer; - if (!layer) return nil; - - Class clazz = [self classFromLayer:layer]; - - id <MGLStyleLayer, MGLStyleLayer_Private> styleLayer = [[clazz alloc] init]; - styleLayer.layerIdentifier = identifier; - styleLayer.layer = layer; - styleLayer.mapView = self.mapView; - return styleLayer; } - (MGLSource *)sourceWithIdentifier:(NSString *)identifier { - auto s = self.mapView.mbglMap->getSource(identifier.UTF8String); + auto mbglSource = self.mapView.mbglMap->getSource(identifier.UTF8String); + if (!mbglSource) { + return nil; + } + + // TODO: Fill in options specific to the respective source classes + // https://github.com/mapbox/mapbox-gl-native/issues/6584 + MGLSource *source; + if (mbglSource->is<mbgl::style::VectorSource>()) { + source = [[MGLVectorSource alloc] initWithIdentifier:identifier]; + } else if (mbglSource->is<mbgl::style::GeoJSONSource>()) { + source = [[MGLGeoJSONSource alloc] initWithIdentifier:identifier]; + } else if (mbglSource->is<mbgl::style::RasterSource>()) { + source = [[MGLRasterSource alloc] initWithIdentifier:identifier]; + } else { + NSAssert(NO, @"Unrecognized source type"); + return nil; + } + + source.source = mbglSource; - if (!s) return nil; - - Class clazz = [self classFromSource:s]; - - MGLSource *source = [[clazz alloc] init]; - source.sourceIdentifier = identifier; - source.source = s; - return source; } -- (Class)classFromSource:(mbgl::style::Source *)source +- (void)removeLayer:(MGLStyleLayer *)layer { - if (source->is<mbgl::style::VectorSource>()) { - return MGLVectorSource.class; - } else if (source->is<mbgl::style::GeoJSONSource>()) { - return MGLGeoJSONSource.class; - } else if (source->is<mbgl::style::RasterSource>()) { - return MGLRasterSource.class; - } - - [NSException raise:@"Source type not handled" format:@""]; - return Nil; -} - -- (Class)classFromLayer:(mbgl::style::Layer *)layer -{ - if (layer->is<mbgl::style::FillLayer>()) { - return MGLFillStyleLayer.class; - } else if (layer->is<mbgl::style::LineLayer>()) { - return MGLLineStyleLayer.class; - } else if (layer->is<mbgl::style::SymbolLayer>()) { - return MGLSymbolStyleLayer.class; - } else if (layer->is<mbgl::style::RasterLayer>()) { - return MGLRasterStyleLayer.class; - } else if (layer->is<mbgl::style::CircleLayer>()) { - return MGLCircleStyleLayer.class; - } else if (layer->is<mbgl::style::BackgroundLayer>()) { - return MGLBackgroundStyleLayer.class; - } - [NSException raise:@"Layer type not handled" format:@""]; - return Nil; + self.mapView.mbglMap->removeLayer(layer.identifier.UTF8String); } -- (void)removeLayer:(id <MGLStyleLayer_Private>)styleLayer +- (void)addLayer:(MGLStyleLayer *)layer { - self.mapView.mbglMap->removeLayer(styleLayer.layer->getID()); -} + if (!layer.layer) { + [NSException raise:NSInvalidArgumentException format: + @"The style layer %@ cannot be added to the style. " + @"Make sure the style layer was created as a member of a concrete subclass of MGLStyleLayer.", + NSStringFromClass(self)]; + } -- (void)addLayer:(id <MGLStyleLayer, MGLStyleLayer_Private>)styleLayer -{ - self.mapView.mbglMap->addLayer(std::unique_ptr<mbgl::style::Layer>(styleLayer.layer)); + self.mapView.mbglMap->addLayer(std::unique_ptr<mbgl::style::Layer>(layer.layer)); } -- (void)insertLayer:(id <MGLStyleLayer, MGLStyleLayer_Private>)styleLayer - belowLayer:(id <MGLStyleLayer, MGLStyleLayer_Private>)belowLayer +- (void)insertLayer:(MGLStyleLayer *)layer belowLayer:(MGLStyleLayer *)otherLayer { - const mbgl::optional<std::string> belowLayerId{[belowLayer layerIdentifier].UTF8String}; - self.mapView.mbglMap->addLayer(std::unique_ptr<mbgl::style::Layer>(styleLayer.layer), belowLayerId); + if (!layer.layer) { + [NSException raise:NSInvalidArgumentException + format: + @"The style layer %@ cannot be added to the style. " + @"Make sure the style layer was created as a member of a concrete subclass of MGLStyleLayer.", + NSStringFromClass(layer)]; + } + if (!otherLayer.layer) { + [NSException raise:NSInvalidArgumentException + format: + @"A style layer cannot be placed before %@ in the style. " + @"Make sure the style layer was created as a member of a concrete subclass of MGLStyleLayer.", + NSStringFromClass(otherLayer)]; + } + + const mbgl::optional<std::string> belowLayerId{otherLayer.identifier.UTF8String}; + self.mapView.mbglMap->addLayer(std::unique_ptr<mbgl::style::Layer>(layer.layer), belowLayerId); } - (void)addSource:(MGLSource *)source { - self.mapView.mbglMap->addSource([source mbglSource]); + self.mapView.mbglMap->addSource(source.mbglSource); } - (void)removeSource:(MGLSource *)source { - self.mapView.mbglMap->removeSource(source.sourceIdentifier.UTF8String); + self.mapView.mbglMap->removeSource(source.identifier.UTF8String); } - (NS_ARRAY_OF(NSString *) *)styleClasses { const std::vector<std::string> &appliedClasses = self.mapView.mbglMap->getClasses(); - + NSMutableArray *returnArray = [NSMutableArray arrayWithCapacity:appliedClasses.size()]; - + for (auto appliedClass : appliedClasses) { [returnArray addObject:@(appliedClass.c_str())]; } - + return returnArray; } @@ -204,12 +234,12 @@ static NSURL *MGLStyleURL_emerald; - (void)setStyleClasses:(NS_ARRAY_OF(NSString *) *)appliedClasses transitionDuration:(NSTimeInterval)transitionDuration { std::vector<std::string> newAppliedClasses; - + for (NSString *appliedClass in appliedClasses) { newAppliedClasses.push_back([appliedClass UTF8String]); } - + mbgl::style::TransitionOptions transition { { MGLDurationInSeconds(transitionDuration) } }; self.mapView.mbglMap->setTransitionOptions(transition); self.mapView.mbglMap->setClasses(newAppliedClasses); @@ -236,5 +266,27 @@ static NSURL *MGLStyleURL_emerald; } } +- (void)setImage:(MGLImage *)image forName:(NSString *)name +{ + NSAssert(image, @"image is null"); + NSAssert(name, @"name is null"); + + self.mapView.mbglMap->addImage([name UTF8String], image.mgl_spriteImage); +} + +- (void)removeImageForName:(NSString *)name +{ + NSAssert(name, @"name is null"); + + self.mapView.mbglMap->removeImage([name UTF8String]); +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"<%@: %p; name = %@, URL = %@>", + NSStringFromClass([self class]), (void *)self, + self.name ? [NSString stringWithFormat:@"\"%@\"", self.name] : self.name, + self.URL ? [NSString stringWithFormat:@"\"%@\"", self.URL] : self.URL]; +} @end |