原文出处:http://www.cnblogs.com/LionGG/archive/2009/04/20/1439905.html

Google Maps、Virtual Earth等网络地理所使用的地图投影,常被称作Web Mercator或Spherical Mercator,它与常规墨卡托投影的主要区别就是把地球模拟为球体而非椭球体。建议先对地图投影知识做一个基本的了解,《地图投影为什么》。

什么是墨卡托投影?

墨卡托(Mercator)投影,又名"等角正轴圆柱投影",荷兰地图学家墨卡托(Mercator)在1569年拟定,假设地球被围在一个中空的圆柱里,其赤道与圆柱相接触,然后再假想地球中心有一盏灯,把球面上的图形投影到圆柱体上,再把圆柱体展开,这就是一幅标准纬线为零度(即赤道)的"墨卡托投影"绘制出的世界地图。从球到平面,肯定有个转换公式,这里就不再罗列。

Google们为什么选择墨卡托投影?

墨卡托投影的"等角"特性,保证了对象的形状的不变行,正方形的物体投影后不会变为长方形。"等角"也保证了方向和相互位置的正确性,因此在航海和航空中常常应用,而Google们在计算人们查询地物的方向时不会出错。

墨卡托投影的"圆柱"特性,保证了南北(纬线)和东西(经线)都是平行直线,并且相互垂直。而且经线间隔是相同的,纬线间隔从标准纬线(此处是赤道,也可能是其他纬线)向两级逐渐增大。

但是,"等角"不可避免的带来的面积的巨大变形,特别是两极地区,明显的如格陵兰岛比实际面积扩大了N倍。不过要是去两极地区探险或可靠的同志们,一般有更详细的资料,不会来查看网络地图的,这个不要紧。

为什么是圆形球体,而非椭球体?

这说来简单,仅仅是由于实现的方便,和计算上的简单,精度理论上差别0.33%之内,特别是比例尺越大,地物更详细的时候,差别基本可以忽略。

Web墨卡托投影坐标系:

以整个世界范围,赤道作为标准纬线,本初子午线作为中央经线,两者交点为坐标原点,向东向北为正,向西向南为负。

X轴:由于赤道半径为6378137米,则赤道周长为2*PI*r = 20037508.3427892,因此X轴的取值范围:[-20037508.3427892,20037508.3427892]。

Y轴:由墨卡托投影的公式可知,同时上图也有示意,当纬度φ接近两极,即90°时,y值趋向于无穷。这是那些"懒惰的工程师"就把Y轴的取值范围也限定在[-20037508.3427892,20037508.3427892]之间,搞个正方形。

懒人的好处,众所周知,事先切好静态图片,提高访问效率云云。俺只是告诉你为什么会是这样子。因此在投影坐标系(米)下的范围是:最小(-20037508.3427892, -20037508.3427892 )到最大 (20037508.3427892, 20037508.3427892)。

对应的地理坐标系:

按道理,先讲地理坐标系才是,比如球体还是椭球体是地理坐标系的事情,和墨卡托投影本关联不大。简单来说,投影坐标系(PROJCS)是平面坐标系,以米为单位;而地理坐标系(GEOGCS)是椭球面坐标系,以经纬度为单位。具体可参考《坐标系、坐标参照系、坐标变换、投影变换》。

经度:这边没问题,可取全球范围:[-180,180]。

纬度:上面已知,纬度不可能到达90°,懒人们为了正方形而取的-20037508.3427892,经过反计算,可得到纬度85.05112877980659。因此纬度取值范围是[-85.05112877980659,85.05112877980659]。其余的地区怎么办?没事,企鹅们不在乎。

因此,地理坐标系(经纬度)对应的范围是:最小(-180,-85.05112877980659),最大(180, 85.05112877980659)。至于其中的Datum、坐标转换等就不再多言。

相关坐标计算:

关于Google Maps等的组织方式——地图瓦片金字塔,估计我在这里重复一遍这玩意,怕也是没人看了。尽管原理都一样,但具体到写不同厂商不同数据源的代码时,你会发现,可缩放级别数不一样,最小级别不一样,编码方式不一样,比如Google的QRST,微软的四叉树,OSGeo的TMS等。

然而,你或许也不必这么麻烦,因为这些算法在网络上早已遍布朝野,你尽可从他人博客中获取,或是从开源软件里学习。这本身都不是秘密,微软自己也是公布的。

《Tiles à la Google Maps》 用交互性地方式可得到任一Tile的边界范围,各种流行编码方式等。该页面的链接都非常有价值,部分也是本文写作的重要参考。作者用python完成了下列坐标之间转换算法:经纬度(出现在KML中的坐标,WMS的BBOX参数等),平面坐标XY(米,Web Mercator投影坐标系),金字塔的XYZ(即X轴的位置,Y轴的位置,和缩放级别ZoomLevel),每个Tile的编码Key值(QRST或0123等)。转换时,还需要注意两个概念,Ground Resolution和Map Scale。

