ArcGIS Runtime SDK for iOS開發系列教程(7)——GeometryService與GeometryEngine使用

      首發地址:http://www.cnblogs.com/esrichina/archive/2012/11/14/2770779.html

      在我們使用其他WebAPIs開發應用時,常常會用到GeometryService進行空間位置判斷、距離面積量測、緩衝區分析等幾何操作。在ArcGIS for Server10.1中提供的GemetryService主要包括以下操作:

  那麼,在ArcGIS for iOS中通過使用GeometryServiceTask可以很方便地使用ArcGIS的GeometryService,它所包括的操作主要有(下圖左側):

  同時,在ArcGIS for iOS中還封裝了本地進行幾何操作的類——GeometryEngine,極大的提高了幾何操作的效率。他所提供的操作主要如上圖的右側。下面我們將通過最簡單的緩衝區操作來向大家展示在ArcGIS for iOS中GeometryService和GeometryEngine的使用方法。

  首先,我們構建一個支持ArcGIS的SDK的工程,在.h文件中添加GeometryServiceTask和相關協議GeometryServiceTaskDelegate,當然包括要素圖層的添加,如下圖:

  有了上一講中Tasks使用流程的實踐,相信大家對使用協議的委託模式已經相當熟悉。接下來,我們需要對GeometryServicesTask進行初始化和實現GeometryServiceTaskDelegate的相關方法,首先在AGSMapViewTouchDelegate的地圖點擊實現方法方法中初始化GeometryServicesTask和相關參數

-(void)mapView:(AGSMapView *)mapView didClickAtPoint:(CGPoint)screen mapPoint:(AGSPoint *)mappoint graphics:(NSDictionary *)graphics
{
    NSMutableArray *geometryArray=[NSMutableArray array];
    <span style="background-color: #ffcc00;">[geometryArray addObject:mappoint];</span>
     
    AGSPictureMarkerSymbol *pt=[AGSPictureMarkerSymbol pictureMarkerSymbolWithImageNamed:@"ArcGIS.bundle/GPSDisplay.png"];
    
    AGSGraphic *pushpin=[[AGSGraphic alloc]initWithGeometry:mappoint symbol:pt attributes:nil infoTemplateDelegate:nil];
    [_graphicsLayer addGraphic:pushpin];
    [pushpin release];
         
    [_graphicsLayer dataChanged];
     
    [_mapView centerAtPoint:mappoint animated:YES];
     
    //GeometryService
    <span style="background-color: #ffcc00;">self.gst=[[[AGSGeometryServiceTask alloc]initWithURL:[NSURL URLWithString:kGeometryBufferService]]autorelease];</span>
    AGSSpatialReference *sr=[[[AGSSpatialReference alloc]initWithWKID:102100 WKT:nil]autorelease];
     
    <span style="background-color: #ffcc00;">self.gst.delegate=self;</span>
     
    <span style="background-color: #ffcc00;">AGSBufferParameters *bufferParams=[[AGSBufferParameters alloc]init];</span>
    bufferParams.unit=kesriSRUnit_Meter;
    bufferParams.bufferSpatialReference=sr;
     
    bufferParams.distances = [NSArray arrayWithObjects:
                              [NSNumber numberWithUnsignedInteger:10000],
                              [NSNumber numberWithUnsignedInteger:30000],
                              [NSNumber numberWithUnsignedInteger:50000],
                              nil];
    bufferParams.geometries = geometryArray;
    bufferParams.outSpatialReference = sr;
    bufferParams.unionResults = FALSE;
     
    <span style="background-color: #ffcc00;">[self.gst bufferWithParameters:bufferParams];</span>
    [bufferParams release];
    
}

  然後,添加GeometryService執行buffer操作的響應操作,成功返回處理:

