ArcGIS API for iOS开发教程(七)Geometry Service
Geometry Service是ArcGIS Server提供的针对几何操作提供的一组服务。在ArcGIS10中,Geometry Service除了投影(project)、简化(simplify)、缓冲(buffer)、面积周长(Areas and lengths)、标注点(Label Points)、关系操作(Relation Operation)等,还提供有一组在线编辑使用的服务,包括union、相交(intersect)、相异(difference)、裁剪 (cut)、修剪(TrimExtend)、偏移(offset)、综合(Generalize)、重构(Reshape)等。
备注:此亦为在使用Web APIs 2.0编辑工具进行编辑时,输入Geometry Service地址的原因
下面我们将以缓冲区分析为例,来介绍ArcGIS API for iOS中的Geometry Service调用。
1、按照【ArcGIS API for iOS开发之旅】MapView介绍的步骤创建一个基本的地图应用程序,命名为GeometryServicesDemo
2、按照【ArcGIS API for iOS开发之旅】Graphic Layer介绍的步骤定义一个GraphicsLayer,并添加到地图视图中
3、打开GeometryServicesDemoViewController.h文件,添加AGSMapViewDelegate和AGSGeometryServiceTaskDelegate,如下面代码所示:
@interface GeometryServicesDemoViewController:
UIViewController <AGSMapViewDelegate,AGSGeometryServiceTaskDelegate>{
AGSMapView *mapView;
AGSGraphicsLayer *graphicsLayer;
}
4、在GeometryServicesDemoViewController.h文件中定义两个宏,分别为Geometry Service地址和单位。代码如下:
#define kGeometryBufferService @"http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer/buffer"
#define kesriSRUnit_Meter 9001
5、打开GeometryServicesDemoViewController.m文件,实现AGSMapViewDelegate中的mapViewDidLoad方法,代码如下:
// Method fired when mapView has finished loading
- (void)mapViewDidLoad:(AGSMapView *)mapView {
// 显示区域放大至北京
AGSEnvelope *env = [[AGSEnvelope alloc] initWithXmin:12896931.118569
ymin:4779566.12743336
xmax:13062266.2487341
ymax:5030121.81554815
spatialReference:[[[AGSSpatialReference alloc] initWithWKID:102100 WKT:nil] autorelease]];
[self.mapView zoomToEnvelope:env animated:TRUE];
[env release];
}
6、在GeometryServicesDemoViewController.m文件中,实现AGSMapViewDelegate中的 -(void)mapView:(AGSMapView *)mapView disclickAtPoint:(CGPoint) screen mapPoint: (AGSPoint *)mappoint graphics:(NSDictionary *)graphics方法。代码如下:
- (void)mapView:(AGSMapView *)mapView didClickAtPoint:(CGPoint)screen mapPoint:(AGSPoint *)mappoint graphics:(NSDictionary *)graphics
{
NSMutableArray *geometryArray = [NSMutableArray array];
[geometryArray addObject:mappoint];
[self.graphicsLayer removeAllGraphics];
AGSPictureMarkerSymbol *pt = [AGSPictureMarkerSymbol pictureMarkerSymbolWithImageNamed:@"pushpin.png"];
// this offset is to line the symbol up with the map was actually clicked
pt.xoffset = 8;
pt.yoffset = -18;
// init pushpin with the AGSPictureMarkerSymbol we just created
AGSGraphic *pushpin = [[AGSGraphic alloc] initWithGeometry:mappoint symbol:pt attributes:nil infoTemplate:nil];
// add pushpin to graphics layer
[self.graphicsLayer addGraphic:pushpin];
// let the graphics layer know it needs to redraw
[pushpin release];
[self.graphicsLayer dataChanged];
// start network activity indicator
[AGSMapView showNetworkActivityIndicator:YES];
AGSGeometryServiceTask *gst = [[AGSGeometryServiceTask alloc] initWithURL:[NSURL URLWithString:kGeometryBufferService]];
AGSSpatialReference *sr = [[[AGSSpatialReference alloc] initWithWKID:102100 WKT:nil] autorelease];
// assign the delegate so we can respond to AGSGeometryServiceTaskDelegate methods
gst.delegate = self;
AGSBufferParameters *bufferParams = [[AGSBufferParameters alloc] init];
// set the units to buffer by to meters
bufferParams.unit = kesriSRUnit_Meter;
bufferParams.bufferSpatialReference = sr;
// set our buffer distances to 100m and 300m respectively
bufferParams.distances = [NSArray arrayWithObjects:
[NSNumber numberWithUnsignedInteger:10000],
[NSNumber numberWithUnsignedInteger:30000],
nil];
// assign the geometries to be buffered…
// self.geometryArray contains the points we clicked
bufferParams.geometries = geometryArray;
bufferParams.outSpatialReference = sr;
bufferParams.unionResults = FALSE;
// execute the task
[gst bufferWithParameters:bufferParams];
// IMPORTANT: since we alloc'd/init'd bufferParams and gst
// we must explicitly release them
[bufferParams release];
[gst release];
}
7、在GeometryServicesDemoViewController.m文件中,实现 AGSGeometryServiceTaskDelegate中的-(void)geometryServiceTask: (AGSGeometryServiceTask*) geometryServiceTask didReturnBufferedGeometries: (NSArray *)bufferedGeometries方法,用来响应缓冲区分析的结果,代码如下:
- (void)geometryServiceTask:(AGSGeometryServiceTask *)geometryServiceTask didReturnBufferedGeometries:(NSArray *)bufferedGeometries {
[AGSMapView showNetworkActivityIndicator:FALSE];
// 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;
// NOTE: the bufferedGeometries returned are in order based on buffer distance…
// so if you clicked 3 points, the order would be:
// objectAtIndex bufferedGeometry
// 0 pt1 buffered at 100m
// 1 pt2 buffered at 100m
// 2 pt3 buffered at 100m
// 3 pt1 buffered at 300m
// 4 pt2 buffered at 300m
// 5 pt3 buffered at 300m
for (AGSGeometry* g in bufferedGeometries) {
// initialize the graphic for geometry
AGSGraphic *graphic = [[AGSGraphic alloc] initWithGeometry:g symbol:nil attributes:nil infoTemplate:nil];
// 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];
}
8、编译,运行,效果如图所示