ArcGIS API for Silverlight 解決眾多密集點分層顯示

暖楓無敵發表於2012-06-07

問題提出:

        在實際中通常會遇到這樣的情況,如果地圖範圍小,而且需要在地圖上展示的元素又比較多的時候(在展現元素符號的同時,還展示元素名稱或其他屬性值等),這樣如果在首次載入地圖的時候一次性全部顯示,必然會出現嚴重的重疊現象,怎麼解決?


解決思路:

      我想大家首先想到的就是分層顯示,不錯,其實這就是一個方便可行的思路。為資料庫表中增加一個顯示層次的欄位,比如叫ShowLevel,預設是0-第一層顯示,1-第二層顯示...,然後在Map的Layers中新增多個Graphics,有幾層就設定多少個,然後在後臺程式中通過判斷元素是ShowLevel屬性,將元素新增到各自不同的Graphics當中去,最後處理Map的ExtendChanged事件,找到一個顯示的邊界值,然後通過判斷當前的縮放比例是否達到了這個邊界值,如果達到了,就顯示第二層,如果沒有達到就隱藏。


具體實現及部分程式碼如下:

 1、首先資料庫中增加一個欄位,ShowLevel,預設值為0

     

2、在MainPage.xaml中多增加幾個Graphics

       

  <esri:Map.Layers>
                <esri:GraphicsLayer ID="MyGraphicsLayer">
                </esri:GraphicsLayer>
                <esri:GraphicsLayer ID="MyGraphicsLayer3">
                </esri:GraphicsLayer>
                <!--站點名稱-->
                <esri:GraphicsLayer ID="GraphicsLayer1">
                </esri:GraphicsLayer>
                <esri:GraphicsLayer ID="GraphicsLayer11">
                </esri:GraphicsLayer>
                <!--站點資料-->
                <esri:GraphicsLayer ID="GraphicsLayer2">
                </esri:GraphicsLayer>
                <esri:GraphicsLayer ID="GraphicsLayer22">
                </esri:GraphicsLayer>
                <!--站點編碼-->
                <esri:GraphicsLayer ID="GraphicsLayer3">
                </esri:GraphicsLayer>
                <esri:GraphicsLayer ID="GraphicsLayer33">
   </esri:Map.Layers>


