|
解决 Google 地图编程内的中文地名翻译问题
Google 地图是一种免费服务,可通过 Internet 提供基于浏览器的方位向导以及特定位置的地图。您可以放大这些交互式地图来显示详细信息,这无疑为用户带来了与 Web 站点更好的交互性。Google 提供的地图不仅可直接由客户使用,而且还能用来借助 Google Maps API 开发定制的地图服务和产品。不过,最新的 Google Maps API 版本不太擅长解析中文地名,非常不便于中国用户在其应用程序中使用。在本篇文章中,我们给出了一个可行的解决方案,再加上IT论坛的一些 Web 服务,就能用目前的这个 Google Maps API 解析中文地名。我们将以北京 2008 奥运会的地点为例来展示我们的方案。
Google 地图概览Google 地图是下一代的在线地图服务。借助其智能和直观的界面,几乎可以搜索任何东西 — 一家公司的名字、感兴趣的一个地点、一个地址或一座城市 — 并且弹出的地图都很有吸引力。地图可通过鼠标移动或键盘操作轻松移动和缩放,并且街道名和大致路况也会清晰展示。同样吸引人的是 Google 地图的驾驶向导,它非常清晰,且所循道路用鲜明的线条标出。
此外,Google 还提供了 Google Maps API。这个 API 具备大量实用工具,可用来通过多种服务处理和向地图添加内容,借此,您就可以创建健壮的地图应用程序,也可以在自己的网站内嵌入 Google 地图。
解析和显示地理位置的常规解决方案Geocodegeocode 是用以指代某个特定位置的地理参数的某种组合,比如经度、纬度或海拔。
Google Maps API 具有一个类 GClientGeocoder,用于与 Google 服务器直接通信来获得用户指定地址的 geocode。geocoder 其自身具有一个地址缓存,这样一来,重复的查询无需重新进行与服务器的通信就可解答。通常,客户可以通过方法 GClientGeocoder.getLatLng(address, callback) 向 Google 服务器发送请求来获得某地址的 geocode。举例来说,当我们把 “Shanghai” 传递给此方法时,返回的是与此地址最匹配的点所在的 geocode。结果是 (31.224353, 121.475916),它表明了上海市所在的纬度和经度。具有这项功能的示例地图如图 1 所示。
图 1. 具有 GClientGeocoder.getLatLng() 功能的示例地图 清单 1(参见所附文件)给出了图 1 所示地图使用的 html 源代码。
针对中文地名存在的问题Google Maps API 内的 GClientGeocoder 类可以很好地翻译英文地名,但却不能很好地处理中文地名。比如,当把 “中国北京国家体育馆” 传递给 GClientGeocoder 时,它无法工作,如图 2 所示。
图 2. 指定中文地名后的示例地图 使用 Google 的地理位置查询 Web 服务的一种新解决方案除了 Google Maps API 内的 GClientGeocoder 类之外,有一些 Web 服务可以用来将中文的地址翻译成(纬度,经度)对。http://maps.google.com/maps/geo 就是其中的一个,它是 Google 用于地名解析的 Web 服务之一。让我们来做个快速的测试,打开一个浏览器并在 URL 框内键入如下的请求字符串:
http://maps.google.com/maps/geo? ... 94QxWIa6N4U6MouMmBA
在上述的查询字符串中,q 是查询的目标地址,output 是响应格式,key 是要使用此 Web 服务的关键字字符串。
按下 Enter 键后,会在 Internet Explorer 出现一个对话框询问是否保存响应字符串,如图 3 所示。Firefox 和IT论坛的浏览器可能只会简单返回文本,这时,您可以手动保存。
图 3. 保存 http 响应的对话框 Google 精度常量Google 精度常量表明的是返回项的比例,而非此项的可信度。比如,4 代表的是城镇大小。在 Google 的 API 文档(参见 参考资料)可以找到这些常量及其含义的定义。
打开此文件,可以看到具有完整翻译信息的响应字符串,如 清单2 所示(参见所附文件)。
最后的部分: "Point":{"coordinates":[-87.624333,41.879535,0]}} 就是所翻译成的(纬度,经度)对,可直接用来在 Google 地图上进行定位。
为了简便起见,我们可以将 ‘output’ 指定为 ‘csv’ 而非 'cvs'。这样就只会返回 4 个数:
200,4,41.879535,-87.624333
注意:在此响应内,200 是 HTTP 状态代码,表明解析成功;4 是精度常量;41.879535 是经度;-87.624333 是纬度。
这之后,我们传递进中文地名 “中国北京国家体育馆” 作为目标地点:
http://maps.google.com/maps/geo?q=中国北京国家体育馆&output=csv&key=ABQIAAAAzr2EBOXUKnm_jVnk0OJI7xSosDVG8KKPE1-m51RBrvYughuyMxQ-i1QfUnH94QxWIa6N4U6MouMmBA
查询服务能成功解析并获得如下(纬度,经度)对:
200,9,39.997005,116.390212
现在,我们就可以使用这个查询 Web 服务作为一种可选解决方案来克服 GClientGeocoder 类的缺点。图 4 所示的是此解决方案的一个图示。
图 4. 解决方案概览 要在中国地图内显示一个地理位置,Geography Translation 模块先会向此 Web 解析服务发送一个 http 请求,该 Web 服务将地名翻译为一个(纬度,经度)对。之后,Google 地图页面再使用这个(纬度,经度)对定位具体的地点。
示例:在中国地图上显示两个地点间的驾驶路线清单 3 所示的这个示例给出了我们解决方案的一个实际应用。为了便于此示例在多个平台上运行,我们还编写了一个简单的 Java 应用程序。它解析北京 2008 奥运会的两个地点并生成一个 Google 地图 HTML 页面,在此页面上两个地点分别标注为 ‘A’ 和 ‘B’,而二者间的驾驶路线则用蓝色标出。读者可以随意打开一个 Web 浏览器并显示所生成的 Google 地图 HTML 页面。
清单 3(参见所附文件)所示的翻译模块会像上面描述的那样发出一个 http 请求、检索响应字符串并解析这个(纬度,经度)对。为了简便起见,http 响应字符串的格式采用的是 ‘csv’。
注意,在清单 3 中: Apache 的开源 ‘HttpClient’ 库(参见 参考资料)的作用是发送 http 请求和接收 http 响应。
AddrPoint 类(如清单 4 所示)是这个(纬度,经度)对所对应的一个 bean 类:
清单 4. AddrPoint Javabeanpublic static class AddrPoint {private float _latitude=0;private float _longtitude=0;private String _name=null;public AddrPoint(float longitude, float latitude, String name) { _latitude=latitude; _longitude=longitude; _name=name;}/*** _cnnew1_cnnew1@return Returns the _latitude. */public float getLatitude() { return _latitude; }/*** @return Returns the _longitude. */ public float getLongitude() { return _longtitude; } /** * @return Returns the _name. */ public String getName() { return _name; }}
为了生成这个 Google 地图页面,我们使用了 Apache 的模板引擎 Velocity(参见 参考资料)。我们的页面模板如 清单 5(参见所附文件)所示。
而生成代码则如 清单 6(参见所附文件)所示。
传递两个奥运会地点 “中国北京奥林匹克公园” 和 “中国北京国家体育馆” 后,在所生成的 Google 地图页面内产生的效果如图 5 所示。
图 5. 所生成 Google 地图页面 图 6 显示了地点 A(北京 2008 奥林匹克公园)的卫星视图。
图 6. 地点 A 的卫星视图 地点 B(北京 2008 奥运会国家体育馆)的卫星视图 如图 7 所示。
图 7. 地点 B 的卫星视图 结束语Google 地图是一种热门技术和服务,客户可基于 Google Maps API 来开发自己的定制地图服务。本文简单介绍了针对中文地点翻译的一种解决方案,可解决默认的翻译类 GClientGeocoder 内存在的问题。本文还用显示北京 2008 奥运会地点的例子展示了此解决方案的可行性以及如何综合多种服务来克服局限性。
参考资料 学习获得产品和技术
解决 Google 地图编程内的中文地名翻译问题
摘自:http://www.ibm.com/developerworks/cn/web/wa-chinesetrans/
|
|