/// <summary>${WP_mapping_FeaturesClusterer_method_OnCreateFeature_D}</summary> /// <param name="cluster">${WP_mapping_FeaturesClusterer_method_OnCreateFeature_param_cluster}</param> /// <param name="center">${WP_mapping_FeaturesClusterer_method_OnCreateFeature_param_center}</param> /// <param name="maxClusterCount">${WP_mapping_FeaturesClusterer_method_OnCreateFeature_param_maxClusterCount}</param> protected override Feature OnCreateFeature(FeatureCollection cluster, GeoPoint center, int maxClusterCount) { lastFC = cluster; lastCenter = center; lastMaxClusterCount = maxClusterCount; if (cluster.Count == 1) { return cluster[0]; } Feature feature = null; double size = (Math.Log((double)(cluster.Count / 10)) * 10.0) + 20.0;//小于10个,size都是负无穷 if (size < 12.0) { size = 12.0; } if (cluster.Count <= this.MaximumCount) { if (!this.cache.ContainsKey(cluster.Count)) { ScatterStyle style = new ScatterStyle(cluster.Count, EnableRotation) { ForeColor = this.Foreground, FillColor = this.Background }; this.cache.Add(cluster.Count, style); }//如果没有这种 样式,就创建新的样式。 根据Count决定。 ScatterStyle style3 = this.cache[cluster.Count]; feature = new Feature { Geometry = center, Style = style3 }; } else { feature = new ClusterFeature(size) { Geometry = center }; }//如果不达到聚合数(太多,比如大于10),则去生成新的样式 feature.Attributes.Add("Count", cluster.Count); feature.Attributes.Add("Size", size); feature.Attributes.Add("Color", ClusterUtil.InterpolateColor((double)cluster.Count, maxClusterCount, this.Gradient)); return feature; }
private static Dictionary<int, Cluster> MergeOverlappingClusters(double diameter, Dictionary<int, Cluster> orig, GeoPoint lowerLeft, out bool overlapExists, BackgroundWorker worker) { overlapExists = false; Dictionary<int, Cluster> dictionary = new Dictionary<int, Cluster>(); foreach (int key in orig.Keys) { Cluster cluster = orig[key]; if (cluster.Count != 0) { overlapExists = SearchAndMerge(cluster, -1, -1, diameter, orig, overlapExists); overlapExists = SearchAndMerge(cluster, -1, 0, diameter, orig, overlapExists); overlapExists = SearchAndMerge(cluster, -1, 1, diameter, orig, overlapExists); overlapExists = SearchAndMerge(cluster, 0, -1, diameter, orig, overlapExists); overlapExists = SearchAndMerge(cluster, 0, 1, diameter, orig, overlapExists); overlapExists = SearchAndMerge(cluster, 1, -1, diameter, orig, overlapExists); overlapExists = SearchAndMerge(cluster, 1, 0, diameter, orig, overlapExists); overlapExists = SearchAndMerge(cluster, 1, 1, diameter, orig, overlapExists); int x = (int)Math.Round((double)((cluster.X - lowerLeft.X) / diameter)); int y = (int)Math.Round((double)((cluster.Y - lowerLeft.Y) / diameter)); cluster.Cx = x; cluster.Cy = y; int num4 = (x << 16) | y; dictionary[num4] = cluster; if (worker.CancellationPending) { return null; } } } return dictionary; }
/// <summary>${WP_mapping_FeaturesClusterer_method_OnCreateFeature_D}</summary> /// <param name="cluster">${WP_mapping_FeaturesClusterer_method_OnCreateFeature_param_cluster}</param> /// <param name="center">${WP_mapping_FeaturesClusterer_method_OnCreateFeature_param_center}</param> /// <param name="maxClusterCount">${WP_mapping_FeaturesClusterer_method_OnCreateFeature_param_maxClusterCount}</param> protected abstract Feature OnCreateFeature(FeatureCollection cluster, GeoPoint center, int maxClusterCount);
//遍历每一个点,把其归类,得到最终的聚类点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 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; }
private static GeoPoint GetBottomLeft(IEnumerable<Feature> features) { GeoPoint point = new GeoPoint(double.MaxValue, double.MaxValue); foreach (Feature f in features) { if ((f != null) && (f.Geometry != null)) { GeoPoint geometry = f.Geometry as GeoPoint; if (geometry == null) { geometry = new GeoPoint(f.Geometry.Bounds.Center.X, f.Geometry.Bounds.Center.Y); ; } if (!double.IsNaN(geometry.X) && !double.IsNaN(geometry.Y)) { point.X = Math.Min(point.X, geometry.X); point.Y = Math.Min(point.Y, geometry.Y); } } } return point; }
//private void Button_Click_3(object sender, RoutedEventArgs e) //{ // DrawLine line = new DrawLine(this.MyMap); // this.MyMap.Action = line; // // this.featuresLayer.ClearFeatures(); // line.DrawCompleted += new EventHandler<DrawEventArgs>(line_DrawCompleted); //} //private void line_DrawCompleted(object sender, DrawEventArgs e) //{ // this.featuresLayer.ClearFeatures(); // Feature feature = new Feature { Geometry=e.Geometry}; // //this.elementLayer.Children.Add(e.Element); // this.featuresLayer.AddFeature(feature); //} //private void Button_Click_4(object sender, RoutedEventArgs e) //{ // DrawPolygon polygon = new DrawPolygon(this.MyMap); // this.MyMap.Action = polygon; // polygon.DrawCompleted += new EventHandler<DrawEventArgs>(polygon_DrawCompleted); //} //private void polygon_DrawCompleted(object sender, DrawEventArgs e) //{ // this.featuresLayer.ClearFeatures(); // Feature feature = new Feature { Geometry=e.Geometry}; // this.featuresLayer.AddFeature(feature); //} private void Button_Click_5(object sender, RoutedEventArgs e) { Feature f = new Feature(); //f.Tap += f_Tap; //f.MouseEnter += f_MouseEnter; //f.MouseLeave += f_MouseLeave; //f.MouseLeftButtonDown += f_MouseLeftButtonDown; //f.MouseLeftButtonUp += f_MouseLeftButtonUp; //f.MouseMove+=f_MouseMove; GeoPoint point = new GeoPoint(0, 0); PredefinedMarkerStyle style = new PredefinedMarkerStyle(); style.Color = new SolidColorBrush(Colors.Red); style.Size = 80; style.Symbol = PredefinedMarkerStyle.MarkerSymbol.Circle; f.Geometry = point; f.Style = style; this.featuresLayer.AddFeature(f); }
//预留接口 private static GeoPoint ToGeoPoint(XElement xe) { GeoPoint point = new GeoPoint(); return point; }
//添加虚拟顶点; private Feature addHoverVertex(Feature feature , GeoPoint p , int index , int partIndex) { Feature hoverVertex = new Feature() { Geometry = p , Style = HoverVertexStyle }; hoverVertex.SetZIndex(2); hoverLayer.Features.Add(hoverVertex); hoverVertex.Attributes.Add("Feature" , feature); hoverVertex.Attributes.Add("Index" , index); hoverVertex.Attributes.Add("PartIndex" , partIndex); hoverVertex.AddDoubleClick((s , e) => { deleteOneVertex(s as Feature); });//双击删除某个顶点,线和面。 return hoverVertex; }
//当线对象时,显示bounds的中心点; private void addCenterFeature(Feature feature) { GeoPoint center = new GeoPoint(feature.Geometry.Bounds.Center.X , feature.Geometry.Bounds.Center.Y); hoverCenterFeature = new Feature { Geometry = center , Style = HoverCenterStyle }; hoverCenterFeature.SetZIndex(3); hoverLayer.AddFeature(hoverCenterFeature); }
private static string convertToString(GeoPoint value) { CultureInfo invariantCulture = CultureInfo.InvariantCulture; string listSeparator = invariantCulture.TextInfo.ListSeparator; return string.Format(invariantCulture, "{0}{2}{1}", new object[] { value.X, value.Y, listSeparator }); }