public IList <MapPoint> RunCluster() { // Skip points outside the grid, not visible to user then skip those //IList<MapPoint> filtered = ClusterInfo.DoFilterData(this._jsonReceive.Zoomlevel) // TODO: by kit // ? FilterUtil.FilterDataByViewport(this.points, Grid) // : this.points; IList <MapPoint> filtered = 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 (GmcConfiguration.Get.DoMergeGridIfCentroidsAreCloseToEachOther) { MergeClustersGrid(); } if (GmcConfiguration.Get.DoUpdateAllCentroidsToNearestContainingPoint) { UpdateAllCentroidsToNearestContainingPoint(); } // Check again // Merge if gridpoint is to close if (GmcConfiguration.Get.DoMergeGridIfCentroidsAreCloseToEachOther && GmcConfiguration.Get.DoUpdateAllCentroidsToNearestContainingPoint) { MergeClustersGrid(); // And again set centroid to closest point in bucket UpdateAllCentroidsToNearestContainingPoint(); } return(GetClusterResult(Grid)); }
public IPoints RunClusterAlgo(ClusterInfo clusterInfo) { // Skip points outside the grid IPoints filtered = clusterInfo.IsFilterData ? FilterDataset(Dataset, Grid) : Dataset; // Put points in buckets foreach (var p in filtered.Data) { 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 (AlgoConfig.DoMergeGridIfCentroidsAreCloseToEachOther) { MergeClustersGrid(); } if (AlgoConfig.DoUpdateAllCentroidsToNearestContainingPoint) { UpdateAllCentroidsToNearestContainingPoint(); } // Check again // Merge if gridpoint is to close if (AlgoConfig.DoMergeGridIfCentroidsAreCloseToEachOther && AlgoConfig.DoUpdateAllCentroidsToNearestContainingPoint) { MergeClustersGrid(); // And again set centroid to closest point in bucket UpdateAllCentroidsToNearestContainingPoint(); } return(GetClusterResult(Grid)); }
void MergeClustersGridHelper(string currentKey, IEnumerable <string> neighborKeys) { double minDistX = DeltaX / GmcSettings.Get.MergeWithin; double minDistY = DeltaY / GmcSettings.Get.MergeWithin; // If clusters in grid are too close to each other, merge them double withinDist = Math.Max(minDistX, minDistY); foreach (var neighborKey in neighborKeys) { if (!BucketsLookup.ContainsKey(neighborKey)) { continue; } var neighbor = BucketsLookup[neighborKey]; if (neighbor.IsUsed == false) { continue; } var current = BucketsLookup[currentKey]; var dist = MathTool.Distance(current.Centroid, neighbor.Centroid); if (dist > withinDist) { continue; } current.Points.AddRange(neighbor.Points); //O(n) // recalc centroid var centroidPoint = GetCentroidFromClusterLatLon(current.Points); current.Centroid = centroidPoint; neighbor.IsUsed = false; // merged, then not used anymore neighbor.Points.Clear(); // clear mem } }