3、MainPage.xaml.cs中根據ShowLevel欄位值,分別新增到各自的Graphics中

            ESRI.ArcGIS.Client.Projection.WebMercator mercator = new ESRI.ArcGIS.Client.Projection.WebMercator();
            //每次載入時先清空地圖上資料
            GraphicsLayer graphicsLayer = myMap.Layers["MyGraphicsLayer"] as GraphicsLayer;
            graphicsLayer.ClearGraphics();
            GraphicsLayer graphicsLayer0 = myMap.Layers["MyGraphicsLayer3"] as GraphicsLayer;
            graphicsLayer0.ClearGraphics();


            GraphicsLayer graphicsLayer1 = myMap.Layers["GraphicsLayer1"] as GraphicsLayer;
            graphicsLayer1.ClearGraphics();
            GraphicsLayer graphicsLayer2 = myMap.Layers["GraphicsLayer2"] as GraphicsLayer;
            graphicsLayer2.ClearGraphics();
            GraphicsLayer graphicsLayer3 = myMap.Layers["GraphicsLayer3"] as GraphicsLayer;
            graphicsLayer3.ClearGraphics();


            GraphicsLayer graphicsLayer11 = myMap.Layers["GraphicsLayer11"] as GraphicsLayer;
            graphicsLayer11.ClearGraphics();
            GraphicsLayer graphicsLayer22 = myMap.Layers["GraphicsLayer22"] as GraphicsLayer;
            graphicsLayer22.ClearGraphics();
            GraphicsLayer graphicsLayer33 = myMap.Layers["GraphicsLayer33"] as GraphicsLayer;
            graphicsLayer33.ClearGraphics();


            //獲取到所有的山洪雨量點
            ObservableCollection<RainFall> lists = e.Result;


            //從集合中找出最大值對應的經緯度座標
            RainFall max = lists.OrderByDescending(s => s.YL24).FirstOrDefault();
            //動態新增點到地圖上
            Graphic graphic = null; //第一層
            Graphic graphic2 = null; //第二層
            foreach (RainFall item in lists)
            {
                if (!string.IsNullOrEmpty(item.Latitute.ToString()) && !string.IsNullOrEmpty(item.Longitute.ToString()))
                {
                    //有座標值時,將該監測點新增到地圖上去
                    if (max.YLZBM == item.YLZBM)
                    {
                        if (max.YL24 != 0)
                        {
                            //最大值不為0,紅點閃爍
                            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
                            };
                        }
                        else
                        {
                            //保持原來的藍色標記點符號
                            graphic = new Graphic()
                            {
                                Geometry = mercator.FromGeographic(new MapPoint(double.Parse(item.Latitute.ToString().Trim()), double.Parse(item.Longitute.ToString().Trim()))),
                                Symbol = LayoutRoot.Resources["BlueMarkerSymbol"] as Symbol
                            };
                        }
                        //儲存屬性
                        graphic.Attributes["YLZBM"] = item.YLZBM; //雨量站編碼
                        graphic.Attributes["YLZMC"] = item.ZDMC; //雨量站名稱
                        graphic.Attributes["YL24"] = item.YL24; //24小時雨量
                        graphic.Attributes["DTNow"] = item.DTNow; //當前時間
                        graphic.Attributes["Latitute"] = item.Latitute; //緯度
                        graphic.Attributes["Longitute"] = item.Longitute; //經度
                        //將該Graphics新增到GraphicsLayer中去
                        graphicsLayer.Graphics.Add(graphic);
                        graphicsLayer.Opacity = 1;


                        //滑鼠移入事件
                        graphic.MouseEnter += new MouseEventHandler(sh_graphic_MouseEnter);
                        graphic.MouseLeave += new MouseEventHandler(sh_graphic_MouseLeave);
                        //滑鼠點選事件


                        #region 站點名稱


                        //動態新增文字
                        TextSymbol textSymbol = new TextSymbol()
                        {
                            FontFamily = new System.Windows.Media.FontFamily("Microsoft YaHei"),
                            Foreground = new System.Windows.Media.SolidColorBrush(Color.FromArgb(255, 117, 20, 99)),
                            FontSize = 12,
                            Text = item.ZDMC,
                            OffsetX = 12,
                            OffsetY = -5
                        };


                        Graphic graphicText1 = new Graphic()
                        {
                            Geometry = mercator.FromGeographic(new MapPoint(double.Parse(item.Latitute.ToString().Trim(), System.Globalization.CultureInfo.InvariantCulture), double.Parse(item.Longitute.ToString().Trim(), System.Globalization.CultureInfo.InvariantCulture))),
                            Symbol = textSymbol
                        };


                        graphicText1.Attributes["TextYLZMC"] = item.ZDMC;
                        graphicsLayer1.Graphics.Add(graphicText1);


                        #endregion


                        #region 水位/雨量 數值


                        if (item.YL24 != 0)
                        {
                            TextSymbol textSymbol2 = new TextSymbol()
                            {
                                FontFamily = new System.Windows.Media.FontFamily("Microsoft YaHei"),
                                Foreground = new System.Windows.Media.SolidColorBrush(Color.FromArgb(255, 255, 0, 0)),
                                FontSize = 14,
                                Text = item.YL24.ToString(),
                                OffsetX = 10,
                                OffsetY = 23
                            };


                            Graphic graphicText2 = new Graphic()
                            {
                                Geometry = mercator.FromGeographic(new MapPoint(double.Parse(item.Latitute.ToString().Trim(), System.Globalization.CultureInfo.InvariantCulture), double.Parse(item.Longitute.ToString().Trim(), System.Globalization.CultureInfo.InvariantCulture))),
                                Symbol = textSymbol2
                            };
                            graphicText2.Attributes["TextYL"] = item.YL24;
                            graphicsLayer2.Graphics.Add(graphicText2);
                        }


                        #endregion


                        #region 站點編碼


                        //動態新增站點編碼
                        TextSymbol textSymbol3 = new TextSymbol()
                        {
                            FontFamily = new System.Windows.Media.FontFamily("Microsoft YaHei"),
                            Foreground = new System.Windows.Media.SolidColorBrush(Color.FromArgb(255, 0, 0, 0)),
                            FontSize = 12,
                            Text = item.YLZBM,
                            OffsetX = 27,
                            OffsetY = 23
                        };


                        Graphic graphicText3 = new Graphic()
                        {
                            Geometry = mercator.FromGeographic(new MapPoint(double.Parse(item.Latitute.ToString().Trim(), System.Globalization.CultureInfo.InvariantCulture), double.Parse(item.Longitute.ToString().Trim(), System.Globalization.CultureInfo.InvariantCulture))),
                            Symbol = textSymbol3
                        };


                        graphicText3.Attributes["TextYLZBM"] = item.YLZBM;
                        graphicsLayer3.Graphics.Add(graphicText3);
                        graphicsLayer3.Visible = false;


                        #endregion


                        //左鍵點選事件
                        graphic.MouseLeftButtonDown += new MouseButtonEventHandler(sh_graphic_MouseLeftButtonDown);
                        graphic.MouseLeftButtonUp += new MouseButtonEventHandler(sh_graphic_MouseLeftButtonUp);
                    }
                    else
                    {
                        //這裡判斷顯示層數
                        if (item.ShowLevel == 0)
                        {
                            #region 顯示第一層資料


                            graphic = new Graphic()
                            {
                                Geometry = mercator.FromGeographic(new MapPoint(double.Parse(item.Latitute.ToString().Trim()), double.Parse(item.Longitute.ToString().Trim()))),
                                Symbol = LayoutRoot.Resources["BlueMarkerSymbol"] as Symbol
                            };
                            //儲存屬性
                            graphic.Attributes["YLZBM"] = item.YLZBM; //雨量站編碼
                            graphic.Attributes["YLZMC"] = item.ZDMC; //雨量站名稱
                            graphic.Attributes["YL24"] = item.YL24; //24小時雨量
                            graphic.Attributes["DTNow"] = item.DTNow; //當前時間
                            graphic.Attributes["Latitute"] = item.Latitute; //緯度
                            graphic.Attributes["Longitute"] = item.Longitute; //經度
                            //將該Graphics新增到GraphicsLayer中去
                            graphicsLayer.Graphics.Add(graphic);
                            graphicsLayer.Opacity = 1;


                            //滑鼠移入事件
                            graphic.MouseEnter += new MouseEventHandler(sh_graphic_MouseEnter);
                            graphic.MouseLeave += new MouseEventHandler(sh_graphic_MouseLeave);
                            //滑鼠點選事件


                            #region 站點名稱


                            //動態新增文字
                            TextSymbol textSymbol = new TextSymbol()
                            {
                                FontFamily = new System.Windows.Media.FontFamily("Microsoft YaHei"),
                                Foreground = new System.Windows.Media.SolidColorBrush(Color.FromArgb(255, 117, 20, 99)),
                                FontSize = 12,
                                Text = item.ZDMC,
                                OffsetX = 12,
                                OffsetY = -5
                            };


                            Graphic graphicText1 = new Graphic()
                            {
                                Geometry = mercator.FromGeographic(new MapPoint(double.Parse(item.Latitute.ToString().Trim(), System.Globalization.CultureInfo.InvariantCulture), double.Parse(item.Longitute.ToString().Trim(), System.Globalization.CultureInfo.InvariantCulture))),
                                Symbol = textSymbol
                            };


                            graphicText1.Attributes["TextYLZMC"] = item.ZDMC;
                            graphicsLayer1.Graphics.Add(graphicText1);


                            #endregion


                            #region 水位/雨量 數值


                            if (item.YL24 != 0)
                            {
                                TextSymbol textSymbol2 = new TextSymbol()
                                {
                                    FontFamily = new System.Windows.Media.FontFamily("Microsoft YaHei"),
                                    Foreground = new System.Windows.Media.SolidColorBrush(Color.FromArgb(255, 255, 0, 0)),
                                    FontSize = 14,
                                    Text = item.YL24.ToString(),
                                    OffsetX = 10,
                                    OffsetY = 23
                                };


                                Graphic graphicText2 = new Graphic()
                                {
                                    Geometry = mercator.FromGeographic(new MapPoint(double.Parse(item.Latitute.ToString().Trim(), System.Globalization.CultureInfo.InvariantCulture), double.Parse(item.Longitute.ToString().Trim(), System.Globalization.CultureInfo.InvariantCulture))),
                                    Symbol = textSymbol2
                                };
                                graphicText2.Attributes["TextYL"] = item.YL24;
                                graphicsLayer2.Graphics.Add(graphicText2);
                            }


                            #endregion


                            #region 站點編碼


                            //動態新增站點編碼
                            TextSymbol textSymbol3 = new TextSymbol()
                            {
                                FontFamily = new System.Windows.Media.FontFamily("Microsoft YaHei"),
                                Foreground = new System.Windows.Media.SolidColorBrush(Color.FromArgb(255, 0, 0, 0)),
                                FontSize = 12,
                                Text = item.YLZBM,
                                OffsetX = 27,
                                OffsetY = 23
                            };


                            Graphic graphicText3 = new Graphic()
                            {
                                Geometry = mercator.FromGeographic(new MapPoint(double.Parse(item.Latitute.ToString().Trim(), System.Globalization.CultureInfo.InvariantCulture), double.Parse(item.Longitute.ToString().Trim(), System.Globalization.CultureInfo.InvariantCulture))),
                                Symbol = textSymbol3
                            };


                            graphicText3.Attributes["TextYLZBM"] = item.YLZBM;
                            graphicsLayer3.Graphics.Add(graphicText3);
                            graphicsLayer3.Visible = false;


                            #endregion


                            //左鍵點選事件
                            graphic.MouseLeftButtonDown += new MouseButtonEventHandler(sh_graphic_MouseLeftButtonDown);
                            graphic.MouseLeftButtonUp += new MouseButtonEventHandler(sh_graphic_MouseLeftButtonUp);


                            #endregion
                        }
                        else
                        {
                            #region 顯示第二層資料


                            graphic2 = new Graphic()
                            {
                                Geometry = mercator.FromGeographic(new MapPoint(double.Parse(item.Latitute.ToString().Trim()), double.Parse(item.Longitute.ToString().Trim()))),
                                Symbol = LayoutRoot.Resources["BlueMarkerSymbol"] as Symbol
                            };
                            //儲存屬性
                            graphic2.Attributes["YLZBM"] = item.YLZBM; //雨量站編碼
                            graphic2.Attributes["YLZMC"] = item.ZDMC; //雨量站名稱
                            graphic2.Attributes["YL24"] = item.YL24; //24小時雨量
                            graphic2.Attributes["DTNow"] = item.DTNow; //當前時間
                            graphic2.Attributes["Latitute"] = item.Latitute; //緯度
                            graphic2.Attributes["Longitute"] = item.Longitute; //經度
                            //將該Graphics新增到GraphicsLayer中去
                            graphicsLayer0.Graphics.Add(graphic2);
                            graphicsLayer0.Opacity = 1;
                            if (currentValue > tip_Base.sideValue)
                            {
                                graphicsLayer0.Visible = false;
                            }
                            else
                            {
                                graphicsLayer0.Visible = true;
                            }


                            //滑鼠移入事件
                            graphic2.MouseEnter += new MouseEventHandler(sh_graphic_MouseEnter);
                            graphic2.MouseLeave += new MouseEventHandler(sh_graphic_MouseLeave);
                            //滑鼠點選事件


                            #region 站點名稱


                            //動態新增文字
                            TextSymbol textSymbol = new TextSymbol()
                            {
                                FontFamily = new System.Windows.Media.FontFamily("Microsoft YaHei"),
                                Foreground = new System.Windows.Media.SolidColorBrush(Color.FromArgb(255, 117, 20, 99)),
                                FontSize = 12,
                                Text = item.ZDMC,
                                OffsetX = 12,
                                OffsetY = -5
                            };


                            Graphic graphicText1 = new Graphic()
                            {
                                Geometry = mercator.FromGeographic(new MapPoint(double.Parse(item.Latitute.ToString().Trim(), System.Globalization.CultureInfo.InvariantCulture), double.Parse(item.Longitute.ToString().Trim(), System.Globalization.CultureInfo.InvariantCulture))),
                                Symbol = textSymbol
                            };


                            graphicText1.Attributes["TextYLZMC"] = item.ZDMC;
                            graphicsLayer11.Graphics.Add(graphicText1);
                            if (currentValue > tip_Base.sideValue)
                            {
                                graphicsLayer11.Visible = false;
                            }
                            else
                            {
                                graphicsLayer11.Visible = true;
                            }
                            #endregion


                            #region 水位/雨量 數值


                            if (item.YL24 != 0)
                            {
                                TextSymbol textSymbol2 = new TextSymbol()
                                {
                                    FontFamily = new System.Windows.Media.FontFamily("Microsoft YaHei"),
                                    Foreground = new System.Windows.Media.SolidColorBrush(Color.FromArgb(255, 255, 0, 0)),
                                    FontSize = 14,
                                    Text = item.YL24.ToString(),
                                    OffsetX = 10,
                                    OffsetY = 23
                                };


                                Graphic graphicText2 = new Graphic()
                                {
                                    Geometry = mercator.FromGeographic(new MapPoint(double.Parse(item.Latitute.ToString().Trim(), System.Globalization.CultureInfo.InvariantCulture), double.Parse(item.Longitute.ToString().Trim(), System.Globalization.CultureInfo.InvariantCulture))),
                                    Symbol = textSymbol2
                                };
                                graphicText2.Attributes["TextYL"] = item.YL24;
                                graphicsLayer22.Graphics.Add(graphicText2);
                                if (currentValue > tip_Base.sideValue)
                                {
                                    graphicsLayer22.Visible = false;
                                }
                                else
                                {
                                    graphicsLayer22.Visible = true;
                                }
                            }


                            #endregion


                            #region 站點編碼


                            //動態新增站點編碼
                            TextSymbol textSymbol3 = new TextSymbol()
                            {
                                FontFamily = new System.Windows.Media.FontFamily("Microsoft YaHei"),
                                Foreground = new System.Windows.Media.SolidColorBrush(Color.FromArgb(255, 0, 0, 0)),
                                FontSize = 12,
                                Text = item.YLZBM,
                                OffsetX = 27,
                                OffsetY = 23
                            };


                            Graphic graphicText3 = new Graphic()
                            {
                                Geometry = mercator.FromGeographic(new MapPoint(double.Parse(item.Latitute.ToString().Trim(), System.Globalization.CultureInfo.InvariantCulture), double.Parse(item.Longitute.ToString().Trim(), System.Globalization.CultureInfo.InvariantCulture))),
                                Symbol = textSymbol3
                            };


                            graphicText3.Attributes["TextYLZBM"] = item.YLZBM;
                            graphicsLayer33.Graphics.Add(graphicText3);
                            graphicsLayer33.Visible = false;


                            #endregion


                            //左鍵點選事件
                            graphic2.MouseLeftButtonDown += new MouseButtonEventHandler(sh_graphic_MouseLeftButtonDown);
                            graphic2.MouseLeftButtonUp += new MouseButtonEventHandler(sh_graphic_MouseLeftButtonUp);


                            #endregion
                        }
                    }
                }
                else
                {
                    //不做任何處理,不新增任何點資訊
                }
            }


