Inheritance: SuperMap.Web.Core.GeoPoint
 private static bool SearchAndMerge(Cluster cluster, int ox, int oy, double diameter, Dictionary<int, Cluster> orig, bool overlapExists)
 {
     int x = cluster.Cx + ox;
     int y = cluster.Cy + oy;
     int key = (x << 16) | y;
     if (orig.ContainsKey(key) && (orig[key].Count > 0))
     {
         Cluster neighbour = orig[key];
         double distanceX = neighbour.X - cluster.X;
         double distanceY = neighbour.Y - cluster.Y;
         if ((Math.Sqrt((distanceX * distanceX) + (distanceY * distanceY)) < diameter) && (neighbour != cluster))
         {
             overlapExists = true;
             Merge(cluster, neighbour);
         }
     }
     return overlapExists;
 }
        //遍历每一个点,把其归类,得到最终的聚类点Cluster,其所在格网index的X/Y组成Key
        private static Dictionary<int, Cluster> AssignGeoPointsToClusters(IEnumerable<Feature> features, GeoPoint bottomLeft, double diameter)
        {
            Dictionary<int, Cluster> dictionary = new Dictionary<int, Cluster>();
            GeoPoint gp = null;
            foreach (Feature feature in features)
            {
                if (feature.Geometry == null)
                {
                    continue;
                }
                if (feature.Geometry is GeoPoint)
                {
                    gp = feature.Geometry as GeoPoint;
                }
                else
                {
                    Rectangle2D bounds = feature.Geometry.Bounds;
                    if (bounds.IsEmpty)
                    {
                        continue;
                    }
                    gp = new GeoPoint(bounds.Center.X, bounds.Center.Y);
                }

                double x = gp.X;
                double y = gp.Y;
                int cx = (int)Math.Round((x - bottomLeft.X) / diameter);
                int cy = (int)Math.Round((y - bottomLeft.Y) / diameter);
                int key = (cx << 16) | cy;//int是32位的  左16位是x,右16位是y
                if (dictionary.ContainsKey(key))
                {
                    Cluster cluster = dictionary[key];
                    cluster.X = (cluster.X + x) / 2.0;
                    cluster.Y = (cluster.Y + y) / 2.0;
                    cluster.Features.Add(feature);
                }//有就合并
                else
                {
                    dictionary[key] = new Cluster(x, y, cx, cy);
                    dictionary[key].Features.Add(feature);
                }//没有就new一个
            }
            return dictionary;
        }
 private static void Merge(Cluster source, Cluster neighbour)
 {
     double num = source.Count + neighbour.Count;
     source.X = ((source.Count * source.X) + (neighbour.Count * neighbour.X)) / num;
     source.Y = ((source.Count * source.Y) + (neighbour.Count * neighbour.Y)) / num;
     foreach (Feature feature in neighbour.Features)
     {
         source.Features.Add(feature);
     }
     neighbour.Features.Clear();
 }
        private static Dictionary<int, Cluster> AssignGeoPointsToClusters(IEnumerable<Feature> features, ObservableCollection<GeoRegion> geos)
        {
            Dictionary<int, Cluster> dictionary = new Dictionary<int, Cluster>();
            GeoPoint gp = null;
            foreach (Feature feature in features)
            {
                if (feature.Geometry == null)
                {
                    continue;
                }
                gp = feature.Geometry as GeoPoint;

                if (gp == null)
                {
                    Rectangle2D bounds = feature.Geometry.Bounds;
                    if (bounds.IsEmpty)
                    {
                        continue;
                    }
                    gp = new GeoPoint(bounds.Center.X, bounds.Center.Y);
                }

                bool isContained = false;
                double x = gp.X;
                double y = gp.Y;

                foreach (GeoRegion clusterRegion in geos)
                {
                    if (clusterRegion.Bounds.Contains(x, y) && clusterRegion.Contains(x, y))
                    {
                        int key = -geos.IndexOf(clusterRegion);
                        if (dictionary.ContainsKey(key))
                        {
                            Cluster cluster = dictionary[key];
                            cluster.X += x;
                            cluster.Y += y;
                            cluster.Features.Add(feature);
                        }//有就合并
                        else
                        {
                            dictionary[key] = new Cluster(x, y);
                            dictionary[key].Features.Add(feature);
                        }//没有就new一个
                        isContained = true;
                        break;
                    }
                }
                int key1 = feature.GetHashCode();
                if (!isContained)
                {
                    if (!dictionary.ContainsKey(key1))
                    {
                        dictionary[key1] = new Cluster(gp.X, gp.Y);
                        dictionary[key1].Features.Add(feature);
                    }
                }
            }

            Cluster cltValue;
            int featuresCount = 0;
            foreach (var clt in dictionary)
            {
                cltValue = clt.Value;
                featuresCount = cltValue.Features.Count;
                clt.Value.X = cltValue.X / featuresCount;
                clt.Value.Y = cltValue.Y / featuresCount;
            }

            return dictionary;
        }