summaryrefslogtreecommitdiff
path: root/platform/darwin/src/MGLShapeSource.mm
diff options
context:
space:
mode:
Diffstat (limited to 'platform/darwin/src/MGLShapeSource.mm')
-rw-r--r--platform/darwin/src/MGLShapeSource.mm223
1 files changed, 88 insertions, 135 deletions
diff --git a/platform/darwin/src/MGLShapeSource.mm b/platform/darwin/src/MGLShapeSource.mm
index 987306a228..d062e656c2 100644
--- a/platform/darwin/src/MGLShapeSource.mm
+++ b/platform/darwin/src/MGLShapeSource.mm
@@ -3,7 +3,6 @@
#import "MGLMapView_Private.h"
#import "MGLSource_Private.h"
#import "MGLFeature_Private.h"
-#import "MGLShapeCollectionFeature_Private.h"
#import "MGLShape_Private.h"
#import "NSURL+MGLAdditions.h"
@@ -26,39 +25,32 @@ const MGLShapeSourceOption MGLShapeSourceOptionSimplificationTolerance = @"MGLSh
@end
-@implementation MGLShapeSource
-{
+@implementation MGLShapeSource {
std::unique_ptr<mbgl::style::GeoJSONSource> _pendingSource;
}
-- (instancetype)initWithIdentifier:(NSString *)identifier geoJSONData:(NSData *)data options:(NS_DICTIONARY_OF(NSString *, id) *)options
-{
- if (self = [super initWithIdentifier:identifier])
- {
- _geoJSONData = data;
- _options = options;
- [self commonInit];
- }
- return self;
-}
-
-- (instancetype)initWithIdentifier:(NSString *)identifier URL:(NSURL *)url options:(NS_DICTIONARY_OF(NSString *, id) *)options
-{
- if (self = [super initWithIdentifier:identifier])
- {
- _URL = url;
- _options = options;
- [self commonInit];
+- (instancetype)initWithIdentifier:(NSString *)identifier URL:(NSURL *)url options:(NS_DICTIONARY_OF(NSString *, id) *)options {
+ if (self = [super initWithIdentifier:identifier]) {
+ auto geoJSONOptions = MGLGeoJSONOptionsFromDictionary(options);
+ auto source = std::make_unique<mbgl::style::GeoJSONSource>(identifier.UTF8String, geoJSONOptions);
+
+ _pendingSource = std::move(source);
+ self.rawSource = _pendingSource.get();
+
+ self.URL = url;
}
return self;
}
-- (instancetype)initWithIdentifier:(NSString *)identifier shape:(nullable MGLShape *)shape options:(NSDictionary<MGLShapeSourceOption,id> *)options
-{
+- (instancetype)initWithIdentifier:(NSString *)identifier shape:(nullable MGLShape *)shape options:(NS_DICTIONARY_OF(MGLShapeSourceOption, id) *)options {
if (self = [super initWithIdentifier:identifier]) {
- _shape = shape;
- _options = options;
- [self commonInit];
+ auto geoJSONOptions = MGLGeoJSONOptionsFromDictionary(options);
+ auto source = std::make_unique<mbgl::style::GeoJSONSource>(identifier.UTF8String, geoJSONOptions);
+
+ _pendingSource = std::move(source);
+ self.rawSource = _pendingSource.get();
+
+ self.shape = shape;
}
return self;
}
@@ -67,8 +59,7 @@ const MGLShapeSourceOption MGLShapeSourceOptionSimplificationTolerance = @"MGLSh
return [super initWithRawSource:rawSource];
}
-- (void)addToMapView:(MGLMapView *)mapView
-{
+- (void)addToMapView:(MGLMapView *)mapView {
if (_pendingSource == nullptr) {
[NSException raise:@"MGLRedundantSourceException"
format:@"This instance %@ was already added to %@. Adding the same source instance " \
@@ -78,135 +69,97 @@ const MGLShapeSourceOption MGLShapeSourceOptionSimplificationTolerance = @"MGLSh
mapView.mbglMap->addSource(std::move(_pendingSource));
}
-- (void)removeFromMapView:(MGLMapView *)mapView
-{
+- (void)removeFromMapView:(MGLMapView *)mapView {
auto removedSource = mapView.mbglMap->removeSource(self.identifier.UTF8String);
_pendingSource = std::move(reinterpret_cast<std::unique_ptr<mbgl::style::GeoJSONSource> &>(removedSource));
self.rawSource = _pendingSource.get();
}
-- (void)commonInit
-{
- auto source = std::make_unique<mbgl::style::GeoJSONSource>(self.identifier.UTF8String, self.geoJSONOptions);
-
- if (self.URL) {
- NSURL *url = self.URL.mgl_URLByStandardizingScheme;
- source->setURL(url.absoluteString.UTF8String);
+- (mbgl::style::GeoJSONSource *)rawSource {
+ return (mbgl::style::GeoJSONSource *)super.rawSource;
+}
+
+- (void)setRawSource:(mbgl::style::GeoJSONSource *)rawSource {
+ super.rawSource = rawSource;
+}
+
+- (NSURL *)URL {
+ auto url = self.rawSource->getURL();
+ return url ? [NSURL URLWithString:@(url->c_str())] : nil;
+}
+
+- (void)setURL:(NSURL *)url {
+ if (url) {
+ self.rawSource->setURL(url.mgl_URLByStandardizingScheme.absoluteString.UTF8String);
_shape = nil;
- } else if (self.geoJSONData) {
- NSString *string = [[NSString alloc] initWithData:self.geoJSONData encoding:NSUTF8StringEncoding];
- const auto geojson = mapbox::geojson::parse(string.UTF8String);
- source->setGeoJSON(geojson);
- _shape = MGLShapeFromGeoJSON(geojson);
} else {
- if ([self.shape isKindOfClass:[MGLShapeCollectionFeature class]]) {
- MGLShapeCollectionFeature *feature = (MGLShapeCollectionFeature *)self.shape;
- source->setGeoJSON(mbgl::GeoJSON{[feature mbglFeatureCollection]});
- } else if ([self.shape conformsToProtocol:@protocol(MGLFeature)]) {
- id<MGLFeaturePrivate> feature = (id<MGLFeaturePrivate>)self.shape;
- source->setGeoJSON(mbgl::GeoJSON{[feature mbglFeature]});
- } else {
- source->setGeoJSON(mbgl::GeoJSON{self.shape.geometryObject});
- }
+ self.shape = nil;
}
-
- _pendingSource = std::move(source);
- self.rawSource = _pendingSource.get();
}
-- (mbgl::style::GeoJSONOptions)geoJSONOptions
-{
- auto mbglOptions = mbgl::style::GeoJSONOptions();
-
- if (id value = self.options[MGLShapeSourceOptionMaximumZoomLevel]) {
- [self validateValue:value];
- mbglOptions.maxzoom = [value integerValue];
- }
-
- if (id value = self.options[MGLShapeSourceOptionBuffer]) {
- [self validateValue:value];
- mbglOptions.buffer = [value integerValue];
- }
-
- if (id value = self.options[MGLShapeSourceOptionSimplificationTolerance]) {
- [self validateValue:value];
- mbglOptions.tolerance = [value doubleValue];
- }
-
- if (id value = self.options[MGLShapeSourceOptionClusterRadius]) {
- [self validateValue:value];
- mbglOptions.clusterRadius = [value integerValue];
- }
-
- if (id value = self.options[MGLShapeSourceOptionMaximumZoomLevelForClustering]) {
- [self validateValue:value];
- mbglOptions.clusterMaxZoom = [value integerValue];
- }
-
- if (id value = self.options[MGLShapeSourceOptionClustered]) {
- [self validateValue:value];
- mbglOptions.cluster = [value boolValue];
- }
-
- return mbglOptions;
+- (void)setShape:(MGLShape *)shape {
+ self.rawSource->setGeoJSON({ shape.geoJSONObject });
+ _shape = shape;
}
-- (void)validateValue:(id)value
-{
- if (! [value isKindOfClass:[NSNumber class]])
- {
- [NSException raise:@"Value not handled" format:@"%@ is not an NSNumber", value];
- }
+- (NSString *)description {
+ return [NSString stringWithFormat:@"<%@: %p; identifier = %@; URL = %@; shape = %@>",
+ NSStringFromClass([self class]), (void *)self, self.identifier, self.URL, self.shape];
}
-- (void)setGeoJSONData:(NSData *)geoJSONData
-{
- _geoJSONData = geoJSONData;
+@end
+
+mbgl::style::GeoJSONOptions MGLGeoJSONOptionsFromDictionary(NS_DICTIONARY_OF(MGLShapeSourceOption, id) *options) {
+ auto geoJSONOptions = mbgl::style::GeoJSONOptions();
- if (self.rawSource == NULL)
- {
- [self commonInit];
+ if (NSNumber *value = options[MGLShapeSourceOptionMaximumZoomLevel]) {
+ if (![value isKindOfClass:[NSNumber class]]) {
+ [NSException raise:NSInvalidArgumentException
+ format:@"MGLShapeSourceOptionMaximumZoomLevel must be an NSNumber."];
+ }
+ geoJSONOptions.maxzoom = value.integerValue;
}
- NSString *string = [[NSString alloc] initWithData:_geoJSONData encoding:NSUTF8StringEncoding];
- const auto geojson = mapbox::geojson::parse(string.UTF8String);
- self.rawSource->setGeoJSON(geojson);
+ if (NSNumber *value = options[MGLShapeSourceOptionBuffer]) {
+ if (![value isKindOfClass:[NSNumber class]]) {
+ [NSException raise:NSInvalidArgumentException
+ format:@"MGLShapeSourceOptionBuffer must be an NSNumber."];
+ }
+ geoJSONOptions.buffer = value.integerValue;
+ }
- _shape = MGLShapeFromGeoJSON(geojson);
-}
-
-- (void)setURL:(NSURL *)URL
-{
- _URL = URL;
+ if (NSNumber *value = options[MGLShapeSourceOptionSimplificationTolerance]) {
+ if (![value isKindOfClass:[NSNumber class]]) {
+ [NSException raise:NSInvalidArgumentException
+ format:@"MGLShapeSourceOptionSimplificationTolerance must be an NSNumber."];
+ }
+ geoJSONOptions.tolerance = value.doubleValue;
+ }
+
+ if (NSNumber *value = options[MGLShapeSourceOptionClusterRadius]) {
+ if (![value isKindOfClass:[NSNumber class]]) {
+ [NSException raise:NSInvalidArgumentException
+ format:@"MGLShapeSourceOptionClusterRadius must be an NSNumber."];
+ }
+ geoJSONOptions.clusterRadius = value.integerValue;
+ }
- if (self.rawSource == NULL)
- {
- [self commonInit];
+ if (NSNumber *value = options[MGLShapeSourceOptionMaximumZoomLevelForClustering]) {
+ if (![value isKindOfClass:[NSNumber class]]) {
+ [NSException raise:NSInvalidArgumentException
+ format:@"MGLShapeSourceOptionMaximumZoomLevelForClustering must be an NSNumber."];
+ }
+ geoJSONOptions.clusterMaxZoom = value.integerValue;
}
- NSURL *url = self.URL.mgl_URLByStandardizingScheme;
- self.rawSource->setURL(url.absoluteString.UTF8String);
-}
-
-
-- (void)setShape:(MGLShape *)shape
-{
- if (self.rawSource == NULL)
- {
- [self commonInit];
+ if (NSNumber *value = options[MGLShapeSourceOptionClustered]) {
+ if (![value isKindOfClass:[NSNumber class]]) {
+ [NSException raise:NSInvalidArgumentException
+ format:@"MGLShapeSourceOptionClustered must be an NSNumber."];
+ }
+ geoJSONOptions.cluster = value.boolValue;
}
-
- const auto geojson = mbgl::GeoJSON{shape.geometryObject};
- self.rawSource->setGeoJSON(geojson);
- _shape = shape;
-}
-
-- (NSString *)description
-{
- return [NSString stringWithFormat:@"<%@: %p; identifier = %@; URL = %@; geoJSONData = %@; shape = %@>",
- NSStringFromClass([self class]), (void *)self, self.identifier, self.URL, self.geoJSONData, self.shape];
+ return geoJSONOptions;
}
-
-@end