最近項目需要做GPS點位的預警分析,其中有用到點聚集的分析。
從網上找了一些文章看了下,結合別人的思路、例子進行了加工。
具體的思路分析:
1、數據存儲類設計,一個的點的設計,一個是聚合點類;
public class Point { /// <summary> /// 經度 /// </summary> public double Longitude { get; set; } /// <summary> /// 緯度 /// </summary> public double Latitude { get; set; } } public class Cluster { /// <summary> /// 聚類中心點 /// </summary> public Point CenterPoint { get; set; } /// <summary> /// 聚集包含的點集 /// </summary> public List<Point> Points { get; set; } }
2、對於傳入的一組點進行初始化,以及對聚類點的初始化;
Cluster cluster = new Cluster() { CenterPoint = points[0], Points = new List<Point> { points[0] } }; clusters.Add(cluster);
3、對所有點進行遍歷,找出距離最近的聚類點,如果距離最近的聚類點小於查找的半徑,該點添加到該聚類點內,否則重新建一個聚類點;
int n = points.Count; // 對所有的點進行遍歷 for (int i = 1; i < n; i++) { double distance = Radius + 1; int clusterIndex = 0; // 存儲距離最近的聚集類的索引 // 對已有的聚類進行遍歷,找出最近的一個聚類 for (int j = 0; j < clusters.Count; j++) { double tempDistance = GeoDistance.GetDistance(clusters[j].CenterPoint, points[i]); if (tempDistance < distance) { distance = tempDistance; clusterIndex = j; } } if (distance <= Radius) { clusters[clusterIndex].Points.Add(points[i]); clusters[clusterIndex].CenterPoint.Latitude = clusters[clusterIndex].Points.Sum(t => t.Latitude) / clusters[clusterIndex].Points.Count; clusters[clusterIndex].CenterPoint.Longitude = clusters[clusterIndex].Points.Sum(t => t.Longitude) / clusters[clusterIndex].Points.Count; } else { cluster = new Cluster() { CenterPoint = points[i], Points = new List<Point> { points[i] } }; clusters.Add(cluster); } }
最后得到的 clusters 就是聚類點集。