diff options
author | Jesse Bounds <jesse@rebounds.net> | 2016-12-09 16:09:10 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-12-09 16:09:10 -0800 |
commit | 7f75eb5d6ae014391f3baf066a9873c5fb1c1ded (patch) | |
tree | 0451999a6d5397a806dc3214bc5e0b8eb9b51daa /platform/darwin/src/MGLShapeSource.mm | |
parent | ce1d9ff5eee2df57ec4c2d1f39b967ecfef4b9bc (diff) | |
download | qtlocation-mapboxgl-7f75eb5d6ae014391f3baf066a9873c5fb1c1ded.tar.gz |
[ios, macos] Rename MGLGeoJSONSource to MGLShapeSource (#7334)
Diffstat (limited to 'platform/darwin/src/MGLShapeSource.mm')
-rw-r--r-- | platform/darwin/src/MGLShapeSource.mm | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/platform/darwin/src/MGLShapeSource.mm b/platform/darwin/src/MGLShapeSource.mm new file mode 100644 index 0000000000..434e6fcb1b --- /dev/null +++ b/platform/darwin/src/MGLShapeSource.mm @@ -0,0 +1,204 @@ +#import "MGLShapeSource_Private.h" + +#import "MGLMapView_Private.h" +#import "MGLSource_Private.h" +#import "MGLFeature_Private.h" +#import "MGLShape_Private.h" + +#import "NSURL+MGLAdditions.h" + +#include <mbgl/style/sources/geojson_source.hpp> + +const MGLShapeSourceOption MGLShapeSourceOptionClustered = @"MGLShapeSourceOptionClustered"; +const MGLShapeSourceOption MGLShapeSourceOptionClusterRadius = @"MGLShapeSourceOptionClusterRadius"; +const MGLShapeSourceOption MGLShapeSourceOptionMaximumZoomLevelForClustering = @"MGLShapeSourceOptionMaximumZoomLevelForClustering"; +const MGLShapeSourceOption MGLShapeSourceOptionMaximumZoomLevel = @"MGLShapeSourceOptionMaximumZoomLevel"; +const MGLShapeSourceOption MGLShapeSourceOptionBuffer = @"MGLShapeSourceOptionBuffer"; +const MGLShapeSourceOption MGLShapeSourceOptionSimplificationTolerance = @"MGLShapeSourceOptionSimplificationTolerance"; + +@interface MGLShapeSource () + +- (instancetype)initWithRawSource:(mbgl::style::GeoJSONSource *)rawSource NS_DESIGNATED_INITIALIZER; + +@property (nonatomic, readwrite) NSDictionary *options; +@property (nonatomic) mbgl::style::GeoJSONSource *rawSource; + +@end + +@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]; + } + return self; +} + +- (instancetype)initWithIdentifier:(NSString *)identifier shape:(nullable MGLShape *)shape options:(NSDictionary<MGLShapeSourceOption,id> *)options +{ + if (self = [super initWithIdentifier:identifier]) { + _shape = shape; + _options = options; + [self commonInit]; + } + return self; +} + +- (instancetype)initWithRawSource:(mbgl::style::GeoJSONSource *)rawSource { + return [super initWithRawSource:rawSource]; +} + +- (void)addToMapView:(MGLMapView *)mapView +{ + if (_pendingSource == nullptr) { + [NSException raise:@"MGLRedundantSourceException" + format:@"This instance %@ was already added to %@. Adding the same source instance " \ + "to the style more than once is invalid.", self, mapView.style]; + } + + mapView.mbglMap->addSource(std::move(_pendingSource)); +} + +- (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); + _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 { + const auto geojson = mbgl::GeoJSON{self.shape.geometryObject}; + source->setGeoJSON(geojson); + } + + _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)validateValue:(id)value +{ + if (! [value isKindOfClass:[NSNumber class]]) + { + [NSException raise:@"Value not handled" format:@"%@ is not an NSNumber", value]; + } +} + +- (void)setGeoJSONData:(NSData *)geoJSONData +{ + _geoJSONData = geoJSONData; + + if (self.rawSource == NULL) + { + [self commonInit]; + } + + NSString *string = [[NSString alloc] initWithData:_geoJSONData encoding:NSUTF8StringEncoding]; + const auto geojson = mapbox::geojson::parse(string.UTF8String); + self.rawSource->setGeoJSON(geojson); + + _shape = MGLShapeFromGeoJSON(geojson); +} + +- (void)setURL:(NSURL *)URL +{ + _URL = URL; + + if (self.rawSource == NULL) + { + [self commonInit]; + } + + NSURL *url = self.URL.mgl_URLByStandardizingScheme; + self.rawSource->setURL(url.absoluteString.UTF8String); +} + + +- (void)setShape:(MGLShape *)shape +{ + if (self.rawSource == NULL) + { + [self commonInit]; + } + + 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]; +} + +@end |