Ground Resolution,地面分辨率,类似Spatial Resolution(空间分辨率),我们这里主要关注用象元(pixel size)表示的形式:一个像素(pixel)代表的地面尺寸(米)。以Virtual Earth为例,Level为1时,图片大小为512*512(4个Tile),那么赤道空间分辨率为:赤道周长/512。其他纬度的空间分辨率则为 纬度圈长度/512,极端的北极则为0。Level为2时,赤道的空间分辨率为 赤道周长/1024,其他纬度为 纬度圈长度1024。很明显,Ground Resolution取决于两个参数,缩放级别Level纬度latitude ,Level决定像素的多少,latitude决定地面距离的长短。地面分辨率的公式为,单位:米/像素:

ground resolution = (cos(latitude * pi/180) * 2 * pi * 6378137 meters) / (256 * 2level pixels)

Map Scale,即地图比例尺,小学知识,图上距离比实地距离,两者单位一般都是米。在Ground Resolution的计算中,由Level可得到图片的像素大小,那么需要把其转换为以米为单位的距离,涉及到DPI(dot per inch),暂时可理解为类似的PPI(pixelper inch),即每英寸代表多少个像素。256 * 2level / DPI 即得到相应的英寸inch,再把英寸inch除以0.0254转换为米。实地距离仍旧是:cos(latitude * pi/180) * 2 * pi * 6378137 meters; 因此比例尺的公式为,一般都化为1:XXX,无单位:

map scale = 256 * 2level / screen dpi / 0.0254 / (cos(latitude * pi/180) * 2 * pi * 6378137)

= 1 : (cos(latitude * pi/180) * 2 * pi * 6378137 * screen dpi) / (256 * 2level * 0.0254)

其实,Map Scale 和 Ground Resolution存在对应关系,毕竟都和实地距离相关联,两者关系:map scale = 1 : ground resolution * screen dpi / 0.0254 meters/inch

《Virtual Earth Tile System》列举了Virtual Earth在赤道上,Level、像素数、地面分辨率、地图比例尺的对应关系,同时本文也简单介绍了Mercator投影和上述两个概念,推荐。

此外,《Addressing Google Maps image tiles》应用程序,输入经纬度和缩放级别,即可缩放到相应的Google Maps位置,而且可以显示出查找过程的QRST。JavaScript实现的算法,也可以抓下来和《Tiles à la Google Maps》对比下,从经纬度到到Tile编码的转换。

WKT形式表示

Google Maps和Virtual Earth等的流行程度不用多讲,然而他们所使用的Web Mercator或Spherical Mercator在很长一段时间内并没有被EPSG的投影数据库所接纳。EPSG认为它不能算作科学意义上的投影,所以只是给了一个EPSG:900913的标号(SRID),这个标号游离在EPSG常规标号范围之外。(EPSG、SRID是什么?参见《EPSG 、SRID》。)

到了2008年5月(据SharpGIS同学), EPSG恍然明白,不管椭球体还是球体,其实都是对地球的模拟,只是精确程度上的差别,没有本质上的不同。或者是不得不接受广泛的事实标准,接纳了这个投影,定义投影坐标系PROJCS的名字为"Popular Visualisation CRS / Mercator",SRID为EPSG:3785;地理坐标系GEOGCS的名字为"Popular Visualisation CRS",SRID为"EPSG:4055"。这些标号已经进入"正常范围"。(PS:这个Visualisation 是英式英语写法?)

PROJCS 的WKT《Well Known Text》写法如下,GEOGCS、Datum等的WKT表示参见《Spherical/Web Mercator: EPSG code 3785》。附带说一句,Web Mercator在ESRI公司的编号(ESRI叫它Well Known ID?)暂时是102113,或许偶尔用得到。

PROJCS["Popular Visualisation CRS / Mercator",
    GEOGCS["Popular Visualisation CRS",
        DATUM["Popular_Visualisation_Datum",
            SPHEROID["Popular Visualisation Sphere",6378137,0,
                AUTHORITY["EPSG","7059"]],
            TOWGS84[0,0,0,0,0,0,0],
            AUTHORITY["EPSG","6055"]],
        PRIMEM["Greenwich",0,
            AUTHORITY["EPSG","8901"]],
        UNIT["degree",0.01745329251994328,
            AUTHORITY["EPSG","9122"]],
        AUTHORITY["EPSG","4055"]],
    UNIT["metre",1,
        AUTHORITY["EPSG","9001"]],
    PROJECTION["Mercator_1SP"],
    PARAMETER["central_meridian",0],
    PARAMETER["scale_factor",1],
    PARAMETER["false_easting",0],
    PARAMETER["false_northing",0],
    AUTHORITY["EPSG","3785"],
    AXIS["X",EAST],
    AXIS["Y",NORTH]]

