本文内容:ArcGIS API中Task的概念,QueryTask的使用,以及Draw对象。
空间查询GIS中一个非常常用的功能:在地图上画出任意多边形,从自己感兴趣的事物中筛选出与所画多边形有指定空间关系(通常是相交)的要素来,进一步查看。在本次开发实例中,第二个功能就是空间查询。用手势在地图上画一个范围,筛选出落入该范围的超市店面,从而进一步查看它们的营业额统计信息。
ArcGIS API中,给我们提供了许多Task类,来完成一些常见的GIS功能,比如属性/控件查询,几何对象的拓扑处理,特定工作流的地理任务等。它们都是已经封装好的Task类,使用起来都遵循3个步骤的原则:1、为某个Task设置所需的相应参数;2、通过Task对象向服务器发送处理请求;3、接受服务器端返回的结果。所有的计算和处理工作都是由ArcGIS Server发布的REST服务来完成,是典型的客户端请求,服务器端相应的流程。
QueryTask是ArcGIS API提供的诸多Task之一,它接受Query类型的参数。该参数有几个常用的属性,比如Where属性和Geometry属性,通过对这两个属性的设置,我们就可以完成最常见的属性查询和空间查询功能。依然将空间查询这个功能封装成一个工具,在主界面中进行调用。
这里为了清晰起见,我省去与空间查询功能无关的代码(所有程序代码会在教程完结后提供下载)。要使用QueryTask的功能,我们按照前面说三个步骤来做。首先设置好查询参数Query,然后通过QueryTask对象提交查询请求:
1: void _draw_DrawComplete(object sender, DrawEventArgs e)
2: {3: Polygon polygon = null;
4: if (_usingFreeHand) //geometry is freehand polyline
5: {6: Polyline polyline = e.Geometry as Polyline;
7: ESRI.ArcGIS.Client.Geometry.PointCollection pc = polyline.Paths[0]; 8: pc.Add(pc[0]);9: polygon = new Polygon()
10: { 11: SpatialReference = map1.SpatialReference, 12: }; 13: polygon.Rings.Add(pc); 14: }15: else //geometry is polygon
16: {17: polygon = e.Geometry as Polygon;
18: } 19: 20: _GLayer.Graphics.Clear();21: Graphic g = new Graphic()
22: { 23: Geometry = polygon,24: Symbol = new SimpleFillSymbol()
25: {26: Fill=new SolidColorBrush(Color.FromArgb(33,255,0,0)),
27: BorderBrush=new SolidColorBrush(Colors.Red),
28: BorderThickness=2 29: } 30: };31: _GLayer.Graphics.Add(g); //display the geometry created by Draw object
32: 33: QueryTask queryTask = new QueryTask(App.Current.Resources["BusinessLayer"] as string);
34: Query query = new Query();
35: //102100 to 4326
36: ESRI.ArcGIS.Client.Projection.WebMercator wm = new ESRI.ArcGIS.Client.Projection.WebMercator();
37: query.Geometry = wm.ToGeographic(polygon);38: query.OutFields.AddRange(new string[] { "*" });//return all attributes fields
39: query.SpatialRelationship = SpatialRelationship.esriSpatialRelIntersects;40: queryTask.ExecuteCompleted += new System.EventHandler<QueryEventArgs>(queryTask_ExecuteCompleted);
41: queryTask.Failed += (s, a) => 42: {43: MessageBox.Show("查询失败" + a.Error.Message);
44: }; 45: _busyIndicator.Visibility = Visibility.Visible; 46: queryTask.ExecuteAsync(query); 47: } 代码中,我们首先利用超市图层的服务地址,初始化了一个QueryTask对象。对于Query参数,这里设置了Geometry属性,作为空间查询的图形;对OutFields参数的设置表示在查询结果中返回所有属性字段;指定空间关系为与Geometry相交。然后通过ExecuteAsync方法将查询请求提交到服务器端。注意到在设置Query的Geometry属性之前,我们对Polygon对象做了空间参考的转换,将其从102100坐标系(WGS 1984 Web Mercator Auxiliary Sphere,这是地图控件的坐标系)转换到了4326坐标系(WGS 1984,这是超市图层的坐标系),如果Query中Geometry的坐标系不正确,查询结果往往会不可预料。
发出请求后,我们就可以在设置好的queryTask_ExecuteCompleted方法中取得查询结果了。
1: void queryTask_ExecuteCompleted(object sender, QueryEventArgs e)
2: { 3: _busyIndicator.Visibility = Visibility.Collapsed;4: if (e.FeatureSet.Features.Count == 0) //typeof(e.FeatureSet.Features)==GraphicCollection
5: {6: MessageBox.Show("未选中任何店面");
7: }8: else
9: {10: string str = "是否查看图表详情?";
11: if (MessageBox.Show(str,
12: "查询结果", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
13: {14: //add selected graphics to app level, so spatialquerychart.xaml could retrieve them
15: App app = Application.Current as App;
16: if (app.AppParameters.ContainsKey("QueryedGraphics"))
17: app.AppParameters["QueryedGraphics"] = e.FeatureSet.Features;
18: else
19: app.AppParameters.Add("QueryedGraphics", e.FeatureSet.Features);
20: 21: (app.AppParameters["MainPage"] as PhoneApplicationPage).NavigationService.Navigate(new Uri("/Tools/SpatialQueryChart.xaml", UriKind.Relative));
22: } 23: _GLayer.ClearGraphics(); 24: } 25: } 可以看到,查询结果(落入所选范围内的超市)以Graphic的形式存储在事件参数中。Graphic的Geometry就是超市的图形信息,而Attributes属性中是我们想要的所有营业信息。如果查询结果不为空,我们将其存入全局变量中,以便在另一个页面中用图表的形式来显示。这里我们使用VisiFire控件来显示图表,它是一套可用于WP上的Silverlight插件,此处不进行过多讨论,有兴趣同学可自己搜索。
整个查询的过程在QueryTask的帮助下变得非常简单。细心的朋友可能会有疑问,我们这个空间查询的图形是如何得到的?在前面的代码中可以看到,发起查询请求的代码是写在_draw_DrawComplete这个事件中的。_draw是我们提前定义好的一个Draw对象:private Draw _draw;。
为了方便与用户的交互,ArcGIS API中提供了Draw这个类,可以利用鼠标或手势来交互地画出Point,Polyline,Polygon,Freehand(Polyline)等几何对象,在2.2版本的API中,Draw还新增了arrow,triangle,circle,ellipses几个原生图形。
使用Draw这个对象也比较简单,初始化,设定好要画的几何图形类型,然后将其IsEnabled属性设为True,就进入了交互状态,绘制完毕后,就会触发DrawComplete事件,在事件的参数中就可以得到画出的Geometry结果,得到结果之后,就可以利用Graphic将这个看不见摸不着的Geometry显示出来了,这样就达到了交互的目的。我们空间查询的几何对象就是利用Draw得到的。
参考资料:
ArcGIS API中各种Task介绍:
http://bbs.esrichina-bj.cn/ESRI/thread-45302-1-1.html
Draw对象的使用:
http://help.arcgis.com/en/arcgismobile/10.0/apis/WindowsPhone/help/011v/011v00000019000000.htm
QueryTask的使用:
http://help.arcgis.com/en/arcgismobile/10.0/apis/WindowsPhone/help/011v/011v00000016000000.htm
VisiFire:
http://www.visifire.com/

没有评论:
发表评论