ArcGIS Runtime SDK for iOS(六) --- 空間幾何分析與操作(中)
2016.4.18 武漢 陰晴
by SevenJohs.
概述
實現緩衝區以及剪下操作。內容:
緩衝區buffer剪下cut
-緩衝區[buffer]: -
續上節內容,緩衝區分析是GIS的基本空間操作功能之一,是指在點、線、面實體的周圍,自動建立的一定寬度的多邊形。
例如,某地區有危險品倉庫,要分析一旦倉庫爆炸所涉及的範圍,這就需要進行點緩衝區分析等等。
續上節內容,緩衝區分析是GIS的基本空間操作功能之一,是指在點、線、面實體的周圍,自動建立的一定寬度的多邊形。
為了在合適的映射位置,使用zoomToEnvelope(縮放/平移映射到指定的包絡圖上)。注意,必須具有相同的spatialReference。
AGSEnvelope* envelope = [self createEnvelope];[_mapView zoomToEnvelope:envelope animated:YES];
–介面:
// Copyright 2016/4/18 by SevenJohs////@property (nonatomic , strong) IBOutlet AGSMapView *mapView;//開始緩衝區操作按鈕@property (strong, nonatomic) IBOutlet UIButton *btnToStartBuffer;//控制緩衝區的Slider@property (strong, nonatomic) IBOutlet UISlider *bufferDegreeSlider;//選擇繪製類型按鈕(點/線/面)@property (strong, nonatomic) IBOutlet UISegmentedControl *geometrySelectSegment;//重設按鈕@property (strong, nonatomic) IBOutlet UIButton *btnToReset;
-點擊事件操作
#pragma MARK -- Button Click Methods/** * 開始對geometry對象進行緩衝區操作 * */- (IBAction)startBuffer:(id)sender { AGSGeometry* sketchGeo = [_skechLayer.geometry copy]; AGSSimpleMarkerSymbol* pointSymbol = [[AGSSimpleMarkerSymbol alloc]init]; pointSymbol.color = [UIColor purpleColor]; pointSymbol.style = AGSSimpleMarkerSymbolStyleCircle; AGSSimpleLineSymbol* lineSymbol = [[AGSSimpleLineSymbol alloc]init]; lineSymbol.color = [UIColor magentaColor]; lineSymbol.width = 4; //判斷類型,添加特定樣式 AGSGraphic* graphic = [AGSGraphic graphicWithGeometry:sketchGeo symbol:nil attributes:nil infoTemplateDelegate:nil]; if ([sketchGeo isKindOfClass:[AGSPoint class]]) { graphic.symbol = pointSymbol; } else { graphic.symbol = lineSymbol; } [_graphicLayer addGraphic:graphic]; //新建立的buffer graphic,並添加 AGSGraphic* newBufferGraphic = [self createBufferGraphicByGeometry:sketchGeo]; //便於重設或移除操作的數組 [_lastBufferArr addObject:newBufferGraphic]; [_graphicLayer addGraphic:newBufferGraphic]; [_skechLayer clear]; }- (IBAction)reset:(id)sender { _lastBufferArr = [NSMutableArray array]; [_graphicLayer removeAllGraphics]; [_skechLayer clear];}/** * Slider Value 改變時,同步更新緩衝區數值 * */- (IBAction)slider:(id)sender { int value = (int)self.bufferDegreeSlider.value; _bufferDistance = value; //remove old buffer之後再建立新的bufferGraphic for (AGSGraphic* oldGraphic in _lastBufferArr) { [self.graphicLayer removeGraphic:oldGraphic]; } NSMutableArray* newGraphicsArr = [NSMutableArray array]; for (AGSGraphic* graphic in _graphicLayer.graphics) { AGSGeometryEngine* geometryEngine = [AGSGeometryEngine defaultGeometryEngine]; AGSGeometry* newGeometry = [geometryEngine bufferGeometry:graphic.geometry byDistance:_bufferDistance]; AGSGraphic* newGraphic = [AGSGraphic graphicWithGeometry:newGeometry symbol:[self setBufferSymbol] attributes:nil infoTemplateDelegate:nil]; [newGraphicsArr addObject:newGraphic]; } //便於移除 _lastBufferArr = newGraphicsArr; [_graphicLayer addGraphics:newGraphicsArr];}/** * 選擇對應的geometry,在sketchLayer上繪製 * */- (IBAction)geometryChoose:(id)sender { switch (_geometrySelectSegment.selectedSegmentIndex) { case 0: _skechLayer.geometry = [[AGSMutablePoint alloc]initWithSpatialReference:_mapView.spatialReference]; break; case 1: _skechLayer.geometry = [[AGSMutablePolyline alloc]initWithSpatialReference:_mapView.spatialReference]; break; case 2: _skechLayer.geometry = [[AGSMutablePolygon alloc]initWithSpatialReference:_mapView.spatialReference]; break; default: break; } [_skechLayer clear];}
–自訂方法
/** * 設定緩衝區樣式 * * @return AGSSimpleFillSymbol* 緩衝區樣式 * */-(AGSSimpleFillSymbol*)setBufferSymbol{ AGSSimpleFillSymbol* bufferSymbol = [AGSSimpleFillSymbol simpleFillSymbol]; bufferSymbol.color = [[UIColor brownColor] colorWithAlphaComponent:0.4]; bufferSymbol.outline.color = [UIColor darkGrayColor]; return bufferSymbol;}/** * 使用engine建立buffer graphic * * @return 新的buffer graphic */-(AGSGraphic*)createBufferGraphicByGeometry:(AGSGeometry*)sketchGeometry{ AGSGeometryEngine* geometryEngine = [AGSGeometryEngine defaultGeometryEngine]; AGSGeometry* newGeometry = [geometryEngine bufferGeometry:sketchGeometry byDistance:_bufferDistance]; AGSGraphic* newGraphic = [AGSGraphic graphicWithGeometry:newGeometry symbol:[self setBufferSymbol] attributes:nil infoTemplateDelegate:nil]; return newGraphic;}/** * 建立envelope */-(AGSEnvelope*)createEnvelope{ AGSSpatialReference *sr = [AGSSpatialReference spatialReferenceWithWKID:SPATIAL_REFERENCE_WKID]; AGSEnvelope* envelope = [AGSEnvelope envelopeWithXmin:X_MIN ymin:Y_MIN xmax:X_MAX ymax:Y_MAX spatialReference:sr]; return envelope;}
–ViewDidLoad & MapViewDidLoad
- (void)viewDidLoad { [super viewDidLoad]; self.mapView.layerDelegate = self; self.mapView.touchDelegate = self; self.mapView.showMagnifierOnTapAndHold = YES; [self.mapView enableWrapAround]; [self addTiledLayer]; [self addGraphicsLayer]; int value = (int)self.bufferDegreeSlider.value; _bufferDistance = value; //建立envelope,中心化目標 AGSEnvelope* envelope = [self createEnvelope]; [_mapView zoomToEnvelope:envelope animated:YES]; _lastBufferArr = [NSMutableArray array];}#pragma mark AGSMapViewLayerDelegate methods-(void) mapViewDidLoad:(AGSMapView*)mapView { _skechLayer = [AGSSketchGraphicsLayer graphicsLayer]; _skechLayer.geometry = [[AGSMultipoint alloc]initWithSpatialReference:_mapView.spatialReference]; [_mapView addMapLayer:_skechLayer withName:@"Sketch Layer"]; _mapView.touchDelegate = _skechLayer;}
–Result :
===================================================
===================================================
-剪下[Cut]: -
–介面:
// Copyright 2016/4/18 by SevenJohs////@property (nonatomic , strong) IBOutlet AGSMapView *mapView;//繪製多邊形的按鈕事件@property (strong, nonatomic) IBOutlet UIButton *btnToDrawPolygon;//將草圖圖形複合化,便於觀察@property (strong, nonatomic) IBOutlet UIButton *btnToAdd;//繪製裁剪線條的按鈕事件@property (strong, nonatomic) IBOutlet UIButton *btnToDrawCutLine;//開始裁剪的按鈕事件@property (strong, nonatomic) IBOutlet UIButton *btnToCut;//重設@property (strong, nonatomic) IBOutlet UIButton *btnToReset;
-點擊事件操作
#pragma MARK -- Button Click Methods/** * 開始繪製多邊形 * */- (IBAction)polygonDraw:(id)sender { _btnToDrawPolygon.enabled = NO; _btnToAdd.enabled = YES; _btnToCut.enabled = NO; _btnToDrawCutLine.enabled = YES; [_skechLayer clear]; _skechLayer.geometry = [[AGSMutablePolygon alloc]initWithSpatialReference:_mapView.spatialReference];}/** * 為在sketchLayer的圖形繪製複合圖形樣式,進行風格一致性填充 * */- (IBAction)add:(id)sender { _btnToDrawCutLine.enabled = YES; _btnToCut.enabled = YES; AGSGeometry* sketchGeo = [_skechLayer.geometry copy]; AGSGraphic* graphic = [AGSGraphic graphicWithGeometry:sketchGeo symbol:nil attributes:nil infoTemplateDelegate:nil]; //建立CompositeSymbol給新的geometry AGSCompositeSymbol* compositeSymbol = [AGSCompositeSymbol compositeSymbol]; [compositeSymbol addSymbol:[self setLineSymbol]]; [compositeSymbol addSymbol:[self setFillSymbol]]; graphic.symbol = compositeSymbol; [_graphicLayer addGraphic:graphic]; [_skechLayer clear];}/** * 繪製線條 * */- (IBAction)cutLineDraw:(id)sender { _btnToDrawPolygon.enabled = YES; _btnToCut.enabled = YES; _btnToAdd.enabled = NO; _btnToDrawCutLine.enabled = NO; _skechLayer.geometry = [[AGSMutablePolyline alloc]initWithSpatialReference:_mapView.spatialReference];}/** * 開始裁剪 * */- (IBAction)startToCut:(id)sender { //建立CompositeSymbol給新的geometry AGSCompositeSymbol* compositeSymbol = [AGSCompositeSymbol compositeSymbol]; [compositeSymbol addSymbol:[self setLineSymbol]]; [compositeSymbol addSymbol:[self setFillSymbol]]; AGSGeometryEngine* geoEngine = [AGSGeometryEngine defaultGeometryEngine]; NSMutableArray* newGraphicsArr = [NSMutableArray array]; //遍曆已經繪製的圖形 for (AGSGraphic* graphic in _graphicLayer.graphics) { NSArray* newGeometryArr = [geoEngine cutGeometry:graphic.geometry withCutter:(AGSPolyline*)_skechLayer.geometry]; if (newGeometryArr.count != 0) { for (AGSGeometry* geometry in newGeometryArr) { AGSGraphic* newGraphic = [[AGSGraphic alloc]initWithGeometry:geometry symbol:compositeSymbol attributes:nil infoTemplateDelegate:nil]; [newGraphicsArr addObject:newGraphic]; } } else { [newGraphicsArr addObject:graphic]; } } [_skechLayer clear]; [_graphicLayer removeAllGraphics]; [_graphicLayer addGraphics:newGraphicsArr];}/** * 重設 * */- (IBAction)reset:(id)sender { _btnToDrawPolygon.enabled = NO; _btnToAdd.enabled = YES; _btnToDrawCutLine.enabled = YES; _btnToCut.enabled = NO; [_graphicLayer removeAllGraphics]; [_skechLayer clear]; _skechLayer.geometry = [[AGSMutablePolygon alloc]initWithSpatialReference:_mapView.spatialReference];}
–自訂方法
/** * 設定緩衝區樣式 * * @return AGSSimpleFillSymbol* 緩衝區樣式 * */-(AGSSimpleFillSymbol*)setBufferSymbol{ AGSSimpleFillSymbol* bufferSymbol = [AGSSimpleFillSymbol simpleFillSymbol]; bufferSymbol.color = [[UIColor brownColor] colorWithAlphaComponent:0.4]; bufferSymbol.outline.color = [UIColor darkGrayColor]; return bufferSymbol;}/** * 使用engine建立buffer graphic * * @return 新的buffer graphic */-(AGSGraphic*)createBufferGraphicByGeometry:(AGSGeometry*)sketchGeometry{ AGSGeometryEngine* geometryEngine = [AGSGeometryEngine defaultGeometryEngine]; AGSGeometry* newGeometry = [geometryEngine bufferGeometry:sketchGeometry byDistance:_bufferDistance]; AGSGraphic* newGraphic = [AGSGraphic graphicWithGeometry:newGeometry symbol:[self setBufferSymbol] attributes:nil infoTemplateDelegate:nil]; return newGraphic;}/** * 建立envelope */-(AGSEnvelope*)createEnvelope{ AGSSpatialReference *sr = [AGSSpatialReference spatialReferenceWithWKID:SPATIAL_REFERENCE_WKID]; AGSEnvelope* envelope = [AGSEnvelope envelopeWithXmin:X_MIN ymin:Y_MIN xmax:X_MAX ymax:Y_MAX spatialReference:sr]; return envelope;}/** * 底圖載入 */-(void)addTiledLayer{ AGSTiledMapServiceLayer *tiledLayer = [[AGSTiledMapServiceLayer alloc] initWithURL:[NSURL URLWithString:kTiledMapServiceURL]]; [self.mapView addMapLayer:tiledLayer withName:@"Tiled Layer"];}/** * 要素圖層的初始化與載入 */-(void)addGraphicsLayer{ _graphicLayer=[AGSGraphicsLayer graphicsLayer]; _graphicLayer.visible = YES; [self.mapView addMapLayer:_graphicLayer withName:@"Graphic layer"];}
–ViewDidLoad & MapViewDidLoad
- (void)viewDidLoad { [super viewDidLoad]; self.mapView.layerDelegate = self; self.mapView.touchDelegate = self; self.mapView.showMagnifierOnTapAndHold = YES; [self.mapView enableWrapAround]; [self addTiledLayer]; [self addGraphicsLayer]; //建立envelope,中心化目標 AGSEnvelope* envelope = [self createEnvelope]; [_mapView zoomToEnvelope:envelope animated:YES];}#pragma mark AGSMapViewLayerDelegate methods-(void) mapViewDidLoad:(AGSMapView*)mapView { _skechLayer = [AGSSketchGraphicsLayer graphicsLayer]; _skechLayer.geometry = [[AGSMultipoint alloc]initWithSpatialReference:_mapView.spatialReference]; [_mapView addMapLayer:_skechLayer withName:@"Sketch Layer"]; _mapView.touchDelegate = _skechLayer;}
–Result:
===================================================
===================================================
-交集和差集:[Union && Difference]
–介面:
// Copyright 2016/4/18 by SevenJohs////@property (nonatomic , strong) IBOutlet AGSMapView *mapView;//選擇功能按鈕@property (strong, nonatomic) IBOutlet UISegmentedControl *chooseSegment;//添加圖形並執行操作@property (strong, nonatomic) IBOutlet UIButton *btnToAdd;@property (strong, nonatomic) IBOutlet UIButton *btnToReset;
-點擊事件操作
#pragma MARK -- Button Click Methods- (IBAction)segmentChoose:(UISegmentedControl *)sender { if (_unionGraphic && _differenceGraphic) { if (sender.selectedSegmentIndex == 0) { [_graphicLayer removeAllGraphics]; [_graphicLayer addGraphic:_unionGraphic]; } else { [_graphicLayer removeAllGraphics]; [_graphicLayer addGraphic:_differenceGraphic]; } }}- (IBAction)btnToAddNewGeometry:(id)sender { //得到草圖的圖形,並添加 AGSGeometry* sketchGeometry = [_skechLayer.geometry copy]; AGSGraphic* sketchGraphic = [AGSGraphic graphicWithGeometry:sketchGeometry symbol:nil attributes:nil infoTemplateDelegate:nil]; [_graphicLayer addGraphic:sketchGraphic]; [_skechLayer clear]; //在graphic有兩個圖形的時候,建立engine並進行幾何分析 if(_graphicLayer.graphicsCount == 2){ _btnToAdd.enabled = NO; AGSGeometryEngine* geoEngine = [AGSGeometryEngine defaultGeometryEngine]; //重新委派對象(copy) AGSGeometry* geometry1 = [[_graphicLayer.graphics objectAtIndex:0] geometry]; AGSGeometry* geometry2 = [[_graphicLayer.graphics objectAtIndex:1] geometry]; _differenceGraphic = [AGSGraphic graphicWithGeometry:[geoEngine differenceOfGeometry:geometry1 andGeometry:geometry2] symbol:nil attributes:nil infoTemplateDelegate:nil]; _unionGraphic = [AGSGraphic graphicWithGeometry:[geoEngine unionGeometries:[NSArray arrayWithObjects:geometry1,geometry2, nil]] symbol:nil attributes:nil infoTemplateDelegate:nil]; [self segmentChoose:_chooseSegment]; }}- (IBAction)btnToResetData:(id)sender { [_graphicLayer removeAllGraphics]; [_skechLayer clear]; _unionGraphic = nil; _differenceGraphic = nil; _btnToAdd.enabled = YES;}
–自訂方法
#pragma mark Privated Method-(void)addTiledLayer{ AGSTiledMapServiceLayer *tiledLayer = [[AGSTiledMapServiceLayer alloc] initWithURL:[NSURL URLWithString:kTiledMapServiceURL]]; [self.mapView addMapLayer:tiledLayer withName:@"Tiled Layer"];}-(void)addGraphicsLayer{ //渲染 AGSCompositeSymbol* compositeSymbol = [AGSCompositeSymbol compositeSymbol]; [compositeSymbol addSymbol:[self setLineSymbol]]; [compositeSymbol addSymbol:[self setFillSymbol]]; [compositeSymbol addSymbol:[self setPointSymbol]]; AGSSimpleRenderer* simpleRenderer = [AGSSimpleRenderer simpleRendererWithSymbol:compositeSymbol]; _graphicLayer = [AGSGraphicsLayer graphicsLayer]; _graphicLayer.visible = YES; _graphicLayer.renderer = simpleRenderer; [_mapView addMapLayer:_graphicLayer withName:@"Graphics Layer"];}-(AGSSimpleLineSymbol *)setLineSymbol{ AGSSimpleLineSymbol* lineSymbol = [[AGSSimpleLineSymbol alloc]init]; lineSymbol.color = [UIColor brownColor]; lineSymbol.width = 4; return lineSymbol;}-(AGSSimpleFillSymbol *)setFillSymbol{ AGSSimpleFillSymbol* innerSymbol = [AGSSimpleFillSymbol simpleFillSymbol]; innerSymbol.color = [[UIColor greenColor]colorWithAlphaComponent:0.40]; innerSymbol.outline = nil; return innerSymbol;}-(AGSSimpleMarkerSymbol*)setPointSymbol{ AGSSimpleMarkerSymbol* pointSymbol = [[AGSSimpleMarkerSymbol alloc]init]; pointSymbol.color = [UIColor orangeColor]; pointSymbol.style = AGSSimpleMarkerSymbolStyleCircle; return pointSymbol;}
–ViewDidLoad & MapViewDidLoad
- (void)viewDidLoad { [super viewDidLoad]; self.mapView.layerDelegate = self; self.mapView.callout.delegate = self; self.mapView.touchDelegate = self; self.mapView.showMagnifierOnTapAndHold = YES; [self.mapView enableWrapAround]; [self addTiledLayer]; [self addGraphicsLayer];}#pragma mark AGSMapViewLayerDelegate methods-(void) mapViewDidLoad:(AGSMapView*)mapView { _skechLayer = [AGSSketchGraphicsLayer graphicsLayer]; _skechLayer.geometry = [[AGSMutablePolygon alloc]initWithSpatialReference:_mapView.spatialReference]; [_mapView addMapLayer:_skechLayer withName:@"Sketch Layer"]; _mapView.touchDelegate = _skechLayer; _skechLayer.geometry = [[AGSMutablePolygon alloc]initWithSpatialReference:_mapView.spatialReference];}
–Result:
END。