1、Google Map 开发整理Google Maps API 是 Google 自己推出编程 API ,可以让全世界对 Google Maps 有兴趣的程序设计师自行开发基于 Google Maps 的服务,建立自己的地图网站。以下是我在 Google Maps API 开发过程中找到的一些 API 的编程资源,包括中文文档,中文说明,示例等等,希望对 Google Maps编程感兴趣的程序员有所帮助。中文资料部分 (包括中文的文档说明等,以下的网址都是中文内容。)下面的关于 API 的中文文档Google Maps API 第 2 版中文文档http:/ Maps API 第 2 版升级指南
2、 http:/ Maps API 第 2 版类参考 http:/ Google Maps API 2 中文文档http:/www.zmap.org/doc/maps/documentation/Google Maps API 第 1 版中文文档http:/ KML 文件的中文文档Google Earth KML 中文说明(一) http:/ Earth KML 中文说明(二) http:/ Earth KML 中文说明(基于 Google Earth 客户端版本 3.0 的 KML 版本 2.0 )http:/ (主要是 Google 官方的文档说明,如果觉得中文翻译的有问题,也可以看看这些原
3、始内容。 )Google Maps API 官方网 http:/ Maps API 英文文档 http:/ Maps API 官方 Blog http:/ Maps API 论坛 http:/ KML 的官方文档 http:/ API 官方网 http:/ Google Map API 中文开发教程Google Map API 中文开发教程最好的教程还是 google 官方的说明文档,而且配有详细的例子,供大家学习,下面是文档的英文原文连接http:/ 面向的读者2. 简介1. “ Hello World ” 程序2. 浏览器兼容性3. XHTML 和 VML4. API 更新5. 地理译码6
4、. 行程规划和本地搜索7. 标注管理3. 示例程序1. 基本操作2. 地图移动及动画3. 给地图添加控件4. 事件处理函数5. 打开气泡提示窗口6. 地图覆盖物7. 单击事件处理8. 给标注增加气泡提示窗口9. 多页的气泡提示窗口10. 创建图标11. 使用图标类12. 可拖拽的标注13. 编码折线14. 在地图中使用 XML 和异步 HTTP 通信 (AJAX)15. 自定义地图控件16. 自定义地图覆盖物1. 标注管理器示例1. 天气预报图 2. 疑难解答1.1. 其它资料2. API 概览1. GMap2 类 2. 事件3. 气泡提示窗口4. 地图覆盖物5. 控件6. XML 和 RPC
5、7. 减少浏览器内存泄露3. 演示程序4. 类参考同步中文文档请参阅: http:/www.codechina.org/doc/google/gmapapi/谷歌地图 API 密钥(API Key)的解读和使用技巧 收藏好了,通過前一篇的介紹,大家對 Google Map 都有所瞭解了吧。不過還得一步步的來。先瞭解 API Key 吧。所谓 API 密钥( API Key ) ,其实就是一个字符串,在使用 script 标签导入 API 类库的时候作为请求参数传给谷歌的地图服务器,形式就是: 我的 API Key 是:ABQIAAAAMWyR7XvYN8KE9N6m_jcU4BRlfWJrPz
6、RGiYSzS4l55_z1ea3VShRolPwARGHvivnEFRLVGXyIlsrYpA使用谷歌地图 API 的第一步就是要 注册一个 API 密钥 , 谷歌的 API 使用条款 对这个密钥的用途有很正式的说明,其实总结起来也很简单: 1 、谷歌地图 API 提供的服务是免费的,对于通过 API 正常使用谷歌地图的网站基本没有任何限制; 2 、说 “ 基本 ” 没有限制的原因是,谷歌对每个 API 密钥对应的网站所作的 地理编码 /地址解析 请求次数有限制,每天( 24 小时)的请求次数不能超过 15000 次;3 、不能使用谷歌地图从事任何非法的行为,否则谷歌应该能够通过这个密钥阻止
7、你的网站使用谷歌地图;更简单的说,谷歌使用这个密钥保证能够对所有 API 用户 / 网站进行区分,方便必要的时候对 “超常规 ” 用户进行阻拦。 对于地址解析的次数限制,一般来说不会有什么影响,这里主要说 API 密钥,所以以后有时间可以再详细说说地址解析相关的东东。对于 API 密钥,还有几点需要记下来: 1 、如果使用 API 的页面还没有发布,只是在本地调试,可以不用密钥,随便用个字符串代替就可以了; 2 、 API 密钥只对网站目录或者域有效,所以,虽然你是使用同一个谷歌帐号登录后注册的密钥,但是,对不同域的网页,需要用这些域分别注册不同的密钥,对于同一个域里的页面,直接拿你网站的域名
8、注册一个,在这个域里的所有页面就可以通用这个密钥了。还有一个关于 API 密钥的实际问题: 在论坛里还有人问过,同一个页面需要支持不同的域名,最简单的就是公司有一个 cn 域名,也有一个 com 域名,这怎么办? 其实,对于这种问题,可以提前先注册好不同域名对应的密钥,存在你的 JS 变量里面,页面加载时通过 window.location 得到当前请求页面的域名,通过这个域名在找到对应的密钥,然后使用script 动态加载的方法加载地图 API ,用代码描述就是:/ 事先已经注册好的密钥var keyMapping = host1:key1, host2:key2;/ 实际请求页面的域名va
9、r requestHost = window.location.hostname;/ 找到需要的密钥var key = keyMappingrequestHost;/ 构造加载 API 的 script urlvar apiUrl = “http:/ + key;/ 使用 script 动态加载的方法加载地图 APIvar scriptTag = document.createElement(script);scriptTag.setAttribute(type, text/javascript);scriptTag.setAttribute(src, apiUrl);document.get
10、ElementsByTagName(head)0.appendChild(scriptTag);使用这段代码时,需要注意把你自己的 JS 代码中对 API 的各个类的调用放在 API 加载完成以后,详细的解释可以先 google 一下 著名的 DomReady 的问题 ,三言两语还是说不清楚的,呵呵。这段代码我没有实际跑过,欢迎斧正,如果你有更好的方法,我更愿意洗耳恭听了。使用谷歌地图 API 应该有所了解的一些技术外背景 收藏这些内容,常用谷歌地图的应该也都知道,我也只写我知道的,了解这些对使用 API 还是有帮助的。1 、 谷歌地图主页 谷歌地图对应不同的地区都会有一些专门的主页,首次登陆
11、时会显示这些地区,比如,香港的:http:/.hk ,台湾的: http:/.tw ,日本的:http:/maps.google.co.jp 不过,我们常用的也就三个: http:/ 这个应该是谷歌地图的全球主页,默认显示老美地图,拖拽到不同地区会对应显示不同语言版本的地图,不过目前对中文数据搜索支持的不如下面正式的中文主页;http:/ 这个么,我叫它是谷歌地图的中文主页,什么意思看下一个你就知道了,用这个可以使用 “ 我的地图 ” ; http:/ 这个,我叫他是谷歌地图的大陆主页,目前还没有 “ 我的地图 ”这个功能; 后面这两个主页只能显示大陆地区的详细地图,如果想看别的地区的,就只能
12、用全球主页了。 当然,别以为你抓着漏洞可以注册个 ,然后卖给谷歌,不信你试试,看它跳到哪里了 :)2 、谷歌地图的类型 其实,谷歌地图的类型主要也就三种: 普通地图:历史悠久的人工绘制地图,不多说了,不知道的给我留个地址,我快递个板砖给你;卫星地图:用卫星图片拼成的地图,不同地图的显示精度有区别,现在中文主页上也有了,曾经可是被禁止的,怕你偷看海南的黑鱼; 地形地图:用等高线标出海拔的地图,对地理教学和教育相关的相当有用,当然,对军迷也超级有吸引力,不展开 !把这三种组合起来 ( 主要是普通地图和卫星地图的组合 ) ,或者在这些地图上添加其他的数据,就又有一些新的类型了,这个层出不穷,我只说
13、主页上现有的: 混合地图:就是把普通地图和卫星地图结合,在卫星地图上显示行政区、街道等等,在全球主页上把鼠标移到 “ 卫星 ” 按钮上,会跳出来一个 “ 显示标签 ” 的复选框,选中后地图就是这个类型了,中文还没支持,不知道什么时候可以用; 交通地图:在地图上显示交通信息。这个理论上是实时的,不过,在目前的中文地图上,吸引眼球的作用更大一些,如果能在手机版上使用就好了(貌似目前还没有) ,而且只有北京和上海有数据支持; 街景地图:这个和交通地图一样,严格上不算是一种地图类型,就是使用 Flash 来显示街道的全景图,我也在等中文地图支持街景了(中文 API 已经支持 StreetView 相关
14、的类了,就是没有数据) ,不久前看到的消息是目前谷歌对这个没有时间表,呵呵,他是 “ 万事俱备,只欠东风 ” ,努力吧! 在地图 API 中,后面组合的这三种除了混合地图算作是一种地图类型外,其他两个都不算是地图类型,被看着是在地图上新增的层(术语:叠加层 /overlay ) 。3 、谷歌地图的数据源 谷歌是一个服务提供商,而不是一个内容提供商,所以,准确的说,谷歌地图向终端用户提供的是基于地图的搜索服务。从这一点上,可以把谷歌地图上的数据分为三类: 地理数据:地理、空间信息,包括经纬坐标、航拍 / 卫星图片、行政区划以及据此绘制的图片等等,由谷歌或其合作伙伴持有; 商业数据:与地理相关的商
15、业数据,比如餐馆、影院、交通、景点等等,这也是由谷歌或其合作伙伴持有,谷歌可能对这些数据有一个采集、过滤、整理的再加工过程。想被客户搜索到,就来这里 标注自己的公司 吧; 用户数据:用户使用谷歌地图 API 定制地图并在地图上标注的数据,这些数据由用户持有。 这样,通过这个分类,我们可以解决两个非常常见的疑问: 1 )使用谷歌地图 API ,地图上的数据存在哪里? 你是你的我是我的。是谷歌提供的数据,由谷歌负责;如果是你自己提供的数据,当然由你负责保存,谷歌相当于给你一个展示数据的平台,除非你愿意把自己的数据无偿贡献给谷歌 :)2 )使用谷歌地图 API ,终端用户会通过谷歌搜索到我的数据吗?
16、 对谷歌地图来说,他的数据源只有地理数据和商业数据,所以在谷歌地图主页上不会搜到你的数据。但是,你可以在你的地图上定制谷歌搜索的数据源,使得用户可以搜索你的数据。 (不是很肯定的哦,要看你的具体情况的)4 、 谷歌地图 API 谷歌地图 API 就是一系列使用 OO 方式组织的 JavaScript 类和静态方法(我有时候也统称为地图 API 类库) ,通过创建这些类的实例(对象)或调用 API 中提供的静态方法,可以在页面上创建和控制地图,也可以在地图上展示任何非谷歌提供的数据 / 信息。谷歌地图 API 只涉及浏览器/ 客户端相关的技术,比如 JavaScript 、 HTML DOM 、
17、 CSS 等,不涉及任何服务器端的技术,或者说,你可以基于任意你需要的服务端使用谷歌地图 API (所以,这里面能够展开的东东就太多了,以后再总结吧,我也在学习) 。加载谷歌地图 API 的 URL 详细解读 收藏谷歌地图的 API 类库是通过 script 标签导入的,形式如下: 我们使用 API 的时候关心的就是这个 script 的 src 属性了,这个属性也就两个部分:路径:http:/ ; 参数:file=apimap.setCenter(new GLatLng(33.0, 106.0), 3);新建一个空白的文本文件,把上面这段代码 copy 过去,不要改变代码的任何顺序,然后把这
18、个文本文件保存为 html 文件,使用浏览器打开(不要使用 MS 的 IE ),看看你能看到什么!对这段代码的详细解释 上面的这段代码就是创建一个地图的核心步骤: 1 、导入地图 API 类库。 注意这里的参数 key ,我在以前的文章里已经详细解释过了,如果你只是在本地运行,暂时可以不用管它。2 、在页面的 body 元素中定义一个地图容器。 这个地图容器一般使用 div 元素来定义,如果你愿意,使用 p 元素或者其他你能想到的元素都可以,但是都应该是块元素,并且必须定义它的 id ,保证在后面的步骤里能够通过document.getElementById 找到这个元素。容器的 style
19、属性在这里是用来定义这个容器的大小,从而决定所显示地图的大小,当然,如果你在这里不定义也可以通过其他的手段来达到目的,这里暂且先认为这个 style 的定义和 id属性一样也是必不可少的吧。 其实 body 元素在这里也有一些特殊的作用,就是保证下一步骤在页面的 html 元素全部加载结束后再执行,详细的理论就不细说了。 3 、定义你自己的 script 区域,在里面 new 一个 GMap2 对象,并且指定其显示所需的两个基本要素:中心、缩放层次。 var map = new GMap2(document.getElementById(“mapContainer“);map.setCente
20、r(new GLatLng(33.0, 106.0), 3);这里的 GMap2 是谷歌地图 API 中最重要的核心类,对应在页面上显示的地图,所有对地图的操作都需要在已经创建(new )了 GMap2 对象的基础上才能够进行。在调用 GMap2 构造函数是使用的参数就是在上一步定义的地图容器,DOM 对象,使用 document.getElementById 获取。要在页面上正常显示地图,仅仅调用 GMap2 类的构造函数创建一个 GMap2 对象还不够,你还需要指定这个 GMap2 对象的中心,通常也顺便指定它的缩放层次,否则就会默认显示缩放层次为0 。 要指定新创建地图的中心,需要使用地
21、图 API 里面定义的另一个常用类 GLatLng ,可以把这个类简单的认为是对地理坐标的封装类,构造函数中第一个参数是南北向的纬度,第二个参数是东西向的经度。 调用 GMap2 的 setCenter 方法设定完地图的中心和缩放层次,这个地图就可以正常显示了。还需要关心的几个问题: 上面的示例代码仅仅是为了显示一个试验性质的简单地图,所以把很多暂时不是很必要的代码都去掉了,如果你需要创建具有很好的兼容性、并且能够发布到你自己的网站上的地图,还需要注意这几个问题: 1 、为了保证有足够的兼容性,谷歌建议使用 XHTML 来定义显示地图的 html 页面,所以,你需要在这个页面的顶部声明 XHT
22、ML 的 DOCTYPE ,并且在 html 中声明 XHTML 的命名空间 当然,最好你自己的页面代码也能够符合 XHTML 的语法规则。相对我们现在的 HTML4.01 来说,可以把 XHTML 语法规则简单的归纳如下: html 、 head 、 title 、 body 元素一个都不能少,并且只能有 html 一个 root 元素; 不要使用简化的属性,必须使用 “name=value” 的形式; 标签名和属性名都用小写字母,属性值要用引号括起来; 标签必须是闭合的,并且不能交叉嵌套; 使用 id 属性而不是 name 属性来获取元素;2 、为了兼容 “ 伟大的 ”IE 浏览器,以便能
23、够在 IE 中也正确显示地图中的折线,需要在html 标签中增加对 VML 命名空间的声明 这个很容易忽略,导致你在 IE 里的折线不能正常显示,所以把这一点单列出来加以强调。3 、对于通用的浏览器兼容性检查,地图 API 提供了一个全局方法 GBrowserIsCompatible()来保证地图 API 是在它所兼容的浏览器里运行的,这个兼容浏览器列表我也没找到最新的,谷歌文档里给出了一个远古时代的列表,所以不列也罢,对我们目前通用的FireFox 、 IE 、 Safari 、 Opera 浏览器里运行地图 API 都没有问题。 这里只说一下 GBrowserIsCompatible()
24、这个方法的使用:从名字也可以看出,GBrowserIsCompatible() 方法返回一个 boolean 类型的值,所以,把我们对地图操作的起点放在对这个方法返回值的判断块中,形如:if(GBrowserIsCompatible()/ 开始创建和操作地图 else / 如果有必要,就在这里定义你对这个异常的处理当然,在你自己的代码中,针对不同的浏览器环境你还是需要自己实现兼容性的代码,这里的 GBrowserIsCompatible() 只是保证地图 API 类库是在它兼容的环境中运行的。4 、注册你要发布页面所在网站的谷歌地图 API 密钥,替换掉示例代码里的 key ,我 在这里详细解
25、释过这个密钥 ,不多说了。 5 、为了保证你的页面在任何可用的网络环境下都能快速加载并且正确显示,建议定义 body元素的 onload 方法,在 onload 方法中开始你的 JS 动作。同时,把读入地图 API 的 script标签放在 head 元素中,而把你自己的 JavaScript 代码块放到 body 标签的后面去定义。如果对浏览器的加载顺序比较熟悉的话,你就不必遵守我说的规则了,自由定义你认为应该的 JavaScript声明顺序。 6 、为了避免 JavaScript 中引用页面的 DOM 元素可能存在的内存泄漏 ( 尤其是在 “ 伟大的 ”IE 浏览器中 ) ,你需要使用地图
26、 API 中定义的 GUnload() 方法作为你的 body 元素的onunload 方法,并且最好把这个作为一个必须的规则记住。但是 GUnload() 方法不是避免内存泄漏的大力丸,所以,你在自己的代码中还是需要注意避免内存泄漏这个问题。 7 、为了能够在页面上正常显示中文,需要把页面的字符集定义为 utf-8 。所以,一个完整的应用谷歌地图 API 的页面代码如下:我的谷歌地图function initialize() if (GBrowserIsCompatible() var map = new GMap2(document.getElementById(“mapContainer
27、“);map.setCenter(new GLatLng(33.0, 106.0), 3);怎样在你的网页里嵌入地图 要想在自己的网页中嵌入地图,常用的方法可以归纳为以下几种: 1 、最简单的方法 使用谷歌地图主页的 “ 链接 “ 如果你只需要在自己的页面上显示某个特定范围的地图,比如你的公司所在地,但是不需要在地图上添加任何额外的内容,比如标记、折线等等,那么,使用这个方法来嵌入谷歌地图是最简单的。 登录 谷歌地图主页 ,定位你需要显示的范围后,点击地图左上角的 “ 链接 ” ,会出现一个信息框,给出两个输入框,把第二个输入框中的内容拷贝到你的页面上就可以了。 其实,这段嵌入代码就是一个 i
28、frame 的声明,所以,虽然地图主页提供一个自定义地图并预览的功能,但是只能自定义地图的大小,如果需要的话,我们完全可以通过手动修改这个 iframe声明来实现更多的自定义,比如,给这段 iframe 加上自定义的样式。 2 、最精简的方法 使用谷歌静态地图 如果你需要显示某个特定范围的地图,而且需要在地图上加上一些标记、折线。但是,你并不在乎你网页上的地图能否拖拽,那么,这个静态地图应该就是你需要的了。 所谓静态地图,意思就是你在页面上嵌入的其实只是一个 GIF 图片,这个 GIF 图片是你通过 URL 从谷歌动态获取的,这样的嵌入地图就有别于我们常用的 “ 动态 ” 地图了,而且,加载这
29、样的地图,比加载一个完整的地图要快捷的多。 要在你的页面上使用这样的静态地图,只需要使用一个 img 标签,把这个标签的 src 属性指定为谷歌静态地图的 url 就可以了。 看一个简单的静态地图URL : http:/ )在你的 JavaScript 代码中 new GMap2(document.getElementById(“your map containers id“);4 )使用 GMarker 、GPolyline 等 API 中提供的类定制你要在地图上添加的标记、折线等等。详细的创建谷歌地图过程可以看看我的 “ 使用 JavaScript 创建地图步骤详解 ” 。但是,要想自如的
30、使用这个 API ,你需要具备一定的 JavaScript 知识和动手能力,此外,强烈建议你先读读谷歌地图 JavaScript API 的开发指南 ,能够解决你的一些常见疑问,当然了,你也可以在我的博客里找找你想了解的知识。除了上面说的这几种方法,其实还有一些比较少用的方法也可以在网页中嵌入地图,比如使用Google Gadget API ,我在博客右边栏嵌入的地图使用的就是 Gadget API 。如果你不需要在自己的页面中嵌入地图,或者,你没有自己的网站,那么,使用 Mapplet API也是一个不错的创建你自己的地图的方式。这是一个可以在谷歌地图主页上 “ 我的地图 ” 中运行的小程序
31、,它的 API 其实就是谷歌地图 API 的一个子集,因为要在谷歌地图主页中嵌入,所以与谷歌地图 API 稍稍有一些不同。详细情况可以参考一下 Mapplet API 的开发文档 。谷歌地图坐标系统总结 要在地图中定位一个点,最常见的就是使用一个地理坐标来定位。但是,谷歌地图 API 还提供了不同于地理坐标的多套坐标系统,方便我们在需要的时候使用不同的坐标来定位在地图上显示的信息。我在右边的地图中演示了这些坐标,可以把的鼠标移到地图上看看,注意要展开 “ 鼠标位置 ”的内容啊 :) 。 这些坐标系统可以简单的总结如下(这些系统是我自己命名的,呵呵,有些系统我也不知道应该怎么称呼): 1 、地理
32、坐标系统 地理坐标纵向以赤道所在维度线为原点,分别向南北极延伸,最大值为 90 。横向以格林威治天文台旧址所在的经度线(本初子午线)为原点,分别向东西延伸,最大值为 180 。海拔坐标在这里就暂时忽略吧。 地理坐标的表示方式主要有两种:一种是以度分秒 / 度分的方式表示,比如( 3956N , 11620E ) ;还有一种是使用十进制数的方式表示,比如( 39.9333 , 116.3333 ) 。在表示一个地理坐标的时候,习惯上都使用先纬度后经度的顺序来描述一个坐标,并且,对前一种坐标,是使用追加字母缩写的方式表示方向,而在后一种方式中,一般会使用 X 轴表示经度, Y 轴表示纬度,按照上北
33、下南左西右东的的原则来给坐标加上对应的符号,所以,对( 39.9333 , 116.3333 )我们通常就理解为北纬 39.9333 度、东经 116.3333 度。 在谷歌地图 API 中使用后一种方式来表示地理坐标,并使用 GLatLng 这个类来规范的定义一个地理坐标,该类的构造函数中,第一个参数是纬度,第二个参数是经度。需要注意的是,这两个参数的顺序不同于我们在坐标系中先 X 后 Y 的表达方式,而是按照地理坐标先纬度后经度的习惯来表示一个地理坐标,这个原则基本适用于地图 API 中所有需要表达地理坐标的地方。 2 、图块坐标系统 谷歌地图是使用一系列的大小相同的图片拼接起来的,这些图
34、片在谷歌地图中称之为图块( Tile) 。所以,你可以把谷歌地图理解为是使用图块 / 图片填充起来的一系列网格,在不同的缩放级别,地图被分解为不同数目的网格。详细的说,在缩放级别为 0 的时候,整个世界地图只有一个网格,缩放级别每增大一级,所有的网格在横向和纵向就分割一次,也就是说,对应于某一特定的缩放级别 N ,网格的数目就是 4 的 N 次方,即 4 N 。这些网格所组成的坐标系统,就是图块坐标系统。 在图块坐标系统中,以缩放级别为 0 时的世界地图为原点,在缩放级别增大的时候分别向下(Y 轴)和向右( X 轴)延伸,这样,在指定的缩放级别,我们就可以用一个坐标来指定特定的图块了,如果你有
35、意用你自己的图片替换掉地图中的某个图块,这个坐标系统就能派上用场了。谷歌地图 API 中还没有一个直接的方法可以取得图块的坐标,要取得这个坐标,你需要继续往下看。 3 、像素坐标系统 上面说到谷歌地图是由一系列大小相同的图片拼接起来的,其实这些图块的大小也是固定的,都是 256256 像素大小,所以,在不同的缩放级别,世界地图的像素大小也是固定,比如在缩放级别为 0 的时候,世界地图的像素大小就是 2562564 0 。这样,在特定的缩放级别,因为世界地图的像素大小是固定的,组成世界地图的所有像素点就可以形成了一个完整的坐标系统,我们也就可以用像素坐标代替地理坐标指定地图上的某个点,这个坐标系
36、统就是像素坐标系统。 像素坐标系统以缩放级别为 0 时的世界地图的左上角为原点,使用与图块坐标系统相同的 X轴和 Y 轴,在缩放级别增大的时候分别向下和向右延伸。像素坐标与地理坐标可以相互转换,他们之间的主要区别在于,像素坐标是平面的二维坐标,而地理坐标是曲面的二维坐标(不考虑海拔坐标) 。 在谷歌地图 API 中,可以使用 GProjection.fromLatLngToPixel(latlng, zoom) 这个方法通过地理坐标得到对应的像素坐标,相反的,可以使用 GProjection.fromPixelToLatLng(pixel, zoom) 这个方法由像素坐标得出对应的地理坐标。
37、现在,我们在看看如何通过像素坐标获取对应的图块坐标。上面已经提到每个图块都是256256 像素的固定大小,所以,使用像素坐标值除以 256 并取整,就可以得到这个像素坐标所在的图块坐标了。使用代码说话: Math.floor(x / 256) , x 就是像素坐标的 x 值,这个表达式得到的结果就是像素所在图块的横坐标,纵坐标算法相同。 4 、 DOM 相对坐标系统 这里的 DOM 是指页面上装载地图的容器,一般是 div 元素。把这个坐标系统看作是基于 DOM元素而不是基于地图的坐标系统或许更易于理解,这个系统里的坐标指定的是某个点在这个 DOM 容器里的位置,以这个容器的左上角为原点,分别
38、向下( Y 轴)和向右( X 轴)延伸。所谓相对坐标,是指这个坐标系统相对地图是固定的,原点不会随地图的拖拽而变化。 在谷歌地图 API 中,使用 GMap2.fromLatLngToContainerPixel(latlng) 可以取得地图上某个点在 DOM 容器中的位置,相反,你可以通过 GMap2.fromContainerPixelToLatLng(pixel)方法来获取 DOM 容器中某个位置在当前地图上的坐标。 这个坐标系统在你需要在 DOM 容器上添加一些自定义控件并与地图交互的时候可能会有用。 5 、 DOM 绝对坐标系统 这个坐标系统是相对上一个系统来说的,从字面可以理解为这
39、是定位在地图上而不是相对地图的坐标系统,如果你在加载地图后只是缩放而没有拖拽地图,那么你会发现这个坐标系统和 DOM 相对坐标系统是重合的。但是,一旦你拖拽地图,就会发现他们的差别了,实际效果你可以在右边的地图里试试。结论就是,这个坐标系统的原点是与 DOM 容器的左上角重合的地图上的点,在拖拽地图的时候原点会随着地图变化,原点左边和上面的点使用负值表示。 这个坐标系统中的坐标和地图上的地理坐标可以用 GMap2.fromLatLngToDivPixel(latlng) 、GMap2.fromDivPixelToLatLng(pixel) 这两个方法实现相互转换,在你自定义地图上的叠加层的时候
40、,这两个方法就可以派上用场了。 有一个问题我还没完全理清,就是在 DOM 容器里出现多个世界地图的时候,也就是 DOM 容器足够大的容纳下多个世界地图的图块时, DOM 相对坐标和 DOM 绝对坐标这两个系统显示的坐标似乎有点紊乱,如果你理清了,找出了规律,欢迎共享出来。 最后提一下 GSize ,在说到地理坐标系统的时候我提到了 GLatLng ,这是在谷歌地图 API 里对地理坐标的规范表达,而在表示非地理坐标的时候,就需要用 GSize 这个类了,这是对以像素为单位的坐标的规范表达,和 GLatLng 不同的是,它的构造函数中第一个参数表示 X 轴的坐标,第二个参数表示 Y 轴的坐标。使
41、用谷歌地图 API 实现自定义控件 收藏使用谷歌地图 API 定义自定义的控件其实非常简单,看看我在右边地图的右上角添加的半透明的状态监控栏,这就是一个自定义的控件。 闲话少说,先看一段 Hello World 的代码 function MyControl()MyControl.prototype = new GControl();MyControl.prototype.initialize = function(map)this.map = map;var container = map.getContainer();var label = document.createElement(“d
42、iv“);container.appendChild(label);lable.innerHTML = “Hello World“;return label;MyControl.prototype.getDefaultPosition = function()return new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(50, 10);上面这段代码中, MyControl 就是一个自定义的控件了,在需要的时候,和添加其他默认控件一样,使用 map.addControl(new MyControl() 就可以在地图上添加这个自定义的控件了,只不
43、过这个控件现在也没什么实际用处,就是在你的地图容器的顶部显示一个 Hello World 的文本,与地图没什么交互。 下面来详细解释一下这段代码: 第一行定义了一个 MyControl 类; 接下来,把这个类定义为 GControl 类的子类,就是把 MyControl 的 prototype 指定为GControl 类的实例 / 对象; 后面的两个方法 initiallize 和 getDefaultPosition 是继承 GControl 类的时候必须实现的两个方法, API 文档 里定义 GControl 是接口类,所以可以把这两个方法认为是抽象方法,就不难理解为什么必须要实现了。需要
44、注意的是,这两个方法我们只负责实现,但是不需要我们去显式的调用,在向地图上添加控件时 API 类库会自动调用这两个方法。 方法 initialize 接受一个参数 map ,就是你创建地图时 new 出来的 GMap2 对象。在这个方法中,你使用 map.getContainer() 方法取得放置地图的 DOM 容器,然后,你就可以向这个 DOM 容器里添加任何你想加入的 DOM 元素了。在上面的示例中我创建了一个 div 元素,用来显示 Hello World ,但是,你可以在这里加入任何你想添加的 DOM 元素,并且可以定义它们的行为,也就是说,这里就是你可以自由发挥的天地了,无论你是想显
45、示动态的信息,还是来控制地图,比如右边地图里的状态监控栏。 initialize 方法最后需要返回你所创建的最外层的 DOM 元素,这个千万别忘了。方法 getDefaultPosition 的作用是定义你的控件在地图容器里的位置,实现起来就更简单了,你可以直接把我这里的代码 copy 过去,改成你需要定位的地方就可以了。 GControlPosition 的第一个参数是你的控件的锚点,只能使用G_ANCHOR_TOP_LEFT 、 G_ANCHOR_TOP_RIGHT 、 G_ANCHOR_BOTTOM_LEFT 、 G_ANCHOR_BOTTOM_RIGHT 这四个代表上左、上右、下左、下
46、右这四个角的常量,后一个参数使用 GSize 来定义你的控件距离地图容器边界的偏移量,第一个参数是横向偏移、第二个参数是纵向偏移。 到这里一个自定义的控件就完成了,没什么复杂的吧?刚才看到 论坛里 有朋友问怎么能把自己的 LOGO 和地图左下角 Google 的 LOGO 并排放在一起,看了自定义控件,你一定知道怎么做了吧。不过,千万别想用你的 LOGO 覆盖 Google 的 LOGO 哦,基本的版权意识咱们还是应该有的,就像你也希望别人能够尊重你的劳动成果一样!使用 GMapOptions 定制你的谷歌地图 收藏前我曾经解释过创建一个地图的详细步骤 ,但是,真正创建地图的核心步骤也就两行代
47、码:var map = new GMap2(document.getElementById(“mapContainer“);map.setCenter(new GLatLng(33.0, 106.0), 3);有这两行代码,你就可以在你的网页上展现你的谷歌地图了。但是,这个是最简单的地图,如果你想要对这个地图做一些小小的变动,更符合你的胃口,可以使用 GMapOptions 来尝试定制地图。简单的说,GMapOptions 是你在 new 一个 GMap2 对象的时候,可以直接使用对象变量的形式作为可选参数传递给 GMap2 的构造函数,GMapOptions 自己没有构造函数(地图 API 中类构造函数的可选参数多用这种形式来定义) ,比如:var options =