ArcGIS for iOS 開發系列(5) – 基礎篇-圖層-靜態圖層

來源:互聯網
上載者:User

    圖層是空間資料的載體,如果你對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)

    國內流行的切片地圖還有:Google地圖、百度地圖、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壓縮格式。

*載入其他線上切片地圖(百度地圖、天地圖和Google地圖)的方法和代碼,我會在後續章節專門做介紹。

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.

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.