ArcGis For Silverlight API,地图显示Gis,绘制点,线,绘制图等(四)--动态绘制点

本文介绍了如何使用ArcGIS for Silverlight API动态地在地图上绘制点、线和图形,并展示了如何根据地图视图变化隐藏或显示图层。通过监听地图的ExtentChanged事件,当地图高度超过特定阈值时隐藏图层。核心代码部分阐述了如何从缓存中选取当前视图范围内的数据加载到地图上,以提高地图滚动时的性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

平台:Vs 2010,Blend 4,Silverlight 4

调用API: ArcGis for Silverligth API(ESRI.ArcGIS.Client)


本节就作为ArcGis 的最后一讲吧,本来想写点其它的,发觉和 Gis 没什么关系。


本节主要以介绍如何动态的在ArcGis上绘制图形,图像并显示隐藏要的层


我们知道如果要在ArcGis上绘制图形的话得先在xmal中加入用户的图层

代码
    
    
            <!-- 与用户交互的GraphicsLayer -->
            < esri:GraphicsLayer ID = " GLayer " >
            </ esri:GraphicsLayer >
            < esri:GraphicsLayer ID = " WDLayer " >
            </ esri:GraphicsLayer >

 

当然我们需要数据源,这里我以调用WebService为例为大家讲解

以下代码调用了一报文并生成了List<Graphics> 以便存储在内存里方便实时绘制时取得数据

 

全局变量

   
   
        List < Graphic > mapPoint = new List < Graphic > (); // 绘制站点的图形
        List < Graphic > WDPic = new List < Graphic > ();    // 绘制风符号图片

 

代码
    
    
/// <summary>
        /// 海浪一号报文
        /// </summary>
        private void WaveIInit()
        {
            GetWaveService.WaveServiceSoapClient porxy = new MapSilverlight.GetWaveService.WaveServiceSoapClient();
            porxy.GetSeaInfoCompleted += new EventHandler < MapSilverlight.GetWaveService.GetSeaInfoCompletedEventArgs > (porxy_GetSeaInfoCompleted);
            porxy.GetSeaInfoAsync();
        }
        /// <summary>
        /// 异步接收完海浪一号报文后即绘制图形到地图上
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void porxy_GetSeaInfoCompleted( object sender, MapSilverlight.GetWaveService.GetSeaInfoCompletedEventArgs e)
        {
            // 获取数据长度
            int length = e.Result.Count;

            // 绘制站点层
            GraphicsLayer glayer = new GraphicsLayer();
            glayer = myMap.Layers[ " GLayer " ] as GraphicsLayer;

            // 绘制风向层
            GraphicsLayer WDLayer = new GraphicsLayer();
            WDLayer = myMap.Layers[ " WDLayer " ] as GraphicsLayer;


            // 定义一个转换类,将字符串地址转化为图片
            ImageSourceConverter converter = new ImageSourceConverter();

            // 实例化站点和风向
            mapPoint = new List < Graphic > ();
            WDPic = new List < Graphic > ();

            // 循环从结果集中取数据
            for ( int i = 0 ; i < length; i ++ )
            {
                waveI.Add( new WebModel.Sites(e.Result[i].Longitude, e.Result[i].Latitude, e.Result[i].SiteNo
                    , e.Result[i].Pressure, e.Result[i].RH, e.Result[i].Temperature, e.Result[i].Visibility));

                // 将站点添加到站点层
                mapPoint.Add( new Graphic()
                {
                    Geometry = new MapPoint(Convert.ToDouble(e.Result[i].Longitude), Convert.ToDouble(e.Result[i].Latitude)),
                    Symbol = new SimpleMarkerSymbol()
                    {
                        Color = new SolidColorBrush(Colors.Red),
                        Size = 6 ,
                        Style = SimpleMarkerSymbol.SimpleMarkerStyle.Circle
                    }
                });

                // 将风向添加到风向层
                WDPic.Add( new Graphic()
                {
                    Geometry = new MapPoint(Convert.ToDouble(e.Result[i].Longitude), Convert.ToDouble(e.Result[i].Latitude)),
                    Symbol = new PictureMarkerSymbol()
                    {
                        Source = (ImageSource)converter.ConvertFromString( " wind/1.png " )
                    }
                });
            }

            // 调用动态绘图方法绘制站点
            DynamicDrawSymbol(glayer, mapPoint, myMap);
            // 调用动态绘图方法绘制风向
            DynamicDrawSymbol(WDLayer, WDPic, myMap);
        }

 


 

当然我们要在地图发生改变时去实时的绘制,需要在ArcGis图层里添加ExtentChanged事件代码如下

代码
    
    
< esri:Map x:Name = " myMap " ExtentChanged = " myMap_ExtentChanged "   Extent = " 117.356,29.4949,124.299,32.567 " RenderTransformOrigin = " 0.5,0.5 " UseLayoutRounding = " False "
                  d:LayoutRounding = " Auto " Margin = " 0,0,0,-30 " d:LayoutOverrides = " GridBox " Background = " Transparent " >

 


 

