Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Commit

Permalink
[ios, macos] Use NSDictionary for geojson source options.
Browse files Browse the repository at this point in the history
This removes a previous implementation of geojson options that used
a new type to transfer the data around. Added in its place is
an options API that takes an NSDictionary that works similarly to
NSAttributedString and many other Cocoa APIs that take options.

The options parser now expects the developer to send values of the
type noted in the documentation and it simply converts the NSNumber
to the correct type (integer, double, or bool) for mbgl. However, an
exception is raised if the value is not an NSNumber.
  • Loading branch information
boundsj committed Sep 2, 2016
1 parent ad095e4 commit 08f55af
Show file tree
Hide file tree
Showing 13 changed files with 218 additions and 74 deletions.
13 changes: 0 additions & 13 deletions platform/darwin/src/MGLGeoJSONOptions.h

This file was deleted.

19 changes: 0 additions & 19 deletions platform/darwin/src/MGLGeoJSONOptions.m

This file was deleted.

66 changes: 62 additions & 4 deletions platform/darwin/src/MGLGeoJSONSource.h
Original file line number Diff line number Diff line change
@@ -1,12 +1,55 @@
#import "MGLSource.h"

#import "MGLTypes.h"
#import "MGLGeoJSONOptions.h"

NS_ASSUME_NONNULL_BEGIN

@protocol MGLFeature;

/**
An `NSNumber` object containing a Boolean enabling or disabling clustering.
If the `features` property contains point features, setting this option to
`YES` clusters the points by radius into groups. The default value is `NO`.
*/
extern NSString * const MGLGeoJSONClusterOption;

/**
An `NSNumber` object containing an integer; specifies the radius of each
cluster when clustering points, measured in <sup>1</sup>/<sub>512</sub>ths of a
tile. The default value is 50.
*/
extern NSString * const MGLGeoJSONClusterRadiusOption;

/**
An `NSNumber` object containing an integer; specifies the maximum zoom level at
which to cluster points. Defaults to one zoom level less than the value of
`MGLGeoJSONMaximumZoomLevelOption`, so that at the last zoom level, the
features are not clustered.
*/
extern NSString * const MGLGeoJSONClusterMaximumZoomLevelOption;

/**
An `NSNumber` object containing an integer; specifies the maximum zoom level at
which to create vector tiles. A greater value produces greater detail at high
zoom levels. The default value is 18.
*/
extern NSString * const MGLGeoJSONMaximumZoomLevelOption;

/**
An `NSNumber` object containing an integer; specifies the tile buffer size on
each side. This option is measured in <sup>1</sup>/<sub>512</sub>ths of a tile.
A higher value reduces rendering artifacts near tile edges but may impact
performance. The default value is 128.
*/
extern NSString * const MGLGeoJSONBufferOption;

/**
An `NSNumber` object containing a double; specifies the Douglas-Peucker
simplification tolerance. A greater value produces simpler geometries and
improves performance. The default value is 0.375.
*/
extern NSString * const MGLGeoJSONToleranceOption;

@interface MGLGeoJSONSource : MGLSource

/**
Expand Down Expand Up @@ -39,8 +82,6 @@ NS_ASSUME_NONNULL_BEGIN
*/
@property (nonatomic, readonly, nullable) NSURL *URL;

@property (nonatomic, readonly, nullable) MGLGeoJSONOptions *geoJSONOptions;

/**
Initializes a source with the given identifier and GeoJSON data.
Expand All @@ -49,7 +90,14 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (instancetype)initWithSourceIdentifier:(NSString *)sourceIdentifier geoJSONData:(NSData *)data NS_DESIGNATED_INITIALIZER;

- (instancetype)initWithSourceIdentifier:(NSString *)sourceIdentifier geoJSONData:(NSData *)data options:(MGLGeoJSONOptions *)options NS_DESIGNATED_INITIALIZER;
/**
Initializes a source with the given identifier, GeoJSON data, and a dictionary of options for the source.
@param sourceIdentifier A string that uniquely identifies the source.
@param geoJSONData An NSData object representing GeoJSON source code.
@param options An NSDictionary of attributes for this source specified by the <a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources-geojson">the style specification</a>.
*/
- (instancetype)initWithSourceIdentifier:(NSString *)sourceIdentifier geoJSONData:(NSData *)data options:(NS_DICTIONARY_OF(NSString *, id) *)options NS_DESIGNATED_INITIALIZER;

