地图下载工具,想必大家见过不少了,最出名的莫过于SGGS了,SGGS可以根据经纬度或者用户自定义拉框来选择地图下载空间范围(SGGS是下载Google地图的)。这几天本人在学习网络的东西,想自己做一个下载谷歌地图的软件。因为通过对网络的学习,发现地图下载实际上就是:通过程序下载地图控件中的小瓦片,下载到本地后,再进行图片的拼接,至于在过程中使用到的多线程,那就另当别论了。
依据传统图片下载的方式,下载一个图片的前提是我们得知道该图片的URL,因此这里就引出了自定义地图下载器的关键步骤:确定小瓦片的URL。
众所周知谷歌地图采用的投影是Web墨卡托投影,它是一个正轴圆柱投影,以往来看,一个地球放置在圆柱里面后,进行投影获得的应该是一个矩形,那么为什么谷歌的第0级瓦片是个正方形呢,因为:在Web墨卡托投影时,不仅纬度长度发生了变形,而且纬度之间的间距也进行了拉伸,所以最终成为正方形。因此在进行谷歌瓦片计算的时候:经度方向即X轴方向的瓦片索引容易计算,而纬度方向即Y轴方向的瓦片索引则要根据Web墨卡托投影的投影公式来计算(其实我们没必要去理解这个公式,会用就行了)。
计算瓦片索引之前,我们需要了解谷歌地图的瓦片坐标系(“坐标系”名词不太准确,呵呵)。
先打开谷歌地图,并同时打开谷歌浏览器的开发者工具,如图1 图 2:
打开图2中的URL
http://mt1.google.cn/vt/lyrs=m@234000000&hl=zh-CN&gl=CN&src=app&x=11&y=7&z=4&s=
从地理行业的角度看,你的第一眼就应该能分别出X,Y,Z分别是X方向瓦片索引、Y方向瓦片索引、瓦片级别。
现在我们修改URL为:
http://mt1.google.cn/vt/lyrs=m@234000000&hl=zh-CN&gl=CN&src=app&x=0&y=0&z=0
得到 图3
通过图3,我们可以看出,谷歌地图是正方形的、南北两级存在明显拉伸、地图的最左上角就是本初子午线的“北极”方向,我们来查看一下经纬度:插入图4.
通过图4我们可以看出谷歌地图的起始点(终止点)是在180E,85N,那么我们怎么区别180E和180W哪个是起始点呢,很简单在开发者工具里查找两个相邻的图片,查看二者的X Y变化趋势即可。
最终我们确定在谷歌地图中瓦片的起点是左上角的(-180,85) (规定向东为正,向北为正),因此经度变化范围为360度,纬度变化范围170度。
如此便可计算任意经纬度的瓦片号:
int level = Convert.ToInt32(txtlevel.Text);
double startX = Convert.ToDouble(txtX.Text); double startY = Convert.ToDouble(txtY.Text);
double endX = 117; double endY = 39;
double resolurtionX = Math.Pow(2, level) * 1.0 /360;//每一度有多少张
double resolurtionY = Math.Pow(2, level) * 1.0 / 170;//每一度有多少张
int startXIndex =(int) ((startX + 180) * resolurtionX);
double sinLatitude = Math.Sin(startY * Math.PI / 180);
double temp = 0.5*Math.Log((1 + sinLatitude) / (1 - sinLatitude));
int startYIndex =(int) Math.Abs((0.5 - temp / (2 * Math.PI)) * Math.Pow(2, level));
获得瓦片的索引后,至于下载图片就很简单了。
string baseURL = string.Format(
"http://mt2.google.cn/vt/lyrs=m@234000000&hl=zh-CN&gl=CN&src=app&x={0}&y={1}&z={2}", startXIndex, startYIndex, level);
HttpWebRequest client = (HttpWebRequest)WebRequest.Create(baseURL);
HttpWebResponse response = (HttpWebResponse)client.GetResponse();
Bitmap target = new Bitmap(response.GetResponseStream());
pictureBoxleft.Image = target;
如此一来,图片就下载了,至于图片拼接,本人建议使用Graphics来做。
另外还有一种更加简单方便的下载谷歌地图的方法,那就是使用GMap.Net类库,该类库中直接提供了根据经纬度计算瓦片索引的方法,不过人家可是提供各种Web地图的瓦片计算方法哦,建议参考博客:
http://www.cnblogs.com/enjoyeclipse/tag/GMAP.NET%20%E5%9C%B0%E5%9B%BE/