当事件改变时:

代码
    
    
GraphicsLayer glayer = new GraphicsLayer();
            glayer = myMap.Layers[ " GLayer " ] as GraphicsLayer;

            GraphicsLayer WDLayer = new GraphicsLayer();
            WDLayer = myMap.Layers[ " WDLayer " ] as GraphicsLayer;

            // 调用动态绘图方法绘制站点
            DynamicDrawSymbol(glayer, mapPoint, myMap);

           
            // 调用动态绘图方法绘制风向
            if (myMap.Extent.Height < 10 )
            {
                WDLayer.Visible = true ;
                DynamicDrawSymbol(WDLayer, WDPic, myMap);
            }
            else
            {
                WDLayer.Visible = false ;
            }

 


 

上面的代码中我们看到了myMap.Extent.Height < 10当地图的高度大于10时会隐藏WDLayer
这样我们就实现了动态隐藏层

我们再看最重要的一段代码,这就是动态的从缓存中绘制到图层上

代码
    
    
/// <summary>
        /// 动态的绘制图层
        /// 当然地图移动到相应的坐标后绘制(保留原来的点,绘制新的数据)
        /// 实现了无刷新绘制
        /// </summary>
        /// <param name="glayer"> 表示地图上的层 </param>
        /// <param name="cacheGraphic"> 存放 Graphics 的缓存 </param>
        /// <param name="map"> 表示一张 ArcGis 地图 </param>
        private void DynamicDrawSymbol(ESRI.ArcGIS.Client.GraphicsLayer glayer,List < ESRI.ArcGIS.Client.Graphic > cacheGraphic, ESRI.ArcGIS.Client.Map map)
        {
            // 以下四个变量分别表示地图的四个边
            // 即最大经纬度和最小经纬度
            // xMax最大经度,yMax最大纬度
            double xMax = map.Extent.XMax;
            double xMin = map.Extent.XMin;
            double yMax = map.Extent.YMax;
            double yMin = map.Extent.YMin;

            // 去除不在坐标范围内的点,先检查图层是否为空
            if (glayer != null )
            {
                int graphicCount = glayer.Graphics.Count;
                for ( int i = 0 ; i < graphicCount; i ++ )
                {
                    // 判断经度,纬度
                    if ( ! ((glayer.Graphics[i].Geometry.Extent.XMax < xMax && glayer.Graphics[i].Geometry.Extent.XMax > xMin)
                        && (glayer.Graphics[i].Geometry.Extent.YMax < yMax && glayer.Graphics[i].Geometry.Extent.YMax > yMin)))
                    {
                        // 将点在地图上移除,并放在缓存中
                        cacheGraphic.Add(glayer.Graphics[i]);
                        glayer.Graphics.Remove(glayer.Graphics[i]);
                        graphicCount -- ;  // 当从集合中移除元素时应该把 graphicCount 减1
                        i -- ;              // 元素被移除后相当于当前元素的后一位元素会 -1,应该再循环一次本次循环所以应该 -1
                    }
                } // i
            }

            // 检查缓存是否为空,并将点绘制到图形上
            if (cacheGraphic != null )
            {
                int count = cacheGraphic.Count;
                for ( int i = 0 ; i < count; i ++ )
                {
                    // 判断经度,纬度
                    if ((cacheGraphic[i].Geometry.Extent.XMax < myMap.Extent.XMax && cacheGraphic[i].Geometry.Extent.XMax > myMap.Extent.XMin)
                        && (cacheGraphic[i].Geometry.Extent.YMax < myMap.Extent.YMax && cacheGraphic[i].Geometry.Extent.YMax > myMap.Extent.YMin))
                    {
                        // 运行到此则该点在目前地图范围内,将该点加入到地图中
                        glayer.Graphics.Add(cacheGraphic[i]);
                        cacheGraphic.Remove(cacheGraphic[i]);
                        count -- ;    // 当从集合中移除元素时应该把 count 减1
                        i -- ;        // 元素被移除后相当于当前元素的后一位元素会 -1,应该再循环一次本次循环所以应该 -1
                        continue ;
                    }
                }
            }
        }

 


 

这篇文章早在已前已经写好了,其实恩路很简单,在Gis大量数据加载到地图上的时候我们拖动地图的时候就会比较卡,

我们当然把在地图上的数据加载到地图上,也就是当前 myMap.Extent 里的 XMax,YMax,Xmin,YMin,这个范围内的点

加载到地图上!不在这个范围内的就移除,这样速度就会快一点,但是看到网上有人用CacheMode来解决游戏的问题的不知道

在Gis上可不可行,个人认为还是可行的,有空再去研究这个东西吧!


OK,Gis东西就先写到这,大家有什么问题可以给我留言!欢迎大家一起讨论!


OK, happy every day~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值