/**
Initializes a source with the given identifier and URL.
Expand All @@ -60,6 +108,16 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (instancetype)initWithSourceIdentifier:(NSString *)sourceIdentifier URL:(NSURL *)url NS_DESIGNATED_INITIALIZER;

/**
Initializes a source with the given identifier, a URL, and a dictionary of options for the source.
@param sourceIdentifier A string that uniquely identifies the source.
@param URL An HTTP(S) URL, absolute file URL, or local file URL relative to the
current application’s resource bundle.
@param options An NSDictionary of attributes for this source specified by the <a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources-geojson">the style specification</a>.
*/
- (instancetype)initWithSourceIdentifier:(NSString *)sourceIdentifier URL:(NSURL *)url options:(NS_DICTIONARY_OF(NSString *, id) *)options NS_DESIGNATED_INITIALIZER;

@end

NS_ASSUME_NONNULL_END
105 changes: 85 additions & 20 deletions platform/darwin/src/MGLGeoJSONSource.mm
Original file line number Diff line number Diff line change
Expand Up @@ -7,48 +7,113 @@

#include <mbgl/style/sources/geojson_source.hpp>

NSString * const MGLGeoJSONClusterOption = @"MGLGeoJSONCluster";
NSString * const MGLGeoJSONClusterRadiusOption = @"MGLGeoJSONClusterRadius";
NSString * const MGLGeoJSONClusterMaximumZoomLevelOption = @"MGLGeoJSONClusterMaximumZoomLevel";
NSString * const MGLGeoJSONMaximumZoomLevelOption = @"MGLGeoJSONMaximumZoomLevel";
NSString * const MGLGeoJSONBufferOption = @"MGLGeoJSONBuffer";
NSString * const MGLGeoJSONToleranceOption = @"MGLGeoJSONOptionsClusterTolerance";

@interface MGLGeoJSONSource ()

@property (nonatomic, readwrite) NSDictionary *options;

@end

@implementation MGLGeoJSONSource

