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

Computed (on-demand) shape source #6940

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
403ac49
Sketching out CustomVectorSource interface
Nov 1, 2016
5d74f08
Sketch out interface
Nov 2, 2016
579ef87
Add to Mapbox.h header
Nov 3, 2016
095281e
Move tilesize into options
Nov 3, 2016
1656672
obj-c class is getting called for tiles
Nov 3, 2016
d2c62ef
Get rid of setSourceLoaded non-sense
Nov 3, 2016
908a7e2
It works!
Nov 3, 2016
30c9cb9
Inherit Options from GeoJSONOptions
Nov 3, 2016
aa5b27e
Create a common base class between MGLGeoJSONSource and MGLCustomVect…
Nov 3, 2016
b6015b8
Dont use hardcoded default tile size
Nov 3, 2016
6986db5
Fix indentation
Nov 3, 2016
7482313
Revert development team setting
Nov 3, 2016
f556388
Revert more project file changes
Nov 3, 2016
0f61a1f
Update docs
Nov 3, 2016
7434506
Run MGLCustomSource queries on an NSOperationQueue
Nov 7, 2016
474905b
Add example usage of MGLCustomVectorSource to setting in iosapp target
Nov 7, 2016
b2cdaa3
Add method to reload a tile
Nov 7, 2016
36f0dd2
Change names in obj-c classes to be consistent with project naming co…
Nov 7, 2016
a530538
Change indentation to match project standards
Nov 7, 2016
6c589ed
Fix Options not getting used for geojson or custom source
Nov 7, 2016
dcd7f8e
add function to custom source to reload all tiles
Nov 8, 2016
e403ed9
Fix crash when parsing an empty feature collection with clustering en…
Nov 8, 2016
50e7fe9
Revert unintended changes to project file
Nov 10, 2016
adfc031
Revert unintended whitespace
Nov 10, 2016
570da2c
re-indent to 4 spaces
Nov 10, 2016
cb76fe9
naming/spelling changes
Nov 10, 2016
f6a908f
Change MGLCustomVectorSourceDataSource to not use a callback
Nov 10, 2016
d731490
Make custom source demo work
Nov 10, 2016
92ed922
Use MGLGeoJSONSourceOption type
Nov 10, 2016
18e7c60
add boost to header search paths so mbgl/util/tile_cover.hpp can be i…
Nov 10, 2016
d742e84
Revert "add boost to header search paths so mbgl/util/tile_cover.hpp …
Nov 10, 2016
ccb17de
Add -reloadTileInCoordinateBounds:zoomLevel: method to MGLCustomVecto…
Nov 10, 2016
d8ffb91
Add import to Mapbox.h
Nov 10, 2016
d737370
Add new MGLCustomVectorSourceDataSource method based on bounds instea…
Nov 14, 2016
2e9e568
updated cmake file list
Nov 17, 2016
244d689
Move hash functions for tile_id into their own header, so tile_id.hpp…
Nov 29, 2016
2f68306
Enable featuresInCoordinateBounds:zoomLevel: in MGLCustomVectorSource…
Nov 29, 2016
c9fba94
Fix error after rebasing to master
Dec 8, 2016
6bde7e8
add removeFromMapView function
Dec 8, 2016
286550a
Merge branch 'master' into custom-vector-source-rebase-master
Jan 23, 2017
b591f5b
Update based on changes in master
Jan 23, 2017
fb37624
re-add min zoom option that was removed in merge
Jan 23, 2017
517f447
Fix typoed option name
Jan 24, 2017
daa5209
Fix build for macos
Jan 24, 2017
fc0b94b
Add ComputedShapeSource to macos target
Jan 24, 2017
fcaa6e8
Export classes, and add docs for MGLAbstractShapeSource
Jan 24, 2017
1597509
Add Graticule layer to mac app to test MGLComputedShapeSource
Jan 24, 2017
206783b
Documentation fixes
Jan 24, 2017
bee3b28
Add entries to iOS and macOS change logs
Jan 24, 2017
16fb067
Clear cache when reloading source
Jan 26, 2017
9e8dc9a
Merge remote-tracking branch 'origin/master' into feature/custom-vect…
Mar 1, 2017
cbe2815
Fix duplicated options after merging
Mar 1, 2017
b31841d
Fix merge error
Mar 1, 2017
13ef94e
fix `make test` failing
Mar 1, 2017
ab55326
Fix failing test
Mar 1, 2017
3fcb46f
Test for MGLComputedShapeSource, but all it tests is the initializer
Mar 1, 2017
f01e1f2
First test for CustomVectorSource
Mar 1, 2017
f75b34d
A couple more tests
Mar 1, 2017
c73f6de
Fix memory corruption when removing a ComputedShapeSource
Mar 3, 2017
0be7292
Change indent in MGLComputedShapeSourceTests to 4 spaces
Mar 3, 2017
86ab288
Update layer removal to be consistent with #7962
Mar 6, 2017
4bb3a9c
Fix crash when source is dealloced
Mar 6, 2017
883f72e
Address review comments
Mar 7, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions cmake/core-files.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -364,9 +364,13 @@ set(MBGL_CORE_FILES
src/mbgl/style/layers/symbol_layer_properties.hpp

# style/sources
include/mbgl/style/sources/custom_vector_source.hpp
include/mbgl/style/sources/geojson_source.hpp
include/mbgl/style/sources/raster_source.hpp
include/mbgl/style/sources/vector_source.hpp
src/mbgl/style/sources/custom_vector_source.cpp
src/mbgl/style/sources/custom_vector_source_impl.cpp
src/mbgl/style/sources/custom_vector_source_impl.hpp
src/mbgl/style/sources/geojson_source.cpp
src/mbgl/style/sources/geojson_source_impl.cpp
src/mbgl/style/sources/geojson_source_impl.hpp
Expand Down Expand Up @@ -421,6 +425,7 @@ set(MBGL_CORE_FILES
src/mbgl/tile/tile_cache.cpp
src/mbgl/tile/tile_cache.hpp
src/mbgl/tile/tile_id.hpp
src/mbgl/tile/tile_id_hash.hpp
src/mbgl/tile/tile_id_io.cpp
src/mbgl/tile/tile_loader.hpp
src/mbgl/tile/tile_loader_impl.hpp
Expand Down
1 change: 1 addition & 0 deletions cmake/test-files.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ set(MBGL_TEST_FILES
test/style/conversion/stringify.test.cpp

# style
test/style/custom_vector_source.test.cpp
test/style/filter.test.cpp

# style/function
Expand Down
31 changes: 31 additions & 0 deletions include/mbgl/style/sources/custom_vector_source.hpp
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(const CanonicalTileID&)> fetchTile);

void setTileData(const CanonicalTileID&, const mapbox::geojson::geojson&);
void reloadTile(const CanonicalTileID&);
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
3 changes: 3 additions & 0 deletions include/mbgl/style/sources/geojson_source.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>

Expand All @@ -26,7 +27,9 @@ using SuperclusterPointer = std::unique_ptr<mapbox::supercluster::Supercluster>;

struct GeoJSONOptions {
// GeoJSON-VT options
uint8_t minzoom = 0;
uint8_t maxzoom = 18;
uint16_t tileSize = util::tileSize;
uint16_t buffer = 128;
double tolerance = 0.375;

Expand Down
1 change: 1 addition & 0 deletions platform/darwin/docs/theme/assets/css/jazzy.css.scss
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,7 @@ pre code {
.nav-group-task[data-name="MGLStyleFunction"],
.nav-group-task[data-name="MGLStyleLayer"],
.nav-group-task[data-name="MGLTileSource"],
.nav-group-task[data-name="MGLAbstractShapeSource"],
.nav-group-task[data-name="MGLVectorStyleLayer"] {
.nav-group-task-link::after {
@extend %nav-group-task-gloss;
Expand Down
99 changes: 99 additions & 0 deletions platform/darwin/src/MGLAbstractShapeSource.h
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`.
*/
Copy link
Contributor

Choose a reason for hiding this comment

The 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


@end
81 changes: 81 additions & 0 deletions platform/darwin/src/MGLAbstractShapeSource.mm
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;
}

18 changes: 18 additions & 0 deletions platform/darwin/src/MGLAbstractShapeSource_Private.h
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
77 changes: 77 additions & 0 deletions platform/darwin/src/MGLComputedShapeSource.h
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
Loading