ArcGIS for iOS 開發系列(5) – 基礎篇-圖層-靜態圖層
圖層是空間資料的載體,如果你對ArcGIS Server稍有了解的話,就能明白API裡不同型別的圖層對應了伺服器端釋出的不同Service,可以分成兩大類:靜態圖層和動態圖層。
靜態圖層泛指快取過的地圖服務,除非服務端刪除或更新快取,否則客戶端請求的資料永遠是固定不變的,而動態圖層正好相反,伺服器根據每個請求動態的生成資料,一靜一動各有用途。
表3-2-1 不同型別圖層的繼承關係
AGSLayer是所有圖層的基類,宣告瞭空間參考、最大範圍、初始範圍、單位和圖層委託等基本屬性,還有圖層載入的相關方法。
表3-2-2圖層類的屬性和方法
1 靜態圖層
靜態圖層根據一定的規則提前生成快取,這樣客戶端的請求就能直接呼叫快取地圖切片,顯著提高了地圖請求的響應速度。常常用於那些使用頻率高、更新週期長的基礎地理資料,包括大家常常用到的電子地圖、地形圖、衛星影像圖等。
AGSTiledLayer繼承自AGSLayer,同時也派生出不同型別的靜態圖層:
表3-2-3 靜態圖層的繼承關係
在MVC結構中,AGSTiledLayer屬於Model角色,對應的View角色是AGSTiledLayerView。其中實現了關鍵的非同步獲取切片資料操作,並獲取到切片服務的快取規則:
表3-2-4 靜態圖層的方法和屬性
注意:如果靜態服務圖層的空間參考與MapView的不一致,就無法顯示。
1.1 切片地圖服務圖層(AGSTiledMapServiceLayer)
切片地圖服務圖層是最常用的服務,ArcGIS線上提供了一系列,其切片規則(tiling Schema)裡描述了切片的尺寸、格式、比例尺、級別等資訊。
“雖然圖層已經初始化並新增到地圖中,但切片資訊還是空值?”,建議先判斷載入成功與否,尤其是在網速不好的情況下:
//圖層載入完成後才能獲取完整的屬性
if(layer.loaded){
NSLog(@"TilingScheme: %@", layer.tileInfo);}
1.2 微軟Bing服務圖層(AGSBingMapLayer)
由於Esri與微軟之間的合作關係,保證了ArcGIS使用者也能使用最新的微軟Bing全球影像地圖服務,當然這也是靜態服務,加入使用者的密匙(在ArcGISServer Manager頁面可獲取)就能使用:
NSString* bingMapsKey = @"--your--key--";
AGSBingMapLayer* layer = [[AGSBingMapLayeralloc]initWithAppID:bingMapsKeystyle:AGSBingMapLayerStyleAerial];
*Bing服務空間參考為橫軸Web摩卡託:
WGS1984 Web Mercator (Auxiliary Sphere) ,WKID=102100:
1.3 OSM服務圖層(AGSOpenStreetMapLayer)
Esri與OpenStreetMap之間也建立了合作關係, ArcGIS使用者同樣也能使用OpenStreetMap全球向量地圖服務:
AGSOpenStreetMapLayer* OSMLyr = [[AGSOpenStreetMapLayeralloc]init];
*OpenStreetMap服務空間參考為橫軸Web摩卡託:
WGS1984 Web Mercator (Auxiliary Sphere) ,WKID=102100:
1.4 自定義切片圖層(Custom TiledLayer)
國內流行的切片地圖還有:谷歌地圖、百度地圖、MapABC、天地圖等,各家地圖的切片策略有差異但原理相同,瞭解其切片策略資訊後,繼承AGSTiledLayer擴充自定義切片圖層 (Custom TiledLayer),就能正常使用該切片地圖。
Esri提供了一個訪問本地切片(png或jpg)的類 “OfflineTiledLayer”,可以作為我們設計自定義切片圖層的參考,包含3部分:切片圖層物件,切片資料解析委託和切片請求操作。下面的流程示意圖能看出自定義切片載入的整個過程:
圖3-2-6 自定義切片圖層的呼叫流程
“OfflineTiledLayer“繼承了AGSTiledLayer,並重寫了切片資訊(tileInfo)和切片獲取方法(retrieveImageAsyncForTile),其初始化方法(initWithDataFramePath)也很簡單:
//繼承了AGSTiledLayer
@interface OfflineTiledLayer :AGSTiledLayer {
...
}
//自定義切片服務後設資料
@implementation OfflineTiledLayer
-(AGSUnits) units { //todo }
-(AGSSpatialReference*) spatialReference {//todo }
-(AGSEnvelope*) fullEnvelope { //todo }
-(AGSEnvelope*) initialEnvelope { //todo }
-(AGSTileInfo*) tileInfo { //todo }
-(NSOperation<AGSTileOperation>*)retrieveImageAsyncForTile:(AGSTile*)tile {
//todo }
//初始化方法-path:切片路徑
- (id)initWithDataFramePath:(NSString*)patherror:(NSError**)outError;
...
@end
初始化方法中需要輸入“切片檔案路徑”,下圖的示例資料是10.0版本的鬆散型(Exploded)切片快取,切片服務後設資料就儲存在conf.cdi和conf.xml兩個XML檔案中,其中conf.cdi記錄了地圖全圖範圍、而conf.xml記錄了空間參考、切片格式等資訊,其中和切片組織(LODInfos)對應了_alllayers目錄下的級別(L)-行號(R)-列號(C),簡單理解就是用指定網格按指定比例尺一層層的把地圖切成規則的圖片矩陣,建立起了網格與切片檔案的對應關係,使用時按網格檢索切片檔案,並動態拼接起來。
*關於切片規則的詳細介紹,請參考網上其他資料。
圖3-2-7 鬆散型切片的組織結構
1. 解析切片後設資料:
“OfflineCacheParserDelegate“負責從後設資料(conf.cdi和conf.xml)中解析出自定義的切片資訊並構建出關鍵的AGSTileInfo物件:
- (id)initWithDataFramePath:(NSString *)path error:(NSError**) outError {
if (self = [super init]) {
self.dataFramePath = path;
//解析 conf.cdi
NSString* confCDI = [[NSBundlemainBundle] pathForResource:@"conf" ofType:@"cdi"inDirectory: _dataFramePath ];
NSXMLParser* xmlParser = [[NSXMLParser alloc]initWithContentsOfURL:[NSURL fileURLWithPath:confCDI]];
OfflineCacheParserDelegate*parserDelegate = [[[OfflineCacheParserDelegate alloc] init] autorelease] ;
[xmlParsersetDelegate:parserDelegate];
[xmlParser parse];
[xmlParser release];
//解析 conf.xml
NSString* confXML = [[NSBundlemainBundle] pathForResource:@"conf" ofType:@"xml"inDirectory: _dataFramePath];
...
}
以下是XML後設資料的具體解析方法:
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementNamenamespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if ([elementNameisEqualToString:@"LODInfo"]){
self.lod = [[[AGSLODalloc]initWithLevel:_level resolution:_resolution scale:_scale] autorelease];
[self.lods addObject:_lod];
}else if ([elementNameisEqualToString:@"CacheInfo"]){
_tileSize = CGSizeMake(_tileWidth,_tileHeight);
self.spatialReference =[[[AGSSpatialReference alloc] initWithWKID:_WKID WKT:_WKT] autorelease];
self.tileOrigin = [[[AGSPointalloc] initWithX:_tileOriginX y:_tileOriginYspatialReference:_spatialReference] autorelease];
self.fullEnvelope = [AGSEnvelopeenvelopeWithXmin:_xmin
ymin:_ymin
xmax:_xmax
ymax:_ymax
spatialReference:_spatialReference];
self.tileInfo = [[[AGSTileInfoalloc] initWithDpi: _dpi
format:_tileFormat
lods:_lods
origin:_tileOrigin
spatialReference:_spatialReference
tileSize:_tileSize] autorelease];
}
}
2. 請求和獲取切片資料:
“OfflineTileOperation“按照地圖所請求AGSTile的level, row, column引數獲取本地切片圖片檔案,將其填充到Image屬性:
//根據 Level, Row,Column獲取切片
@try {
//Level ('L' followed by 2 digits)
NSString *decLevel = [NSStringstringWithFormat:@"L%02d",self.tile.level];
//Row ('R' followed by 8hexadecimal digits)
NSString *hexRow = [NSStringstringWithFormat:@"R%08x",self.tile.row];
//Column ('C' followed by 8hexadecimal digits)
NSString *hexCol = [NSStringstringWithFormat:@"C%08x",self.tile.column];
NSString*dir = [_allLayersPathstringByAppendingFormat:@"/%@/%@",decLevel,hexRow];
//查詢PNG格式切片
NSString *tileImagePath =[[NSBundle mainBundle] pathForResource:hexCol ofType:@"png"inDirectory:dir];
...
}
@catch (NSException *exception) {
NSLog(@"main: Caught Exception%@: %@", [exception name], [exception reason]);
}
@finally {
//Invoke the layer's action method
[_target performSelector:_actionwithObject:self];
}
*OfflineTiledLayer用來解釋自定義切片服務圖層設計原理,不適合大規模離線使用,因為鬆散型的切片小檔案分發、更新非常耗時,建議採用下一節的AGSLocalTiledLayer介面+切片包TPK壓縮格式。
*載入其他線上切片地圖(百度地圖、天地圖和谷歌地圖)的方法和程式碼,我會在後續章節專門做介紹。
1.5 本地切片圖層(AGSLocalTiledLayer)
本地切片圖層(AGSLocalTiledLayer)也叫離線切片圖層,是上一節“OfflineTiledLayer”示例的升級版,其面向的切片快取資料來源是ArcGIS 10.1新推出的切片地圖包(.tpk檔案)。如果用localTiledLayerWithName方法載入,會依次遍歷該應用的bundle和Document目錄,意味著如果tpk檔案不大,可以直接將其打包在應用的資原始檔中分發,如果tpk檔案很大,也允許使用者通過Itunes手動載入資料,前者的優點是分發簡單,後者的優點是應用與資料不繫結,自由載入。
AGSLocalTiledLayer* layer = [AGSLocalTiledLayerlocalTiledLayerWithName:@"world"];
切片地圖包(tile package)是緊湊型(compact)切片快取資料的壓縮包,提高了切片快取資料的分發效率,可以用10.1桌面“分享為TPK”,也可以自己手動構建,詳細過程可參考:http://blog.csdn.net/arcgis_mobile/article/details/8048549.
相關文章
- arcgis api for js入門開發系列十九圖層線上編輯APIJS
- arcgis怎樣把面圖層按另一面圖層分割
- iOS圖層效能優化iOS優化
- ArcGIS Server ADF開發:根據圖層不同屬性用不同圖示定位興趣點Server
- 基於Echarts的百度地圖疊加arcgis server的WMS圖層服務Echarts地圖Server
- iOS Animation] CALayer 專用圖層iOS
- CAD學習筆記基礎課【圖層】筆記
- ArcGIS API for Silverlight 動態圖層(ArcGISDynamicMapServiceLayer)的顯示與隱藏API
- 影像處理的基礎知識(11)——圖層(1)
- (三)arcpy開發&利用arcpy實現接邊處理(arcgis要素建立、更新、圖層選擇)
- 深入iOS系統底層之靜態庫介紹iOS
- 分層圖
- ArcGIS for iOS 開發系列(1) – 基本概念iOS
- Cesium官方教程5--地形圖層
- Go基礎系列:雙層channel用法示例Go
- iOS開發小記-基礎篇iOS
- iOS 藍芽開發·基礎篇iOS藍芽
- Xamarin圖表開發基礎教程(5)OxyPlot框架框架
- iOS 靜態庫開發iOS
- C# 操作PDF 圖層(Layer)—新增、刪除圖層、設定圖層可見性C#
- iOS底層原理 runtime-object_class拾遺基礎篇--(6)iOSObject
- 資料庫開發基礎--層次查詢+資料庫
- 資料庫開發基礎---層次查詢資料庫
- 【IOS開發基礎系列】Cocoa基礎專題iOS
- ArcGis api配合vue開發入門系列(一)引入arcgis api以及載入地圖APIVue地圖
- Java基礎系列-靜態代理和動態代理Java
- 【ArcGIS For JS】前端geojson渲染行政區劃圖層並加標籤前端JSON
- iOS 背景圖層的顏色漸變效果iOS
- 入學管理系統的頂層圖和一層圖
- ArcGIS Engine開發基礎總結(一)
- UML基礎系列:類圖
- 畫出入學管理系統的頂層圖和1層圖
- ArcGIS API for Silverlight 呼叫GP服務載入等值線圖層API
- iOS開發基礎篇--NSNotificationCenter使用小結iOS
- iOS底層原理 runtime- objc_msgSend拾遺基礎篇--(7)iOSOBJGse
- 2^n層圖譜的最基礎~夢幻之匙系統
- CALayer CAEmitterLayer(粒子圖層)MIT
- 分層圖最短路