移動(dòng)GIS中,通常將數(shù)據(jù)分為兩大類:basemap layer和operational layer。前者是指漫游或?qū)Ш綍r(shí)起參考作用的圖層,這些圖層內(nèi)容通常不會(huì)變化,只起到視覺輔助作用,稱為底圖圖層;后者是指存儲(chǔ)GIS數(shù)據(jù)的圖層,比如可通過這些圖層來提供屬性/空間查詢操作,或者對(duì)其內(nèi)容進(jìn)行編輯,然后與服務(wù)器端進(jìn)行同步,稱為業(yè)務(wù)圖層。 目前ArcGIS移動(dòng)產(chǎn)品有5種,基于Windows Mobile平臺(tái)的ArcPad和ArcGIS Mobile,這兩個(gè)產(chǎn)品已經(jīng)很成熟了,都有各自的離線緩存格式,其中ArcGIS Mobile從10版本開始,可以直接讀取ArcGIS Server緩存地圖服務(wù)的切片文件做為basemap layer,支持exploded和compact兩種格式。 相對(duì)于以上兩個(gè)老牌移動(dòng)產(chǎn)品,三個(gè)剛出道的小弟ArcGIS for iOS,ArcGIS for Android和ArcGIS for Windows Phone就走了不同路線:依賴于ArcGIS Server的REST服務(wù)。因此幾乎所有操作,包括顯示地圖,都需要用到ArcGIS Server發(fā)布的各種服務(wù)。這三個(gè)產(chǎn)品的離線功能將來肯定是會(huì)有的,但具體的時(shí)間表還無法確定。 針對(duì)ArcGIS for iOS/Android/Windows Phone,本文提出3種可行的離線底圖(basemap layer)的解決方案,供各位參考。以ArcGIS for Windows Phone為例。 1、ArcGIS Server地圖服務(wù)的Exploded格式緩存文件
ArcGIS API for Windows Phone中,提供了ArcGISTiledMapServiceLayer用來加載ArcGIS
Server發(fā)布的緩存地圖服務(wù),它的原理是Map控件計(jì)算好需要加載的切片的row,col,level參數(shù),利用ArcGISTiledMapServiceLayer里的GetTileUrl方法提供如何獲得指定參數(shù)的切片文件,最后拼接成完整的地圖。 包含conf.cdi(ArcGIS Server 10版本中才有,記錄了緩存的全圖范圍)和conf.xml文件的好處是,我們可以在代碼中讀取這兩個(gè)文件來動(dòng)態(tài)生成我們的Tiling Scheme,以完成圖層初始化的工作。從配置文件中讀取參數(shù)后,就可以重寫GetTileSource方法了。部分代碼如下:
1: protected override void GetTileSource(int level, int row, int col,
Action<System.Windows.Media.ImageSource> onComplete)
2: { 3: string f = string.Empty; 4: if (_cacheTileFormat.ToLower().Contains("png")) 5: f = ".png"; 6: else if (_cacheTileFormat.ToLower().Contains("jpeg") || _cacheTileFormat.ToLower().Contains("jpg")) 7: f = ".jpg"; 8: else 9: throw new Exception("切片格式不明:" + _cacheTileFormat); 10: #region Exploded讀取 11: if (_storageFormat == StorageFormat.esriMapCacheStorageModeExploded) 12: { 13: string baseUrl = _path;// "/WP_LocalCacheReader;component/Assets/usa_exploded/" 14: baseUrl += @"/_alllayers"; 15: string l = "L"; 16: l = level.ToString().PadLeft(2, '0'); 17: string r = "R"; 18: r = String.Format("{0:X}", row).PadLeft(8, '0'); 19: string c = "C"; 20: c = String.Format("{0:X}", col).PadLeft(8, '0'); 21: string str = baseUrl 22: + @"/L" + l 23: + @"/R" + r 24: + @"/C" + c + f; 25: BitmapImage img = new BitmapImage(new Uri(str,UriKind.RelativeOrAbsolute)) 26: { 27: CreateOptions = BitmapCreateOptions.DelayCreation 28: }; 29: img.ImageFailed += (s, a) => 30: { 31: string uri = _path + "/missing" + _tileRows.ToString() + f; 32: BitmapImage image = new BitmapImage(new Uri(uri, UriKind.RelativeOrAbsolute)) 33: { 34: CreateOptions = BitmapCreateOptions.DelayCreation 35: }; 36: onComplete(image); 37: return; 38: }; 39: onComplete(img); 40: } 41: #endregion 42: }
當(dāng)指定的切片文件不存在(也許還未創(chuàng)建)時(shí),可以加載事先準(zhǔn)備好的missing圖片來替換。 2、ArcGIS Server地圖服務(wù)的Compact格式緩存文件
這是ArcGIS Server 10推出的新的緩存格式,緩存圖片都保存在.bundle文件中,一個(gè)bundle目前可存儲(chǔ)128*128張切片。切片文件更少,主要目的是為了遷移方便。文檔中并未給出讀取這種格式文件的方法,不過牛魔王已經(jīng)憑空推斷出了這種格式的內(nèi)容,這里就借鑒了他的方法。還是先將緩存文件拷貝到手機(jī)中:
利用conf.cdi和conf.xml獲得tiling scheme,之后重寫GetTileSource方法。具體思路牛魔王文中已經(jīng)給出,感興趣的同學(xué)還是看原文,學(xué)習(xí)牛牛的思路比較好。 3、第三方離線地圖文件
除了ArcGIS Server的緩存切片之外,我們還可以讀取第三方的離線地圖文件來做為我們的底圖。比如以前面介紹過的Mobile Atlas Creator為例,我現(xiàn)在已經(jīng)有了很多自己下載好的離線地圖,如果能在ArcGIS移動(dòng)客戶端使用起步兩全其美?其實(shí)在目前的離線導(dǎo)航軟件中,很多都用sqlite數(shù)據(jù)庫做為地圖存儲(chǔ)格式,因?yàn)樗鼞?yīng)用廣泛,輕巧,緊湊,Android,iOS,Symbian等系統(tǒng)對(duì)它都有原生的支持。Mobile
Atlas Creator中,RMaps和OruxMaps都用Sqlite保存離線地圖。這里以應(yīng)用較為廣泛的RMaps格式為例,進(jìn)行試驗(yàn)。
我們利用FireFox里的Sqlite Manager插件先來查看一下數(shù)據(jù)庫的內(nèi)容:
可以看出,我們所需的內(nèi)容都保存在tiles這張表中,而x,y,z三個(gè)參數(shù)與我們所需的row,col,level很像。經(jīng)過試驗(yàn)(保存一個(gè)全球范圍的地圖),很快驗(yàn)證出level=17-z。
關(guān)于離線地圖文件的打包。1、在Silverlight程序中,Build Action的選擇決定了文件最后的保存位置,比如你選擇Resource,則會(huì)嵌入到工程的dll中,如果選擇Content,則會(huì)保存在dll之外,xap文件之內(nèi)。以上三種解決方案里,我們可以選擇任意的Build Action,這樣地圖都會(huì)通過xap部署到手機(jī)里;如果有需要,我們還可以將文件拷貝到程序的IsolatedStorage中去。2、對(duì)于Exploded格式的緩存,WP的編程建議中提到,媒體文件Build
Action設(shè)為Content效率會(huì)更高。3、對(duì)于Exploded格式的緩存,如果為了拷貝方便,我們也可以將其打包為.zip文件,部署到手機(jī)中,在程序加載的時(shí)候再將其解壓縮來讀取。 轉(zhuǎn)自:http://blog./uid-10914615-id-3023158.html |
|