只是加载数据难免乏味,更多时候需要可交互,让用户控制地图的可视化效果,比如:地图上加标签、高亮显示查询到的街道、修改化学品污染区域的渲染样式等等,基本流程就像画画,先找张空白的纸,再把房子、花园、马路什么的用不同颜色画上去,纸就是图形图层(AGSGraphicLayer),房子等地物就是空间要素(AGSGraphic)。
图形图层(AGSGraphicLayer)之前已经介绍过,它是由客户端创建的动态图层,承载并管理其中的空间要素:
//创建新的图形图层 AGSGraphicsLayer* myGraphicsLayer = [AGSGraphicsLayer graphicsLayer]; UIView* graphicsView = [self.mapview addMapLayer:myGraphicsLayer withName:@"Graphics Layer"]; //从现有图层中找出图形图层 NSDictionary<AGSLayerView> *myLayerViewDict = self.mapView.mapLayerViews; id<AGSLayerView> myGraphicsLayerView = [myLayerViewDict objectForKey:@”Graphics Layer”]; AGSGraphicsLayer* myGraphicsLayer = (AGSGraphicsLayer*)myGraphicsLayerView.agsLayer;
空间要素(AGSGraphic)是对空间对象的标准描述,包括:几何形状(AGSGeometry)、符号(AGSSymbol)、属性(attributes)等,因此SDK里很多方法的输入输出项都是空间要素。空间要素的几何形状(AGSGeometry)必须要有,符号(AGSSymbol)默认是简单符号样式,而属性(attributes)则是可选的。
//创建点状符号
AGSSimpleMarkerSymbol *myMarkerSymbol = [AGSSimpleMarkerSymbol simpleMarkerSymbol];
myMarkerSymbol.color = [UIColor blueColor];
//创建点形状
AGSPoint* myMarkerPoint = [AGSPoint pointWithX:112.2984 y:34.9409
spatialReference:self.mapView.spatialReference];
//组装点要素
AGSGraphic* myGraphic = [AGSGraphic graphicWithGeometry:myMarkerPoint
symbol:myMarkerSymbol attributes:nil infoTemplateDelegate:nil];
//将点要素添加到图形图层
[myGraphicsLayer addGraphic:myGraphic];
//刷新该图形图层
[myGraphicsLayer dataChanged];
1 几何形状
二维几何形状包括点、线、面三大类,每类又有单独和联合(Multi)两种,GIS数据类型里没有弧(Arc),为此cad用户常开玩笑:“Arc GIS”竟然没有Arc?!目前移动端支持以下几何形状:
· 点 (Point)
· 多点 (Multipoint)
· 线 (Polyline)
· 面 (Polygon)
· 最小包络矩形 (Envelope)
AGSGeometry是所有几何形状的基类,其中定义了基本属性:最小包络矩形envelope和空间参考(ArcGIS Android SDK定义要素时不要求有空间参考,因此在要素参与空间运算前要指定空间参考)。因为Object-C中有Mutable变量的设计,因此每种几何形状也都延伸了对应的可编辑类型(Mutable)。
图3-3-1-1 几何形状的继承关系
AGSGeometry继承了AGSCoding,其中已经封装好Json解析方法,当需要和其他系统进行交互时,通过encodeToJSON和AGSJSONRepresentation方法把几何对象转成JSON字符串。
AGSPoint* point = … NSDictionary* json = [point encodeToJSON]; NSString* jsonPointAsString = [json AGSJSONRepresentation];
1.1 点
点(AGSPoint)由x、y和spatailReference构成,通常使用静态方法(pointWithX:y:spatialReference:)初始化,不能修改:
图3-3-1-2 AGSPoint主要属性和方法
在创建新点或要修改已有点时需要用AGSMutabelPoint声明,提供了updateWithX:y:方法或者offsetByX:y:修改点坐标。
AGSPoint* point = [AGSPoint pointWithX:114.0 y:30.0 spatialReference:[AGSSpatialReference spatialReferenceWithWKID:4326 WKT:nil]]; //更新点的坐标 AGSMutablePoint* mutable = [point mutableCopy]; [mutable updateWithX:120.0 y:20.0];
1.2 多点
多点(AGSMultiPoint)相当与点数组,适合存储具有相同性质的一组点,比如一棵树的Lidar扫描数据本身是数以万计的点,将其导入地理数据库(Geodatabase)的话显然用多点存储更高效,numPoints属性记录了点数组的长度:
图3-3-1-3 AGSMultiPoint主要属性和方法
在创建新多点或修改已有多点时需要用AGSMutabelMultiPoint声明,提供了添加和修改其中点的方法。
AGSMutableMultipoint multiPoint = [[AGSMutableMultipoint alloc] initWithSpatialReference:[AGSSpatialReference spatialReferenceWithWKID:4326 WKT:nil]]; [multiPoint addPoint: [AGSPoint pointWithX:10 y:10 spatialReference:nil]]; [multiPoint addPoint: [AGSPoint pointWithX:20 y:20 spatialReference:nil]]; [multiPoint addPoint: [AGSPoint pointWithX:30 y:30 spatialReference:nil]];
1.3 线
线(AGSPolyline)由轨迹(Paths)组成,每一条轨迹都包含数量可穷举的连续节点(vertice),此外也需要指定spatailReference。numPointsInPath方法记录了节点数量,通过pointOnPath:atIndex方法可以找到对应节点。
图3-3-1-4 AGSPolyLine主要属性和方法
在创建新的线或修改已有线时需要用AGSMutabelPolyline声明,提供了添加和修改其中点的方法。
AGSMutablePolyline* poly = [[AGSMutablePolyline alloc] initWithSpatialReference:[AGSSpatialReference spatialReferenceWithWKID:4326 WKT:nil]]; //添加轨迹 [poly addPathToPolyline]; //往轨迹中添加节点 [poly addPointToPath:[AGSPoint pointWithX:10 y:10 spatialReference:nil]]; [poly addPointToPath:[AGSPoint pointWithX:30 y:10 spatialReference:nil]]; [poly addPointToPath:[AGSPoint pointWithX:30 y:30 spatialReference:nil]];
1.4 面
“一生二、二生三、三生万物…”,面(Polygon)由闭合环(rings)组成,每一个环包含若干连续的节点(vertice),其中首尾两个节点相同,保证闭合性。闭合环彼此之间如果是包含关系,就能构建出中空的面。注意环之间拓扑关系不允许相接(touch)或相交(intersect)。
图3-3-1-5 AGSPolygon主要属性和方法
在创建新的面或修改已有面时需要用AGSMutabelPolygon声明,提供了添加和修改其中点的方法。
AGSMutablePolygon* poly = [[AGSMutablePolygon alloc] initWithSpatialReference:[AGSSpatialReference spatialReferenceWithWKID:4326 WKT:nil]]; //添加环 [poly addRingToPolygon]; //添加节点 [poly addPointToRing:[AGSPoint pointWithX:10 y:10 spatialReference:nil]]; [poly addPointToRing:[AGSPoint pointWithX:30 y:10 spatialReference:nil]]; [poly addPointToRing:[AGSPoint pointWithX:30 y:30 spatialReference:nil]]; [poly addPointToRing:[AGSPoint pointWithX:10 y:30 spatialReference:nil]]; [poly addPointToRing:[AGSPoint pointWithX:10 y:10 spatialReference:nil]];
1.5 包络矩形
包络矩形(AGSEnvelope)是几何形状的矩形外框,可以表示小到一条线的外框,大到一副地图的范围(Extent),提供了中心点、高宽、四角坐标等属性,同样也有一个可编辑版(AGSMutableEnvelope)。
图3-3-1-6 AGSEnvelope主要属性和方法
AGSEnvelope env = [AGSEnvelope envelopeWithXmin:10 ymin:10 xmax:30 ymax:30 spatialReference:[AGSSpatialReference spatialReferenceWithWKID:4326 WKT:nil]];