-(void)geometryServiceTask:(AGSGeometryServiceTask *)geometryServiceTask operation:(NSOperation *)op didReturnBufferedGeometries:<span style="background-color: #ffcc00;">(NSArray *)bufferedGeometries</span>
{
    UIAlertView *av = [[UIAlertView alloc] initWithTitle:@"GeometryService"
                                                 message:[NSString stringWithFormat:@"成功返回%d個緩衝區!", [bufferedGeometries count]]
                                                delegate:self
                                       cancelButtonTitle:@"確定"
                                       otherButtonTitles:nil];
    [av show];
    [av release];
        
    // Create a SFS for the inner buffer zone
    AGSSimpleFillSymbol *innerSymbol = [AGSSimpleFillSymbol simpleFillSymbol];
    innerSymbol.color = [[UIColor redColor] colorWithAlphaComponent:0.40];
    innerSymbol.outline.color = [UIColor darkGrayColor];
    // Create a SFS for the outer buffer zone
    AGSSimpleFillSymbol *outerSymbol = [AGSSimpleFillSymbol simpleFillSymbol];
    outerSymbol.color = [[UIColor yellowColor] colorWithAlphaComponent:0.25];
    outerSymbol.outline.color = [UIColor darkGrayColor];
    // counter to help us determine if the geometry returned is inner/outer
     
    NSUInteger i = 0;
     
    for (<span style="background-color: #ffcc00;">AGSGeometry* g    in bufferedGeometries</span>) {
         
        // initialize the graphic for geometry
        <span style="background-color: #ffcc00;">AGSGraphic *graphic = [[AGSGraphic alloc] initWithGeometry:g symbol:nil attributes:nil infoTemplateDelegate:nil];</span>
         
        // since we have 2 buffer distances, we know that 0-2 will be 100m buffer and 3-5 will be 300m buffer
        if (i < [bufferedGeometries count]/2) {
            graphic.symbol = innerSymbol;
        }
        else {
            graphic.symbol = outerSymbol;
        }
         
        // add graphic to the graphic layer
        [self.graphicsLayer addGraphic:graphic];
         
        // release our alloc'd graphic
        [graphic release];
         
        // increment counter so we know which index we are at
        i++;
    }
    // let the graphics layer know it has new graphics to draw
    [self.graphicsLayer dataChanged];
}

  可以看出成功執行GeometryService的buffer操作後,返回結果是數組(NSArray *)bufferedGeometries,通過遍歷將Geometry轉化爲要素來展示。另外,我們還需要添加出錯的處理:

- (void)geometryServiceTask:(AGSGeometryServiceTask *)geometryServiceTask operation:(NSOperation*)op didFailBufferWithError:(NSError *)error {
    UIAlertView *av = [[UIAlertView alloc] initWithTitle:@"Error"
                                                 message:@"There was an error with the buffer task"
                                                delegate:self
                                       cancelButtonTitle:@"Ok"
                                       otherButtonTitles:nil];
    [av show];
    [av release];
}

  這個與其他Tasks的提示類似,不做過多解釋。這樣,我們就完成了使用GeometryServiceTask來實現緩衝區分析的操作。

  接下來,我們來看如何通過GeometryEngine來實現同樣的操作:

-(void)mapView:(AGSMapView *)mapView didClickAtPoint:(CGPoint)screen mapPoint:(AGSPoint *)mappoint graphics:(NSDictionary *)graphics
{
    NSMutableArray *geometryArray=[NSMutableArray array];
    [geometryArray addObject:mappoint];
     
    //[_graphicsLayer removeAllGraphics];
     
    AGSPictureMarkerSymbol *pt=[AGSPictureMarkerSymbol pictureMarkerSymbolWithImageNamed:@"ArcGIS.bundle/GPSDisplay.png"];
    
    AGSGraphic *pushpin=[[AGSGraphic alloc]initWithGeometry:mappoint symbol:pt attributes:nil infoTemplateDelegate:nil];
    [_graphicsLayer addGraphic:pushpin];
    [pushpin release];
         
    [_graphicsLayer dataChanged];
     
    [_mapView centerAtPoint:mappoint animated:YES];
    //GeometryEngine
    <span style="background-color: #ffcc00;">AGSGeometryEngine *geoEng=[AGSGeometryEngine defaultGeometryEngine];</span>
     
    // Create a SFS for the inner buffer zone
    AGSSimpleFillSymbol *innerSymbol = [AGSSimpleFillSymbol simpleFillSymbol];
    innerSymbol.color = [[UIColor redColor] colorWithAlphaComponent:0.40];
    innerSymbol.outline.color = [UIColor darkGrayColor];
    // Create a SFS for the outer buffer zone
    AGSSimpleFillSymbol *outerSymbol = [AGSSimpleFillSymbol simpleFillSymbol];
    outerSymbol.color = [[UIColor yellowColor] colorWithAlphaComponent:0.25];
    outerSymbol.outline.color = [UIColor darkGrayColor];
     
    for (int i=10; i>0;i--)
    {
        <span style="background-color: #ffcc00;">AGSPolygon *geBuffer=[geoEng bufferGeometries:geometryArray byDistance:i*1000];</span>
        AGSGraphic *gr = [[AGSGraphic alloc] initWithGeometry:geBuffer symbol:nil attributes:nil infoTemplateDelegate:nil];
        if (i%2==1)
        {
            gr.symbol=outerSymbol;
        }
        else
        {
            gr.symbol=innerSymbol;
        }       
         
        //[self.graphicsLayer addGraphic:gr];
    }
     
    [self.graphicsLayer dataChanged];
}

  我們不難發現,使用GeometryEngine實現同樣的buffer操作更加便捷,如果你實際操作的話,你還好發現它的效率要比GeomertyServiceTask高很多。

效果:

   總結:本講主要通過GeometryServiceTask和GeometryEngine的使用來向大家展示在ArcGIS for iOS中如何實現幾何相關的操作,其他具體操作,如長度計算、面積量測等大家可以參考幫助文檔。下一講將向大家介紹Geoprocessor相關的操作,歡迎大家繼續關注!


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