Skip to content

Commit

Permalink
Add clusterProperties to ShapeSource (#46)
Browse files Browse the repository at this point in the history
* Add clusterProperties to ShapeSource

* Update CHANGELOG.md
  • Loading branch information
sarahsporck authored Sep 11, 2023
1 parent a2b72b6 commit d856138
Show file tree
Hide file tree
Showing 14 changed files with 2,218 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
Please add unreleased changes in the following style:
PR Title ([#123](link to my pr))
```
Add clusterProperties to ShapeSource ([#46](https://github.com/maplibre/maplibre-react-native/pull/46))

## 9.1.0

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import com.mapbox.rctmgl.components.mapview.RCTMGLMapView;
import com.mapbox.rctmgl.events.AndroidCallbackEvent;
import com.mapbox.rctmgl.events.FeatureClickEvent;
import com.mapbox.rctmgl.utils.ClusterPropertyEntry;
import com.mapbox.rctmgl.utils.DownloadMapImageTask;
import com.mapbox.rctmgl.utils.ImageEntry;

Expand All @@ -44,6 +45,7 @@ public class RCTMGLShapeSource extends RCTSource<GeoJsonSource> {
private Boolean mCluster;
private Integer mClusterRadius;
private Integer mClusterMaxZoom;
private List<Map.Entry<String, ClusterPropertyEntry>> mClusterProperties;

private Integer mMaxZoom;
private Integer mBuffer;
Expand Down Expand Up @@ -110,6 +112,10 @@ public void setClusterMaxZoom(int clusterMaxZoom) {
mClusterMaxZoom = clusterMaxZoom;
}

public void setClusterProperties(List<Map.Entry<String, ClusterPropertyEntry>> clusterProperties) {
mClusterProperties = clusterProperties;
}

public void setMaxZoom(int maxZoom) {
mMaxZoom = maxZoom;
}
Expand Down Expand Up @@ -145,6 +151,14 @@ private GeoJsonOptions getOptions() {
options.withClusterMaxZoom(mClusterMaxZoom);
}

if (mClusterProperties != null) {
for (Map.Entry<String, ClusterPropertyEntry> entry : mClusterProperties) {
ClusterPropertyEntry property = entry.getValue();

options.withClusterProperty(entry.getKey(), property.operator, property.mapping);
}
}

if (mMaxZoom != null) {
options.withMaxZoom(mMaxZoom);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.ViewGroupManager;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.mapbox.mapboxsdk.style.expressions.Expression;
import com.mapbox.rctmgl.components.AbstractEventEmitter;
import com.mapbox.rctmgl.components.annotation.RCTMGLCallout;
import com.mapbox.rctmgl.components.mapview.RCTMGLMapView;
import com.mapbox.rctmgl.components.styles.layers.RCTLayer;
import com.mapbox.rctmgl.events.constants.EventKeys;
import com.mapbox.rctmgl.utils.ClusterPropertyEntry;
import com.mapbox.rctmgl.utils.ExpressionParser;
import com.mapbox.rctmgl.utils.ImageEntry;
import com.mapbox.rctmgl.utils.ResourceUtils;
Expand Down Expand Up @@ -113,6 +115,30 @@ public void setClusterMaxZoomLevel(RCTMGLShapeSource source, int clusterMaxZoom)
source.setClusterMaxZoom(clusterMaxZoom);
}

@ReactProp(name = "clusterProperties")
public void setClusterProperties(RCTMGLShapeSource source, ReadableMap map) {
List<Map.Entry<String, ClusterPropertyEntry>> properties = new ArrayList<>();

ReadableMapKeySetIterator iterator = map.keySetIterator();
while (iterator.hasNextKey()) {
String name = iterator.nextKey();
ReadableArray expressions = map.getArray(name);

Expression operator;
if (expressions.getType(0) == ReadableType.Array) {
operator = ExpressionParser.from(expressions.getArray(0));
} else {
operator = Expression.literal(expressions.getString(0));
}

Expression mapping = ExpressionParser.from(expressions.getArray(1));

properties.add(new AbstractMap.SimpleEntry<>(name, new ClusterPropertyEntry(operator, mapping)));
}

source.setClusterProperties(properties);
}

@ReactProp(name = "maxZoomLevel")
public void setMaxZoomLevel(RCTMGLShapeSource source, int maxZoom) {
source.setMaxZoom(maxZoom);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.mapbox.rctmgl.utils;

import com.mapbox.mapboxsdk.style.expressions.Expression;

public class ClusterPropertyEntry {
public Expression operator;
public Expression mapping;

public ClusterPropertyEntry(Expression _operator, Expression _mapping) {
operator = _operator;
mapping = _mapping;
}
}
1 change: 1 addition & 0 deletions docs/ShapeSource.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
| cluster | `bool` | `none` | `false` | Enables clustering on the source for point shapes. |
| clusterRadius | `number` | `none` | `false` | Specifies the radius of each cluster if clustering is enabled.<br/>A value of 512 produces a radius equal to the width of a tile.<br/>The default value is 50. |
| clusterMaxZoomLevel | `number` | `none` | `false` | Specifies the maximum zoom level at which to cluster points if clustering is enabled.<br/>Defaults to one zoom level less than the value of maxZoomLevel so that, at the maximum zoom level,<br/>the shapes are not clustered. |
| clusterProperties | `object` | `none` | `false` | Specifies custom properties on the generated clusters if clustering<br/>is enabled, aggregating values from clustered points.<br/><br/>Has the form `{ "property_name": [operator, map_expression]}`, where<br/> `operator` is a custom reduce expression that references a special `["accumulated"]` value -<br/> it accumulates the property value from clusters/points the cluster contains<br/> `map_expression` produces the value of a single point<br/><br/>Example: `{ "resultingSum": [["+", ["accumulated"], ["get", "resultingSum"]], ["get", "scalerank"]] }` |
| maxZoomLevel | `number` | `none` | `false` | Specifies the maximum zoom level at which to create vector tiles.<br/>A greater value produces greater detail at high zoom levels.<br/>The default value is 18. |
| buffer | `number` | `none` | `false` | Specifies the size of the tile buffer on each side.<br/>A value of 0 produces no buffer. A value of 512 produces a buffer as wide as the tile itself.<br/>Larger values produce fewer rendering artifacts near tile edges and slower performance.<br/>The default value is 128. |
| tolerance | `number` | `none` | `false` | Specifies the Douglas-Peucker simplification tolerance.<br/>A greater value produces simpler geometries and improves performance.<br/>The default value is 0.375. |
Expand Down
7 changes: 7 additions & 0 deletions docs/docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -3934,6 +3934,13 @@
"default": "none",
"description": "Specifies the maximum zoom level at which to cluster points if clustering is enabled.\nDefaults to one zoom level less than the value of maxZoomLevel so that, at the maximum zoom level,\nthe shapes are not clustered."
},
{
"name": "clusterProperties",
"required": false,
"type": "object",
"default": "none",
"description": "Specifies custom properties on the generated clusters if clustering\nis enabled, aggregating values from clustered points.\n\nHas the form `{ \"property_name\": [operator, map_expression]}`, where\n `operator` is a custom reduce expression that references a special `[\"accumulated\"]` value -\n it accumulates the property value from clusters/points the cluster contains\n `map_expression` produces the value of a single point\n\nExample: `{ \"resultingSum\": [[\"+\", [\"accumulated\"], [\"get\", \"resultingSum\"]], [\"get\", \"scalerank\"]] }`"
},
{
"name": "maxZoomLevel",
"required": false,
Expand Down
Loading

0 comments on commit d856138

Please sign in to comment.