分類:C#、Android、VS2015、百度地圖應用; 創建日期:2016-02-04
一、簡介
地圖SDK自v3.6.0起,新增瓦片圖層(tileOverlay), 該圖層支持開發者添加自有瓦片數據,包括本地加載和在線下載兩種方式。該圖層可隨地圖的平移、縮放、旋轉等操作做相應的變換,它僅位於底圖之上(即瓦片圖層將會遮擋底圖,不遮擋其他圖層),瓦片圖層的添加順序不會影響其他圖層(例如:POI搜索圖層、我的位置圖層等)的疊加關系,適用於開發者擁有某一區域的地圖,並希望使用此區域地圖覆蓋相應位置的百度地圖。
1、瓦片划分規則
百度地圖SDK會根據不同的比例尺將地圖划分成若干個瓦片,並且以中心點經緯度(0,0)開始計算瓦片,當地圖顯示縮放級別增大時,每一個瓦片被划分成4個瓦片。如:
地圖級別為0時,只有1張瓦片;
地圖級別為1時,會分成 1 * 4 = 4 張瓦片;
依次類推。
當地圖級別為n時,總共划分的瓦片為:4的n次方。
為了保證瓦片的顯示效果,第n級的瓦片顯示的地圖level范圍為[n - 0.5, n + 0.5)
2、本地加載和在線下載
瓦片圖層分為本地加載和在線下載兩種繪制方式。
(1)本地加載方式,將圖片打包於應用內(保存到Assets文件夾下),適用於圖片較小且不需要頻繁變更的情況。
(2)在線下載,將圖片存放於開發者提供的服務中,提供給SDK一個URL模板,通過URLTileLayer調用在線瓦片圖層的URL。
二、運行截圖
簡介:瓦片圖層支持開發者添加自有瓦片數據,包括在線下載和本地加載兩種方式。
詳述:
(1)在線下載方式
(2)本地加載方式
本示例運行截圖如下:
三、設計步驟
1、添加demo23_tile_overlay.xml文件
在layout文件夾下添加該文件,代碼不再列出。
2、添加Demo23TileOverlay.cs文件
在SrcSdkDemos文件夾下添加該文件,然后將代碼改為下面的內容:
using System; using Android.App; using Android.OS; using Android.Widget; using Com.Baidu.Mapapi.Map; using Com.Baidu.Mapapi.Model; using Android.Graphics; using Android.Util; namespace BdMapV371Demos.SrcSdkDemos { /// <summary> /// TileOverlay 測試demo /// </summary> [Activity(Label = "@string/demo_name_tileoverlay")] public class Demo23TileOverlay : Activity, BaiduMap.IOnMapLoadedCallback { private TextureMapView mMapView; private BaiduMap mBaiduMap; // 設置瓦片圖的在線緩存大小,默認為20 M public const int TileTmpOnlineCache = 20 * 1024 * 1024; public string onlineUrl = "http://api0.map.bdimg.com/customimage/tile" + "?&x={x}&y={y}&z={z}&udt=20150601&customid=light"; private TileOverlay tileOverlay; private MapStatusUpdate mMapStatusUpdate; private bool mapLoaded = false; protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); SetContentView(Resource.Layout.demo23_tile_overlay); mMapView = FindViewById<TextureMapView>(Resource.Id.mapview); mBaiduMap = mMapView.Map; mBaiduMap.SetOnMapLoadedCallback(this); MapStatus.Builder builder = new MapStatus.Builder(); builder.Zoom(16.0f); builder.Target(new LatLng(39.914935D, 116.403119D)); mMapStatusUpdate = MapStatusUpdateFactory.NewMapStatus(builder.Build()); mBaiduMap.SetMapStatus(mMapStatusUpdate); Button btnOnline = FindViewById<Button>(Resource.Id.online); Button btnOffline = FindViewById<Button>(Resource.Id.offline); CheckBox hidePoiInfo = FindViewById<CheckBox>(Resource.Id.hide_poiinfo); // 設置在線方法監聽 btnOnline.Click += delegate { OnlineTile(); }; // 設置離線方法監聽 btnOffline.Click += delegate { OfflineTile(); }; hidePoiInfo.CheckedChange += (s, e) => { if (e.IsChecked) { mBaiduMap.ShowMapPoi(false);//僅顯示交通圖 } else { mBaiduMap.ShowMapPoi(true); } }; Button btnClearTile = FindViewById<Button>(Resource.Id.btnClearTile); btnClearTile.Click += delegate { RemoveTile(); }; } private void RemoveTile() { if (tileOverlay != null && mBaiduMap != null) { tileOverlay.RemoveTileOverlay(); } } /// <summary>使用瓦片圖的在線方式</summary> private void OnlineTile() { RemoveTile(); // 構造顯示瓦片圖范圍,當前為世界范圍 LatLng northeast = new LatLng(80, 180); LatLng southwest = new LatLng(-80, -180); LatLngBounds bounds = new LatLngBounds.Builder() .Include(northeast) .Include(southwest) .Build(); var tileProvider = new MyUrlTileProvider(this); // 通過option指定相關屬性,向地圖添加在線瓦片圖對象 TileOverlayOptions options = new TileOverlayOptions() .TileProvider(tileProvider) .SetMaxTileTmp(TileTmpOnlineCache) .SetPositionFromBounds(bounds); tileOverlay = mBaiduMap.AddTileLayer(options); if (mapLoaded) { //mBaiduMap.MapType = BaiduMap.MapTypeNormal; mBaiduMap.SetMaxAndMinZoomLevel(21.0f, 3.0f); mBaiduMap.SetMapStatusLimits(new LatLngBounds.Builder() .Include(northeast).Include(southwest) .Build()); mBaiduMap.SetMapStatus(mMapStatusUpdate); } } /// <summary>瓦片圖的離線添加</summary> private void OfflineTile() { RemoveTile(); //// 構造顯示瓦片圖范圍,當前為世界范圍 LatLng northeast = new LatLng(80, 180); LatLng southwest = new LatLng(-80, -180); var tileProvider = new MyFileTileProvider(this); // 通過option指定相關屬性,向地圖添加離線瓦片圖對象 LatLngBounds bounds = new LatLngBounds.Builder() .Include(northeast).Include(southwest).Build(); //// 設置離線瓦片圖屬性option TileOverlayOptions options = new TileOverlayOptions() .TileProvider(tileProvider) .SetPositionFromBounds(bounds); mBaiduMap.MapType = BaiduMap.MapTypeSatellite; tileOverlay = mBaiduMap.AddTileLayer(options); if (mapLoaded) { mBaiduMap.MapType = BaiduMap.MapTypeNormal; LatLng northeast1 = new LatLng(39.94001804746338, 116.41224644234747); LatLng southwest1 = new LatLng(39.90299859954822, 116.38359947963427); LatLngBounds.Builder builder = new LatLngBounds.Builder(); builder.Include(northeast1) .Include(southwest1); mBaiduMap.SetMapStatusLimits(builder.Build()); mBaiduMap.SetMaxAndMinZoomLevel(17.0f, 16.0f); mBaiduMap.SetMapStatus(mMapStatusUpdate); } } //實現接口 public void OnMapLoaded() { mapLoaded = true; } protected override void OnPause() { base.OnPause(); mMapView.OnPause(); } protected override void OnResume() { base.OnResume(); mMapView.OnResume(); } protected override void OnDestroy() { base.OnDestroy(); mMapView.OnDestroy(); } } // 定義瓦片圖的在線Provider,並實現相關接口 public class MyUrlTileProvider : UrlTileProvider { private Demo23TileOverlay a; public MyUrlTileProvider(Demo23TileOverlay a) { this.a = a; } public override int MaxDisLevel { get { return 21; } //顯示瓦片圖的最大級別 } public override int MinDisLevel { get { return 3; }//顯示瓦片圖的最小級別 } public override string TileUrl { get { return a.onlineUrl; } } } /// <summary> /// 定義瓦片圖的離線Provider,並實現相關接口 /// </summary> public class MyFileTileProvider : FileTileProvider { private Demo23TileOverlay a; public MyFileTileProvider(Demo23TileOverlay a) { this.a = a; } public override int MaxDisLevel { get { return 21; } } public override int MinDisLevel { get { return 3; } } public override Tile GetTile(int x, int y, int z) { // 根據地圖某一狀態下x、y、z加載指定的瓦片圖 string filedir = string.Format( "LocalTileImage/{0}/{0}_{1}_{2}.jpg", z, x, y); Android.Graphics.Bitmap bm = null; System.IO.Stream inputStream = null; try { inputStream = a.Assets.Open(filedir); bm = BitmapFactory.DecodeStream(inputStream); } catch (Exception e) { Log.Debug("MyFileTileProvider", "瓦片圖加載錯誤。\n" + e.StackTrace); return null; } if (bm == null) { Log.Debug("MyFileTileProvider", "bm為null"); return null; } byte[] bytes = new byte[bm.ByteCount]; inputStream.Read(bytes, 0, bytes.Length); // 瓦片圖尺寸必須滿足256 * 256 var offlineTile = new Tile(bm.Width, bm.Height, bytes); bm.Recycle(); return offlineTile; } } }
3、修改MainActivity.cs文件
在MainActivity.cs文件的demos字段定義中,去掉【示例23】下面的注釋。
運行觀察效果。

