public IList <P> RunCluster() { // Skip points outside the grid, not visible to user then skip those IList <P> filtered = ClusterInfo.DoFilterData(this._jsonReceive.Zoomlevel) ? FilterUtil.FilterDataByViewport(this.points, Grid) : this.points; // Put points in buckets foreach (var p in filtered) { var idxy = GetPointMappedIds(p, Grid, DeltaX, DeltaY); var idx = idxy[0]; var idy = idxy[1]; // Bucket id var id = GetId(idx, idy); // Bucket exists, add point if (BucketsLookup.ContainsKey(id)) { BucketsLookup[id].Points.Add(p); } // New bucket, create and add point else { var bucket = new Bucket(idx, idy, id); bucket.Points.Add(p); BucketsLookup.Add(id, bucket); } } // Calculate centroid for all buckets SetCentroidForAllBuckets(BucketsLookup.Values); // Merge if gridpoint is to close if (GmcSettings.Get.DoMergeGridIfCentroidsAreCloseToEachOther) { MergeClustersGrid(); } if (GmcSettings.Get.DoUpdateAllCentroidsToNearestContainingPoint) { UpdateAllCentroidsToNearestContainingPoint(); } // Check again // Merge if gridpoint is to close if (GmcSettings.Get.DoMergeGridIfCentroidsAreCloseToEachOther && GmcSettings.Get.DoUpdateAllCentroidsToNearestContainingPoint) { MergeClustersGrid(); // And again set centroid to closest point in bucket UpdateAllCentroidsToNearestContainingPoint(); } return(GetClusterResult(Grid)); }