- (instancetype)initWithSourceIdentifier:(NSString *)sourceIdentifier geoJSONData:(NSData *)data {
if (self = [super initWithSourceIdentifier:sourceIdentifier]) {
- (instancetype)initWithSourceIdentifier:(NSString *)sourceIdentifier geoJSONData:(NSData *)data
{
if (self = [super initWithSourceIdentifier:sourceIdentifier])
{
_geoJSONData = data;
}
return self;
}

- (instancetype)initWithSourceIdentifier:(NSString *)sourceIdentifier geoJSONData:(NSData *)data options:(MGLGeoJSONOptions *)options
- (instancetype)initWithSourceIdentifier:(NSString *)sourceIdentifier geoJSONData:(NSData *)data options:(NS_DICTIONARY_OF(NSString *, id) *)options
{
if (self = [super initWithSourceIdentifier:sourceIdentifier]) {
if (self = [super initWithSourceIdentifier:sourceIdentifier])
{
_geoJSONData = data;
_geoJSONOptions = options;
_options = options;
}
return self;
}

- (instancetype)initWithSourceIdentifier:(NSString *)sourceIdentifier URL:(NSURL *)url {
if (self = [super initWithSourceIdentifier:sourceIdentifier]) {
- (instancetype)initWithSourceIdentifier:(NSString *)sourceIdentifier URL:(NSURL *)url
{
if (self = [super initWithSourceIdentifier:sourceIdentifier])
{
_URL = url;
}
return self;
}

- (mbgl::style::GeoJSONOptions)mbgl_geoJSONOptions
- (instancetype)initWithSourceIdentifier:(NSString *)sourceIdentifier URL:(NSURL *)url options:(NS_DICTIONARY_OF(NSString *, id) *)options
{
if (self = [super initWithSourceIdentifier:sourceIdentifier])
{
_URL = url;
_options = options;
}
return self;
}

- (mbgl::style::GeoJSONOptions)geoJSONOptions
{
auto mbglOptions = mbgl::style::GeoJSONOptions();

if (self.options[MGLGeoJSONMaximumZoomLevelOption]) {
id value = self.options[MGLGeoJSONMaximumZoomLevelOption];
[self validateValue:value];
mbglOptions.maxzoom = [value integerValue];
}

if (self.options[MGLGeoJSONBufferOption]) {
id value = self.options[MGLGeoJSONBufferOption];
[self validateValue:value];
mbglOptions.buffer = [value integerValue];
}

if (self.options[MGLGeoJSONToleranceOption]) {
id value = self.options[MGLGeoJSONToleranceOption];
[self validateValue:value];
mbglOptions.tolerance = [value doubleValue];
}

if (self.options[MGLGeoJSONClusterRadiusOption]) {
id value = self.options[MGLGeoJSONClusterRadiusOption];
[self validateValue:value];
mbglOptions.clusterRadius = [value integerValue];
}

if (self.options[MGLGeoJSONClusterMaximumZoomLevelOption]) {
id value = self.options[MGLGeoJSONClusterMaximumZoomLevelOption];
[self validateValue:value];
mbglOptions.clusterMaxZoom = [value integerValue];
}

if (self.options[MGLGeoJSONClusterOption]) {
id value = self.options[MGLGeoJSONClusterOption];
[self validateValue:value];
mbglOptions.cluster = [value boolValue];
}

return mbglOptions;
}

- (void)validateValue:(id)value
{
auto options = mbgl::style::GeoJSONOptions();
options.maxzoom = self.geoJSONOptions.maximumZoom;
options.buffer = self.geoJSONOptions.buffer;
options.tolerance = self.geoJSONOptions.tolerance;
options.cluster = self.geoJSONOptions.cluster;
options.clusterRadius = self.geoJSONOptions.clusterRadius;
options.clusterMaxZoom = self.geoJSONOptions.clusterMaximumZoom;
return options;
if (! [value isKindOfClass:[NSNumber class]])
{
[NSException raise:@"Value not handled" format:@"%@ is not an NSNumber", value];
}
}

- (std::unique_ptr<mbgl::style::Source>)mbgl_source
- (std::unique_ptr<mbgl::style::Source>)mbglSource
{
auto source = self.geoJSONOptions
? std::make_unique<mbgl::style::GeoJSONSource>(self.sourceIdentifier.UTF8String, [self mbgl_geoJSONOptions])
: std::make_unique<mbgl::style::GeoJSONSource>(self.sourceIdentifier.UTF8String);
auto source = std::make_unique<mbgl::style::GeoJSONSource>(self.sourceIdentifier.UTF8String, [self geoJSONOptions]);

if (self.URL) {
NSURL *url = self.URL.mgl_URLByStandardizingScheme;
Expand Down
9 changes: 9 additions & 0 deletions platform/darwin/src/MGLGeoJSONSource_Private.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#import "MGLGeoJSONSource_Private.h"

#include <mbgl/style/sources/geojson_source.hpp>

@interface MGLGeoJSONSource (Private)

- (mbgl::style::GeoJSONOptions)geoJSONOptions;

@end
2 changes: 1 addition & 1 deletion platform/darwin/src/MGLRasterSource.mm
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ - (instancetype)initWithSourceIdentifier:(NSString *)sourceIdentifier URL:(NSURL
return self;
}

- (std::unique_ptr<mbgl::style::Source>)mbgl_source {
- (std::unique_ptr<mbgl::style::Source>)mbglSource {
auto source = std::make_unique<mbgl::style::RasterSource>(self.sourceIdentifier.UTF8String,
self.URL.absoluteString.UTF8String,
uint16_t(self.tileSize));
Expand Down
2 changes: 1 addition & 1 deletion platform/darwin/src/MGLSource.mm
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ - (instancetype)initWithSourceIdentifier:(NSString *)sourceIdentifier {
return self;
}

- (std::unique_ptr<mbgl::style::Source>)mbgl_source {
- (std::unique_ptr<mbgl::style::Source>)mbglSource {
[NSException raise:@"Subclasses must override this method" format:@""];
return nil;
}
Expand Down
2 changes: 1 addition & 1 deletion platform/darwin/src/MGLSource_Private.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

@interface MGLSource (Private)

- (std::unique_ptr<mbgl::style::Source>)mbgl_source;
- (std::unique_ptr<mbgl::style::Source>)mbglSource;

@property (nonatomic) mbgl::style::Source *source;

Expand Down
2 changes: 1 addition & 1 deletion platform/darwin/src/MGLStyle.mm
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ - (void)insertLayer:(id <MGLStyleLayer, MGLStyleLayer_Private>)styleLayer

- (void)addSource:(MGLSource *)source
{
self.mapView.mbglMap->addSource([source mbgl_source]);
self.mapView.mbglMap->addSource([source mbglSource]);
}

- (void)removeSource:(MGLSource *)source
Expand Down
2 changes: 1 addition & 1 deletion platform/darwin/src/MGLVectorSource.mm
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ - (instancetype)initWithSourceIdentifier:(NSString *)sourceIdentifier URL:(NSURL
return self;
}

- (std::unique_ptr<mbgl::style::Source>)mbgl_source
- (std::unique_ptr<mbgl::style::Source>)mbglSource
{
auto source = std::make_unique<mbgl::style::VectorSource>(self.sourceIdentifier.UTF8String, self.URL.absoluteString.UTF8String);
return std::move(source);
Expand Down
Loading

0 comments on commit 08f55af

Please sign in to comment.