Tuesday, March 24, 2009

利用Firebug实现Google Maps中国的地理译码

2007年8月在北京参加首届研究生地理信息系统论坛,在论坛上有幸介绍了一下陈汝烨和我在创建roommap网站时期的一个地理译码的过程,现在Google Maps中文的地理译码已经公开了一些地理译码信息,之前需要自己去“hack”这部分信息:
http://www.codechina.org/doc/google/gmapapi/#Geocoding_Etc

所谓地理译码:是把地址(如"1600 Amphitheatre Parkway, Mountain View, CA")转换为地理坐标(如经度-122.083739,纬度37.423021)的流程,您可以用它把数据库里面的街道地址或用户提供的地址信息标记在地图上。

现在将我们俩当时(2007年)的思路共享给大家:

摘 要:目前Google Maps 中国的API已经提供了地图所需要的基本服务,比如任何网站可以引用浏览Google maps中国地图,以及一些简单应用比如显示气象图等,但使用者不能进行地理译码。地理译码是把地址(如“中国科学院遥感应用研究所”)转换为地理坐标(如经度-122.083739,纬度37.423021)的过程。通过它,您就可以把数据库中的街道地址或用户提供的地址信息标记在地图上。但是,到目前为止,在Google maps US 已经实现了地理译码的API(GClientGeocoder 类中有相应的方法实现)。Google Maps中国地图中,用户可以对地名搜索并进行地理坐标定位,然而,中文 Google Maps API尚不提供地理译码功能。不过,我们可以根据Google提供的规范开发自己的地理译码器。本文介绍了利用Google maps网络已有资源,如何实现对中文地理位置名称到地理经纬度坐标的转换,从而在自己的网站中利用Google maps中国对任何国内的地理位置进行搜索定位。

作者采用Firebug监测工具,分析Google中国地图程序产生的Http响应,从中解析经纬度坐标信息,最终实现Google Maps中国的地理译码功能。

首先登录http://ditu.google.cn/网站,将需要查询的地名提交并提交。查看Firebug中获得命名为maps的Http响应(response),从相应的html文本中发现名为markers: [] 数组, [] 内每个id: 的内容就表示一个对象或称一个地理信息结果。由此按照markers: [] 数组内对象(或id)的数量,我们可以把地理译码过程分成一下三种情况:

1. markers: [] 数组中有多个对象(或id)。比如搜索“扬州大学“,那么地图上可以得到多个结果,包含扬州大学的多个校区的地址。在这种情况下markers: [] 数组中每个对象(或id)存在一个geocode的属性,在这个属性中我们发现了一个没有经过加密的该地址的地理坐标。因此,我们可以直接用正则表达式获取到改对象(或id)的经纬度信息,从而遍历得到每个地址的地理位置。

2. markers: [] 数组中仅有一个对象(或id)。比如搜索“中国科学院遥感应用研究所”,只有一个精确地址。这种情况下的http响应结果中包含一个markers数组,数组长度为1,这个数组包含的元素对象有laddr和mapabcPoiid两个属性。laddr就是中文地址描述,而作者发现Firebug监测到浏览器发送了标识为mapabcPoi的请求,从地址中中可以看到 Google地图的地理数据用的mapabc.com的数据,那么推断mapabcPoiid是该地理点在mapabc数据库中的标识符。作者查看mapabcPoi请求的响应内容(response),得到类似这样的代码notpcoStrbase64=…发现这个结果应该是base64编码后的结果,所以作者利用base64解码后就可以获得该地址的地理坐标了。

3. 找到多个不确定的结果。这种情况下,返回结果中包含一系列的建议的地址,比如搜索“上海马戏城” ,结果提示您找的是不是“某某路上的马戏城”。从响应的html文本中利用正则表达式取得这些建议的地址,然后再重新搜索就可以得到建议地址的坐标了

《注:代码部分已经由陈汝烨同学利用javascript实现》

结语:有时候,结果并不重要,过程更重要 :)

No comments:

Post a Comment