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的委託處理;具體的操作這裏不再贅述。

  這裏介紹下給控件動態綁定操作的方法,類似與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];
}

  運行程序,結果如圖

  以上就是同步方式執行Geoprocessor的使用流程,那麼對於異步方式執行Geoprocessor使用思路與同步方式完全相同,除了調用方法和對應的結果處理

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

  對於調用結果的處理大家可以參考SDK中AGSGeoprocessorDelegate協議的相應方法

  總結:本講主要通過同步方式調用GP服務實現當前要素範圍內人口分佈狀況查詢,對於異步方式與同步類似,大家可以參考幫助。如果大家已經熟悉基於協議的代理模式實現相應操作的方式,那麼也就熟悉了ArcGIS Runtime for iOS使用的基本流程。下一講我將給大家介紹網絡分析相關的操作,歡迎大家繼續關注!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章