平台:Vs 2010,Blend 4,Silverlight 4
调用API: ArcGis for Silverligth API(ESRI.ArcGIs.CLIENt)
本节就作为ArcGis 的最后一讲吧,本来想写点其它的,发觉和 Gis 没什么关系。
本节主要以介绍如何动态的在ArcGis上绘制图形,图像并显示隐藏要的层
我们知道如果要在ArcGis上绘制图形的话得先在xmal中加入用户的图层
1
2
3
4
5 |
<!--与用户交互的GraphicsLayer-->
<esri:GraphicsLayer ID="GLayer">
</esri:GraphicsLayer>
<esri:GraphicsLayer ID="WDLayer">
</esri:GraphicsLayer>
|
当然我们需要数据源,这里我以调用Webservice为例为大家讲解
以下代码调用了一报文并生成了List 以便存储在内存里方便实时绘制时取得数据
全局变量
1
2 |
List<Graphic> mapPoint = new List<Graphic>(); // 绘制站点的图形
List<Graphic> WDPic = new List<Graphic>(); // 绘制风符号图片
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69 |
/// <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),Symbol = new PictuREMARKerSymbol()
{
source = (ImagesourcE)converter.ConvertFromString("wind/1.png")
}
});
}
// 调用动态绘图方法绘制站点
DynamicDrawSymbol(glayer,mapPoint,mymap);
// 调用动态绘图方法绘制风向
DynamicDrawSymbol(WDLayer,WDPic,mymap);
}
|
当然我们要在地图发生改变时去实时的绘制,需要在ArcGis图层里添加ExtentChanged事件代码如下:
@H_350_262@@H_607_265@<esri:Map x:Name="@H_998_272@mymap" ExtentChanged="@H_998_272@mymap_ExtentChanged"
@H_350_262@@H_607_265@ Extent="117.356,29.4949,124.299,32.567" RenderTransformOrigin="0.5,0.5" UseLayoutRounding="false"@H_607_265@
@H_350_262@@H_607_265@
d:LayoutRounding="Auto" Margin="0,-30" d:LayoutOverrides="GridBox" BACkground="Transparent">
当事件改变时:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 |
GraphicsLayer glayer = new GraphicsLayer();
glayer = mymap.Layers["GLayer"] as GraphicsLayer;
GraphicsLayer WDLayer = new GraphicsLayer();
WDLayer = mymap.Layers["WDLayer"] as GraphicsLayer;
// 调用动态绘图方法绘制站点
DynamicDrawSymbol(glayer,mymap);
// 调用动态绘图方法绘制风向
if (mymap.Extent.Height < 10)
{
WDLayer.Visible = true;
DynamicDrawSymbol(WDLayer,mymap);
}
else
{
WDLayer.Visible = false;
}
|
上面的代码中我们看到了mymap.Extent.Height < 10当地图的高度大于10时会隐藏WDLayer
这样我们就实现了动态隐藏层
我们再看最重要的一段代码,这就是动态的从缓存中绘制到图层上
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57 |
/// <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~
本文来自Royal_Wh的博客,原文地址:http://www.cnblogs.com/Royal_WH/archive/2010/11/10/1873779.html