ArcGIS API for Silverlight开发入门(5):任务外包——Tasks

ArcGIS API for Silverlight开发入门(5):任务外包——Tasks,第1张

概述通过上一节的学习,我们已经知道了如何与GraphicLayer交互,但毕竟GIS不是一个画板,所以这节来看一下如何通过Silverlight API完成GIS中的分析功能。 GIS之所以是一个通用的工具,就是因为它具有各种各样分析和处理数据的能力。Silverlight API中提供了Task,使我们能够轻松完成常见的分析任务。 先来考虑一下吃饺子的场景。要想吃饺子,我们需要先去买菜,买肉,回家后 通过上一节的学习,我们已经知道了如何与GraphicLayer交互,但毕竟GIS不是一个画板,所以这节来看一下如何通过Silverlight API完成GIS中的分析功能。
GIS之所以是一个通用的工具,就是因为它具有各种各样分析和处理数据的能力。Silverlight API中提供了Task,使我们能够轻松完成常见的分析任务。
先来考虑一下吃饺子的场景。要想吃饺子,我们需要先去买菜,买肉,回家后在厨房里洗菜,揉面, 拌馅,包饺子,煮饺子,吃饺子,之后别忘了洗碗;另一种情况就是去饭馆,告诉服务员我要吃3两茴香,3两韭菜的饺子,然后等着饺子端到你面前,开吃,走人。
在ArcGISServer程序开发中,要完成GIS的分析功能其实和吃饺子是一样的。用ADF编程就像在家里吃饺子,除了架设服务器,所有的工作基本上也都得我们自己在服务器端来完成,要处理的地方比较多;而用客户端API编程相当于去外面吃饺子,我们只要把任务交给相应的Task,之后接受结果就行了,不用做饺子。唯一不同的就是在外面吃完饺子别忘了付钱,而用Task完成分析任务则是免费的。这点也体现在使用客户端API中的Task时,是由ArcGISOnline提供给你的,不需要自己购买AGS软件。
现在来看看Silverlight API目前给我们提供了那些Task功能:
query:能够在已经发布的服务数据中,通过属性条件(可以属性字段中进行关系判断,字符查找等),图形条件(与输入的图形相交、包含、相离等),或者是两者的组合,查询出满足条件的数据并返回。相当于Engine中的SpatialFilter,当然也是queryFilter。
Find:在地图数据的属性字段中查找包含有关键字参数的数据并返回。
IDentity:对鼠标当前点击位置上的数据进行辨识并返回结果,可以对多个图层的数据进行辨识。
Address Locator:输入经纬度,返回地址结果(GeoCoding);输入一个地方的地址,返回经纬度结果(Reverse GeoCoding)。由于国内地图数据保密工作做的相当好,这个Task暂时用不到。
Geometry Service:可以对输入的地理数据进行如缓冲区,动态投影,面积/周长量算等几何 *** 作。
Geoprocessing:能够完成复杂的GIS任务,类似ToolBox中的工具。
抽象一下,可以看出,query完全可以完成IDentity和Find的工作,但后两者在特定场合下使用起来比query要方便的多;Geoprocessing完全可以替代Geometry Service,但是在利用REST API编写的程序中,要尽量使用GeometryService。
再抽象一下,Silverlight API中的这几个Task和JavaScript/FlexAPI中的Task是大同小异的,因为其实它们都是AGS 9.3 REST API中暴露出来的 *** 作资源(OperationResource)见下图:

下载 (120.11 KB)
2009-4-26 13:27


后面的代码中实际上也是把输入参数封装起来提交到了REST API的特定Endpoint上。要理解好客户端API中的Task,建议熟读AGS的 REST SDK。
Task的用法基本上相同,都遵循这几个步骤:初始化Task,设置Task所需参数,提交任务,等待服务器完成任务后,处理返回的结果;进饭馆,想好你要吃什么饺子,告诉服务员,等饺子做好端上来,开始吃。好了,下面我们就通过一个实例( 点击这里,查看实例),来学习一下query和Geometry两个Task的用法。

下载 (113.44 KB)
2009-4-26 13:27



