Skip to content

Commit

Permalink
make initial option in map/reduce optional (#114)
Browse files Browse the repository at this point in the history
  • Loading branch information
mourner authored Jan 16, 2019
1 parent ab61d0c commit 2b0e89b
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 10 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,15 +80,15 @@ Returns the zoom on which the cluster expands into several children (useful for

In addition to the options above, supercluster supports property aggregation with the following three options:

- `initial`: a function that returns an object with cluster's initial properties.
- `map`: a function that returns properties to use for individual points.
- `reduce`: a reduce function for calculating properties in clusters.
- `initial`: an optional function that returns an object with cluster's initial properties;
if not provided, reduce will start with mapped values of the first cluster item.

Example of setting up a `sum` cluster property that accumulates the sum of `myValue` property values:

```js
var index = new Supercluster({
initial: function() { return {sum: 0}; },
map: function(props) { return {sum: props.myValue}; },
reduce: function(accumulated, props) { accumulated.sum += props.sum; }
});
Expand Down
18 changes: 10 additions & 8 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const defaultOptions = {
reduce: null, // (accumulated, props) => { accumulated.sum += props.sum; }

// initial properties of a cluster (before running the reducer)
initial: () => ({}), // () => ({sum: 0})
initial: null, // () => ({sum: 0})

// properties to use for individual points when running the reducer
map: props => props // props => ({sum: props.my_value})
Expand Down Expand Up @@ -238,8 +238,12 @@ export default class Supercluster {
let clusterProperties = null;

if (reduce) {
clusterProperties = initial();
this._accumulate(clusterProperties, p);
if (initial) {
clusterProperties = initial();
reduce(clusterProperties, this._map(p));
} else {
clusterProperties = this._map(p);
}
}

// encode both zoom and point index on which the cluster originated
Expand All @@ -259,7 +263,7 @@ export default class Supercluster {
b.parentId = id;

if (reduce) {
this._accumulate(clusterProperties, b);
reduce(clusterProperties, this._map(b));
}
}

Expand All @@ -274,10 +278,8 @@ export default class Supercluster {
return clusters;
}

_accumulate(clusterProperties, point) {
const {map, reduce} = this.options;
const properties = point.numPoints ? point.properties : map(this.points[point.index].properties);
reduce(clusterProperties, properties);
_map(point) {
return point.numPoints ? point.properties : this.options.map(this.points[point.index].properties);
}
}

Expand Down
11 changes: 11 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,17 @@ test('returns cluster expansion zoom for maxZoom', (t) => {
});

test('aggregates cluster properties with reduce', (t) => {
const index = new Supercluster({
map: props => ({sum: props.scalerank}),
reduce: (a, b) => { a.sum += b.sum; }
}).load(places.features);

t.equal(index.getTile(0, 0, 0).features[0].tags.sum, 69);

t.end();
});

test('aggregates cluster properties with initial provided', (t) => {
const index = new Supercluster({
initial: () => ({sum: 0}),
map: props => ({sum: props.scalerank}),
Expand Down

0 comments on commit 2b0e89b

Please sign in to comment.