Google Maps API 是 Google 自己推出编程 API ,可以让全世界对 Google Maps 有兴趣的程序设计师自行开发基于 Google Maps 的服务,建立自己的地图网站。以下是我在 Google Maps API 开发过程中找到的一些 API 的编程资源,包括中文文档,中文说明,示例等等,希望对 Google Maps 编程感兴趣的程序员有所帮助。
中文资料部分 (包括中文的文档说明等,以下的网址都是中文内容。)
下面的关于 API 的中文文档
Google Maps API 第 2 版中文文档 http://www.step1.cn/GoogleApi/map2/documentation.htm
Google Maps API 第 2 版升级指南 http://www.step1.cn/GoogleApi/map2/upgrade.htm
Google Maps API 第 2 版类参考 http://www.step1.cn/GoogleApi/map2/reference.htm
另外一个版本的 Google Maps API 2 中文文档 http://www.zmap.org/doc/maps/documentation/
Google Maps API 第 1 版中文文档 http://www.step1.cn/GoogleAPI/map/documentation.htm
下面是关于 KML 文件的中文文档
Google Earth KML 中文说明(一) http://gisman.bokee.com/5294713.html
Google Earth KML 中文说明(二) http://gisman.bokee.com/5294722.html
Google Earth KML 中文说明(基于 Google Earth 客户端版本 3.0 的 KML 版本 2.0 ) http://www.step1.cn/googleapi/map/kml.htm
英文资料部分 (主要是 Google 官方的文档说明,如果觉得中文翻译的有问题,也可以看看这些原始内容。 )
Google Maps API 官方网 http://www.google.com/apis/maps/
Google Maps API 英文文档 http://www.google.com/apis/maps/documentation/
Google Maps API 官方 Blog http://googlemapsapi.blogspot.com/
Google Maps API 论坛 http://groups.google.com/group/Google-Maps-API
Google KML 的官方文档 http://earth.google.com/kml/
Google API 官方网 http://code.google.com/
附: Google Map API 中文开发教程
Google Map API 中文开发教程最好的教程还是 google 官方的说明文档,而且配有详细的例子,供大家学习,下面是文档的英文原文连接 http://www.google.com/apis/maps/documentation/index.html
目录包括
1. 面向的读者
2. 简介
1. “ Hello World ” 程序
2. 浏览器兼容性
3. XHTML 和 VML
4. API 更新
5. 地理译码
6. 行程规划和本地搜索
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
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_jcU4BRlfWJrPzRGiYSzS4l55_z1ea3VShRolPwARGHvivnEFRLVGXyIlsrYpA
使用谷歌地图 API 的第一步就是要 注册一个 API 密钥 , 谷歌的 API 使用条款 对这个密钥的用途有很正式的说明,其实总结起来也很简单:
1 、谷歌地图 API 提供的服务是免费的,对于通过 API 正常使用谷歌地图的网站基本没有任何限制;
2 、说 “ 基本 ” 没有限制的原因是,谷歌对每个 API 密钥对应的网站所作的 地理编码 / 地址解析 请求次数有限制,每天( 24 小时)的请求次数不能超过 15000 次;
3 、不能使用谷歌地图从事任何非法的行为,否则谷歌应该能够通过这个密钥阻止你的网站使用谷歌地图;
更简单的说,谷歌使用这个密钥保证能够对所有 API 用户 / 网站进行区分,方便必要的时候对 “超常规 ” 用户进行阻拦。
对于地址解析的次数限制,一般来说不会有什么影响,这里主要说 API 密钥,所以以后有时间可以再详细说说地址解析相关的东东。
对于 API 密钥,还有几点需要记下来:
1 、如果使用 API 的页面还没有发布,只是在本地调试,可以不用密钥,随便用个字符串代替就可以了;
2 、 API 密钥只对网站目录或者域有效,所以,虽然你是使用同一个谷歌帐号登录后注册的密钥,但是,对不同域的网页,需要用这些域分别注册不同的密钥,对于同一个域里的页面,直接拿你网站的域名注册一个,在这个域里的所有页面就可以通用这个密钥了。
还有一个关于 API 密钥的实际问题:
在论坛里还有人问过,同一个页面需要支持不同的域名,最简单的就是公司有一个 cn 域名,也有一个 com 域名,这怎么办?
其实,对于这种问题,可以提前先注册好不同域名对应的密钥,存在你的JS 变量里面,页面加载时通过window.location 得到当前请求页面的域名,通过这个域名在找到对应的密钥,然后使用script 动态加载的方法加载地图API ,用代码描述就是:
// 事先已经注册好的密钥
var keyMapping = {host1:key1, host2:key2};
// 实际请求页面的域名
var requestHost = window.location.hostname;
// 找到需要的密钥
var key = keyMapping[requestHost];
// 构造加载API 的script url
var apiUrl = "http://ditu.google.com/maps?file=api&v=2&key=" + key;
// 使用script 动态加载的方法加载地图API
var scriptTag = document.createElement('script');
scriptTag.setAttribute('type', 'text/javascript');
scriptTag.setAttribute('src', apiUrl);
document.getElementsByTagName('head')[0].appendChild(scriptTag);
使用这段代码时,需要注意把你自己的JS 代码中对API 的各个类的调用放在API 加载完成以后,详细的解释可以先google 一下著名的DomReady 的问题 ,三言两语还是说不清楚的,呵呵。
这段代码我没有实际跑过,欢迎斧正,如果你有更好的方法,我更愿意洗耳恭听了。
这些内容,常用谷歌地图的应该也都知道,我也只写我知道的,了解这些对使用 API 还是有帮助的。
1 、 谷歌地图主页
谷歌地图对应不同的地区都会有一些专门的主页,首次登陆时会显示这些地区,比如,香港的: http://maps.google.com.hk ,台湾的: http://maps.google.com.tw ,日本的: http://maps.google.co.jp
不过,我们常用的也就三个:
http://maps.google.com 这个应该是谷歌地图的全球主页,默认显示老美地图,拖拽到不同地区会对应显示不同语言版本的地图,不过目前对中文数据搜索支持的不如下面正式的中文主页;
http://ditu.google.com 这个么,我叫它是谷歌地图的中文主页,什么意思看下一个你就知道了,用这个可以使用 “ 我的地图 ” ;
http://ditu.google.cn 这个,我叫他是谷歌地图的大陆主页,目前还没有 “ 我的地图 ” 这个功能;
后面这两个主页只能显示大陆地区的详细地图,如果想看别的地区的,就只能用全球主页了。
当然,别以为你抓着漏洞可以注册个 maps.google.cn ,然后卖给谷歌,不信你试试 maps.google.cn,看它跳到哪里了 :)
2 、谷歌地图的类型
其实,谷歌地图的类型主要也就三种:
普通地图:历史悠久的人工绘制地图,不多说了,不知道的给我留个地址,我快递个板砖给你;
卫星地图:用卫星图片拼成的地图,不同地图的显示精度有区别,现在中文主页上也有了,曾经可是被禁止的,怕你偷看海南的黑鱼;
地形地图:用等高线标出海拔的地图,对地理教学和教育相关的相当有用,当然,对军迷也超级有吸引力,不展开 !
把这三种组合起来 ( 主要是普通地图和卫星地图的组合 ) ,或者在这些地图上添加其他的数据,就又有一些新的类型了,这个层出不穷,我只说主页上现有的:
混合地图:就是把普通地图和卫星地图结合,在卫星地图上显示行政区、街道等等,在全球主页上把鼠标移到 “ 卫星 ” 按钮上,会跳出来一个 “ 显示标签 ” 的复选框,选中后地图就是这个类型了,中文还没支持,不知道什么时候可以用;
交通地图:在地图上显示交通信息。这个理论上是实时的,不过,在目前的中文地图上,吸引眼球的作用更大一些,如果能在手机版上使用就好了(貌似目前还没有),而且只有北京和上海有数据支持;
街景地图:这个和交通地图一样,严格上不算是一种地图类型,就是使用 Flash 来显示街道的全景图,我也在等中文地图支持街景了(中文 API 已经支持 StreetView 相关的类了,就是没有数据),不久前看到的消息是目前谷歌对这个没有时间表,呵呵,他是 “ 万事俱备,只欠东风 ” ,努力吧!
在地图 API 中,后面组合的这三种除了混合地图算作是一种地图类型外,其他两个都不算是地图类型,被看着是在地图上新增的层(术语:叠加层 /overlay )。
3 、谷歌地图的数据源
谷歌是一个服务提供商,而不是一个内容提供商,所以,准确的说,谷歌地图向终端用户提供的是基于地图的搜索服务。从这一点上,可以把谷歌地图上的数据分为三类:
地理数据:地理、空间信息,包括经纬坐标、航拍 / 卫星图片、行政区划以及据此绘制的图片等等,由谷歌或其合作伙伴持有;
商业数据:与地理相关的商业数据,比如餐馆、影院、交通、景点等等,这也是由谷歌或其合作伙伴持有,谷歌可能对这些数据有一个采集、过滤、整理的再加工过程。想被客户搜索到,就来这里 标注自己的公司 吧;
用户数据:用户使用谷歌地图 API 定制地图并在地图上标注的数据,这些数据由用户持有。
这样,通过这个分类,我们可以解决两个非常常见的疑问:
1 )使用谷歌地图 API ,地图上的数据存在哪里?
你是你的我是我的。是谷歌提供的数据,由谷歌负责;如果是你自己提供的数据,当然由你负责保存,谷歌相当于给你一个展示数据的平台,除非你愿意把自己的数据无偿贡献给谷歌 :)
2 )使用谷歌地图 API ,终端用户会通过谷歌搜索到我的数据吗?
对谷歌地图来说,他的数据源只有地理数据和商业数据,所以在谷歌地图主页上不会搜到你的数据。但是,你可以在你的地图上定制谷歌搜索的数据源,使得用户可以搜索你的数据。(不是很肯定的哦,要看你的具体情况的)
4 、 谷歌地图 API
谷歌地图 API 就是一系列使用 OO 方式组织的 JavaScript 类和静态方法(我有时候也统称为地图 API 类库),通过创建这些类的实例(对象)或调用 API 中提供的静态方法,可以在页面上创建和控制地图,也可以在地图上展示任何非谷歌提供的数据 / 信息。谷歌地图 API 只涉及浏览器 / 客户端相关的技术,比如 JavaScript 、 HTML DOM 、 CSS 等,不涉及任何服务器端的技术,或者说,你可以基于任意你需要的服务端使用谷歌地图 API (所以,这里面能够展开的东东就太多了,以后再总结吧,我也在学习)。
谷歌地图的 API 类库是通过 script 标签导入的,形式如下:
我们使用API 的时候关心的就是这个script 的src 属性了,这个属性也就两个部分:路径:http://ditu.google.com/maps ; 参数:file=api&hl=zh-CN&v=2&key=abcdefg 。
解剖一下:
1 、 路径: http://ditu.google.com/maps
路径在这里需要注意的就是它的域名: ditu.google.com 。
这个和 谷歌地图简单背景 里介绍的谷歌地图主页的问题类似,就是说,我们主要可以使用 maps.google.com 、 ditu.google.com 、 ditu.google.cn 这三个域名,有些区别和说明:
1 ) 如果你需要在地图上显示大陆以外的详细地图,就非 maps.google.com 莫属了,不过,这个域名对国内地理数据的查询 ( 比如查询地址、路线等等 ) 支持能力有限,如果你这方面有需求就要小心了,而且,这个应该是使用的国外的服务器,所以,访问速度也需要注意;
2 )相反,如果你需要使用谷歌提供的与国内地理数据查询相关的 API ,就是用 ditu.google.com 吧,使用这个域名的缺点就在于它和 maps.google.com 提供的类库不是完全一致,更新稍微有点滞后,而且,受限于国内数据源在法律等方面的限制,有些功能方面的支持也会受限,比如地址解析(现在已经放开了,这里只是拿来举例);
3 )至于 ditu.google.com 和 ditu.google.cn 的区别,我也很糊涂,如果你很想做个听话的好公民,不出一丝差错,那么 .cn 可能会比 .com 更让你放心一点吧,臆测,呵呵。
总得来说,一般的应用使用 ditu.google.com 就可以了,如果需要使用大陆以外的详细地图,就考虑使用 maps.google.com 吧。不过,因为使用了相同的命名空间,这两者在一个页面中不能共存,所以,可以考虑用两个 iframe 来动态切换,这里有个 火炬传递 的例子,就是这么实现的,咱当初也贡献过一把。
2 、 参数:file=api&hl=zh-CN&v=2&key=abcdefg
1 ) file=api
这个是请求API 的JS 文件用的,少不了,不需多说;
2 ) hl=zh-CN
这个是在设定地图上除了地图图片以外的诸如控件名称、版权声明、使用提示等所需要显示文本的语言版本时候用的,如果没有指定这个参数就使用 API 的默认值,对 ditu.google.com 来说,默认是中文简体, maps.google.com 默认的是英文。其他的语言版本在这里有一个 简单的英文说明 (好像好久没更新了)。
3 ) v=2
这个是用来指定需要导入的 API 类库的版本号,可以有四种设定方式:
v=2.s 稳定版本,更新最慢,但是最可靠;
v=2 当前版本(只用主版本号),更新速度和可靠性介于 s 和 x 之间;
v=2.x 最新版本,更新最快,包括最新功能,可能没有当前版本可靠;
v=2.76 指定版本。不建议使用。
目前谷歌地图 API 的主版本号是 2 ,这是从 2006 年 4 月开放的版本,对之前的第 1 版做了一些比较重要的升级,不过估计国内用第 1 版的应该很少,所以也没必要多说了,注意第二版里定义地图对象时使用 GMap2 而不是 GMap 就可以了,否则可能会导致一些奇怪的问题,我是见过这样的。
多罗嗦两句,谷歌地图 API 正常情况下还是相当稳定的,不过也有一些比较著名的 Bug ,比如超长的 Polyline 在某些特定环境下可能会显示不正常。万一有什么问题可以去这里 找找是不是别人报过的 Bug (英文版),当然,更简单的办法是到谷歌地图 API 论坛里问问,不过别忘了把你的问题、运行环境描述清楚。我碰到过很多次这样的情况:对 JavaScript 或者浏览器端的某些技术特性不是很了解,出了一些奇怪的问题,撂一句话就走人,唉,就不评论了, “ 活到老学到老 ” 还是很有道理的。
4 ) key=abcdefg
这个是设定你注册的 API 密钥,我 在这里费了不少口舌 ,不是很了解的话可以看看。
一段经过精简的代码:
对这段代码的详细解释
上面的这段代码就是创建一个地图的核心步骤:
1 、导入地图 API 类库。
注意这里的参数key ,我在以前的文章里已经详细解释过了,如果你只是在本地运行,暂时可以不用管它。
2 、在页面的 body 元素中定义一个地图容器。
2 、为了兼容 “ 伟大的 ”IE 浏览器,以便能够在 IE 中也正确显示地图中的折线,需要在 html 标签中增加对 VML 命名空间的声明
这个很容易忽略,导致你在 IE 里的折线不能正常显示,所以把这一点单列出来加以强调。
3 、对于通用的浏览器兼容性检查,地图 API 提供了一个全局方法 GBrowserIsCompatible()来保证地图 API 是在它所兼容的浏览器里运行的,这个兼容浏览器列表我也没找到最新的,谷歌文档里给出了一个远古时代的列表,所以不列也罢,对我们目前通用的 FireFox 、 IE 、 Safari 、 Opera 浏览器里运行地图 API 都没有问题。
这里只说一下GBrowserIsCompatible() 这个方法的使用:
从名字也可以看出,GBrowserIsCompatible() 方法返回一个boolean 类型的值,所以,把我们对地图操作的起点放在对这个方法返回值的判断块中,形如:
if(GBrowserIsCompatible()){
// 开始创建和操作地图
} else {
// 如果有必要,就在这里定义你对这个异常的处理
}
当然,在你自己的代码中,针对不同的浏览器环境你还是需要自己实现兼容性的代码,这里的GBrowserIsCompatible() 只是保证地图API 类库是在它兼容的环境中运行的。
4 、注册你要发布页面所在网站的谷歌地图 API 密钥,替换掉示例代码里的 key ,我 在这里详细解释过这个密钥 ,不多说了。
5 、为了保证你的页面在任何可用的网络环境下都能快速加载并且正确显示,建议定义 body 元素的 onload 方法,在 onload 方法中开始你的 JS 动作。同时,把读入地图 API 的 script 标签放在 head 元素中,而把你自己的 JavaScript 代码块放到 body 标签的后面去定义。如果对浏览器的加载顺序比较熟悉的话,你就不必遵守我说的规则了,自由定义你认为应该的 JavaScript 声明顺序。
6 、为了避免 JavaScript 中引用页面的 DOM 元素可能存在的内存泄漏 ( 尤其是在 “ 伟大的 ”IE 浏览器中 ) ,你需要使用地图 API 中定义的 GUnload() 方法作为你的 body 元素的 onunload 方法,并且最好把这个作为一个必须的规则记住。但是 GUnload() 方法不是避免内存泄漏的大力丸,所以,你在自己的代码中还是需要注意避免内存泄漏这个问题。
7 、为了能够在页面上正常显示中文,需要把页面的字符集定义为 utf-8 。
所以,一个完整的应用谷歌地图API 的页面代码如下:
"-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtmll/DTD/xhtmll-strict.dtd">
要想在自己的网页中嵌入地图,常用的方法可以归纳为以下几种:
1 、最简单的方法 —— 使用谷歌地图主页的 " 链接 "
如果你只需要在自己的页面上显示某个特定范围的地图,比如你的公司所在地,但是不需要在地图上添加任何额外的内容,比如标记、折线等等,那么,使用这个方法来嵌入谷歌地图是最简单的。
登录 谷歌地图主页 ,定位你需要显示的范围后,点击地图左上角的 “ 链接 ” ,会出现一个信息框,给出两个输入框,把第二个输入框中的内容拷贝到你的页面上就可以了。
其实,这段嵌入代码就是一个 iframe 的声明,所以,虽然地图主页提供一个自定义地图并预览的功能,但是只能自定义地图的大小,如果需要的话,我们完全可以通过手动修改这个 iframe声明来实现更多的自定义,比如,给这段 iframe 加上自定义的样式。
2 、最精简的方法 —— 使用谷歌静态地图
如果你需要显示某个特定范围的地图,而且需要在地图上加上一些标记、折线。但是,你并不在乎你网页上的地图能否拖拽,那么,这个静态地图应该就是你需要的了。
所谓静态地图,意思就是你在页面上嵌入的其实只是一个 GIF 图片,这个 GIF 图片是你通过URL 从谷歌动态获取的,这样的嵌入地图就有别于我们常用的 “ 动态 ” 地图了,而且,加载这样的地图,比加载一个完整的地图要快捷的多。
要在你的页面上使用这样的静态地图,只需要使用一个 img 标签,把这个标签的 src 属性指定为谷歌静态地图的 url 就可以了。
看一个简单的静态地图 URL : http://ditu.google.cn/staticmap?center=39.915175,116.389332&zoom=14&size=500x300&key=YOUR_KEY_HERE
在这个 URL 中,你可以编辑 center 、 zoom 、 size 这些参数来指定地图的中心点、缩放级别、地图大小等等,当然,如果需要在地图上添加标记、折线,你还可以加上对应的参数。不过,不用担心你要记住这么多参数,这里有一个 定制静态地图的向导 ,简单的几步就可以得到你需要的 URL 了。如果有兴趣,可以去研究一下 谷歌静态地图的 API 文档 。
严格来说,谷歌静态地图也是谷歌地图 API 的一种,所以,使用静态地图是需要你的谷歌地图API 密钥的,如果你之前定义过地图 API 的密钥,直接 copy 过来就可以了,不需要再去注册。如果你不知道密钥是怎么回事,那就看看 我之前对密钥的解读 吧。
3 、最自由的方法 -- 使用谷歌地图 API
如果上面两种方式都不能满足你的需求,那么,就来试试 谷歌地图 API 吧。虽然谷歌地图 API 已经细分为 JavaScript 、 Flash 、 Earth 、 Static 等等多个版本,但是,在我看来, JavaScript API 是谷歌地图 API 的根本,所以,在我的博客里,除非特别指明,说到谷歌地图 API 都是指谷歌地图 JavaScript API 。使用这个 API ,你可以用你愿意的任何可行的表现形式在地图上展现你的数据,甚至可以把你自己的地图做的比谷歌地图还漂亮。
要使用这个API 在页面中嵌入地图,简单的步骤就是:
1 )使用JavaScript 标签导入地图API 类库;
2 )在页面上定义一个装载地图的元素,通常使用一个div 标签,指定width 和height;
3 )在你的JavaScript 代码中new GMap2(document.getElementById("your map container's id"));
4 )使用GMarker 、GPolyline 等API 中提供的类定制你要在地图上添加的标记、折线等等。
详细的创建谷歌地图过程可以看看我的 “ 使用 JavaScript 创建地图步骤详解 ” 。但是,要想自如的使用这个 API ,你需要具备一定的 JavaScript 知识和动手能力,此外,强烈建议你先读读谷歌地图 JavaScript API 的开发指南 ,能够解决你的一些常见疑问,当然了,你也可以在我的博客里找找你想了解的知识。
除了上面说的这几种方法,其实还有一些比较少用的方法也可以在网页中嵌入地图,比如使用Google Gadget API ,我在博客右边栏嵌入的地图使用的就是Gadget API 。
如果你不需要在自己的页面中嵌入地图,或者,你没有自己的网站,那么,使用 Mapplet API也是一个不错的创建你自己的地图的方式。这是一个可以在谷歌地图主页上 “ 我的地图 ” 中运行的小程序,它的 API 其实就是谷歌地图 API 的一个子集,因为要在谷歌地图主页中嵌入,所以与谷歌地图 API 稍稍有一些不同。详细情况可以参考一下 Mapplet API 的开发文档 。
谷歌地图坐标系统总结要在地图中定位一个点,最常见的就是使用一个地理坐标来定位。但是,谷歌地图 API 还提供了不同于地理坐标的多套坐标系统,方便我们在需要的时候使用不同的坐标来定位在地图上显示的信息。我在右边的地图中演示了这些坐标,可以把的鼠标移到地图上看看,注意要展开 “ 鼠标位置 ” 的内容啊 :) 。
这些坐标系统可以简单的总结如下(这些系统是我自己命名的,呵呵,有些系统我也不知道应该怎么称呼):
1 、地理坐标系统
地理坐标纵向以赤道所在维度线为原点,分别向南北极延伸,最大值为 90 。横向以格林威治天文台旧址所在的经度线(本初子午线)为原点,分别向东西延伸,最大值为 180 。海拔坐标在这里就暂时忽略吧。
地理坐标的表示方式主要有两种:一种是以度分秒 / 度分的方式表示,比如( 39°56'N , 116°20'E );还有一种是使用十进制数的方式表示,比如( 39.9333 , 116.3333 )。在表示一个地理坐标的时候,习惯上都使用先纬度后经度的顺序来描述一个坐标,并且,对前一种坐标,是使用追加字母缩写的方式表示方向,而在后一种方式中,一般会使用 X 轴表示经度, Y 轴表示纬度,按照上北下南左西右东的的原则来给坐标加上对应的符号,所以,对( 39.9333 , 116.3333 )我们通常就理解为北纬 39.9333 度、东经 116.3333 度。
在谷歌地图 API 中使用后一种方式来表示地理坐标,并使用 GLatLng 这个类来规范的定义一个地理坐标,该类的构造函数中,第一个参数是纬度,第二个参数是经度。需要注意的是,这两个参数的顺序不同于我们在坐标系中先 X 后 Y 的表达方式,而是按照地理坐标先纬度后经度的习惯来表示一个地理坐标,这个原则基本适用于地图 API 中所有需要表达地理坐标的地方。
2 、图块坐标系统
谷歌地图是使用一系列的大小相同的图片拼接起来的,这些图片在谷歌地图中称之为图块( Tile)。所以,你可以把谷歌地图理解为是使用图块 / 图片填充起来的一系列网格,在不同的缩放级别,地图被分解为不同数目的网格。详细的说,在缩放级别为 0 的时候,整个世界地图只有一个网格,缩放级别每增大一级,所有的网格在横向和纵向就分割一次,也就是说,对应于某一特定的缩放级别 N ,网格的数目就是 4 的 N 次方,即 4N 。这些网格所组成的坐标系统,就是图块坐标系统。
在图块坐标系统中,以缩放级别为 0 时的世界地图为原点,在缩放级别增大的时候分别向下(Y 轴)和向右( X 轴)延伸,这样,在指定的缩放级别,我们就可以用一个坐标来指定特定的图块了,如果你有意用你自己的图片替换掉地图中的某个图块,这个坐标系统就能派上用场了。谷歌地图 API 中还没有一个直接的方法可以取得图块的坐标,要取得这个坐标,你需要继续往下看。
3 、像素坐标系统
上面说到谷歌地图是由一系列大小相同的图片拼接起来的,其实这些图块的大小也是固定的,都是 256×256 像素大小,所以,在不同的缩放级别,世界地图的像素大小也是固定,比如在缩放级别为 0 的时候,世界地图的像素大小就是 256×256×40 。这样,在特定的缩放级别,因为世界地图的像素大小是固定的,组成世界地图的所有像素点就可以形成了一个完整的坐标系统,我们也就可以用像素坐标代替地理坐标指定地图上的某个点,这个坐标系统就是像素坐标系统。
像素坐标系统以缩放级别为 0 时的世界地图的左上角为原点,使用与图块坐标系统相同的 X 轴和 Y 轴,在缩放级别增大的时候分别向下和向右延伸。像素坐标与地理坐标可以相互转换,他们之间的主要区别在于,像素坐标是平面的二维坐标,而地理坐标是曲面的二维坐标(不考虑海拔坐标)。
在谷歌地图 API 中,可以使用 GProjection.fromLatLngToPixel(latlng, zoom) 这个方法通过地理坐标得到对应的像素坐标,相反的,可以使用 GProjection.fromPixelToLatLng(pixel, zoom) 这个方法由像素坐标得出对应的地理坐标。
现在,我们在看看如何通过像素坐标获取对应的图块坐标。上面已经提到每个图块都是 256×256 像素的固定大小,所以,使用像素坐标值除以 256 并取整,就可以得到这个像素坐标所在的图块坐标了。使用代码说话:
Math.floor(x / 256) , x 就是像素坐标的 x 值,这个表达式得到的结果就是像素所在图块的横坐标,纵坐标算法相同。
4 、 DOM 相对坐标系统
这里的 DOM 是指页面上装载地图的容器,一般是 div 元素。把这个坐标系统看作是基于 DOM元素而不是基于地图的坐标系统或许更易于理解,这个系统里的坐标指定的是某个点在这个 DOM容器里的位置,以这个容器的左上角为原点,分别向下( Y 轴)和向右( X 轴)延伸。所谓相对坐标,是指这个坐标系统相对地图是固定的,原点不会随地图的拖拽而变化。
在谷歌地图 API 中,使用 GMap2.fromLatLngToContainerPixel(latlng) 可以取得地图上某个点在 DOM 容器中的位置,相反,你可以通过 GMap2.fromContainerPixelToLatLng(pixel)方法来获取 DOM 容器中某个位置在当前地图上的坐标。 这个坐标系统在你需要在 DOM 容器上添加一些自定义控件并与地图交互的时候可能会有用。
5 、 DOM 绝对坐标系统
这个坐标系统是相对上一个系统来说的,从字面可以理解为这是定位在地图上而不是相对地图的坐标系统,如果你在加载地图后只是缩放而没有拖拽地图,那么你会发现这个坐标系统和 DOM 相对坐标系统是重合的。但是,一旦你拖拽地图,就会发现他们的差别了,实际效果你可以在右边的地图里试试。结论就是,这个坐标系统的原点是与 DOM 容器的左上角重合的地图上的点,在拖拽地图的时候原点会随着地图变化,原点左边和上面的点使用负值表示。
这个坐标系统中的坐标和地图上的地理坐标可以用 GMap2.fromLatLngToDivPixel(latlng) 、GMap2.fromDivPixelToLatLng(pixel) 这两个方法实现相互转换,在你自定义地图上的叠加层的时候,这两个方法就可以派上用场了。
有一个问题我还没完全理清,就是在 DOM 容器里出现多个世界地图的时候,也就是 DOM 容器足够大的容纳下多个世界地图的图块时, DOM 相对坐标和 DOM 绝对坐标这两个系统显示的坐标似乎有点紊乱,如果你理清了,找出了规律,欢迎共享出来。
最后提一下 GSize ,在说到地理坐标系统的时候我提到了 GLatLng ,这是在谷歌地图 API 里对地理坐标的规范表达,而在表示非地理坐标的时候,就需要用 GSize 这个类了,这是对以像素为单位的坐标的规范表达,和 GLatLng 不同的是,它的构造函数中第一个参数表示 X 轴的坐标,第二个参数表示 Y 轴的坐标。
使用谷歌地图 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("div");
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()) 就可以在地图上添加这个自定义的控件了,只不过这个控件现在也没什么实际用处,就是在你的地图容器的顶部显示一个 Hello World 的文本,与地图没什么交互。
下面来详细解释一下这段代码:
第一行定义了一个 MyControl 类;
接下来,把这个类定义为 GControl 类的子类,就是把 MyControl 的 prototype 指定为 GControl 类的实例 / 对象;
后面的两个方法 initiallize 和 getDefaultPosition 是继承 GControl 类的时候必须实现的两个方法, API 文档 里定义 GControl 是接口类,所以可以把这两个方法认为是抽象方法,就不难理解为什么必须要实现了。需要注意的是,这两个方法我们只负责实现,但是不需要我们去显式的调用,在向地图上添加控件时 API 类库会自动调用这两个方法。
方法 initialize 接受一个参数 map ,就是你创建地图时 new 出来的 GMap2 对象。在这个方法中,你使用 map.getContainer() 方法取得放置地图的 DOM 容器,然后,你就可以向这个 DOM容器里添加任何你想加入的 DOM 元素了。在上面的示例中我创建了一个 div 元素,用来显示 Hello World ,但是,你可以在这里加入任何你想添加的 DOM 元素,并且可以定义它们的行为,也就是说,这里就是你可以自由发挥的天地了,无论你是想显示动态的信息,还是来控制地图,比如右边地图里的状态监控栏。 initialize 方法最后需要返回你所创建的最外层的 DOM 元素,这个千万别忘了。
方法 getDefaultPosition 的作用是定义你的控件在地图容器里的位置,实现起来就更简单了,你可以直接把我这里的代码 copy 过去,改成你需要定位的地方就可以了。
GControlPosition 的第一个参数是你的控件的锚点,只能使
用 G_ANCHOR_TOP_LEFT 、 G_ANCHOR_TOP_RIGHT 、 G_ANCHOR_BOTTOM_LEFT 、 G_ANCHOR_BOTTOM_RIGHT 这四个代表上左、上右、下左、下右这四个角的常量,后一个参数使用 GSize 来定义你的控件距离地图容器边界的偏移量,第一个参数是横向偏移、第二个参数是纵向偏移。
到这里一个自定义的控件就完成了,没什么复杂的吧?刚才看到 论坛里 有朋友问怎么能把自己的 LOGO 和地图左下角 Google 的 LOGO 并排放在一起,看了自定义控件,你一定知道怎么做了吧。不过,千万别想用你的 LOGO 覆盖 Google 的 LOGO 哦,基本的版权意识咱们还是应该有的,就像你也希望别人能够尊重你的劳动成果一样!
前我曾经解释过创建一个地图的详细步骤 ,但是,真正创建地图的核心步骤也就两行代码:
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 = {size:GSize(400, 300), backgroundColor:"#FF0000"};
var map = new GMap2(document.getElementById("mapContainer"), options);
这里options 就是一个GMapOptions ,size 、backgroundColor 就是他的选项。
在 GMapOptions 中,我们可以定义以下这些属性来指定地图的某些特性:
1 ) size
默认情况下,你创建的地图大小就是你给定的地图容器的大小,所以,通常情况下,你需要显式的声明你的地图容器的 width 和 height 属性,否则,地图是不能正常显示的。但是,有了 size 这个可选属性后,你就多了一个选择了。你可以在创建地图的时候直接通过 size 这个属性指定地图的大小,而不需要听命于地图容器了,即使这个地图容器已经显示的定义了 width 和 height 的大小。当然, size 属性对应的值是一个 GSize 类型的数据,比如,如果给定 options={size:GSize(400, 300)} ,那么,你所创建的地图大小就是 400×300 的一个矩形块,而和你指定的容器大小无关,但是地图的左上角和地图容器的左上角还是重合的。
2 ) mapTypes
创建地图后,默认显示的地图类型是普通地图,如果要加上可以选择的卫星地图、地形地图等等其他类型的地图,可以使用 GMap2.setMapType() 方法,但这样往往会罗列一堆的 setMapType 。 GMapOptions 提供了 mapTypes 这个可选项,通过一个数组就可以给地图加上多种支持类型,比如使用 {mapTypes:[G_NORMAL_MAP,G_SATELLITE_MAP,G_PHYSICAL_MAP]} ,你的地图就拥有三种普通、卫星、地形三种类型了。 mapTypes 数组中的第一项是地图加载的默认类型,所以,如果你想默认加载卫星地图,把 G_SATELLITE_MAP 移到数组的第一项就可以了。
3 ) draggableCursor 、 draggingCursor
这两个选项是用来定义地图上你的光标类型,我把它们放在一起介绍不等于它们必须一起使用,你可以单独使用任何一个。其中, draggableCursor 是地图可拖拽状态(默认就是可拖拽的)下的光标, draggingCursor 是拖拽地图时的光标,对应的值和你在 JavaScript 里面设置其他的光标时使用的值一样,比如, {draggableCursor:"crosshair",draggingCursor:"move"} 。当然,你也可以使用 url 形式加上你自己的图标,看你发挥了!
4 ) backgroundColor
在地图图块的图片还没有传送完成之前,地图的显示区域默认会使用灰色填充,这个就是 backgroundColor 可以发挥作用的地方了,你可以把灰色换成其他任何符合 W3C 标准的颜色,比如 {backgroundColor:"#FF0000"}, 不过估计没人会喜欢用这种大红做背景的 :) 。可惜的是这里只能定义 color ,要是这个选项是 background 而不是 backgroundColor ,千方百计想打个 Logo 的兄弟就真能找着好地方了。
5 )googleBarOptions
这个和你在地图上通过GMap2.enableGoogleBar() 时有关系,指定你添加GoogleBar 时的一些默认属性,在以后说GoogleBar 的时候再来专门说吧,定制性还是很强的。
初始化一个 GMap2 对象除了可以 使用 GMapOptions 参数设置谷歌地图 外,在创建 GMap2 对象后还可以用一些方法设置地图的一些通用属性,照我的使用习惯和频率,做个分类 ( 如果我在标题后没有添加 “ 默认 ” ,则这个属性在默认状态下地图是不支持的,另外,文中的 map 指 GMap2 的实例对象,省得用 GMap2 来作方法声明的时候有人误解 ) :
1 、可以连续缩放
地图缩放的时候旧图块在新图块加载完成之前不会直接消失,图块的切换比较平滑,在网速较慢的时候这种效果会好一些。地图默认情况下不支持,建议打开这个功能。使用 map.enableContinuousZoom() / map.disableContinuousZoom() 方法来切换。另外,需要的时候你可以使用map.continuousZoomEnabled() 方法来探测一下地图是否支持连续缩放。
2 、支持滚轮缩放
使用鼠标滚轮来实现地图缩放,默认也是不支持的,建议打开。使用 map.enableScrollWheelZoom() / map.disableScrollWheelZoom() 方法来切换,使用 map.scrollWheelZoomEnabled() 方法来探测。
3 、支持双击缩放
左键双击放大地图,默认也是不支持,建议打开。使用 map.enableDoubleClickZoom() / map.disableDoubleClickZoom() 方法切换,使用 map.doubleClickZoomEnabled() 方法探测。另外,右键双击缩小地图默认是支持的,没有发现地图 API 中有方法可以改变右键双击的属性。
4 、支持地图拖动(默认)
按住左键拖动地图,默认是支持的。使用 enableDragging/disableDragging 方法切换,使用draggingEnabled() 方法探测。这个估计是个比较老的方法,因为在已经有静态地图 API 的情况下实在想不出来有什么理由不让地图可以拖动,除非你是想临时的禁止地图可拖动。
5 、支持信息窗口(默认)
在需要的时候地图可以弹出一个泡状的东东,在里面显示信息,默认也是支持的。使用 enableInfoWindow/disableInfoWindow 方法切换,使用 infoWindowEnabled() 方法探测。一般情况下,这个属性让它保持默认就好了,如果你只需要在地图上标注并且不允许任何信息窗口的弹出,或者想上一个地图拖动的属性一样,需要临时性的禁止。
6 、添加搜索栏
把地图左下角的 Logo 换成一个带搜索框的控件,这样你就可以在你的地图中直接使用谷歌的数据源来支持用户搜索,定制好的话简直就可以当作一个微型的地图主页来用。这个是中文 API 中新增的功能,以前的文章中我提到使用 GMapOptions 中的 googleBarOptions 属性可以来定制这个控件的。这个在地图上默认是没有添加的,所以,如果你没有使用 map.enableGoogleBar()方法来显式的声明加上搜索栏的话, googleBarOptions 也是不会起作用的。 添加搜索栏反向的禁用操作是 map.disableGoogleBar() 。
地图上的控件一般是指悬浮在地图上、不随地图移动的图片、按钮等等 DOM 元素,可以用来控制地图、帮助用户和地图交互、显示地图的特定信息和状态。
在谷歌地图主页上,有可以控制地图缩放的控件、有切换地图类型的控件、有显示缩略图的控件等等,这些控件在地图 API 里默认也都是提供的,所以,你可以在你的地图上加上这些控件,并且可以根据你的需要随意调整地图控件的位置、改变控件的外观,就像我在右边的地图上把缩放控件移到右上角而不是默认的左上角、并且使用了一个微型化的外观。下面先看看可以在地图上添加哪些控件吧。
地图 API 中默认控件的种类
1 、地图缩放控件
缩放控件是可以控制地图移动和放大级别的,默认有三种:
1 ) 全功能控件 GLargeMapControl
有方向按钮、恢复按钮、缩放按钮和缩放滑块
2 ) 微型化控件 GSmallMapControl
把全功能控件去掉恢复按钮和缩放滑块后的控件
3 ) 微型缩放控件 GSmallZoomControl
只有放大 / 缩小两个按钮
下面从左到右依次是 GLargeMapControl , GSmallMapControl , GSmallZoomControl 这三个控件,选用哪一个就看你的空间有多大了。不过,我认为通过 GMap2 提供的设置项允许用户使用滚轮和双击缩放地图比使用一个大大的缩放控件更方便。
word/media/image1.png
word/media/image2.png
word/media/image3.png
这几天谷歌地图主页刚刚换了新的缩放控件,有点类似于谷歌地球上哪个,不过使用 API 实现的还没有变,仍然是上面显示的这个样子。
2 、地图类型选择控件
地图类型选择控件是用来选定所显示地图的类型的,比如普通地图、卫星地图、地形地图等等,也有三种,唉,突然想起孔乙己 :)
1 )按钮式标准控件 GMapTypeControl
每种地图类型对应一个按钮,点击不同的按钮切换地图类型,比如
word/media/image4.png
2 )菜单式控件 GMenuMapTypeControl
所有的地图类型使用一个下拉菜单来显示,选择菜单中的不同项来切换地图类型,比如
word/media/image5.png
3 )阶层式标准控件 GHierarchicalMapTypeControl
类似标准的按钮控件,不过在某些按钮下可以选择在该类型地图下的嵌套内容,比如卫星地图中还可以选择是否使用标签、即是否使用混合类型 (Hybrid) 的地图,如下:
word/media/image6.png
这个控件目前在中文地图上没有什么作用,因为中文地图还不支持 Hybrid 类型的地图,也不能在地图上显示 Panoramio 的图片和 Wikipedia 的内容。
3 、缩略图控件 GOverviewMapControl
在地图上显示一个比现有地图范围更大、但是尺寸要小得多的缩略图,默认位置在右下角,在该控件的右下角有一个箭头,点击可以收放这个控件,需要移动地图时你也可以直接拖动缩略图里的那个蓝框,会比你直接拖动地图要快一些。
word/media/image7.png
4 、比例尺控件 GScaleControl
显示当前地图的比例尺,所以上面的数值会随地图的缩放变化,这个控件不是特别引人注目
word/media/image8.png
5 、本地搜索控件 GoogleBar
上一篇介绍 GMap2 设置项的文章里把这个包括了进去,还是放在这里比较合适,是什么我就不多说了,看图
word/media/image9.png
谷歌地图上常用的默认控件基本就这些了,你在我右边的地图里基本都能找到这些控件,想把这些控件加到你的地图上也不难,接着来看。
向地图上添加控件的方法
上面我已经给出了每个控件对应的类名,添加的步骤(以添加右边地图中的微型缩放控件为例):
1 、重置控件的位置,如果你使用控件的默认位置,这一步就不需要了。一般情况下也确实不需要,只有在你的地图空间狭小,控件摆布不开的时候才会有,右边的地图就是这种情况。
GSmallMapControl.prototype.getDefaultPosition = function(){
return new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(10, 30));
}
注意G_ANCHOR_TOP_RIGHT 和new GSize(10, 30) 这两个参数,这个其实就决定了右边地图里微型缩放控件的位置,位于右上角(TOP_RIGHT ),距地图右边距10px ,上边距30px 。
2 、创建控件对象
var mapControl = new GSmallMapControl();
3 、调用map.addControl() 方法添加控件
map.addControl(mapControl);
怎么样,还没过瘾?API 里提供的默认控件基本就这些了,如果你还想加上你自己设置的控件,比如右边地图上的状态控制,那就看看我之前介绍的自定义地图控件的方法 吧。
到这里为止,通过 指定 GMapOptions 、 设定地图设置项 、添加默认控件,我们可以在不需要添加任何叠加层、信息窗口、事件侦听的情况下,就可以创建一个内容比较丰富的地图了。当然,等我介绍完本地搜索控件的定制方法,我们的地图内容会更丰富。
前面设置地图的博文里面其实漏掉了一个很有意思而又不太引人注目的地图特性,就是设置地图的快捷键。
说实话,之前我也没有注意过这一点,甚至都没有想过地图可以支持快捷键,一个以拖拽成名的应用,谁又能想到可以用快捷键来控制呢。
有一天无聊的上下翻动地图 API 的文档,突然发现一个很陌生的类, GKeyboardHandler ,没见过!
仔细看了一下,居然是用来使地图支持键盘操作的,更有意思的是,这个类在文档顶部的类名列表中没有出现,不知道是整理文档的疏漏,还是因为这个类太小,小的连一个方法或者参数都没有,只有光秃秃一个类充作构造函数。也可能是这个类所支持的键盘操作有限吧,我把支持的键做了个列表:
键
动作
方向键
向对应的方向连续移动地图,同时按下邻近的两个会向对角移动
Home /End
以 3 / 4 的幅度左右平移地图 ,动画效果
Page Up /Page Down
以 3 / 4 的幅度上下平移地图,动画效果
+ / -
放大/缩小一个级别的地图
只有地图的移动和缩放操作,特意到地图主页上试了试,支持,没有问题,只不过你需要先点击地图,使地图容器处于激活状态。用起来也不错,感觉地图的移动居然比鼠标拖动时还要平滑。
如果需要在你自己的地图上使用,只需要一句话:
new GKeyboardHandler(map);
够简单吧,呵呵,赶紧扔开你的鼠标到右边的地图上试试吧。
在提到 地图上的默认控件 和 GMap2 的设置项 的时候,我都提过谷歌地图的本地搜索栏这个控件,要在地图上加上这个控件很简单,不需要调用 GMap2.addControl() ,只需要一句话:
map.enableGoogleBar();
这样就可以在地图的左下角加上这个搜索栏了,并且替换掉了原来的谷歌 Logo 的图片。
目前用这个搜索栏可以搜索两种类型的数据:
1 、地名;
2 、谷歌提供的商业数据,比如 “ 餐馆 ” ,默认是在当前显示的地图范围内搜索;
具体的搜索结果是上面的哪种类型由你输入的关键字决定,没有什么特别的方法。搜索返回结果后会自动在地图上加上所有结果的标记,同时会用 DOM 形式显示这个搜索结果,至于 DOM 会是什么样的形式展现,接着看就知道了。
定制这个搜索栏对应的类是GGoogleBarOptions ,没有构造函数,对应一个对象变量,使用方式类似于使用GMapOptions 定制谷歌地图 ,不过GGoogleBarOptions 是作为GMapOptions 里的一项在创建GMap2 对象的时候使用。如果你了解过Google AJAX Search API 的话,你对下面这些设置项会很熟悉,因为,这个本地搜索栏就是对AJAX Search 中的GLocalSearchControl 的一个封装。
先看几个基本的设置项:
1 、 showOnLoad
这个是 boolean 类型的项,决定加载完成后搜索栏的显示状态,默认是 false ,意思是搜索栏是闭合的,不显示输入框,如果你想提醒用户这里有个输入框可以搜索,可以把这一项设成 true ,即 {showOnLoad:true};
2 、linkTarget
简单的说,这个就是搜索结果里每一条记录对应link 的target 属性值,四个可选值,默认是等价于target="blank_" 的G_GOOGLEBAR_LINK_TARGET ,其他还有parent, self, top 这几项,准确的参数我就不列了,开发文档里有。不过这一项基本用不着,不用设置;
3 、resultList
用来指定搜索结果的DOM 显示样式,默认是用列表的方式显示(G_GOOGLEBAR_RESULT_LIST_INLINE ),还有一种是添加一对方向箭头让你逐个翻阅,就像右边的地图里显示的那样。如果你的地图空间比较小的话可以用后一种,设定{resultList:G_GOOGLEBAR_RESULT_LIST_SUPPRESS} ;
4 、suppressInitialResultSelection
这个用来指定搜索完成后是否自动选中第一个搜索结果并且打开它的信息窗口,默认是false ,就是打开第一条记录的信息窗口,不需要的话就指定{suppressInitialResultSelection:true};
5 、 suppressZoomToBounds
按照文档的说法,这个用来设定搜索完成后是否需要地图自动缩放移到来完整显示所有的标记点,默认是 false ,不缩放的,不过我在试用时发现不管搜索结果如何,地图都不会缩放。所以,暂时忽略这一项。
6 、 searchFormHint
这个在文档里没有列出来,但是也可以使用,用来设定输入框处于非激活状态时的提示语,默认的是 “ 搜索地图 ” ,你也可以设成你自己的提示语,比如: {searchFormHint:"hi ,在这里可以直接搜索地图 "}
再来看几个用来设定搜索操作时的回调函数,类似于事件监听,这几个可以做很多文章:
1 、 onIdleCallback
这个在搜索结果被清除的时候调用,也就是在你点击搜索结果上的 “ 清除结果 ” 这个链接后,是不是在本次搜索结果返回并且自动清除上一次搜索结果后调用我还不确定,看开发文档似乎有这个意思。
2 、onSearchCompleteCallback
在已经得到搜索结果但是还没有添加到地图上的时候调用,会传递一个GlocalSearch 对象作为参数,GlocalSearch 是Google AJAX Search API 里定义的一个类,想了解的先去看文档 吧,我就不多说了。
3 、onGenerateMarkerHtmlCallback
在打开一条搜索记录的信息窗口前会被调用,传入marker, html, result 三个参数,分别对应这条记录在地图上的标记(GMarker) 、填充信息窗口的html 字符串、对应的搜索结果(GlocalResult )。 这里定义的回调方法必须返回一个 dom 对象,用在打开的信息窗口中。所以,通过这一项的设置,你就可以更改搜索结果的信息窗口里的默认内容了。右边的地图里就把默认的信息窗口内容换了,去掉了 “ 从这里来 ” 、 “ 到这里去 ” 的链接,加上了一个静态地图,
4 、 onMarkersSetCallback
这个在所有的结果标记都已经创建但还没有添加到地图之前调用,传入的参数是一个搜索结果的数组 results ,数组里的每一项对应一条搜索记录,包括 latLng, marker, result ,对应结果的坐标 GLatLng 、标记 GMarker 、结果记录 GlocalResult 。这个时候结果的显示列表已经创建完成了,所以,如果你想修改这个现实结果不妨试试这个设置项。
追加一些说明,上面说到的GlocalResult 也是在Google AJAX Search API 里定义的一个类,没有构造函数,当作对象变量使用,需要了解可以看看文档 ,这里列一下这个类的一些主要属性:
.title, .titleNoFormatting, .lat, .lng, .streetAddress, .city, .country, .phoneNumbers[], .staticMapUrl
使用地图API实现自定义叠加层与地图上的控件不同,地图上的叠加层( Overlay )指的是和某个经纬度坐标绑定,能够跟随地图的缩放拖拽而相应移动的 DOM 原始,地图 API 文档里定义的 GMarker 、 GPolyline 、 GInfoWindow 都属于叠加层。右边地图上显示的交通信息的图标就是一个叠加层。
先看一段Hello World 的代码吧:
var MyOverlay = function(latlng_) {
this.latlng = latlng_;
};
MyOverlay.prototype.initialize = function(map_) {
this.map = map_;
var label_ = document.createElement("div");
var container_ = map_.getPane(G_MAP_FLOAT_PANE);
container_.appendChild(label_);
label_.innerHTML = "Hello World!";
label_.style.position = "absolute";
this.label = label_;
this.redraw();
}
MyOverlay.prototype.redraw = function() {
var position = this.map.fromLatLngToDivPixel(this.latlng);
this.label.style.left = position.x + "px";
this.label.style.top = position.y + "px";
}
MyOverlay.prototype.remove = function() {
this.label.parentNode.removeChild(this.label);
}
上面的代码中, MyOverlay 就是一个自定义的叠加层,需要的时候可以创建一个 MyOverlay 的实例,然后使用 map.addOverlay() 就可以在地图上加上这个叠加层了。这里的叠加层是在给定的位置(地图加载时的中心点)加上一个 Hello World 的文本,以后,无论你怎么拖动缩放地图,这个文本在地图上的位置会跟着地图变化。
下面详细解释一下代码:
var MyOverlay = function(latlng_) {
this.latlng = latlng_;
};
声明 MyOverlay 类的构造函数,创建该类的实例是需要给一个 GLatLng 类型的坐标对象作为参数。
MyOverlay.prototype = new GOverlay();
声明这个类继承自GOverlay
接下来的initialize 、redraw 、remove 都是实现了在GOverlay 接口中定义的抽象方法,这些方法在MyOverlay 类的对象初始化、地图拖拽缩放、从地图上删除的时候都会被自动调用。
Overlay 也是一个DOM 元素,所以在initialize 方法中需要做的就是定义这个DOM 元素并且把它添加到合适的地方去。 使用 GMap2 对象(作为参数传递进来)的 getPane 方法取得 Overlay 需要依附的图层(这个图层按照 z-index 的不同现在可以分为七种不同的图层,我就不列举了,需要的可以到文档里查查 GMapPane 这个类),也就是 Overlay 所要依附的 DOM 容器(不同于 GMap2 对象的DOM 容器),定义好 Overlay 的样式和内容,然后作为子元素添加到刚才取到的图层里就可以了。
在initialize 方法中需要注意的是,作为叠加层的DOM 元素的position 样式属性必须设置为absolute ,并且需要显式的调用redraw 方法,才能保证在叠加层第一次加载时的位置显示正确。
对于 redraw 方法,就是在地图的位置发生变动以后能够重新计算叠加层的坐标并重新设定叠加层的显示位置,关键点就是使用 GMap2.fromLatLngToDivPixel() 方法来取得叠加层的 DOM 绝对坐标,不是很理解这个坐标的话可以看看 我以前总结果的地图坐标系统 。
对于 remove 方法,地图在调用 removeOverlay 的时候会自动调用这个方法,把你的叠加层从地图上删除。
这里展示的只是一个添加简单文本的 Overlay 的例子,如果你需要添加更丰富的文本、图片,或者需要这个 Overlay 能够监听一些事件,比如单击、双击等等,只需要在 initialize() 方法里对 Overlaly的 DOM 元素做更多的声明和控制就可以了,和你在网页中其他地方定义一个 DOM 元素没什么两样。
《google map api 开发快速入门》相关文档:
青少年足球入门训练详细计划10-01
化工设计入门05-03