最近项目需要做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 就是聚类点集。