在《地圖下載1之天地圖瓦片解析》中我們分析了天地圖瓦片的結構;在《地圖下載2之天超圖瓦片格式》中我們分析了超圖的WMTS瓦片的結構,本文,我們大致來講一下實現下載的過程。
指定分辨率
分辨率是固定的,根據需要下載的級別(1-20)獲取對應分辨率:
/// <summary> /// 獲取某一級別下的分辨率 /// </summary> /// <param name="level">級別</param> /// <returns>分辨率</returns> public static double Resolution(int level) { switch (level) { case 1: return 0.70312500015485435; case 2: return 0.35156250007742718; case 3: return 0.17578125003871359; case 4: return 0.0878906250193568; case 5: return 0.0439453125096784; case 6: return 0.0219726562548392; case 7: return 0.0109863281274196; case 8: return 0.0054931640637098; case 9: return 0.0027465820318549957; case 10: return 0.0013732910159274978; case 11: return 0.00068664549607834132; case 12: return 0.00034332275992416907; case 13: return 0.00017166136807812298; case 14: return 8.5830684039061379E-05; case 15: return 4.2915342019530649E-05; case 16: return 2.1457682893727977E-05; case 17: return 1.0728841446864E-05; case 18: return 5.3644207234319882E-06; case 19: return 2.6822103617159941E-06; case 20: return 1.341105180858E-06; default: return 0; } }
獲取下載范圍
根據需要下載的范圍、級別及分辨率,獲取地圖瓦片起始、結束行列值(其他地圖如百度地圖、谷歌地圖算法可能 不一樣)
/// <summary> /// 根據范圍獲取行列號范圍 /// </summary> /// <param name="resolution">分辨率</param> /// <param name="level">級別</param> /// <param name="xMin">X最小</param> /// <param name="xMax">X最大</param> /// <param name="yMin">Y最小</param> /// <param name="yMax">Y最大</param> /// <returns>起始、結束行列值</returns> public static int[] GetRowCol(double resolution,int level,double xMin,double xMax,double yMin,double yMax) { //計算所選范圍地圖瓦片起始、結束行列值 (天地圖范圍(-180,90,180,90),瓦片大小256) double buffer = 0; //double buffer = resolution * 0.5; int startX = (int)Math.Floor((xMin + 180+ buffer) / (256 * resolution)); int startY = (int)Math.Floor((90 - yMax+ buffer) / (256 * resolution)); int endX = (int)Math.Floor((xMax + 180- buffer) / (256 * resolution)); int endY = (int)Math.Floor((90 - yMin- buffer) / (256 * resolution)); return new int[] { startX, startY, endX, endY }; }
確定下載的類型
/// <summary> /// 天地圖底圖類型 /// </summary> public enum TdType { /// <summary> /// 影像注記(墨卡托,WGS1984) /// </summary> cia_w, /// <summary> /// 影像(墨卡托,WGS1984) /// </summary> img_w, /// <summary> ///街道注記(墨卡托,WGS1984) /// </summary> cva_w, /// <summary> /// 街道(墨卡托,WGS1984) /// </summary> vec_w, /// <summary> /// 影像注記(經緯度,CGCS2000) /// </summary> cia_c, /// <summary> /// 影像(經緯度,CGCS2000) /// </summary> img_c, /// <summary> /// 天地圖街道注記(經緯度,CGCS2000) /// </summary> cva_c, /// <summary> /// 天地圖街道(經緯度,CGCS2000) /// </summary> vec_c }
構造下載鏈接
下載所需要的參數前面都提到了。
/// <summary> /// 構造下載地址 /// </summary> /// <param name="tdType">類型</param> /// <param name="x">列號(0~n)</param> /// <param name="y">行號(0~n)</param> /// <param name="level">級別(1~20)</param> /// <returns>下載地址</returns> public static string Url(TdType tdType,int x,int y,int level) { return string.Format("http://t0.tianditu.com/DataServer?T={0}&x={1}&y={2}&l={3}", tdType,x,y, level); }
構造輸出路徑
超圖的瓦片路徑構造:
/// <summary> /// 構造超圖瓦片路徑 /// </summary> /// <param name="level">級另</param> /// <param name="row">行號</param> /// <param name="col">列號</param> /// <returns>相對路徑</returns> public static string GetTileFilePath(int level, int row, int col) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(@"/"); //stringBuilder.Append(@"/JP_256_/"); stringBuilder.Append(level); stringBuilder.Append(@"/"); //超圖行號 int value = (row < 0) ? (row / 128 - 1) : (row / 128); stringBuilder.Append(value); stringBuilder.Append("/"); //超圖列號 value = ((col < 0) ? (col / 128 - 1) : (col / 128)); stringBuilder.Append(value); stringBuilder.Append("/"); stringBuilder.Append(row); stringBuilder.Append("x"); stringBuilder.Append(col); stringBuilder.Append(".jpg"); return stringBuilder.ToString(); }
接下來就是遍歷下載、多線程優化、界面設計等問題了。各方面還需優化,不過能解決問題了!