ArcGIS Runtime SDK for iOS开发系列教程(8)——Geoprocessor使用

首发地址:http://www.cnblogs.com/esrichina/archive/2012/11/24/2785296.html

      Geoprocessor工具是ArcGIS进行数据处理与空间分析的利器。通过Geoprocessor框架我们可以很方便的将许多空间分析功能或者是自定义的业务处理流程以GP服务的形式实现在线处理与分享。与其他APIs中调用GP服务类似,ArcGIS Runtime for iOS中AGSGeoprocessor使用与Tasks使用方式相同,它需要包含的协议是AGSGeoprocessorDelegate。GP服务的调用分为同步方式和异步方式,具体调用方式应该和GP服务发布的方式或GP服务支持的操作方式对应。下面我将通过同步方式调用GP服务来实现空间人口分布的查询,向大家介绍Geoprocessor使用的一般流程。

  同样,我们首先来新建一个支持ArcGIS的工程,然后添加AGSGeoprocessorDelegate协议以及相应的属性。这里我希望通过在地图上点击,首先通过GeometryServices生成一个多边形,然后用多边形作为Geoprocessor的输入参数,来查询当前范围内的人口情况,对于服务的参数与返回值情况,大家可以通过服务地址去查看。回顾下,我们这里添加的三个协议在之前的教程里都已经使用过了,AGSMapViewTouchDelegate协议实现地图点击的委托处理;AGSGeometryServiceTaskDelegate实现GeometryServiceTask的委托处理;具体的操作这里不再赘述。

ArcGIS Runtime SDK for iOS开发系列教程(8)——Geoprocessor使用_第1张图片

  这里介绍下给控件动态绑定操作的方法,类似与flex等绑定监听事件,之前,我们常用拖拽连线的形式,两者其实是等效的。

- ( void )viewDidLoad
{
     [ super  viewDidLoad];
     // Do any additional setup after loading the view, typically       <br>     .......................

            self.mapView.touchDelegate=self;

<span style= "background-color: #ffcc00;" >     [ self .distance addTarget: self  action: @selector (changeValue:) forControlEvents: UIControlEventValueChanged];</span>
 
}
-( void )changeValue:( id )sender
{    <br>   //拖动改变缓冲半径
     <span style= "background-color: #ffcc00;" > self .showDis.text=[ NSString  stringWithFormat:@ "Distance:%0.0f" ,[ self .distance value]];</span>
}   

  另外,跟大家分享下使用GeometryEngine和GeometryService进行buffer的结果类型是有区别的。前者返回类型是AGSMutablePolygon,后者是AGSPolygon,在有些GP服务调用的参数类型并不支持AGSMutablePolygon,希望大家在使用时注意,以下是输出结果。

GeometryEngine geometry is :geometry: AGSMutablePolygon: [envelope: AGSEnvelope: xmin = 12983839.390300, ymin = 4875893.536200, xmax = 12985839.390300, ymax = 4877893.536200, spatial reference: [AGSSpatialReference: wkid = 102100, wkt = null]], symbol: <AGSSimpleFillSymbol: 0xb079ba0>, attributes: (null), visible: 1

GeomertyService geometry is geometry: AGSPolygon: [envelope: AGSEnvelope: xmin = 12974839.514609, ymin = 4866894.033494, xmax = 12994839.265942, ymax = 4886893.536163, spatial reference: [AGSSpatialReference: wkid = 102100, wkt = null]], symbol: <AGSSimpleFillSymbol: 0x9a66580>, attributes: (null), visible: 1

  接着来看Geoprocessor,我们在GeometryService成功返回后继续将放回要素作为GP服务调用的输入参数

