Skip to content

Commit

Permalink
Add getClusterExpansionZoom to ShapeSource (rnmapbox#1279)
Browse files Browse the repository at this point in the history
  • Loading branch information
janicduplessis authored and mikalaiulasevich committed Sep 23, 2021
1 parent 2e6e702 commit dc6d860
Show file tree
Hide file tree
Showing 9 changed files with 146 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -188,4 +188,33 @@ public void querySourceFeatures(String callbackID,
AndroidCallbackEvent event = new AndroidCallbackEvent(this, callbackID, payload);
mManager.handleEvent(event);
}

public void getClusterExpansionZoom(String callbackID, int clusterId) {
if (mSource == null) {
WritableMap payload = new WritableNativeMap();
payload.putString("error", "source is not yet loaded");
AndroidCallbackEvent event = new AndroidCallbackEvent(this, callbackID, payload);
mManager.handleEvent(event);
return;
}
List<Feature> features = mSource.querySourceFeatures(Expression.eq(Expression.id(), clusterId));
int zoom = -1;
if (features.size() > 0) {
zoom = mSource.getClusterExpansionZoom(features.get(0));
}

if (zoom == -1) {
WritableMap payload = new WritableNativeMap();
payload.putString("error", "Could not get zoom for cluster id " + clusterId);
AndroidCallbackEvent event = new AndroidCallbackEvent(this, callbackID, payload);
mManager.handleEvent(event);
return;
}

WritableMap payload = new WritableNativeMap();
payload.putInt("data", zoom);

AndroidCallbackEvent event = new AndroidCallbackEvent(this, callbackID, payload);
mManager.handleEvent(event);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -151,12 +151,14 @@ public Map<String, String> customEvents() {

//region React Methods
public static final int METHOD_FEATURES = 103;
public static final int METHOD_GET_CLUSTER_EXPANSION_ZOOM = 104;

@Nullable
@Override
public Map<String, Integer> getCommandsMap() {
return MapBuilder.<String, Integer>builder()
.put("features", METHOD_FEATURES)
.put("getClusterExpansionZoom", METHOD_GET_CLUSTER_EXPANSION_ZOOM)
.build();
}

Expand All @@ -169,6 +171,9 @@ public void receiveCommand(RCTMGLShapeSource source, int commandID, @Nullable Re
ExpressionParser.from(args.getArray(1))
);
break;
case METHOD_GET_CLUSTER_EXPANSION_ZOOM:
source.getClusterExpansionZoom(args.getString(0), args.getInt(1));
break;
}
}
}
16 changes: 16 additions & 0 deletions docs/ShapeSource.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,22 @@ shapeSource.features()
```


#### getClusterExpansionZoom(clusterId)

Returns the zoom needed to expand the cluster.

##### arguments
| Name | Type | Required | Description |
| ---- | :--: | :------: | :----------: |
| `clusterId` | `number` | `Yes` | The id of the cluster to expand. |



```javascript
const zoom = await shapeSource.getClusterExpansionZoom(clusterId);
```


#### onPress(event)


Expand Down
27 changes: 27 additions & 0 deletions docs/docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -3573,6 +3573,33 @@
"\nshapeSource.features()\n\n"
]
},
{
"name": "getClusterExpansionZoom",
"docblock": "Returns the zoom needed to expand the cluster.\n\n@example\nconst zoom = await shapeSource.getClusterExpansionZoom(clusterId);\n\n@param {number} clusterId - The id of the cluster to expand.\n@return {number}",
"modifiers": [
"async"
],
"params": [
{
"name": "clusterId",
"description": "The id of the cluster to expand.",
"type": {
"name": "number"
},
"optional": false
}
],
"returns": {
"description": null,
"type": {
"name": "number"
}
},
"description": "Returns the zoom needed to expand the cluster.",
"examples": [
"\nconst zoom = await shapeSource.getClusterExpansionZoom(clusterId);\n\n"
]
},
{
"name": "onPress",
"docblock": null,
Expand Down
4 changes: 3 additions & 1 deletion index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,9 @@ declare namespace MapboxGL {
* Sources
*/
class VectorSource extends Component<VectorSourceProps> { }
class ShapeSource extends Component<ShapeSourceProps> { }
class ShapeSource extends Component<ShapeSourceProps> {
getClusterExpansionZoom(clusterId: number): Promise<number>;
}
class RasterSource extends Component<RasterSourceProps> { }

/**
Expand Down
2 changes: 2 additions & 0 deletions ios/RCTMGL/RCTMGLShapeSource.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,6 @@

- (nonnull NSArray<id <MGLFeature>> *)featuresMatchingPredicate:(nullable NSPredicate *)predicate;

- (double)getClusterExpansionZoom:(nonnull NSNumber *)clusterId;

@end
34 changes: 22 additions & 12 deletions ios/RCTMGL/RCTMGLShapeSource.m
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ - (void)setUrl: (NSString*) url
- (void)setShape:(NSString *)shape
{
_shape = shape;

if (self.source != nil) {
MGLShapeSource *source = (MGLShapeSource *)self.source;
[source setShape: shape == nil ? nil : [RCTMGLUtils shapeFromGeoJSON:_shape]];
Expand All @@ -46,19 +46,19 @@ - (void)removeFromMap
if (self.map.style == nil) {
return;
}

[super removeFromMap];
}

- (nullable MGLSource*)makeSource
{
NSDictionary<MGLShapeSourceOption, id> *options = [self _getOptions];

if (_shape != nil) {
MGLShape *shape = [RCTMGLUtils shapeFromGeoJSON:_shape];
return [[MGLShapeSource alloc] initWithIdentifier:self.id shape:shape options:options];
}

if (_url != nil) {
NSURL *url = [[NSURL alloc] initWithString:_url];
return [[MGLShapeSource alloc] initWithIdentifier:self.id URL:url options:options];
Expand All @@ -69,39 +69,49 @@ - (nullable MGLSource*)makeSource
- (NSDictionary<MGLShapeSourceOption, id>*)_getOptions
{
NSMutableDictionary<MGLShapeSourceOption, id> *options = [[NSMutableDictionary alloc] init];

if (_cluster != nil) {
options[MGLShapeSourceOptionClustered] = [NSNumber numberWithBool:[_cluster intValue] == 1];
}

if (_clusterRadius != nil) {
options[MGLShapeSourceOptionClusterRadius] = _clusterRadius;
}

if (_clusterMaxZoomLevel != nil) {
options[MGLShapeSourceOptionMaximumZoomLevelForClustering] = _clusterMaxZoomLevel;
}

if (_maxZoomLevel != nil) {
options[MGLShapeSourceOptionMaximumZoomLevel] = _maxZoomLevel;
}

if (_buffer != nil) {
options[MGLShapeSourceOptionBuffer] = _buffer;
}

if (_tolerance != nil) {
options[MGLShapeSourceOptionSimplificationTolerance] = _tolerance;
}

return options;
}

- (nonnull NSArray<id <MGLFeature>> *)featuresMatchingPredicate:(nullable NSPredicate *)predicate
{
MGLShapeSource *shapeSource = (MGLShapeSource *)self.source;

return [shapeSource featuresMatchingPredicate:predicate];
}

- (double)getClusterExpansionZoom:(nonnull NSNumber *)clusterId
{
MGLShapeSource *shapeSource = (MGLShapeSource *)self.source;
NSArray<id<MGLFeature>> *features = [shapeSource featuresMatchingPredicate: [NSPredicate predicateWithFormat:@"%K = %i", @"cluster_id", clusterId.intValue]];
if (features.count == 0) {
return -1;
}
return [shapeSource zoomLevelForExpandingCluster:(MGLPointFeatureCluster *)features[0]];
}

@end
27 changes: 24 additions & 3 deletions ios/RCTMGL/RCTMGLShapeSourceManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -46,25 +46,46 @@ - (UIView*)view
{
[self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *manager, NSDictionary<NSNumber*, UIView*> *viewRegistry) {
RCTMGLShapeSource* shapeSource = viewRegistry[reactTag];

if (![shapeSource isKindOfClass:[RCTMGLShapeSource class]]) {
RCTLogError(@"Invalid react tag, could not find RCTMGLMapView");
return;
}

NSPredicate* predicate = [FilterParser parse:filter];
NSArray<id<MGLFeature>> *shapes = [shapeSource featuresMatchingPredicate: predicate];

NSMutableArray<NSDictionary*> *features = [[NSMutableArray alloc] initWithCapacity:shapes.count];
for (int i = 0; i < shapes.count; i++) {
[features addObject:shapes[i].geoJSONDictionary];
}

resolve(@{
@"data": @{ @"type": @"FeatureCollection", @"features": features }
});
}];
}

RCT_EXPORT_METHOD(getClusterExpansionZoom:(nonnull NSNumber*)reactTag
clusterId:(nonnull NSNumber*)clusterId
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
[self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *manager, NSDictionary<NSNumber*, UIView*> *viewRegistry) {
RCTMGLShapeSource* shapeSource = (RCTMGLShapeSource *)viewRegistry[reactTag];

if (![shapeSource isKindOfClass:[RCTMGLShapeSource class]]) {
RCTLogError(@"Invalid react tag, could not find RCTMGLMapView");
return;
}

double zoom = [shapeSource getClusterExpansionZoom:clusterId];
if (zoom == -1) {
reject(@"zoom_error", [NSString stringWithFormat:@"Could not get zoom for cluster id %@", clusterId], nil);
return;
}
resolve(@{@"data":@(zoom)});
}];
}

@end
18 changes: 18 additions & 0 deletions javascript/components/ShapeSource.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,24 @@ class ShapeSource extends NativeBridgeComponent(AbstractSource) {
return res.data;
}

/**
* Returns the zoom needed to expand the cluster.
*
* @example
* const zoom = await shapeSource.getClusterExpansionZoom(clusterId);
*
* @param {number} clusterId - The id of the cluster to expand.
* @return {number}
*/
async getClusterExpansionZoom(clusterId) {
const res = await this._runNativeCommand(
'getClusterExpansionZoom',
this._nativeRef,
[clusterId],
);
return res.data;
}

setNativeProps(props) {
const shallowProps = Object.assign({}, props);

Expand Down

0 comments on commit dc6d860

Please sign in to comment.