Google Maps API加载MBTiles离线地图

第一次写博客,好忐忑。。。

上周看了这篇网文http://www.cnblogs.com/i-gps/p/3919475.html,深受启发虽尚未实践但感觉颇有价值,只是苦于没有内中细节,遂利用周末时间重新查阅Google Maps API尝试一番。

文档中Google Maps图片地图类型加载本地的瓦片文件,创建地图类型的方法如下:

function GMapsMapTypeFactory() {}
GMapsMapTypeFactory.createMapType = function (name,mapTilePath) {
    var getTileUrl = function (coord, zoom) {
        var numTiles = (1 << zoom);if ((coord.y < 0) || (coord.y >= numTiles)) {
            return null;
        }
        var numx = (coord.x % numTiles + numTiles ) % numTiles;    /*水平方向重复,垂直方向重复方法类似*/


        if (name == "卫星")
            return mapTilePath + zoom + "/" + numx + "/" + coord.y + ".png";
        else
            return mapTilePath + zoom + "/" + numx + "/" + coord.y + ".jpg";
    };

    var imageMapTypeOptions = {
        "name":name,
        "alt": name,
        "tileSize": new google.maps.Size(256, 256),
        "maxZoom": 11,
        "minZoom": 1,
        "getTileUrl": getTileUrl,
        "isPng": true,
        "opacity": 1.0
    };
    return new google.maps.ImageMapType(imageMapTypeOptions);
}

方法调用:

setMapTypeId = "roadmap";
map.mapTypes.set(setMapTypeId, GMapsMapTypeFactory.createMapType("地图", GooglePath + "/maptile/roadmap/"));

其中,getTileUrl是关键函数,根据世界坐标和缩放级别来选择指定文件夹中的瓦片文件,返回string类型。

但是,如引用网文中所述,MBTiles数据库中直接存放瓦片文件,tile_data字段为BLOB类型,通过PHP、Java、C或Delphi读取MBTiles表返回的二进制数据不能直接在getTileUrl中使用。

那么问题来了,一是二进制数据,不通过另存为临时文件方式,能不能在页面中显示呢?二是Google Maps API除了ImageMapType类还有其它可用接口么?

经搜索发现,在html中img的src属性通常为图片的url地址,但是使用base64格式的数据也能显示,即

<img src="data:image/jpg;base64,base64格式的图片数据" />

 
 本地试验,将读取的tile_data,经过base64_encode(PHP中函数,其它语言类似)在页面中显示成功,该方法有效。 
 

然后在Google Maps API中找到基本地图类型条目,文档中提供一个实例:

function CoordMapType(){}
CoordMapType.prototype.tileSize = new google.maps.Size(256,256);
CoordMapType.prototype.maxZoom = 11;
CoordMapType.prototype.minZoom = 1;
CoordMapType.prototype.getTile = function(coord, zoom, ownerDocument){
	var div = ownerDocument.createElement("div");
	div.innerHTML = coord;
	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 = '#aaa';
	return div;
}
CoordMapType.prototype.name = 'Tile #s';
CoordMapType.prototype.alt = 'Tile Coordinate Map Type';
var coordinateMapType = new CoordMapType();// 声明使用

getTile方法中出现了HTML元素的创建、属性和样式设置,那如果将div元素换成img,再设置其src,不就正好满足需要?修改部分代码如下:

var div = ownerDocument.createElement("img");
$.getJSON(URLPath + "/getTile", {z:zoom, x:coord.x, y:coord.y}, function(data){
    div.setAttribute("src", "data:image/jpeg;base64," + data.tile_data);
}

jQuery访问服务端URLPath的自定义getTile方法,参数依然为世界坐标和缩放级别,经过base64_encode返回tile_data,再利用HTML DOM操作设置属性,效果图如下:

Google Maps API加载MBTiles离线地图_第1张图片

图中显示第5级的6张瓦片图片,请忽略上下顺序颠倒和四周的空白。。。

前端html没有直接使用Google Maps API,而是使用leaflet封装一下。数据库如下:

Google Maps API加载MBTiles离线地图_第2张图片


大体过程差不多就是这样,服务端操作数据库和表,以及前端html代码就不贴出来了,以上。


你可能感兴趣的:(Google,地图,maps,MBtiles)