ArcGIS API for Silverlight 地圖中解決點眾多的簇解決方法

暖楓無敵發表於2012-03-17

1、通用類

   #region 多點的簇顯示
    public class SumClusterer : GraphicsClusterer
    {
        public SumClusterer()
        {
            MinimumColor = Colors.Red;
            MaximumColor = Colors.Yellow;
            SymbolScale = 2;
            base.Radius = 100;
        }

        public string AggregateColumn { get; set; }
        public double SymbolScale { get; set; }
        public Color MinimumColor { get; set; }
        public Color MaximumColor { get; set; }

        protected override Graphic OnCreateGraphic(GraphicCollection cluster, MapPoint point, int maxClusterCount)
        {
            if (cluster.Count == 1) return cluster[0];
            Graphic graphic = null;

            double sum = 0;

            foreach (Graphic g in cluster)
            {
                if (g.Attributes.ContainsKey(AggregateColumn))
                {
                    try
                    {
                        sum += Convert.ToDouble(g.Attributes[AggregateColumn]);
                    }
                    catch { }
                }
            }
            double size = (sum + 450) / 30;
            size = (Math.Log(sum * SymbolScale / 10) * 10 + 20);
            if (size < 12) size = 12;
            graphic = new Graphic() { Symbol = new ClusterSymbol() { Size = size }, Geometry = point };
            graphic.Attributes.Add("Count", sum);
            graphic.Attributes.Add("Size", size);
            graphic.Attributes.Add("Color", InterpolateColor(size - 12, 100));
            return graphic;
        }

        private static Brush InterpolateColor(double value, double max)
        {
            value = (int)Math.Round(value * 255.0 / max);
            if (value > 255) value = 255;
            else if (value < 0) value = 0;
            return new SolidColorBrush(Color.FromArgb(127, 255, (byte)value, 0));
        }
    }

    internal class ClusterSymbol : ESRI.ArcGIS.Client.Symbols.MarkerSymbol
    {
        public ClusterSymbol()
        {
            string template = @"
            <ControlTemplate xmlns=""http://schemas.microsoft.com/client/2007"" xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"" >
                <Grid IsHitTestVisible=""False"">
					<Ellipse
						Fill=""{Binding Attributes[Color]}"" 
						Width=""{Binding Attributes[Size]}""
						Height=""{Binding Attributes[Size]}"" />
					<Grid HorizontalAlignment=""Center"" VerticalAlignment=""Center"">
					<TextBlock 
						Text=""{Binding Attributes[Count]}"" 
						FontSize=""9"" Margin=""1,1,0,0"" FontWeight=""Bold""
						Foreground=""#99000000"" />
					<TextBlock
						Text=""{Binding Attributes[Count]}"" 
						FontSize=""9"" Margin=""0,0,1,1"" FontWeight=""Bold""
						Foreground=""White"" />
					</Grid>
				</Grid>
			</ControlTemplate>";

            this.ControlTemplate = System.Windows.Markup.XamlReader.Load(template) as ControlTemplate;
        }

        public double Size { get; set; }

        public override double OffsetX
        {
            get
            {
                return Size / 2;
            }
            set
            {
                throw new NotSupportedException();
            }
        }
        public override double OffsetY
        {
            get
            {
                return Size / 2;
            }
            set
            {
                throw new NotSupportedException();
            }
        }
    }
    #endregion

        void client_GetMonitorInfoCompleted(object sender, GetMonitorInfoCompletedEventArgs e)
        {
            ObservableCollection<MonitorInfo> list = e.Result;
            ESRI.ArcGIS.Client.Projection.WebMercator mercator = new ESRI.ArcGIS.Client.Projection.WebMercator();
            GraphicsLayer graphicsLayer = myMap.Layers["MyGraphicsLayer"] as GraphicsLayer;
            //每次載入時先清空地圖上資料
            graphicsLayer.ClearGraphics();

            Uri uri = null;
            Graphic graphic = null;
            foreach (MonitorInfo item in list)
            {
                if (!string.IsNullOrEmpty(item.Latitute.ToString()) && !string.IsNullOrEmpty(item.Longitute.ToString()))
                {
                    //有座標值時,將該監測點新增到地圖上去
                    graphic = new Graphic()
                    {
                        Geometry = mercator.FromGeographic(new MapPoint(double.Parse(item.Latitute.ToString().Trim()), double.Parse(item.Longitute.ToString().Trim()))),
                        Symbol = LayoutRoot.Resources["DefaultMarkerSymbol"] as Symbol,
                    };
                    //手動為graphic新增屬性(需要用到的和資料庫表之間的關聯)
                    graphic.Attributes["Id"] = item.ID;
                    graphic.Attributes["Name"] = item.Name;
                    graphic.Attributes["AreaID"] = item.CountyAreaID;
                    for (int i = 0; i < areaId.Length; i++)
                    {
                        if (areaId[i] == item.ID.ToString())
                        {
                            switch (seedlingType[i])
                            {
                                case "1":
                                    uri = new Uri("Images/red.png", UriKind.Relative);
                                    break;
                                case "2":
                                    uri = new Uri("Images/yellow.png", UriKind.Relative);
                                    break;
                                case "3":
                                    uri = new Uri("Images/green.png", UriKind.Relative);
                                    break;
                                case "4":
                                    uri = new Uri("Images/red.png", UriKind.Relative);
                                    break;
                                default:
                                    break;
                            }
                        }
                    }
                    BitmapImage image = new BitmapImage(uri);
                    //定義Symbol樣式,包括填充顏色
                    Symbol symbol = new PictureMarkerSymbol()
                    {
                        OffsetX = 8,
                        OffsetY = 8,
                        Source = image
                    };
                    graphic.Symbol = symbol;

                    //將該Graphics新增到GraphicsLayer中去
                    graphicsLayer.Graphics.Add(graphic);
                    //為眾多的監測點提供簇聚合功能
                    graphicsLayer.Clusterer = new SumClusterer() { AggregateColumn = "AreaID", SymbolScale = 0.008 };

                    //左鍵選單
                    graphic.MouseLeftButtonDown += new MouseButtonEventHandler(Feature_MouseLeftButtonDown);
                    graphic.MouseLeftButtonUp += new MouseButtonEventHandler(Feature_MouseLeftButtonUp);
                    //右鍵選單
                    graphic.MouseRightButtonDown += new MouseButtonEventHandler(Feature_MouseRightButtonDown);
                    graphic.MouseRightButtonUp += new MouseButtonEventHandler(Feature_MouseRightButtonUp);
                }
                else
                {
                    //不做任何處理,不新增任何點資訊
                }

                //座標點聚焦
                ESRI.ArcGIS.Client.Geometry.Envelope selectedFeatureExtent = graphic.Geometry.Extent; //最後一個點的位置
                double expandPercentage = 30;
                double widthExpand = selectedFeatureExtent.Width * (expandPercentage / 100);
                double heightExpand = selectedFeatureExtent.Height * (expandPercentage / 100);

                ESRI.ArcGIS.Client.Geometry.Envelope displayExtent = new ESRI.ArcGIS.Client.Geometry.Envelope(
                selectedFeatureExtent.XMin - (widthExpand / 2),
                selectedFeatureExtent.YMin - (heightExpand / 2),
                selectedFeatureExtent.XMax + (widthExpand / 2),
                selectedFeatureExtent.YMax + (heightExpand / 2));

                myMap.ZoomTo(displayExtent);
            }
        }



相關文章