1 图例
一图胜千言的佳话里肯定少不了图例(MapLegend),尤其当要素类型复杂时,通过图例能简明标示关键要素,图例包括一组符号图片和对应的文字标注。
图3-2-3-1 常见的地图图例样式
ArcGIS for iOS v1.8之后下列图层都支持获取图例信息:
· 切片地图服务图层
· 动态地图服务图层
· 要素服务图层
· 图形图层
1.1. 对于切片和动态地图服务图层:
ArcGIS Server v10 SP1以上版本发布的切片和动态地图服务提供了图例信息,通过AGSMapServiceInfo对象的retrieveLegendInfo方法异步获取到legendLabels和legendImages:
//AGSMapServiceInfoDelegate 方法 -(void) mapServiceInfo:(AGSMapServiceInfo *)mapServiceInfo operationDidRetrieveLegendInfo:(NSOperation *)op { //loop through all sub-layers NSArray* layerInfos = mapServiceInfo.layerInfos; for(int i=0;i<[layerInfos count];i++){ //access legend information of each sub-layer AGSMapServiceLayerInfo* layerInfo = [layerInfos objectAtIndex:i]; NSArray* legendLabels = layerInfo.legendLabels; NSArray* legendImages = layerInfo.legendImages; ... } }
1.2. 对于要素和图形图层:
成功加载了要素和图形服务,其符号和文件标注已经下载到终端,所以只需要导出简单符号或渲染色带就好:
//导出symbol图片 AGSSymbol* symbol = ...; UIImage* image = [symbol swatchForGeometryType:AGSGeometryTypePoint size:CGSizeMake(20,30)]; //导出渲染色带 AGSRenderer* renderer = ...; AGSGraphic* graphic = ...; UIImage* image = [renderer swatchForGraphic:graphic size:CGSizeMake(20,30)];
目前还没有封装成拿来即用的组件,需要开发者手动填充到View或UITableView里,稍显麻烦。
2 经向环绕
平面地图都是从经度-180展开到180,如果你要同时浏览东西经180的数据就很不方便,因此在v1.8中新增加了经向环绕“Wrap Around”的设置,使得地图数据在东西向平移时无缝环绕:
//地图组件开启环绕 self.mapView.wrapAround = YES;
经向环绕的原理类似与屏幕扩展:-180~180是当前屏幕0,-180再往西就是屏幕-1(-180~-540),而正180再往东就是屏幕1(180~-540)。在采集坐标时这会造成困扰,因此需要先对进行标准化(normalize),Geometry Engine里提供了该方法normalizeCentralMeridianOfGeometry。
经向环绕的使用条件:
· 最大范围覆盖全球
· 地图空间参考是WGS 84 (WKID=4326) 或Web Mercator (WKID=102113, 102100, or 3857)
· 支持WKT关键字的动态服务(ArcGIS Server10.0以上版本发布)
3 时态展示
包含时间信息的地理数据在服务器端注册成“时态(Time-aware Layer)”数据后, 客户端就能展示时态,比如:24小时内飓风的推进过程、1周的气温变化过程等。支持时态的地图服务都是动态服务,包括:动态地图服务、影像服务和要素服务。
时间范围(TimeExtent)属性,定义了显示数据的时间区间,利用它能快速过滤时态数据,范围外的数据都不会显示:
NSDate* now = [NSDate date]; NSDate* yesterday = ... [NSDate dateWithTimeIntervalSinceNow: -(24 * 60 * 60)]; //过滤显示最近1天的数据 AGSTimeExtent* extent = [[AGSTimeExtent alloc] initWithStart:now end: yesterday]; map.timeExtent = extent; //只显示某一时间点的数据 AGSTimeExtent* extent = [[AGSTimeExtent alloc] initWithStart:now end: now]; map.timeExtent = extent;
*要表示截止某时间点前(后),起始(终止)时间参数可以输入nil。
如果输入时间的时区是本机的系统时区(如:中国上海-香港-乌鲁木齐时间),而请求的时态服务又是其他时区,则需要统一时间格式:
//定义时间格式
NSDateFormatter* inputFormatter = [[NSDateFormatter alloc] init];
[inputFormatter setDateFormat:@"M/d/yyyy h:mm a"];
//设定时区
[inputFormatter setTimeZone:[NSTimeZone timeZoneWithName:@"GMT"]];
//按格式构造NSDate
NSDate* date = [inputFormatter dateFromString:@"1/1/2001 12:00 AM"];
AGSTimeExtent* extent = [[AGSTimeExtent alloc] initWithStart:date end:date];
*更多NSDate时间转换的内容请参考博文-http://blog.youkuaiyun.com/diyagoanyhacker/article/details/7096612。
如果不需要按时间过滤,设定图层的时间开关(useTime)为false即可:
AGSLayerTimeOptions* op = [[[AGSLayerTimeOptions alloc] init] autorelease];op.layerId = 1;
//关闭指定图层的时态响应
op.useTime = FALSE;