首先选择工具条中的画线工具,在屏幕上画一条曲线,会根据曲线自动生成一个距离100公里的缓冲区显示在地图上,之后开始查询缓冲区图形经过的州(相交),将结果显示在地图上。可以单击每个州查看详细信息。这里假设你已学习了前几节的内容,只讨论Task用法的部分。
1、利用所画的线生成缓冲区。画线利用的是Draw工具中的Freehand,在这个动作完成后会触发Draw的OnDrawCompleted事件,自然可以在这里开始进行缓冲区的工作,用的是Geometry Service里的Buffer。
初始化Geometry Service。假设已经在Map1中添加了ID为glayerResult的Graphicslayer,linesymbolred是提前设置好的Cartographiclinesymbol: private voID Draw1_OnDrawComplete(object sender,DrawEventArgs args)
{
Draw1.Deactivate();//Freehand动作失效
//将Freehand画的曲线显示在地图上
Graphicslayer glayer = Map1.Layers["glayerResult"] as Graphicslayer;
Graphic g = new Graphic();
g.Symbol = linesymbolred;
g.Geometry = args.Geometry;
glayer.Graphics.Add(g);
//初始化Geometry Service
GeometryService geometrytask = new GeometryService("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer");
} 复制代码 GeometryService的初始化使用构造函数来完成的,里面接受一个URL,这个是Geometry Service的REST APIEndpoint。顺便说一下,不同于其他服务比如MapService,一个GISServer只能发布一个GeometryService,并且它的名称必须是Geometry。
当一个Task完成时会触发Completed事件,失败时也有@R_502_5138@事件,对这两个事件进行监听: geometrytask.BufferCompleted += new EventHandler(geometrytask_BufferCompleted);
geometrytask.@R_502_5138@ += new EventHandler(geometrytask_@R_502_5138@); 复制代码 设置Buffer *** 作所需的参数: BufferParameters bufferparameters = new BufferParameters();
bufferparameters.Unit = linearUnit.Kilometer;
//必须指定下面两个spatialreference,否则buffer结果集为空
bufferparameters.BufferSpatialReference = new SpatialReference(3395);
bufferparameters.OutSpatialReference = Map1.SpatialReference;
bufferparameters.distances.Add(100);
bufferparameters.Features.Add(g); 复制代码 BufferParameters是专门用于Buffer的参数;BufferSpatialReference是将要Buffer的图形重新投影到这个坐标系下(常常需要根据地图数据所在地方的情况来设置这个参数),并设置Buffer距离的单位为公里,Buffer的输出一般与地图坐标系一致;Buffer参数有一个Features属性,是List类型,里面的Graphic都将被Buffer。下来将Buffer的任务提交到服务器(可以看出为什么这些动作要叫Task): geometrytask.BufferAsync(bufferparameters); 复制代码 以上代码都放在Draw1_OnDrawComplete函数中。任务提交到服务器后,由GeometryService接管,计算,完成后会立刻将结果返回给我们,通知我们结果已经完成的方式就是前面绑定的Completed事件。接收到结果后,首先将缓冲区显示出来: private voID geometrytask_BufferCompleted(object sender,GraphicsEventArgs args)
{
if (args.Results.Count>0)
{
Graphicslayer glayer = Map1.Layers["glayerResult"] as Graphicslayer;
Graphic g = new Graphic();
g.Symbol = fillsymbolBuffer;
g.Geometry = args.Results[0].Geometry;
glayer.Graphics.Add(g);
}
} 复制代码 如图:

下载 (138.03 KB)
2009-4-26 13:27


