首發地址: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相關的操作,歡迎大家繼續關注!