关于如何将地球经纬度坐标系统转换成程序中常用到的平面2D坐标系统,网上的文章很多,参考http://www.cnblogs.com/beniao/archive/2010/04/18/1714544.html(本文图1 图3来自此处).谷歌地图采用的投影方式为“墨卡托投影法”(维基百科网址http://en.wikipedia.org/wiki/Mercator_projection),大概意思就是将地球放在一个圆柱中,让地球赤道和圆柱壁相接触,在地球中心放一盏灯,地球上的图像在圆柱壁上会产生阴影,然后将圆柱壁展开,得到的一张“长方形地图”即为转换之后的平面2D地图,描述很简单,实际展开后的地图还进行了其他处理。

图1

可以想象到,地球上的经度经过灯光的照射之后,在圆柱壁上生成的阴影应该是均匀分步的,而纬度就不一样了,纬度经过灯光照射之后,离赤道越近的分布越密,离赤道越远的分步越稀,到了地球两极(南极和北极),就会趋向无穷稀,因此谷歌地图并没有包含地球两极的区域(北边到北纬85度,南边到南纬85度,大概)。

谷歌地图包含的地球范围为 经度:0度~东经180,0度~西经180(共360度),纬度:0度~北纬85,0度~南纬85(共170度)。注:以上0经度表示通过英国的本初子午线,0纬度指赤道。转换成平面2D图之后,原点(0,0)在左上方(跟程序中一致),用像素作为单位,这样一来,地球上任何一个点(经度,纬度)都能转换成平面2D坐标系统中的一个点(x,y),转换算法已经提供了,直接可以拿来使用。前面说到,经度和纬度在圆柱壁上的阴影分步密度不同,纬度远离赤道分步越稀,因此,虽然经度范围为360度(-180~180,西经为负,东经为正,自西往东,经度越来越大),远远大于纬度170度(-85~85,南纬为负,北纬为正),但是映射到圆柱壁之后生成的图片的长宽却是相等的(这个也有后期经过处理的原因),实质上,谷歌地图的长宽确实是相同的。

由于平面地图是可以放大缩小的,因此地图不可能使用同一张图,这样放大后就会失真,谷歌地图的做法就是给地图预先定义缩放等级(0级~22级,常用的0~17),每一个缩放级别均对应许许多多的小方块图片(称为瓦片),这些小方块都是256*256像素,然后将这些瓦片拼接起来生成一张大的清晰的地图。谷歌地图的缩放级别与瓦片数目有一个对应关系:瓦片数目=2的n次方*2的n次方(n为缩放级别)。也就是说,当缩放级别为0时,整个世界地图只1*1张256*256的图,当缩放级别为1,整个世界地图包含2*2张256*256大小的图,当缩放级别为2,整个世界地图包含4*4张256*256大小的图。下图为缩放级别为0时,坐标对应关系:

图2

当缩放级别改变时,整个世界地图组成变化如下图:

图3

谷歌地图背景显示原理就是将每个缩放级别下的瓦片下载下来,然后拼接在一起,如果我们知道了下载瓦片的方法,那么我们也能模拟一个类似谷歌地图的显示界面。下面提供的一个demo演示了如何根据你提供的两个经纬度点(左上角,右下角),以及缩放级别,下载这两点包含区域的瓦片,最后拼接起来。

demo不做过多说明,代码中注释很详细,注意一下几点:

  • 谷歌地图提供API,通过http请求,给出瓦片的列、行以及缩放级别,就可以下载对应的瓦片,

国内地址:http://mt0.google.cn/vt/lyrs=m@234000000&hl=zh-CN&gl=CN&src=app&x=0&y=0&z=0

国外地址:http://mts0.googleapis.com/vt?lyrs=m&x=0&y=0&z=0

其中,地址前面的mt0可以是mt1、mt2、mt3,分别为不同服务器,对应的,mts0可以为mts1、mts2、mts3。x、y、z分别表示瓦片的列号、行号以及缩放级别。

lyrs表示地图类型:

m:路线图

t:地形图

p:带标签的地形图

s:卫星图

y:带标签的卫星图

  • demo中填写的左上角和右下角点的经纬度范围分别为(-180~180)和(-85~85),而且左上角点的经度一定要小于右下角的经度,左上角的纬度一定要大于右下角的纬度,至于为什么,原因就是必须能通过这两点确定一个区域。demo程序中未作判断。
  • 不要选择区域过大,或者缩放级别过大,因为包含的要下载瓦片太多,程序没做任何性能优化,可能出现bug。线程不宜太多,太多反而速度慢。如果下载图片有失败的,可以重新下载几次,可以完善一下,比如只下载上次失败的图片。
  • demo针对google map,其他地图类似。本人公司实际项目中用到了从谷歌地图中下载下来的这些瓦片,模仿谷歌地图显示原理做了一个地图显示模块。

效果图:

图4 demo主界面

图5 下载完成的瓦片

图6 拼接瓦片成一张大图

