论坛首页 Web前端技术论坛

googleMap本地化(离线)

浏览 33980 次
精华帖 (1) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2012-04-13  

在web开发中可能遇到这样的需求:需要一个地图系统,选择google map来完成地图的展示,但是该web系统由于特殊性而不允许与外网链接,还有就是现在对google的访问越来越不稳定(国家网络限制),因此希望将google map移植到内网中使用。
可以将google map api分为3个部分来看待:
1、负责与服务器交互的js文件
2、google提供的技术支持,例如查找路径、周边搜索
3、google提供的地图数据

如果需要开发的功能中包含第2部分的需求,那么可能比较复杂。因为路径算法在google服务器上实现,只是对外提供了接口,如果无法连接google网络则无法实现。
但如果开发的web中对map的使用比较简单,例如只是加载地图,有简单的地图移动等功能,那么这样的需求是可以将google map移植到内网来处理的。这种方法也适用于自定义周边搜索,例如需要完成的web功能就是通过查询,获取指定范围内的建筑物、获取自定的标记(开发本地商户搜索系统的时候,地图上商户数据的维护肯定是有web自己维护,而并非google提供的数据,这种场景正好适合)。

下来来说如何将google map本地化,可以分为两个步骤:
1、将google map使用的与服务器交互的js文件本地化
这个当然是根据google map加载时候,所需要的js下载到本地,以后再应用程序开发的时候,不引用google站点上的js,而是换成本地的js文件。具体有些什么js需要下载的,这里就不做详细介绍了,可以通过firefox的firebug插件,或是google chrome等工具查看到http请求,分析并下载有效的js文件,可能还需要分析各个js之间在使用过程中加载外链js的地址,并予以修改、替换问对本地js的调用。google map api中需要使用到的js本地化,网络上一个叫做rover.tang的朋友已经做得很好,提供了google map api v3.8的本地化js,可以在网络上找到。
2、将google map的地图数据(tiles:瓦片)下载到本地,以及应用的开发
说到地图数据,需要了解google map的一点基础知识。google把在浏览器中显示的地图,分割成一块一块的图片,称之为tile,在浏览其中显示地图的部分,从google下载各个tile,然后拼接在一起,就能够看到完整的一幅地图。每一个tile的大小都是256*256的png图片,因为存在缩放(缩放级别为0-19),每个缩放级别中,浏览器中显示地图的区域被划分为多个tile,每个tile会根据去google站点下载对应的地图数据,其实就是一张png图片,在浏览器分别请求以获取tile地图图片数据的时候,会传递给google 三个重要的参数,1、tile的x坐标;2、tile的y坐标;3、当前浏览器中显示的地图的缩放级别。
google map可以自定义地图类型(MapType),详细的可以参考https://developers.google.com/maps/documentation/javascript/maptypes
下面说说如何通过自定义方式加载地图(地图数据本地化)
//js代码
<script type="text/javascript">
var map;
var myCenter = new google.maps.LatLng(29.568381,106.552219);//重庆  
function CoordMapType() {
}
CoordMapType.prototype.tileSize = new google.maps.Size(256,256);
CoordMapType.prototype.maxZoom = 19;
CoordMapType.prototype.getTile = function(coord, zoom, ownerDocument) {
  var div = ownerDocument.createElement('div');
  div.innerHTML = '<img name="" src="./tiles/zoom_10/x_814-y_424-z_10.png"/>';
  //div.innerHTML = '<img name="" src="./tiles/zoom_' + zoom + '/x_' + coord.x + '-y_' + coord.y + '-z_' + zoom + '.png"/>'; 
  div.style.width = this.tileSize.width + 'px';
  div.style.height = this.tileSize.height + 'px';
  div.style.fontSize = '10';
  div.style.borderStyle = 'solid';
  div.style.borderWidth = '1px';
  div.style.borderColor = '#AAAAAA';
  return div;
};

var coordinateMapType = new CoordMapType();

function initialize() {
  var mapOptions = {
    zoom: 10,
    center: myCenter,
	mapTypeId: "coordinate"
  };
  map = new google.maps.Map(document.getElementById("map_canvas"),mapOptions);
  map.mapTypes.set('coordinate',coordinateMapType);
}
google.setOnLoadCallback(initialize);
</script>

//html代码
<div id="map_canvas"></div>

重点是代码div.innerHTML = '<img name="" src="./tiles/zoom_10/x_814-y_424-z_10.png"/>',该代码定义了自定义地图到哪里加载地图数据(tile),我们需要本地化google map,因此将google map对应的tile下载到本地,按照自己的意愿命名存放在服务器上,因此我们需要根据自己存储google map的地图数据,代码示例中,统统只加载一个固定的图片,仅作为测试,实际情况可以修改这里的规则。这样,在加载地图的时候,或是在移动地图的时候,就会加载本地(本地服务器)的地图的地图数据。

完成到这一步,就差google 地图数据下载了,通过在线google地图的移动,可以看出google map会去类似这样的地址http://mt0.googleapis.com/vt?src=apiv3&x=814&y=423&z=10下载地图数据,x即tile的x坐标,y即tile的y坐标,z即缩放级别。因此采用任意的开发语言,或脚本,到google的服务器上下载对应需要区域的地图数据,存放到本地即可。java实现网络下载当然有很多可以使用的东西了,这个就随意发挥了。:)
   发表时间:2012-04-14  
正需要这个
0 请登录后投票
   发表时间:2012-04-17  
可惜,地图无法下载。。。
0 请登录后投票
   发表时间:2012-04-17  
其实,地图的瓦片数据下载下来后。前端js可以用openlayer之类的来加载。
0 请登录后投票
   发表时间:2012-04-17  
看到这篇文章是我这个月最开心的事
0 请登录后投票
   发表时间:2012-04-17  
我想问下怎么通过当前的经纬度坐标转换成各个tile的坐标信息呢
0 请登录后投票
   发表时间:2012-04-17  
siwei 写道
可惜,地图无法下载。。。

地图数据可以下载,附件中有个工具,正确设置里面的参数就可以下载,具体的设计里面都有一定的说明。
0 请登录后投票
   发表时间:2012-04-17  
cpenet 写道
我想问下怎么通过当前的经纬度坐标转换成各个tile的坐标信息呢

坐标系之间的转换在以下网址已有详细的说明,附件中源码也能找到相关代码。
http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#lon.2Flat_to_tile_numbers
0 请登录后投票
   发表时间:2012-04-17  
离线包多大呢? 这...
0 请登录后投票
   发表时间:2012-04-17  
地图可以通过Mobile Atlas Creator 这个工具下载,可惜新版本很多地图都没有了,
你这个程序功能比较简单,网上有个大牛liongis做了一个GoogleMapAPI,能够在上面画标注,画折线等。
完全不依赖网络。
0 请登录后投票
论坛首页 Web前端技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics