summaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
authorMinh Nguyễn <mxn@1ec5.org>2016-08-18 18:00:58 -0700
committerMinh Nguyễn <mxn@1ec5.org>2016-11-28 15:45:37 -0800
commit850b70ff91e582916829c5248afcafa195070a43 (patch)
tree3362e95001983e3029e006dbd99579a5bf68e97d /platform
parentf71dd14bb74be22fb27646b8732843d92cf72c62 (diff)
downloadqtlocation-mapboxgl-850b70ff91e582916829c5248afcafa195070a43.tar.gz
[core, ios, macos] Added layers and sources properties to MGLStyle
Added new layers and sources properties to MGLStyle that contain all the style’s layers and sources, respectively. These properties are KVC-compliant with all the mutable to-many methods. Layers are ordered from topmost to bottommost, for consistency with Cocoa APIs where front/first means top and back/last means bottom. Also added storage for mbgl::style::Source in MGLSource proper for wrapping AnnotationSource. Until the style finishes loading, its name property is set to nil. Fixes #6003.
Diffstat (limited to 'platform')
-rw-r--r--platform/darwin/src/MGLBackgroundStyleLayer.mm3
-rw-r--r--platform/darwin/src/MGLCircleStyleLayer.mm3
-rw-r--r--platform/darwin/src/MGLFillStyleLayer.mm3
-rw-r--r--platform/darwin/src/MGLLineStyleLayer.mm3
-rw-r--r--platform/darwin/src/MGLRasterStyleLayer.mm3
-rw-r--r--platform/darwin/src/MGLSource.mm22
-rw-r--r--platform/darwin/src/MGLStyle.h35
-rw-r--r--platform/darwin/src/MGLStyle.mm198
-rw-r--r--platform/darwin/src/MGLStyleLayer.mm.ejs3
-rw-r--r--platform/darwin/src/MGLSymbolStyleLayer.mm3
-rw-r--r--platform/darwin/src/MGLVectorSource.mm2
11 files changed, 259 insertions, 19 deletions
diff --git a/platform/darwin/src/MGLBackgroundStyleLayer.mm b/platform/darwin/src/MGLBackgroundStyleLayer.mm
index 883a6d139c..6e30a20c97 100644
--- a/platform/darwin/src/MGLBackgroundStyleLayer.mm
+++ b/platform/darwin/src/MGLBackgroundStyleLayer.mm
@@ -51,6 +51,9 @@
- (void)removeFromMapView:(MGLMapView *)mapView
{
auto removedLayer = mapView.mbglMap->removeLayer(self.identifier.UTF8String);
+ if (!removedLayer) {
+ return;
+ }
_pendingLayer = std::move(reinterpret_cast<std::unique_ptr<mbgl::style::BackgroundLayer> &>(removedLayer));
_rawLayer = _pendingLayer.get();
}
diff --git a/platform/darwin/src/MGLCircleStyleLayer.mm b/platform/darwin/src/MGLCircleStyleLayer.mm
index 16f27991f8..aca8ff028c 100644
--- a/platform/darwin/src/MGLCircleStyleLayer.mm
+++ b/platform/darwin/src/MGLCircleStyleLayer.mm
@@ -83,6 +83,9 @@ namespace mbgl {
- (void)removeFromMapView:(MGLMapView *)mapView
{
auto removedLayer = mapView.mbglMap->removeLayer(self.identifier.UTF8String);
+ if (!removedLayer) {
+ return;
+ }
_pendingLayer = std::move(reinterpret_cast<std::unique_ptr<mbgl::style::CircleLayer> &>(removedLayer));
_rawLayer = _pendingLayer.get();
}
diff --git a/platform/darwin/src/MGLFillStyleLayer.mm b/platform/darwin/src/MGLFillStyleLayer.mm
index 3a3b443849..d670fd31e9 100644
--- a/platform/darwin/src/MGLFillStyleLayer.mm
+++ b/platform/darwin/src/MGLFillStyleLayer.mm
@@ -78,6 +78,9 @@ namespace mbgl {
- (void)removeFromMapView:(MGLMapView *)mapView
{
auto removedLayer = mapView.mbglMap->removeLayer(self.identifier.UTF8String);
+ if (!removedLayer) {
+ return;
+ }
_pendingLayer = std::move(reinterpret_cast<std::unique_ptr<mbgl::style::FillLayer> &>(removedLayer));
_rawLayer = _pendingLayer.get();
}
diff --git a/platform/darwin/src/MGLLineStyleLayer.mm b/platform/darwin/src/MGLLineStyleLayer.mm
index e367290416..34c58aa49a 100644
--- a/platform/darwin/src/MGLLineStyleLayer.mm
+++ b/platform/darwin/src/MGLLineStyleLayer.mm
@@ -90,6 +90,9 @@ namespace mbgl {
- (void)removeFromMapView:(MGLMapView *)mapView
{
auto removedLayer = mapView.mbglMap->removeLayer(self.identifier.UTF8String);
+ if (!removedLayer) {
+ return;
+ }
_pendingLayer = std::move(reinterpret_cast<std::unique_ptr<mbgl::style::LineLayer> &>(removedLayer));
_rawLayer = _pendingLayer.get();
}
diff --git a/platform/darwin/src/MGLRasterStyleLayer.mm b/platform/darwin/src/MGLRasterStyleLayer.mm
index b832b0ad29..49dc261be8 100644
--- a/platform/darwin/src/MGLRasterStyleLayer.mm
+++ b/platform/darwin/src/MGLRasterStyleLayer.mm
@@ -50,6 +50,9 @@
- (void)removeFromMapView:(MGLMapView *)mapView
{
auto removedLayer = mapView.mbglMap->removeLayer(self.identifier.UTF8String);
+ if (!removedLayer) {
+ return;
+ }
_pendingLayer = std::move(reinterpret_cast<std::unique_ptr<mbgl::style::RasterLayer> &>(removedLayer));
_rawLayer = _pendingLayer.get();
}
diff --git a/platform/darwin/src/MGLSource.mm b/platform/darwin/src/MGLSource.mm
index 4f9cfb014f..2fa580df89 100644
--- a/platform/darwin/src/MGLSource.mm
+++ b/platform/darwin/src/MGLSource.mm
@@ -2,6 +2,14 @@
#include <mbgl/style/source.hpp>
+@interface MGLSource ()
+
+// Even though this class is abstract, MGLStyle uses it to represent some
+// special internal source types like mbgl::AnnotationSource.
+@property (nonatomic) mbgl::style::Source *rawSource;
+
+@end
+
@implementation MGLSource
- (instancetype)initWithIdentifier:(NSString *)identifier
@@ -12,6 +20,20 @@
return self;
}
+- (void)addToMapView:(MGLMapView *)mapView {
+ [NSException raise:NSInvalidArgumentException format:
+ @"The source %@ cannot be added to the style. "
+ @"Make sure the source was created as a member of a concrete subclass of MGLSource.",
+ self];
+}
+
+- (void)removeFromMapView:(MGLMapView *)mapView {
+ [NSException raise:NSInvalidArgumentException format:
+ @"The source %@ cannot be removed from the style. "
+ @"Make sure the source was created as a member of a concrete subclass of MGLSource.",
+ self];
+}
+
- (NSString *)description {
return [NSString stringWithFormat:@"<%@: %p; identifier = %@>",
NSStringFromClass([self class]), (void *)self, self.identifier];
diff --git a/platform/darwin/src/MGLStyle.h b/platform/darwin/src/MGLStyle.h
index 96dc8fba49..b3e1b28eee 100644
--- a/platform/darwin/src/MGLStyle.h
+++ b/platform/darwin/src/MGLStyle.h
@@ -177,6 +177,11 @@ static const NSInteger MGLStyleDefaultVersion = 9;
#pragma mark Managing Sources
/**
+ A set containing the style’s sources.
+ */
+@property (nonatomic, strong) NS_MUTABLE_SET_OF(MGLSource *) *sources;
+
+/**
Returns a source with the given identifier in the current style.
@return An instance of a concrete subclass of `MGLSource` associated with the
@@ -201,6 +206,12 @@ static const NSInteger MGLStyleDefaultVersion = 9;
#pragma mark Managing Style Layers
/**
+ The layers included in the style, arranged according to their front-to-back
+ ordering on the screen.
+ */
+@property (nonatomic, strong) NS_MUTABLE_ARRAY_OF(MGLStyleLayer *) *layers;
+
+/**
Returns a style layer with the given identifier in the current style.
@return An instance of a concrete subclass of `MGLStyleLayer` associated with
@@ -218,12 +229,30 @@ static const NSInteger MGLStyleDefaultVersion = 9;
- (void)addLayer:(MGLStyleLayer *)layer;
/**
+ Inserts a new layer into the style at the given index.
+
+ @param layer The layer to insert.
+ @param index The index at which to insert the layer. An index of 0 would send
+ the layer to the back; an index equal to the number of objects in the
+ `layers` property would bring the layer to the front.
+ */
+- (void)insertLayer:(MGLStyleLayer *)layer atIndex:(NSUInteger)index;
+
+/**
Inserts a new layer below another layer.
- @param layer Layer to be inserted.
- @param belowLayer A layer that's already on the map view.
+ @param layer The layer to insert.
+ @param sibling An existing layer in the style.
+ */
+- (void)insertLayer:(MGLStyleLayer *)layer belowLayer:(MGLStyleLayer *)sibling;
+
+/**
+ Inserts a new layer above another layer.
+
+ @param layer The layer to insert.
+ @param sibling An existing layer in the style.
*/
-- (void)insertLayer:(MGLStyleLayer *)layer belowLayer:(MGLStyleLayer *)otherLayer;
+- (void)insertLayer:(MGLStyleLayer *)layer aboveLayer:(MGLStyleLayer *)sibling;
/**
Removes a layer from the map view.
diff --git a/platform/darwin/src/MGLStyle.mm b/platform/darwin/src/MGLStyle.mm
index 69d76614c0..4169c7a5d3 100644
--- a/platform/darwin/src/MGLStyle.mm
+++ b/platform/darwin/src/MGLStyle.mm
@@ -101,7 +101,8 @@ static NSURL *MGLStyleURL_emerald;
#pragma mark Metadata
- (NSString *)name {
- return @(self.mapView.mbglMap->getStyleName().c_str());
+ std::string name = self.mapView.mbglMap->getStyleName();
+ return name.empty() ? nil : @(name.c_str());
}
- (NSURL *)URL {
@@ -110,13 +111,43 @@ static NSURL *MGLStyleURL_emerald;
#pragma mark Sources
+- (NS_MUTABLE_SET_OF(MGLSource *) *)sources {
+ auto rawSources = self.mapView.mbglMap->getSources();
+ NSMutableSet *sources = [NSMutableSet setWithCapacity:rawSources.size()];
+ for (auto rawSource = rawSources.begin(); rawSource != rawSources.end(); ++rawSource) {
+ MGLSource *source = [self sourceFromMBGLSource:*rawSource];
+ [sources addObject:source];
+ }
+ return sources;
+}
+
+- (void)setSources:(NS_MUTABLE_SET_OF(MGLSource *) *)sources {
+ for (MGLSource *source in self.sources) {
+ [self removeSource:source];
+ }
+ for (MGLSource *source in sources) {
+ [self addSource:source];
+ }
+}
+
+- (NSUInteger)countOfSources {
+ auto rawSources = self.mapView.mbglMap->getSources();
+ return rawSources.size();
+}
+
+- (MGLSource *)memberOfSources:(MGLSource *)object {
+ return [self sourceWithIdentifier:object.identifier];
+}
+
- (MGLSource *)sourceWithIdentifier:(NSString *)identifier
{
- auto mbglSource = self.mapView.mbglMap->getSource(identifier.UTF8String);
- if (!mbglSource) {
- return nil;
- }
+ auto rawSource = self.mapView.mbglMap->getSource(identifier.UTF8String);
+ return rawSource ? [self sourceFromMBGLSource:rawSource] : nil;
+}
+- (MGLSource *)sourceFromMBGLSource:(mbgl::style::Source *)mbglSource {
+ NSString *identifier = @(mbglSource->getID().c_str());
+
// TODO: Fill in options specific to the respective source classes
// https://github.com/mapbox/mapbox-gl-native/issues/6584
MGLSource *source;
@@ -160,13 +191,93 @@ static NSURL *MGLStyleURL_emerald;
#pragma mark Style layers
-- (MGLStyleLayer *)layerWithIdentifier:(NSString *)identifier
+- (NS_MUTABLE_ARRAY_OF(MGLStyleLayer *) *)layers
{
- auto mbglLayer = self.mapView.mbglMap->getLayer(identifier.UTF8String);
- if (!mbglLayer) {
+ auto layers = self.mapView.mbglMap->getLayers();
+ NSMutableArray *styleLayers = [NSMutableArray arrayWithCapacity:layers.size()];
+ for (auto layer = layers.rbegin(); layer != layers.rend(); ++layer) {
+ MGLStyleLayer *styleLayer = [self layerFromMBGLLayer:*layer];
+ [styleLayers addObject:styleLayer];
+ }
+ return styleLayers;
+}
+
+- (void)setLayers:(NS_MUTABLE_ARRAY_OF(MGLStyleLayer *) *)layers {
+ for (MGLStyleLayer *layer in self.layers.reverseObjectEnumerator) {
+ [self removeLayer:layer];
+ }
+ for (MGLStyleLayer *layer in layers.reverseObjectEnumerator) {
+ [self addLayer:layer];
+ }
+}
+
+- (NSUInteger)countOfLayers
+{
+ return self.mapView.mbglMap->getLayers().size();
+}
+
+- (MGLStyleLayer *)objectInLayersAtIndex:(NSUInteger)index
+{
+ auto layers = self.mapView.mbglMap->getLayers();
+ if (index > layers.size() - 1) {
+ [NSException raise:NSRangeException
+ format:@"No style layer at index %lu.", (unsigned long)index];
return nil;
}
+ auto layer = layers.at(layers.size() - 1 - index);
+ return [self layerFromMBGLLayer:layer];
+}
+
+- (void)getLayers:(MGLStyleLayer **)buffer range:(NSRange)inRange
+{
+ auto layers = self.mapView.mbglMap->getLayers();
+ if (NSMaxRange(inRange) > layers.size()) {
+ [NSException raise:NSRangeException
+ format:@"Style layer range %@ is out of bounds.", NSStringFromRange(inRange)];
+ }
+ NSUInteger i = 0;
+ for (auto layer = *(layers.rbegin() + inRange.location); i < inRange.length; ++layer, ++i) {
+ MGLStyleLayer *styleLayer = [self layerFromMBGLLayer:layer];
+ buffer[i] = styleLayer;
+ }
+}
+
+- (void)insertObject:(MGLStyleLayer *)styleLayer inLayersAtIndex:(NSUInteger)index
+{
+ if (!styleLayer.rawLayer) {
+ [NSException raise:NSInvalidArgumentException format:
+ @"The style layer %@ cannot be inserted into the style. "
+ @"Make sure the style layer was created as a member of a concrete subclass of MGLStyleLayer.",
+ styleLayer];
+ }
+ auto layers = self.mapView.mbglMap->getLayers();
+ if (index > layers.size()) {
+ [NSException raise:NSRangeException
+ format:@"Cannot insert style layer at out-of-bounds index %lu.", (unsigned long)index];
+ } else if (index == 0) {
+ [styleLayer addToMapView:self.mapView];
+ } else {
+ MGLStyleLayer *sibling = [self layerFromMBGLLayer:layers.at(layers.size() - index)];
+ [styleLayer addToMapView:self.mapView belowLayer:sibling];
+ }
+}
+
+- (void)removeObjectFromLayersAtIndex:(NSUInteger)index
+{
+ auto layers = self.mapView.mbglMap->getLayers();
+ if (index > layers.size() - 1) {
+ [NSException raise:NSRangeException
+ format:@"Cannot remove style layer at out-of-bounds index %lu.", (unsigned long)index];
+ }
+ auto layer = layers.at(layers.size() - 1 - index);
+ self.mapView.mbglMap->removeLayer(layer->getID());
+}
+- (MGLStyleLayer *)layerFromMBGLLayer:(mbgl::style::Layer *)mbglLayer
+{
+ NSParameterAssert(mbglLayer);
+
+ NSString *identifier = @(mbglLayer->getID().c_str());
MGLStyleLayer *styleLayer;
if (auto fillLayer = mbglLayer->as<mbgl::style::FillLayer>()) {
MGLSource *source = [self sourceWithIdentifier:@(fillLayer->getSourceID().c_str())];
@@ -195,6 +306,12 @@ static NSURL *MGLStyleURL_emerald;
return styleLayer;
}
+- (MGLStyleLayer *)layerWithIdentifier:(NSString *)identifier
+{
+ auto mbglLayer = self.mapView.mbglMap->getLayer(identifier.UTF8String);
+ return mbglLayer ? [self layerFromMBGLLayer:mbglLayer] : nil;
+}
+
- (void)removeLayer:(MGLStyleLayer *)layer
{
if (!layer.rawLayer) {
@@ -217,7 +334,11 @@ static NSURL *MGLStyleURL_emerald;
[layer addToMapView:self.mapView];
}
-- (void)insertLayer:(MGLStyleLayer *)layer belowLayer:(MGLStyleLayer *)otherLayer
+- (void)insertLayer:(MGLStyleLayer *)layer atIndex:(NSUInteger)index {
+ [self insertObject:layer inLayersAtIndex:index];
+}
+
+- (void)insertLayer:(MGLStyleLayer *)layer belowLayer:(MGLStyleLayer *)sibling
{
if (!layer.rawLayer) {
[NSException raise:NSInvalidArgumentException
@@ -226,14 +347,58 @@ static NSURL *MGLStyleURL_emerald;
@"Make sure the style layer was created as a member of a concrete subclass of MGLStyleLayer.",
layer];
}
- if (!otherLayer.rawLayer) {
+ if (!sibling.rawLayer) {
+ [NSException raise:NSInvalidArgumentException
+ format:
+ @"A style layer cannot be placed below %@ in the style. "
+ @"Make sure sibling was obtained using -[MGLStyle layerWithIdentifier:].",
+ sibling];
+ }
+ [self willChangeValueForKey:@"layers"];
+ [layer addToMapView:self.mapView belowLayer:sibling];
+ [self didChangeValueForKey:@"layers"];
+}
+
+- (void)insertLayer:(MGLStyleLayer *)layer aboveLayer:(MGLStyleLayer *)sibling {
+ if (!layer.rawLayer) {
+ [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.",
+ layer];
+ }
+ if (!sibling.rawLayer) {
[NSException raise:NSInvalidArgumentException
format:
- @"A style layer cannot be placed before %@ in the style. "
- @"Make sure otherLayer was obtained using -[MGLStyle layerWithIdentifier:].",
- otherLayer];
+ @"A style layer cannot be placed above %@ in the style. "
+ @"Make sure sibling was obtained using -[MGLStyle layerWithIdentifier:].",
+ sibling];
}
- [layer addToMapView:self.mapView belowLayer:otherLayer];
+
+ auto layers = self.mapView.mbglMap->getLayers();
+ std::string siblingIdentifier = sibling.identifier.UTF8String;
+ NSUInteger index = 0;
+ for (auto layer : layers) {
+ if (layer->getID() == siblingIdentifier) {
+ break;
+ }
+ index++;
+ }
+
+ [self willChangeValueForKey:@"layers"];
+ if (index + 1 > layers.size()) {
+ [NSException raise:NSInvalidArgumentException
+ format:
+ @"A style layer cannot be placed above %@ in the style. "
+ @"Make sure sibling was obtained using -[MGLStyle layerWithIdentifier:].",
+ sibling];
+ } else if (index + 1 == layers.size()) {
+ [layer addToMapView:self.mapView];
+ } else {
+ MGLStyleLayer *sibling = [self layerFromMBGLLayer:layers.at(index + 1)];
+ [layer addToMapView:self.mapView belowLayer:sibling];
+ }
+ [self didChangeValueForKey:@"layers"];
}
#pragma mark Style classes
@@ -270,6 +435,11 @@ static NSURL *MGLStyleURL_emerald;
self.mapView.mbglMap->setClasses(newAppliedClasses);
}
+- (NSUInteger)countOfStyleClasses {
+ const auto &classes = self.mapView.mbglMap->getClasses();
+ return classes.size();
+}
+
- (BOOL)hasStyleClass:(NSString *)styleClass
{
return styleClass && self.mapView.mbglMap->hasClass([styleClass UTF8String]);
diff --git a/platform/darwin/src/MGLStyleLayer.mm.ejs b/platform/darwin/src/MGLStyleLayer.mm.ejs
index f8b8305616..8febd69a20 100644
--- a/platform/darwin/src/MGLStyleLayer.mm.ejs
+++ b/platform/darwin/src/MGLStyleLayer.mm.ejs
@@ -120,6 +120,9 @@ namespace mbgl {
- (void)removeFromMapView:(MGLMapView *)mapView
{
auto removedLayer = mapView.mbglMap->removeLayer(self.identifier.UTF8String);
+ if (!removedLayer) {
+ return;
+ }
_pendingLayer = std::move(reinterpret_cast<std::unique_ptr<mbgl::style::<%- camelize(type) %>Layer> &>(removedLayer));
_rawLayer = _pendingLayer.get();
}
diff --git a/platform/darwin/src/MGLSymbolStyleLayer.mm b/platform/darwin/src/MGLSymbolStyleLayer.mm
index 9ba1bd7bc2..0acc36d2dc 100644
--- a/platform/darwin/src/MGLSymbolStyleLayer.mm
+++ b/platform/darwin/src/MGLSymbolStyleLayer.mm
@@ -137,6 +137,9 @@ namespace mbgl {
- (void)removeFromMapView:(MGLMapView *)mapView
{
auto removedLayer = mapView.mbglMap->removeLayer(self.identifier.UTF8String);
+ if (!removedLayer) {
+ return;
+ }
_pendingLayer = std::move(reinterpret_cast<std::unique_ptr<mbgl::style::SymbolLayer> &>(removedLayer));
_rawLayer = _pendingLayer.get();
}
diff --git a/platform/darwin/src/MGLVectorSource.mm b/platform/darwin/src/MGLVectorSource.mm
index 1b3406e5e6..ae69456b45 100644
--- a/platform/darwin/src/MGLVectorSource.mm
+++ b/platform/darwin/src/MGLVectorSource.mm
@@ -18,8 +18,6 @@
std::unique_ptr<mbgl::style::VectorSource> _pendingSource;
}
-static NSString *MGLVectorSourceType = @"vector";
-
- (instancetype)initWithIdentifier:(NSString *)identifier URL:(NSURL *)url
{
if (self = [super initWithIdentifier:identifier])