Reputation: 1022
I'm messing with the migration of HERE Maps JS API from v2.5.4 to v3.
The biggest issue I'm facing is related to the H.clustering.Provider
. While the v2.x version worked like a charm, the v3 version seems to be really slow.
Given the following code:
var clusterProvider = new H.clustering.Provider([], {
clusteringOptions: {
eps: 32,
minWeight: 3,
max: 20,
min: 10
}
});
var clusteringLayer = new H.map.layer.ObjectLayer(clusterProvider);
map.addLayer(clusteringLayer);
for(i = 0; i < 1000; i++)
{
var lat = 43 + (i * 0.001);
var lng = 13 + (i * 0.001);
var dp = new H.clustering.DataPoint(lat, lng, null, null);
clusterProvider.addDataPoint(dp); // <- this line cause hanging
}
The page hangs for many seconds before rendering the cluster.
In the documentation, I read:
addDataPoint (dataPoint)
This method adds a data point to the provider. Beware that this method provokes reclustering of the whole data set.
However, I cannot use the setDataPoints
method because I need the cluster to refresh at every map pan or zoom (and not to start over).
In the v2 version I would have called the addObject
method of the clustering provider for each data point and the cluster
at the end. This workflow was immediate.
Any idea?
Thanks in advance
Upvotes: 1
Views: 799
Reputation: 932
So, from what I get from the documentation and the example here, I think your issue is that for every point you add you're running a full re-clustering of the entire data set (whatever you have already added). So you will have 1000 clustering operations becoming more and more complex as you add individual data points.
In your case, you should be fine either filling the data points array before instantiating the Provider or using setDataPoints at a later stage. The clustering operation has to happen at some point. In the old API it would happen when you call 'cluster' but now it happens on demand when the object layer is rendered and every time you either add data points or set the data points.
The map already takes care of updating the markers for you based on the static cluster calculation.
In summary the process is as follows:
So give the example linked above a spin (it clusters more than a thousand points with hardly any delay for me) and see if it does what you're looking for.
EDIT: (based on comments below) Here are my suggestions: Keep two arrays, one representing your whole data set, one keeping track of change batches. Always populate the batch array from your server responses. Once mapviewchangeend hits add the batch array to the data array and then set the data set array on the provider.
var clusterProvider = new H.clustering.Provider([], {
clusteringOptions: {
eps: 32,
minWeight: 3,
max: 20,
min: 10
}
});
var clusteringLayer = new H.map.layer.ObjectLayer(clusterProvider);
map.addLayer(clusteringLayer);
var clusterSet = [],
batchSet = [],
maxDataSetSize = 5000;
map.addEventListener('mapviewchangeend', function() {
// if we added any points between mapviewchangestart / end
if(batchSet.length > 0) {
// we add the data and slice take a subset of 5000 points to keep
// the data set at manageable size (adjust to your liking)
clusterSet = batchSet.concat(clusterSet).slice(0, maxDataSetSize);
clusteringProvider.setDataPoints(clusterSet);
}
batchSet = [];
});
//whereever you receive your data:
function onReceiveData(dataPoints) {
// always push to the batch set
batchSet = batchSet.concat(dataPoints);
}
Upvotes: 2