4、在Map的ExtendChanged事件中處理

      

 private void myMap_ExtentChanged(object sender, ExtentEventArgs e)
{
      currentValue = (e.NewExtent.XMax - e.NewExtent.XMin) / (myMap.Layers.GetFullExtent().XMax - myMap.Layers.GetFullExtent().XMin);
      ShowSiteByGrade();
}

        /// <summary>
        /// 判斷是在第一層還是第二層顯示
        /// </summary>
        private void ShowSiteByGrade()
        {
            if (currentValue >= tip_Base.sideValue)
            {
                GraphicsLayer graphicsLayer0 = myMap.Layers["MyGraphicsLayer3"] as GraphicsLayer;
                graphicsLayer0.Visible = false;
                GraphicsLayer graphicsLayer2 = myMap.Layers["GraphicsLayer11"] as GraphicsLayer;
                graphicsLayer2.Visible = false;
                GraphicsLayer graphicsLayer3 = myMap.Layers["GraphicsLayer22"] as GraphicsLayer;
                graphicsLayer3.Visible = false;
                GraphicsLayer graphicsLayer4 = myMap.Layers["GraphicsLayer33"] as GraphicsLayer;
                graphicsLayer4.Visible = false;
            }
            else
            {
                GraphicsLayer graphicsLayer = myMap.Layers["MyGraphicsLayer3"] as GraphicsLayer;
                graphicsLayer.Visible = true;
                GraphicsLayer graphicsLayer2 = myMap.Layers["GraphicsLayer11"] as GraphicsLayer;
                graphicsLayer2.Visible = true;
                GraphicsLayer graphicsLayer3 = myMap.Layers["GraphicsLayer22"] as GraphicsLayer;
                graphicsLayer3.Visible = true;
                GraphicsLayer graphicsLayer4 = myMap.Layers["GraphicsLayer33"] as GraphicsLayer;
                graphicsLayer4.Visible = false;
            }
        }
     

相關文章