附记:这个问题算是老问题,费这么多时间,主要就是分享,毕竟自己还算是相当明白。也是看见有人不懂乱说,写篇文章纠正下。当然谁都会犯错误,包括我这篇是否100%正确,你也可以质疑。起这个题目其实不是本意,因为它不科学,甚至EPSG的INFORMATION_SOURCE字段写的都是Microsoft,只不过国内Google更火些,SEO一下。

这篇文章除了参考文中所列链接外, Microsoft、Google、EPSG、OGC等组织相关的说明外,Charlie Savage、SharpGIS、Nelson John等博客也是非常重要的来源,在此致以谢意。

转载于:https://www.cnblogs.com/bluespot/archive/2009/05/25/1488845.html

Google Maps地图投影全解析相关推荐

  1. Java解析Google Maps API返回的Json

    Google Maps API是一个很强大的东西,能够进行经纬度的查询和反查等,对于Java,Google提供了一个Webservices,地址为如下形式: http://maps.googleapi ...

  2. Google Maps Api Geocoding 传递参数和返回参数的解析(Json)

    转https://blog.csdn.net/zkdemon/article/details/7019117 Google Geocoding API    http://code.google.co ...

  3. Google Earth Engine (GEE) ——Earth Engine Explorer (EE Explorer)使用最全解析(8000字长文)

    Google 地球引擎简介 Earth Engine Explorer (EE Explorer) 是一个轻量级地理空间图像数据查看器,可以访问Earth Engine Data Catalog 中提 ...

  4. Google Maps嵌入参数

    转自:http://www.oulan.com/topics/google-maps-embed-parameters.html Google Maps嵌入参数 发表回复 最近接了个不赚钱的活.需要嵌 ...

  5. Google maps API开发

    Google maps API开发 注:经纬度的查询,找了半天,终于找着活神仙了,(*^__^*) 嘻嘻-- 1.经纬度查询工具:http://www.playgoogle.com/googlemap ...

  6. 关于Keyhole和Google Maps(二)

    1.并购 Keyhole一直寻求融资.         2004年,Keyhole和硅谷投资机构Menlo Ventures接洽投资事宜.         期间,Google的布林对EarthView ...

  7. Android系统Google Maps开发实例浅析

    Google Map(谷歌地图)是Google公司提供的电子地图服务.包括了三种视图:矢量地图.卫星图片.地形地图.对于Android系统来说,可以利用Google提供的地图服务来开发自己的一些应用. ...

  8. Google Maps——页面提示[For development purposes only]解决方案

    问题描述 填写Google Maps JavaScript API密钥之后,加载Google Maps JavaScript API会出现这样的显示: 问题解析 由于谷歌政策的变革,需要填写一些相关信 ...

  9. Google Maps JavaScript API V3 根据地址 加载地图

    效果图如下: javascript代码: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" &qu ...

最新文章

  1. 【C语言】宏offsetof的模拟实现 (计算结构体中某变量相对于首地址的偏移)
  2. Spring MVC报异常:org.springframework.web.util.NestedServletException: Request processing failed
  3. 使用FindFirstFile,FindNextFile遍历一个文件夹
  4. 【Python】快速认识Pandas的10大索引
  5. vuex最简单、最详细的入门文档
  6. 域名可以转让注册人吗_网店可以转让吗?
  7. 2019年最佳Python学习路线
  8. 如何从初级程序员变成高级程序员?赶紧看一看
  9. 在ASP.NET Web Application 中如何处理图片 【转】-有用
  10. WebStorm 8.0.3下简单运行pomelo项目
  11. 由树的定义和递归想到的
  12. 如何使用MySQL Workbench建立数据库
  13. C语言实现——查找凶手
  14. 【hiho一下_week256】Diligent Robots
  15. 661. Image Smoother
  16. 嘘!捡漏啦!1919元=高性能电脑,满额+500京东卡...
  17. 0基础单片机入门知识:怎么使用数字万用表以及注意事项
  18. 计算机中的信息表示教学计划,人教版小学五年级信息技术教学计划(小编推荐)...
  19. 软件产品登记证书申请程序 软件产品登记证书用途
  20. 网鼎杯2020 青龙组 jocker

热门文章

  1. 程序员需要了解的一点组织行为学知识
  2. C# 反射机制(转)
  3. matlab reshape矩阵维度变换
  4. C++ 异常 与 ”为什么析构函数不能抛出异常“ 问题
  5. Matlab里evalin和assignin的用法
  6. java remove(index)_方法removeElementAt(int index)在Java中做什么?
  7. 干货|训练神经网络时要知道的几个要点
  8. byte数组转为string_String类
  9. 【TypeScript系列教程06】基础类型
  10. Java Mail+MYSQL+Tomcate+jsp实现企业快信系统