源码下载地址:http://files.cnblogs.com/xiaozhi_5638/GoogleMapDownLoader.rar

VS2010 win7调试通过,希望有帮助!

.NET开发笔记(二十三) 谷歌地图下载的更多相关文章

  1. .NET破解之谷歌地图下载助手-睿智版

    今天在整理文件是,发现手上还有个谷歌地图下载助手-睿智版,是C#写的.查了它们的官网,好像很久没有更新了,可能是垮了吧. 我把.NET程序破解分为三个阶段:软件分析,从软件使用上来分析功能的限制,即为 ...

  2. Django开发笔记二

    Django开发笔记一 Django开发笔记二 Django开发笔记三 Django开发笔记四 Django开发笔记五 Django开发笔记六 1.xadmin添加主题.修改标题页脚和收起左侧菜单 # ...

  3. python3.4学习笔记(二十三) Python调用淘宝IP库获取IP归属地返回省市运营商实例代码

    python3.4学习笔记(二十三) Python调用淘宝IP库获取IP归属地返回省市运营商实例代码 淘宝IP地址库 http://ip.taobao.com/目前提供的服务包括:1. 根据用户提供的 ...

  4. C#版谷歌地图下载器设计与实现

    关于如何将地球经纬度坐标系统转换成程序中常用到的平面2D坐标系统,网上的文章很多,参考http://www.cnblogs.com/beniao/archive/2010/04/18/1714544. ...

  5. SDL开发笔记(二):音频基础介绍、使用SDL播放音频

    若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...

  6. EasyUI 开发笔记(二)

    接上篇 :EasyUI 开发笔记(一)  (http://www.cnblogs.com/yiayi/p/3485258.html) 这期就简单介绍下, easyui 的 list 展示, 在easy ...

  7. Java开发笔记(十三)利用关系运算符比较大小

    前面在<Java开发笔记(九)赋值运算符及其演化>中提到,Java编程中的等号“=”表示赋值操作,并非数学上的等式涵义.Java通过等式符号“==”表示左右两边相等,对应数学的等号“=”: ...

  8. (C/C++学习笔记) 二十三. 运行时类型识别

    二十三. 运行时类型识别 ● 定义 运行时类型识别(Run-time Type Identification, RTTI) 通过RTTI, 程序能够使用基类的指针或引用来检查(check)这些指针或引 ...

  9. 树莓派开发笔记(十三):入手研华ADVANTECH工控树莓派UNO-220套件(二):安装rtc等驱动

    前言   前面运行了系统,本篇是安装对应套装的驱动,使rtc等外设生效,树莓派本身是不带rtc外设的.   UNO-220-P4N1AE 驱动下载     官方下载:https://www.advan ...

随机推荐

  1. Spring Security4.X 简单实例介绍

    简介 本例子采用的是SpringMVC.SpringSecurity和Spring整合的简单使用 使用gradle搭建的项目(gradle比maven更加便捷),可以自行了解 web.xml配置 &l ...

  2. 【leetcode】LRU Cache

    题目简述: Design and implement a data structure for Least Recently Used (LRU) cache. It should support t ...

  3. 继承映射关系 TPH、TPT、TPC<EntityFramework6.0>

    每个类型一张表[TPT] 声明方式 public class Business { [Key] public int BusinessId { get; protected set; } public ...

  4. apache的AB测试

    A/B测试A/B测试是一种新兴的网页优化方法,可以用于增加转化率注册率等网页指标..A/B测试的目的在于通过科学的实验设计.采样样本代表性.流量分割与小流量测试等方式来获得具有代表性的实验结论,并确信 ...

  5. 【web maven】新建的项目 controller也有,从前台跳转后台 无法找到对应的controller

    碰上很 愣的问题: 使用maven搭建项目完成,项目页面写好,实体.Dao.Service.Controller都有了,但是指定Controller中的某个方法中一直不能从前台进入后台 原因: 没有w ...

  6. HTML5开发笔记:图片上传预览

    我们知道通过<input type="file">可以用来进行一个图片或者文件的上传,然而浏览器自带的一个缩略图预览的功能其实是相当不美观的,很多时候我们希望可以在上传 ...

  7. JAVA 引入 junit工具框架

    我遇到的麻烦 : 开始直接按照视频上的来做,直接也是引入的他上面的jar ,但是我只引入了一个,就是上面的junit-4.4.jar,然后就会报错,会出现,空指针的错误, 后面我又按照网上的教程 这里 ...

  8. Ajax跨域Post方法调用Web Api(NuGet配置的环境)

    没安装的去NuGet安装, 然后安装, 建立Web Api项目.需要在里的WebApiConfig.cs里配置 config.EnableSystemDiagnosticsTracing(); //感 ...

  9. JS应用,表单上的一些东西

    例: <body> <form>我的生日是哪一年? <input type="text" value="" id="t1 ...

  10. 通过 listboxitem 查找属于listbox第几条数据

    public override System.Windows.Style SelectStyle(object item, System.Windows.DependencyObject contai ...