rename to createClusterFeature

This commit is contained in:
jkonieczny
2021-07-12 19:24:23 +02:00
parent 9fd25dddbf
commit a8f7d955af
2 changed files with 73 additions and 12 deletions
+43 -9
View File
@@ -38,10 +38,20 @@ import {getUid} from '../util.js';
* return feature.getGeometry(); * return feature.getGeometry();
* } * }
* ``` * ```
* @property {function(Feature, Array<Feature>):any} [hydrate] Function called after creating
* cluster feature
* See {@link module:ol/geom/Polygon~Polygon#getInteriorPoint} for a way to get a cluster * See {@link module:ol/geom/Polygon~Polygon#getInteriorPoint} for a way to get a cluster
* calculation point for polygons. * calculation point for polygons.
* @property {function(Point, Array<Feature>):Feature} [createClusterFeature]
* Function that takes cluster's ceter {@link module:ol/geom/Point} and array
* of {@link module:ol/Feature} included in this cluster, must return
* {@link module:ol/Feature} that will be used to render. Default implementation is:
* ```js
* function(point, features) {
* return new Feature({
* geometry: point,
* features: features
* });
* }
* ```
* @property {VectorSource} [source] Source. * @property {VectorSource} [source] Source.
* @property {boolean} [wrapX=true] Whether to wrap the world horizontally. * @property {boolean} [wrapX=true] Whether to wrap the world horizontally.
*/ */
@@ -111,10 +121,10 @@ class Cluster extends VectorSource {
}; };
/** /**
* @type {function(Feature, Array<Feature>):any} * @type {function(Point, Array<Feature>):Feature}
* @protected * @protected
*/ */
this.hydrate = options.hydrate; this.createClusterFeature = options.createClusterFeature;
/** /**
* @type {VectorSource} * @type {VectorSource}
@@ -188,6 +198,28 @@ class Cluster extends VectorSource {
this.updateDistance(this.distance, minDistance); this.updateDistance(this.distance, minDistance);
} }
/**
* Current function used to create cluster features
* @return {function(Point, Array<Feature>):Feature | undefined} cluster creation function
* @api
*/
getCreateClusterFeature() {
return this.createClusterFeature;
}
/**
* Set function used to create cluster features
* @param {function(Point, Array<Feature>):Feature | undefined} createClusterFeature creation function
* @api
*/
setCreateClusterFeature(createClusterFeature) {
const changed = this.createClusterFeature != createClusterFeature;
this.createClusterFeature = createClusterFeature;
if (changed) {
this.refresh();
}
}
/** /**
* The configured minimum distance between clusters. * The configured minimum distance between clusters.
* @return {number} The minimum distance in pixels. * @return {number} The minimum distance in pixels.
@@ -302,12 +334,14 @@ class Cluster extends VectorSource {
centroid[0] * (1 - ratio) + searchCenter[0] * ratio, centroid[0] * (1 - ratio) + searchCenter[0] * ratio,
centroid[1] * (1 - ratio) + searchCenter[1] * ratio, centroid[1] * (1 - ratio) + searchCenter[1] * ratio,
]); ]);
const cluster = new Feature(geometry); if (this.createClusterFeature) {
if (this.hydrate) { return this.createClusterFeature(geometry, features);
this.hydrate(cluster, features); } else {
return new Feature({
geometry,
features,
});
} }
cluster.set('features', features, true);
return cluster;
} }
} }
+30 -3
View File
@@ -75,7 +75,7 @@ describe('ol.source.Cluster', function () {
expect(source.getFeatures().length).to.be(1); expect(source.getFeatures().length).to.be(1);
expect(source.getFeatures()[0].get('features').length).to.be(2); expect(source.getFeatures()[0].get('features').length).to.be(2);
}); });
it('hydrates cluster feature with additional fields', function () { it('custom cluster feature with additional fields', function () {
const feature1 = new Feature(new Point([0, 0])); const feature1 = new Feature(new Point([0, 0]));
const feature2 = new Feature(new Point([0, 0])); const feature2 = new Feature(new Point([0, 0]));
feature1.set('value', 1); feature1.set('value', 1);
@@ -84,14 +84,41 @@ describe('ol.source.Cluster', function () {
source: new VectorSource({ source: new VectorSource({
features: [feature1, feature2], features: [feature1, feature2],
}), }),
hydrate: function (clusterFeature, features) { createClusterFeature: function (clusterPoint, features) {
clusterFeature.set('sum', 3); let sum = 0;
for (const ft of features) {
sum += ft.get('value');
}
return new Feature({
geometry: clusterPoint,
sum: sum,
});
}, },
}); });
source.loadFeatures(extent, 1, projection); source.loadFeatures(extent, 1, projection);
expect(source.getFeatures().length).to.be(1); expect(source.getFeatures().length).to.be(1);
expect(source.getFeatures()[0].get('sum')).to.be(3); expect(source.getFeatures()[0].get('sum')).to.be(3);
}); });
it('reacts setCreateClusterFeature', function () {
const feature1 = new Feature(new Point([0, 0]));
const feature2 = new Feature(new Point([0, 0]));
const source = new Cluster({
source: new VectorSource({
features: [feature1, feature2],
}),
});
source.loadFeatures(extent, 1, projection);
expect(source.getFeatures().length).to.be(1);
expect(source.getFeatures()[0].get('sum')).to.be(undefined);
source.setCreateClusterFeature(function (clusterPoint, features) {
return new Feature({
geometry: clusterPoint,
sum: features.length,
});
});
expect(source.getFeatures().length).to.be(1);
expect(source.getFeatures()[0].get('sum')).to.be(2);
});
}); });
describe('#setDistance', function () { describe('#setDistance', function () {