-( void )geometryServiceTask:(AGSGeometryServiceTask *)geometryServiceTask operation:( NSOperation  *)op <span style= "background-color: #ffcc00;" >didReturnBufferedGeometries:( NSArray  *)bufferedGeometries</span>
{  
     //定义多边形要素的渲染样式
     AGSSimpleFillSymbol *outerSymbol = [AGSSimpleFillSymbol simpleFillSymbol];
     outerSymbol.color = [[UIColor yellowColor] colorWithAlphaComponent:0.25];
     outerSymbol.outline.color = [UIColor darkGrayColor];
     
     AGSGraphic *graphic= nil ;
     for  (AGSGeometry* g in bufferedGeometries)
     {   <br>      // initialize the graphic for geometry
         <span style= "background-color: #ffcc00;" >graphic= [[AGSGraphic alloc] initWithGeometry:g symbol: nil  attributes: nil  infoTemplateDelegate: nil ];</span>
     graphic.symbol = outerSymbol;
         
     [ self .graphicsLayer addGraphic:graphic];
     //NSLog(@"gr is %@",graphic);
     [graphic release];     
     }
     [ self .graphicsLayer dataChanged];
     <br>   //以当前返回要素的区域对地图进行缩放
     AGSMutableEnvelope *newEnv =[AGSMutableEnvelope envelopeWithXmin:graphic.geometry.envelope.xmin ymin:graphic.geometry.envelope.ymin xmax:graphic.geometry.envelope.xmax ymax:graphic.geometry.envelope.ymax spatialReference: self .mapView.spatialReference];
     [newEnv expandByFactor:2.8];
     [ self .mapView zoomToEnvelope:newEnv animated: YES ];
     
     //Geoprocessor<br>    //初始化Geoprocessor
   <span style= "background-color: #ffcc00;" self .agp=[AGSGeoprocessor geoprocessorWithURL:[ NSURL  URLWithString:kGPurl]];</span>
     self .agp.delegate= self ;
     self .agp.interval=10;
     self .agp.processSpatialReference= self .mapView.spatialReference;
     self .agp.outputSpatialReference= self .mapView.spatialReference;
     
     AGSFeatureSet *fs=[[[AGSFeatureSet alloc]init]autorelease];
     fs.features=[ NSArray  arrayWithObjects:graphic, nil ];
     <br>    //创建调用GP服务的相应参数,其参数个数和类型(type)应该与GP服务的要求相对应 <br> <span style="background-color: #ffcc00;">   AGSGPParameterValue *param=[AGSGPParameterValue parameterWithName:@"inputPoly" type:AGSGPParameterTypeFeatureRecordSetLayer value:fs]; NSArray *params=[NSArray arrayWithObjects:param,nil ];</span> <br>    <br>     //使用同步方式调用GP服务<br>    <span style="background-color: #ffcc00;">[self.agp executeWithParameters:params];</span> }

  与其他Task使用方式相类似,接下来,我们需要实现AGSGeoprocessorDelegate协议中对GP服务调用的相应处理函数

-( void )geoprocessor:(AGSGeoprocessor *)geoprocessor operation:( NSOperation  *)op <span style= "background-color: #ffcc00;" >didExecuteWithResults:( NSArray  *)results messages:( NSArray  *)message</span>s
{   //成功执行Geoprocessor返回结果时数组类型的results,我们来进行相应处理
     if  (results!= nil  && [results count]>0)
     {<br>        //返回值数组包含的时AGSGParameterValue类型的对象,具体大家可以参考SDK自带帮助,很全面哦
         <span style= "background-color: #ffcc00;" >AGSGPParameterValue *result=[results objectAtIndex:0];</span>
         AGSFeatureSet *resultFS= result.value;
         for  (AGSGraphic *resultgr in resultFS.features)
         {
             <span style= "background-color: #ffcc00;" > NSDictionary  *attr=resultgr.attributes;</span>
             <span style= "background-color: #ffcc00;" > NSString  *peo=[ NSString  stringWithFormat:@ "%@" ,[attr objectForKey:@ "SUM" ]];</span>
             NSArray  *peoArr=[peo componentsSeparatedByString:@ "." ];
             NSLog (@ "this is %@" ,peoArr[0]);
             <br>        //输出要素的所有属性
             for ( id  key in attr)
             {
                 NSLog (@ "key: %@,value: %@" ,key,[attr objectForKey:key]);
             }
             //将结果弹出显示
             UIAlertView *av = [[UIAlertView alloc] initWithTitle:@ "Geoprocessor Result"
                                                          message:[ NSString  stringWithFormat:@ "当前范围大约有%@人!" , peoArr[0]]
                                                         delegate: self
                                                cancelButtonTitle:@ "确定"
                                                otherButtonTitles: nil ];
             [av show];
             [av release];
         }
     }
}

  同时,实现Geoprocessor执行出错的提示

-( void )geoprocessor:(AGSGeoprocessor *)geoprocessor operation:( NSOperation  *)op didFailExecuteWithError:( NSError  *)error
{
     UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:@ "Error"
                                                      message:[error localizedDescription]
                                                     delegate: nil
                                            cancelButtonTitle:@ "OK"
                                            otherButtonTitles: nil ] autorelease];
     [alert show];
}

  运行程序,结果如图

ArcGIS Runtime SDK for iOS开发系列教程(8)——Geoprocessor使用_第2张图片

  以上就是同步方式执行Geoprocessor的使用流程,那么对于异步方式执行Geoprocessor使用思路与同步方式完全相同,除了调用方法和对应的结果处理

  异步方式:[self.gpTask submitJobWithParameters:params]; 同步方式:[self.agp executeWithParameters:params];

  对于调用结果的处理大家可以参考SDK中AGSGeoprocessorDelegate协议的相应方法

ArcGIS Runtime SDK for iOS开发系列教程(8)——Geoprocessor使用_第3张图片

  总结:本讲主要通过同步方式调用GP服务实现当前要素范围内人口分布状况查询,对于异步方式与同步类似,大家可以参考帮助。如果大家已经熟悉基于协议的代理模式实现相应操作的方式,那么也就熟悉了ArcGIS Runtime for iOS使用的基本流程。下一讲我将给大家介绍网络分析相关的操作,欢迎大家继续关注!

你可能感兴趣的:(ArcGIS Runtime SDK for iOS开发系列教程(8)——Geoprocessor使用)