Silverlight调用GP服务详解
上一篇主要讲了如何发布GP服来绘制等值线及等直面,这里主要将如何通过Silverlight来调用GP服务。
这里先写一下具体的调用过程:
声明GP服务变量(Geoprocessor),并实例化 注册GP服务任务完成事件及失败事件 根据发布的GP服务,定义GP服务的参数 输入GP服务参数请求GP服务 获取结果:在Compeleted事件函数中完成获取结果的代码,对于是要素类结果,需要注册GetResultDataCompleted事件,对于是栅格数据结果需要注册GetResultimageLayerCompleted事件,然后在事件的回调函数中完成最终结果的获取。这里需要注意的问题:
a. GP服务是同步调用还是异步调用
b. 获得结果的坐标系是否和当前一致
c. GP服务的输入参数必须和发布的GP服务一致(之后会详细说明)
d. 获取结果的名称必须和发布的GP服务一致(之后会详细讲到)
以上大致的说了一下GP服务调用的基本过程,下面就开始正式的工作吧。
一.基本界面
首先我们构建一个简单的Web界面,如下图所示:
这里需要实现的基本功能是:可以保存每一次添加的Graphic(xml格式),并能够再次读取这些Graphic.根据加载的Graphic实现基本的预测,即调用GP服务。
说明:为了节省时间,这里我已将用到的点的数据保存成了一个xml文档,所有需要的数据都从xml中读取。
二.加载xml格式的Graphic信息
这里就是遍历xml中所有Graphic节点,然后读取相应的信息(节点的名称根据我们保存xml时定义的不同而不同,后面会给出保存xml的代码)。读取xml信息的代码如下:
VIEw Code1 //打开加载数据对话框 2 OpenfileDialog openfileDialog = new OpenfileDialog(); 3 //指定xml问价格式 4 openfileDialog.Filter = "XML files(*.xml)|*.xml"; 5 if (openfileDialog.ShowDialog() == true) 6 { 7 using (Stream stream = openfileDialog.file.OpenRead()) 8 { 9 Xdocument doc = Xdocument.Load(stream);10 //遍历xml中的Graphic节点11 foreach (XElement element in doc.Descendants("Graphic"))12 {13 //遍历Graphic节点下的Location节点14 foreach (XElement LocationElement in element.Descendants("Location"))15 {16 //获得Location节点下的坐标17 double LocationX = Convert.Todouble(LocationElement.Element("LocationX").Value);18 double LocationY = Convert.Todouble(LocationElement.Element("LocationY").Value);19 //获得Graphic节点下的浓度值20 double PollutionC = Convert.Todouble(element.Element("PolutionC").Value);21 //绘制Graphic22 CreatGraphic(LocationX,LocationY,PollutionC);23 }24 }25 }26 }@H_403_4@ @H_403_4@
CreatGraphic方法表示在地图上根据获得的坐标和浓度值绘制出一个点。
VIEw Code//定义一个图层,所以的Graphic将在此图层上绘制private Graphicslayer graphicslayer = null;private voID CreatGraphic(double locationx,double locationy,double pollutionc) { //构建一个Graphic,并定义其样式 Graphic g = new Graphic() { Geometry = new MapPoint() { X=locationx,Y=locationy,SpatialReference=map.SpatialReference },Symbol = new SimpleMarkerSymbol() { Size = 9,color = new SolIDcolorBrush(colors.Blue),Style = SimpleMarkerSymbol.SimpleMarkerStyle.Circle },}; if (map.Layers["GraphicsPoints"] == null) { graphicslayer = new Graphicslayer() { ID = "GraphicsPoints" }; map.Layers.Add(graphicslayer); } //添加浓度属性 g.Attributes.Add("PolutionC",pollutionc); // graphicslayer.Graphics.Add(g); }@H_403_4@ @H_403_4@
三.保存xml格式的Graphic信息
这里我们将GraphicLayer上所有的点的信息保存成xml格式。需要注意的是,xml中节点名称必须和读取xml文件时使用的节点名保持一致。否则之后我们无法读取我们保存的信息。具体代码如下:
VIEw Code1 //若要素图层不存在则返回 2 if (map.Layers["GraphicsPoints"] == null) 3 return; 4 //若图层要素为空也返回 5 Graphicslayer graphicslayer = map.Layers["GraphicsPoints"] as Graphicslayer; 6 if (graphicslayer.Graphics.Count <= 0) 7 return; 8 //打开保存对话框 9 SavefileDialog savefileDialog = new SavefileDialog();10 //指定xml文件格栅11 savefileDialog.DefaultExt = "xml";12 savefileDialog.Filter = "XML files (*.xml)|*.xml";13 //指定默认的文件名为当前的时间14 savefileDialog.Defaultfilename = string.Format("GraphicInfo{0}",GetCurrentDateTimeString());15 16 if (savefileDialog.ShowDialog() == true)17 {18 using (Stream stream = savefileDialog.Openfile())19 {20 StreamWriter streamWriter = new StreamWriter(stream,System.Text.EnCoding.UTF8);21 int GraphicNum = 1;22 23 foreach (Graphic g in graphicslayer.Graphics)24 {25 //调用自定义GetGeneratedXML方法,构建xml26 GetGeneratedXML(GraphicNum,g);27 GraphicNum++;28 }29 streamWriter.Write(doc.ToString());30 streamWriter.Close();31 stream.Close();32 }33 }@H_403_4@ @H_403_4@
GetGeneratedXML方法代码如下:
VIEw Code1 private voID GetGeneratedXML(int graphicID,Graphic g) 2 { 3 MapPoint mapPoint = g.Geometry as MapPoint; 4 XElement graphic = new XElement("Graphic",new XAttribute("ID",graphicID), 5 new XElement("Location", 6 new XElement("LocationX",mapPoint.X), 7 new XElement("LocationY",mapPoint.Y)), 8 new XElement("PolutionC",Convert.Todouble(g.Attributes["PolutionC"]))); 9 doc.Root.Add(graphic);10 }@H_403_4@ @H_403_4@
GetCurrentDateTimeString方法如下:
VIEw Code1 private string GetCurrentDateTimeString() 2 { 3 string TimeString; 4 DateTime CurrentTime = new DateTime(); 5 CurrentTime = System.DateTime.Now; 6 int year = CurrentTime.Year; 7 int month = CurrentTime.Month; 8 int day = CurrentTime.Day; 9 int hour = CurrentTime.Hour;10 int minute = CurrentTime.Minute;11 int second = CurrentTime.Second;12 TimeString = string.Format("{0}{1}{2}{3}{4}{5}",year,month,day,hour,minute,second);13 return TimeString;14 }@H_403_4@ @H_403_4@
四.根据添加的点,进行预测及可视化表达(绘制等值线及等值面)
到这里为止,才算是真正开始我们的GP服务。具体的调用过程在开始的时候作了一个大致的介绍,下面开始详细的讲解。
4.1 定义GP服务变量
VIEw Code1 //定义GP服务变量2 private Geoprocessor InterpolationTask = null;//绘制等值面3 private Geoprocessor ContourTask = null;//绘制等值线@H_403_4@ @H_403_4@
并且实例化GP服务变量,并注册相应的事件
VIEw Code1 //等值线GP服务 2 ContourTask = new Geoprocessor("http://qzj-pc/ArcGIS/rest/services/ContourService_with_Focal_Statistics/GPServer/ContourService"); 3 ContourTask.JobCompleted += new EventHandler<JobInfoEventArgs>(ContourTask_JobCompleted); 4 ContourTask.GetResultDataCompleted += new EventHandler<GPParameterEventArgs>(ContourTask_GetResultDataCompleted); 5 ContourTask.Failed += new EventHandler<TaskFailedEventArgs>(ContourTask_Failed); 6 //等值面GP服务 7 InterpolationTask = new Geoprocessor("http://qzj-pc/ArcGIS/rest/services/InterpolationService_Stretch/GPServer/InterpolationModel"); 8 InterpolationTask.JobCompleted += new EventHandler<JobInfoEventArgs>(InterpolationTask_JobCompleted); 9 InterpolationTask.GetResultimageLayerCompleted += new EventHandler<GetResultimageLayerEventArgs>(InterpolationTask_GetResultimageLayerCompleted);10 InterpolationTask.Failed += new EventHandler<TaskFailedEventArgs>(InterpolationTask_Failed);@H_403_4@ @H_403_4@
4.2 定义GP服务的请求参数
这里需要的参数必须和我们发布的GP服务一致。我们打开绘制等值线的GP服务链接,基本参数如下所示:
以上是绘制等值面的GP服务参数列表,并给出了参数信息的详细说明,这里我们可以看出绘制等值面的GP服务只有一个输入参数:PollutionPoints,类型是GPFeatureRecordSetLayer,也就是要素集。同时只有一个输出参数:RasterData,类型是GPRasterDataLayer,即栅格数据。
下面我们定义绘制等值面的GP服务参数。
@H_403_4@1 //添加这段代码,非常有用,否则将无法获取GP服务的结果 2 httpWebRequest.RegisterPrefix("http://",System.Net.browser.WebRequestCreator.ClIEnthttp); 3 //将从xml中解析出来的点构建成要素集,并作为我们GP服务输入的参数 4 Featureset featureset = new Featureset(graphicslayer.Graphics); 5 //定义GP服务参数:InterpolationJobParameter 6 List<GPParameter>InterpolationJobParameter = new List<GPParameter>(); 7 //添加GP服务参数 8 InterpolationJobParameter.Add(new GPFeatureRecordSetLayer("PollutionPoints",featureset)); 9 //请求等直面GP服务10 InterpolationTask.submitJobAsync(InterpolationJobParameter);@H_403_4@ @H_403_4@
注意这里的PollutionPoints,这里的名称必须和之前我们发布的GP服务参数列表一致。而且还需要注意这里的GP服务参数类型,必须是要素集。
同理,我们可以看看绘制等值线的GP服务参数列表,如下图所示:
后台定义的绘制等值线的GP服务参数代码:
@H_403_4@1 //定义绘制等值线的GP服务参数 2 List<GPParameter> ContourJobParameter = new List<GPParameter>(); 3 //添加要素集参数 4 ContourJobParameter.Add(new GPFeatureRecordSetLayer("PollutionPoints",featureset)); 5 //添加等值线间距参数 6 ContourJobParameter.Add(new GPDouble("Contour_interval",4.0001)); 7 //添加容差设置参数 8 ContourJobParameter.Add(new GPlinearUnit("XY_Tolerance",esriUnits.esriMeters,1)); 9 //请求等值线GP服务10 ContourTask.submitJobAsync(ContourJobParameter);@H_403_4@ @H_403_4@
注意上面的GP服务参数名称必须保持一致。
五.获取GP服务的结果,并在地图上显示
之前说过,请求GP服务结果都会有一个Completed事件,所以我们获取结果的代码将在该事件回调函数中完成。之前我们已注册了GP事件,其回调函数如下:
下面我们就开始获取等值面的结果。
在请求等值面GP服务的完成事件中添加如下代码:
@H_403_4@1 private voID InterpolationTask_JobCompleted(object sender,JobInfoEventArgs e) 2 { 3 4 if (e.JobInfo.JobStatus == esriJobStatus.esriJobFailed) 5 { 6 MessageBox.Show("请求服务失败!" + e.JobInfo.Messages.ToString()); 7 return; 8 } 9 httpWebRequest.RegisterPrefix("http://",System.Net.browser.WebRequestCreator.ClIEnthttp);10 //获取GP服务结果,这里需要注意的是结果的名称必须和我们发布的GP服务参数列表一致11 InterpolationTask.GetResultimageLayerAsync(e.JobInfo.JobID,"RasterData");12 }@H_403_4@ @H_403_4@
注意这里的RasterData必须和之前我们发布的GP服务输出参数名称一致,否则将无法获取到结果。
这里我们注意到,GetResultimageLayerAsync也是一个异步请求,因此我们需要在其完成事件的回调函数中获得最终的结果,之前我们已经注册了其完成的事件函数,现在添加如下代码:
1 private voID InterpolationTask_GetResultimageLayerCompleted(object sender,GetResultimageLayerEventArgs e) 2 { 3 //返回的结果实际上是一张图片 4 GPResultimageLayer imagelayer = e.GPResultimageLayer; 5 //定义图层的ID 6 imagelayer.ID = "InterpolationLayer"; 7 //设置透明度 8 imagelayer.Opacity = 0.7; 9 //清空原有的结果10 if (map.Layers["InterpolationLayer"] != null)11 {12 map.Layers.Remove(map.Layers["Interpolation"]);13 }14 //添加当前结果到图层中15 map.Layers.Add(imagelayer);16 MessageBox.Show("绘制完成!");17 }@H_403_4@ @H_403_4@
这里说明一点:由于栅格数据不支持在Web客户端直接读取,因此我们通过结果地图服务,将其在服务器端根据我们设置的渲染格式,生成一张图片。然后在客户端实际上是获取这张图片,而不是栅格数据,当客户端的地图范围发生改变时(移动,缩放),就会在服务器端动态的生成响应的图片,并在Web客户端显示其相应的结果。
最后,你还可以在Failed事件中添加GP服务请求失败时的相应处理。
private voID InterpolationTask_Failed(object sender,TaskFailedEventArgs e) { MessageBox.Show("请求服务失败:" + e.Error.ToString()); }@H_403_4@
以上的过程便是获取GP绘制等直面的结果。
下面是获得的结果:
点击加载xml文档,打开xml文件,就会添加相应的Graphic,如下图所示:
接着点击预测,结果如下:
接下来,我们看看如何获取等值线的结果。其过程和等值面的获取相似,只不过等值线的结果是线要素,而等值面则是一张图片,两则在获取和显示上有一点点的差别。
下面是绘制等值线GP请求的Completed事件响应函数代码,和等值面的差不多,唯一不同的就是异步请求的函数,以及阐述不一样。
@H_403_4@1 private voID ContourTask_JobCompleted(object sender,JobInfoEventArgs e) 2 { 3 if (e.JobInfo.JobStatus == esriJobStatus.esriJobFailed) 4 { 5 MessageBox.Show("请求等值线服务失败:" + e.JobInfo.Messages); 6 return; 7 } 8 httpWebRequest.RegisterPrefix("http://",System.Net.browser.WebRequestCreator.ClIEnthttp); 9 //请求绘制等值线GP服务,注意这里和等值面的异步请求函数不一样10 ContourTask.GetResultDataAsync(e.JobInfo.JobID,"Contourline_shp");11 }@H_403_4@ @H_403_4@
同样需要注意请求结果的参数必须和发布的等值线GP服务输出参数名称一致。
然后我们在GetResultDataCompleted事件响应函数中添加相应的代码获取结果,并在地图上显示出来。代码如下:
1 private voID ContourTask_GetResultDataCompleted(object sender,GPParameterEventArgs e) 2 { 3 if (map.Layers["ContourLayer"] != null) 4 { 5 map.Layers.Remove(map.Layers["ContourLayer"]); 6 } 7 Graphicslayer contourLayer = new Graphicslayer() { 8 ID="ContourLayer" 9 };10 11 GPFeatureRecordSetLayer featuresetLayer = e.Parameter as GPFeatureRecordSetLayer;12 //遍历结果获取其中包含的要素,并添加到等值线图层中13 foreach (Graphic graphic in featuresetLayer.Featureset.Features)14 {15 //设置等值线的样式16 graphic.Symbol = new Simplelinesymbol()17 {18 Style = Simplelinesymbol.linestyle.solID,19 color = new SolIDcolorBrush(colors.Blue),20 WIDth = 321 };22 contourLayer.Graphics.Add(graphic);23 }24 //将结果添加到当前的地图中25 map.Layers.Add(contourLayer);26 MessageBox.Show("等值线绘制完成!");27 }@H_403_4@ @H_403_4@
同理添加GP服务请求失败处理函数:
private voID ContourTask_Failed(object sender,TaskFailedEventArgs e) { MessageBox.Show("请求等值线服务失败:" + e.Error.ToString()); }@H_403_4@
这样获取等值线结果的工作已经完成,下面看一看效果:
@H_22_1403@
到此,关于Silverlight调用GP服务绘制等值线以及等值面的所有过程已经讲述完毕。
@H_403_4@ @H_403_4@ @H_403_4@ 总结以上是内存溢出为你收集整理的Silverlight调用GP服务第二篇之调用GP服务(Geoprocessing Service)过程详解全部内容,希望文章能够帮你解决Silverlight调用GP服务第二篇之调用GP服务(Geoprocessing Service)过程详解所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)