2、利用生成缓冲区的缓冲区进行空间查询。要达到我们的目的,就还需要进行一个query的Task,那么就可以在这里马不停蹄的开始query的Task。步骤基本都是一样的,初始化,设置参数,提交结果,处理结果: private voID geometrytask_BufferCompleted(object sender,GraphicsEventArgs args)
{
if (args.Results.Count>0)
{
Graphicslayer glayer = Map1.Layers["glayerResult"] as Graphicslayer;
Graphic g = new Graphic();
g.Symbol = fillsymbolBuffer;
g.Geometry = args.Results[0].Geometry;
glayer.Graphics.Add(g);
//初始化queryTask
queryTask querytask = new queryTask("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer/5");
//准备接收结果或者处理失败的通知
querytask.ExecuteCompleted += new EventHandler(querytask_ExecuteCompleted);
querytask.@R_502_5138@ += new EventHandler(querytask_@R_502_5138@);
//设置query Task所需的参数
query query = new query();
query.OutFIElds.Add("*");//也顺便设置了query.ReturnGeometry=true;
query.Geometry = g.Geometry;
query.SpatialRelationship = SpatialRelationship.esriSpatialRelintersects;
//向服务器上的对应图层提交任务
querytask.ExecuteAsync(query);
Map1.Cursor = System.windows.input.Cursors.Wait;
}

} 复制代码 这里的查询实在美国州的图层上进行的,详细信息将queryTask构造函数里的那个参数输入浏览器查看;query.Geometry是设置需要进行空间查询的图形,就是上面缓冲区的结果;OutFIElds是查询结果需要返回的字段,这里返回全部字段,如果返回全部字段,则强制设置了ReturnGeometry为true,如果我们不需要处理结果的图形信息,则可以将这个参数设为false,以节省流量,显然这里不是;空间关系可以参考API,与Engine中的完全一致。
接下来处理queryTask完成后的结果: private voID querytask_ExecuteCompleted(object sender,queryEventArgs args)
{
Graphicslayer graphicslayer = Map1.Layers["glayerResult"] as Graphicslayer;
Featureset featureset = args.Featureset;
if (featureset != null && featureset.Features.Count > 0)
{
graphicslayer.Cleargraphics();
ListBoxResults.Items.Clear();
foreach (Graphic graphic in featureset.Features)
{
graphic.Symbol = fillsymbolresult;
graphicslayer.Graphics.Add(graphic);
}
}
MyMapTip.Graphicslayer = graphicslayer;
Map1.Cursor = System.windows.input.Cursors.Arrow;
} 复制代码 上面处理空间查询的结果只是将图形显示了出来,那么对于单击某个州后,显示出其详细信息该怎么办呢?从图一可以看出,用到了Silverlight的DataGrID控件,信息从哪里去呢?记得上面我们设置结果中返回的全部属性字段吗?它们存储在每个Graphic的Attributes属性中。要么绑定到DataGrID里,要么一条条添加……你可能已经发现了这条语句MyMapTip.Graphicslayer =graphicslayer;,还记得第三节的Widgets吗?那里我们落下了MapTip这个小家伙,现在派上用场了。除了在这里设置MapTip的Graphicslayer属性外,在xaml中有如下的定义: <esriWidgets:MapTip x:name="MyMapTip" borderBrush="#99000000"
borderThickness="1" title="详细信息" VerticalOffset="10"
HorizontalOffset="10" Background="#DDFFFFFF" /> 复制代码 仅此而已。MapTip会自动找寻自己Graphicslayer中的Graphic,当鼠标悬停在某个Grpahic上时,会自动读取它的Attributes属性并显示,小玩具又发挥了大作用。
别忘了万一处理任务失败时的提示: private voID geometrytask_@R_502_5138@(object sender,Task@R_502_5138@EventArgs args)
{
MessageBox.Show("Buffer Error:" + args.Error);
}

private voID querytask_@R_502_5138@(object sender,Task@R_502_5138@EventArgs args)
{
MessageBox.Show("query @R_502_5138@: " + args.Error);
Map1.Cursor = System.windows.input.Cursors.Arrow;
Graphicslayer graphicslayer = Map1.Layers["glayerResult"] as Graphicslayer;
graphicslayer.Cleargraphics();
} 复制代码 本节内容完毕。上面讲的相对简略,要理解各个Task和参数的用法,还是需要熟悉 Silverlight API和前面提到的REST API。另外,Geoprocessing Service实际上是最强大Task,如果有自己的GISServer,完全可以在上面发布自制的Model或者Python脚本,以完成各种GIS分析任务,简单的在线编辑也是可能的。它的用法也万变不离其宗:初始化,设置参数,提交任务,处理结果。不同的是GeoprocessingService有两种提交任务的方法:同步和异步。前者服务器端处理完任务后会立即将结果发送回客户端;后者将任务提交后会得到服务器端返回的一个JobID,即使任务处理完成也不会立即返回,而是需要你拿这个JobID去询问服务器:完成了吗?完成了吗?完成了吗?如果完成,则可以取回相应的结果。
前面说到,虽然去外面吃饺子很方便,但是毕竟那是人家做好的,对于老饕来说还需要自己的口感,自己下厨毕竟能控制整个过程的方方面面,哪怕你想做出饺立方也都是有可能的。同样,ADF编程可以调用服务器端的ArcObjects,让你为所欲为,这点是客户端API无论如何也办不到的。
原文地址: http://bbs.esrichina-bj.cn/ESRI/thread-45302-1-1.html 总结

以上是内存溢出为你收集整理的ArcGIS API for Silverlight开发入门(5):任务外包——Tasks全部内容,希望文章能够帮你解决ArcGIS API for Silverlight开发入门(5):任务外包——Tasks所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1072717.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-26
下一篇 2022-05-26

发表评论

登录后才能评论

评论列表(0条)

保存