-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Computed (on-demand) shape source #6940
Changes from 59 commits
403ac49
5d74f08
579ef87
095281e
1656672
d2c62ef
908a7e2
30c9cb9
aa5b27e
b6015b8
6986db5
7482313
f556388
0f61a1f
7434506
474905b
b2cdaa3
36f0dd2
a530538
6c589ed
dcd7f8e
e403ed9
50e7fe9
adfc031
570da2c
cb76fe9
f6a908f
d731490
92ed922
18e7c60
d742e84
ccb17de
d8ffb91
d737370
2e9e568
244d689
2f68306
c9fba94
6bde7e8
286550a
b591f5b
fb37624
517f447
daa5209
fc0b94b
fcaa6e8
1597509
206783b
bee3b28
16fb067
9e8dc9a
cbe2815
b31841d
13ef94e
ab55326
3fcb46f
f01e1f2
f75b34d
c73f6de
0be7292
86ab288
4bb3a9c
883f72e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
#pragma once | ||
|
||
#include <mbgl/style/source.hpp> | ||
#include <mbgl/util/geojson.hpp> | ||
#include <mbgl/util/geo.hpp> | ||
#include <mbgl/style/sources/geojson_source.hpp> | ||
|
||
namespace mbgl { | ||
namespace style { | ||
|
||
class CustomVectorSource : public Source { | ||
public: | ||
CustomVectorSource(std::string id, GeoJSONOptions options, std::function<void(uint8_t, uint32_t, uint32_t)> fetchTile); | ||
|
||
void setTileData(uint8_t, uint32_t, uint32_t, const mapbox::geojson::geojson&); | ||
void updateTile(uint8_t, uint32_t, uint32_t); | ||
void reloadRegion(mbgl::LatLngBounds bounds, uint8_t z); | ||
void reload(); | ||
|
||
// Private implementation | ||
class Impl; | ||
Impl* const impl; | ||
}; | ||
|
||
template <> | ||
inline bool Source::is<CustomVectorSource>() const { | ||
return type == SourceType::Vector; | ||
} | ||
|
||
} // namespace style | ||
} // namespace mbgl |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,7 @@ | |
#include <mbgl/style/source.hpp> | ||
#include <mbgl/util/geojson.hpp> | ||
#include <mbgl/util/optional.hpp> | ||
#include <mbgl/util/constants.hpp> | ||
|
||
#include <mapbox/geojson.hpp> | ||
|
||
|
@@ -26,7 +27,10 @@ using SuperclusterPointer = std::unique_ptr<mapbox::supercluster::Supercluster>; | |
|
||
struct GeoJSONOptions { | ||
// GeoJSON-VT options | ||
uint8_t minzoom = 0; | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. space |
||
uint8_t maxzoom = 18; | ||
uint16_t tileSize = util::tileSize; | ||
uint16_t buffer = 128; | ||
double tolerance = 0.375; | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
#import "MGLSource.h" | ||
|
||
/** | ||
Options for `MGLShapeSource` objects. | ||
*/ | ||
typedef NSString *MGLShapeSourceOption NS_STRING_ENUM; | ||
|
||
/** | ||
An `NSNumber` object containing a Boolean enabling or disabling clustering. | ||
If the `shape` property contains point shapes, setting this option to | ||
`YES` clusters the points by radius into groups. The default value is `NO`. | ||
|
||
This attribute corresponds to the | ||
<a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources-geojson-cluster"><code>cluster</code></a> | ||
source property in the Mapbox Style Specification. | ||
|
||
This option only affects point features within a shape source. | ||
*/ | ||
extern MGL_EXPORT const MGLShapeSourceOption MGLShapeSourceOptionClustered; | ||
|
||
/** | ||
An `NSNumber` object containing an integer; specifies the radius of each | ||
cluster if clustering is enabled. A value of 512 produces a radius equal to | ||
the width of a tile. The default value is 50. | ||
*/ | ||
extern MGL_EXPORT const MGLShapeSourceOption MGLShapeSourceOptionClusterRadius; | ||
|
||
/** | ||
An `NSNumber` object containing an integer; specifies the maximum zoom level at | ||
which to cluster points if clustering is enabled. Defaults to one zoom level | ||
less than the value of `MGLShapeSourceOptionMaximumZoomLevel` so that, at the | ||
maximum zoom level, the shapes are not clustered. | ||
|
||
This attribute corresponds to the | ||
<a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources-geojson-clusterMaxZoom"><code>clusterMaxZoom</code></a> | ||
source property in the Mapbox Style Specification. | ||
*/ | ||
extern MGL_EXPORT const MGLShapeSourceOption MGLShapeSourceOptionMaximumZoomLevelForClustering; | ||
|
||
/** | ||
An `NSNumber` object containing an integer; specifies the minimum zoom level at | ||
which to create vector tiles. The default value is 0. | ||
|
||
This attribute corresponds to the | ||
<a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources-geojson-minzoom"><code>minzoom</code></a> | ||
source property in the Mapbox Style Specification. | ||
*/ | ||
extern const MGLShapeSourceOption MGLShapeSourceOptionMinimumZoomLevel; | ||
|
||
/** | ||
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. | ||
|
||
This attribute corresponds to the | ||
<a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources-geojson-maxzoom"><code>maxzoom</code></a> | ||
source property in the Mapbox Style Specification. | ||
*/ | ||
extern MGL_EXPORT const MGLShapeSourceOption MGLShapeSourceOptionMaximumZoomLevel; | ||
|
||
/** | ||
An `NSNumber` object containing an integer; specifies the size of the tile | ||
buffer on each side. A value of 0 produces no buffer. A value of 512 produces a | ||
buffer as wide as the tile itself. Larger values produce fewer rendering | ||
artifacts near tile edges and slower performance. The default value is 128. | ||
|
||
This attribute corresponds to the | ||
<a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources-geojson-buffer"><code>buffer</code></a> | ||
source property in the Mapbox Style Specification. | ||
*/ | ||
extern MGL_EXPORT const MGLShapeSourceOption MGLShapeSourceOptionBuffer; | ||
|
||
/** | ||
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. | ||
|
||
This attribute corresponds to the | ||
<a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources-geojson-tolerance"><code>tolerance</code></a> | ||
source property in the Mapbox Style Specification. | ||
*/ | ||
extern MGL_EXPORT const MGLShapeSourceOption MGLShapeSourceOptionSimplificationTolerance; | ||
|
||
/** | ||
`MGLAbstractShapeSource` is an abstract base class for map content sources that | ||
supply vector shapes to be shown on the map. A shape source is added to an | ||
`MGLStyle` object along with an `MGLVectorStyleLayer` object. The vector style | ||
layer defines the appearance of any content supplied by the shape source. | ||
|
||
|
||
Do not create instances of this class directly, and do not create your own | ||
subclasses of this class. Instead, create instances of `MGLShapeSource` or | ||
`MGLComputedShapeSource`. | ||
*/ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. By the way, this is totally optional, but we have a mechanism for inserting a Swift code example into a documentation comment via unit tests. Feel free to use MGLShapeSource’s documentation as a model. |
||
MGL_EXPORT | ||
@interface MGLAbstractShapeSource : MGLSource | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Due to a change in the framework's visibility settings, aimed at reducing the framework's size, all publicly visible classes must now be declared with the MGL_EXPORT macro. See CONTRIBUTING.md for details. (There's a make rule you can run to scan for missing exports.) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This class needs a documentation comment. As with the other abstract classes (such as MGLSource and MGLVectorStyleLayer), be sure to point out that this class shouldn't be initialized directly. |
||
|
||
|
||
@end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
#import "MGLAbstractShapeSource.h" | ||
#import "MGLAbstractShapeSource_Private.h" | ||
|
||
const MGLShapeSourceOption MGLShapeSourceOptionBuffer = @"MGLShapeSourceOptionBuffer"; | ||
const MGLShapeSourceOption MGLShapeSourceOptionClusterRadius = @"MGLShapeSourceOptionClusterRadius"; | ||
const MGLShapeSourceOption MGLShapeSourceOptionClustered = @"MGLShapeSourceOptionClustered"; | ||
const MGLShapeSourceOption MGLShapeSourceOptionMaximumZoomLevel = @"MGLShapeSourceOptionMaximumZoomLevel"; | ||
const MGLShapeSourceOption MGLShapeSourceOptionMaximumZoomLevelForClustering = @"MGLShapeSourceOptionMaximumZoomLevelForClustering"; | ||
const MGLShapeSourceOption MGLShapeSourceOptionMinimumZoomLevel = @"MGLShapeSourceOptionMinimumZoomLevel"; | ||
const MGLShapeSourceOption MGLShapeSourceOptionSimplificationTolerance = @"MGLShapeSourceOptionSimplificationTolerance"; | ||
|
||
@interface MGLAbstractShapeSource () | ||
|
||
@end | ||
|
||
@implementation MGLAbstractShapeSource | ||
|
||
@end | ||
|
||
mbgl::style::GeoJSONOptions MGLGeoJSONOptionsFromDictionary(NS_DICTIONARY_OF(MGLShapeSourceOption, id) *options) { | ||
auto geoJSONOptions = mbgl::style::GeoJSONOptions(); | ||
|
||
if (NSNumber *value = options[MGLShapeSourceOptionMinimumZoomLevel]) { | ||
if (![value isKindOfClass:[NSNumber class]]) { | ||
[NSException raise:NSInvalidArgumentException | ||
format:@"MGLShapeSourceOptionMaximumZoomLevel must be an NSNumber."]; | ||
} | ||
geoJSONOptions.minzoom = value.integerValue; | ||
} | ||
|
||
if (NSNumber *value = options[MGLShapeSourceOptionMaximumZoomLevel]) { | ||
if (![value isKindOfClass:[NSNumber class]]) { | ||
[NSException raise:NSInvalidArgumentException | ||
format:@"MGLShapeSourceOptionMaximumZoomLevel must be an NSNumber."]; | ||
} | ||
geoJSONOptions.maxzoom = value.integerValue; | ||
} | ||
|
||
if (NSNumber *value = options[MGLShapeSourceOptionBuffer]) { | ||
if (![value isKindOfClass:[NSNumber class]]) { | ||
[NSException raise:NSInvalidArgumentException | ||
format:@"MGLShapeSourceOptionBuffer must be an NSNumber."]; | ||
} | ||
geoJSONOptions.buffer = value.integerValue; | ||
} | ||
|
||
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 (NSNumber *value = options[MGLShapeSourceOptionMaximumZoomLevelForClustering]) { | ||
if (![value isKindOfClass:[NSNumber class]]) { | ||
[NSException raise:NSInvalidArgumentException | ||
format:@"MGLShapeSourceOptionMaximumZoomLevelForClustering must be an NSNumber."]; | ||
} | ||
geoJSONOptions.clusterMaxZoom = value.integerValue; | ||
} | ||
|
||
if (NSNumber *value = options[MGLShapeSourceOptionClustered]) { | ||
if (![value isKindOfClass:[NSNumber class]]) { | ||
[NSException raise:NSInvalidArgumentException | ||
format:@"MGLShapeSourceOptionClustered must be an NSNumber."]; | ||
} | ||
geoJSONOptions.cluster = value.boolValue; | ||
} | ||
|
||
return geoJSONOptions; | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
#import "MGLAbstractShapeSource.h" | ||
|
||
#import "MGLFoundation.h" | ||
#import "MGLTypes.h" | ||
#import "MGLShape.h" | ||
|
||
#include <mbgl/style/sources/geojson_source.hpp> | ||
|
||
NS_ASSUME_NONNULL_BEGIN | ||
|
||
@interface MGLAbstractShapeSource (Private) | ||
|
||
MGL_EXPORT | ||
|
||
mbgl::style::GeoJSONOptions MGLGeoJSONOptionsFromDictionary(NS_DICTIONARY_OF(MGLShapeSourceOption, id) *options); | ||
|
||
@end | ||
NS_ASSUME_NONNULL_END |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
#import "MGLAbstractShapeSource.h" | ||
|
||
#import "MGLFoundation.h" | ||
#import "MGLGeometry.h" | ||
#import "MGLTypes.h" | ||
#import "MGLShape.h" | ||
|
||
NS_ASSUME_NONNULL_BEGIN | ||
|
||
@protocol MGLFeature; | ||
|
||
/** | ||
Data source for `MGLComputedShapeSource`. This protocol defines two optionak methods for fetching | ||
data, one based on tile coordinates, and one based on a bounding box. Clases that implement this | ||
protocol must implement one, and only one of the methods. | ||
*/ | ||
@protocol MGLComputedShapeSourceDataSource <NSObject> | ||
|
||
@optional | ||
/** | ||
Fetch features for a tile. This will not be called on the main queue, it will be called on the callers requestQueue. | ||
@param x tile X coordinate | ||
@param y tile Y coordinate | ||
@param zoomLevel tile zoom level | ||
*/ | ||
- (NSArray<MGLShape <MGLFeature> *>*)featuresInTileAtX:(NSUInteger)x y:(NSUInteger)y zoomLevel:(NSUInteger)zoomLevel; | ||
|
||
/** | ||
Fetch features for a tile. This will not be called on the main queue, it will be called on the callers requestQueue. | ||
@param bounds The bounds to fetch data for | ||
@param zoomLevel tile zoom level | ||
*/ | ||
- (NSArray<MGLShape <MGLFeature> *>*)featuresInCoordinateBounds:(MGLCoordinateBounds)bounds zoomLevel:(NSUInteger)zoomLevel; | ||
|
||
@end | ||
|
||
/** | ||
A source for vector data that is fetched 1 tile at a time. Useful for sources that are | ||
too large to fit in memory, or are already divided into tiles, but not in Mapbox Vector Tile format. | ||
*/ | ||
MGL_EXPORT | ||
@interface MGLComputedShapeSource : MGLAbstractShapeSource | ||
|
||
/** | ||
Returns a custom vector datasource initialized with an identifier, datasource, and a | ||
dictionary of options for the source according to the | ||
<a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources-geojson">style | ||
specification</a>. | ||
|
||
@param identifier A string that uniquely identifies the source. | ||
@param options An `NSDictionary` of options for this source. | ||
*/ | ||
- (instancetype)initWithIdentifier:(NSString *)identifier options:(nullable NS_DICTIONARY_OF(MGLShapeSourceOption, id) *)options NS_DESIGNATED_INITIALIZER; | ||
|
||
/** | ||
Request that the source reloads a region. | ||
*/ | ||
- (void)reloadTileInCoordinateBounds:(MGLCoordinateBounds)bounds zoomLevel:(NSUInteger)zoomLevel; | ||
|
||
/** | ||
Reload all tiles. | ||
*/ | ||
- (void)reloadData; | ||
|
||
/** | ||
An object that implements the `MGLComputedShapeSource` protocol that will be queried for tile data. | ||
*/ | ||
@property (nonatomic, weak, nullable) id<MGLComputedShapeSourceDataSource> dataSource; | ||
|
||
/** | ||
A queue that calls to the datasource will be made on. | ||
*/ | ||
@property (nonatomic, readonly) NSOperationQueue *requestQueue; | ||
|
||
@end | ||
|
||
NS_ASSUME_NONNULL_END |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the difference between
setTileData
andupdateTile
? If they're distinct, can we add some documentation?