diff options
Diffstat (limited to 'platform/darwin/src/MGLShapeSource.mm')
-rw-r--r-- | platform/darwin/src/MGLShapeSource.mm | 223 |
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 |