提供地图图块包供离线使用

时间:2013-11-26 21:22:17

标签: javascript openstreetmap leaflet mapbox

我正在创建一个必须脱机工作的Web应用程序。到目前为止一切正常,我的最后一步是将地图图块脱机。幸运的是,我确切地知道用户需要访问地图的哪些区域,因此我不必允许缓存数百万个磁贴。

地图分为几个区域,因此我们的想法是为这些区域提供可下载的“套餐”。

例如,当我在线时,我会转到“瓷砖包”页面,该页面提供了多个区域的下载。我选择了我感兴趣的区域,下载了瓷砖,当我离线时,我可以使用这些瓷砖。我只需要大约2个缩放级别,一个用于快速导航,另一个用于更多细节。

我正在使用传单来提供地图。有没有人不得不这样做,可以给我一些指导?我真的只是不知道如何处理这个,这是最后一块拼图。

3 个答案:

答案 0 :(得分:5)

可悲的是,你没有指出,确切的问题是什么,或者你失败的步骤。所以我会尝试给出一般答案:

Leaflet使用Tiles by 不同的提供程序来使用JS来获取slippymap。地图图块(aka rasterimages)可以通过Tile Map Service (TMS)或稍微不同的方法提供(对于OSM编号here described)。
因此,您可以创建一个图片列表,并可以通过重新定义法律和技术条款来转移它们。对于OSM,这是例如:

所以你需要创建一个服务器/客户端脚本,它能够进行批量传输(可能是打包存档文件?)并要求将它放在某个地方供用户使用。我在Leaflet中经验不足,无法告诉你如何提供它们,除了你可以将它们添加到浏览器缓存本身,或者使用本地服务器将它们作为localhost提供。

无论如何,如果你有更多问题,请问。

答案 1 :(得分:2)

所以这就是我想出来的。我将地图的一个区域导入我的数据库。然后我将此部分作为可下载的包提供。当用户下载包时,将查询数据库并以JSON格式返回与该区域关联的所有切片。图像存储为blob。然后我将这个tile数组传递给一个解析数据的自定义传单层。这是图层的代码:

define([], function() {
    L.TileLayer.IDBTiles = L.TileLayer.extend({
        initialize: function(url, options, tiles) {
            options = L.setOptions(this, options);

            // detecting retina displays, adjusting tileSize and zoom levels
            if (options.detectRetina && L.Browser.retina && options.maxZoom > 0) {

                options.tileSize = Math.floor(options.tileSize / 2);
                options.zoomOffset++;

                if (options.minZoom > 0) {
                    options.minZoom--;
                }
                this.options.maxZoom--;
            }

            this._url = url;

            var subdomains = this.options.subdomains;

            if (typeof subdomains === 'string') {
                this.options.subdomains = subdomains.split('');
            }

            this.tiles = tiles;
        },
        getTileUrl: function (tilePoint) {
            this._adjustTilePoint(tilePoint);

            var z = this._getZoomForUrl();
            var x = tilePoint.x;
            var y = tilePoint.y;

            var result = this.tiles.filter(function(row) {
                return (row.value.tile_column === x
                        && row.value.tile_row === y
                        && row.value.zoom_level === z);
            });

            if(result[0]) return result[0].value.tile_data;
            else return;
        }
    });
});

答案 2 :(得分:0)

我认为你可以使用四叉树,即。空间填充曲线。 MS Bing Map使用最简单的图块地图:http://bcdcspatial.blogspot.de/2012/01/onlineoffline-mapping-map-tiles-and.html?m=1。我认为其他地图服务器也使用空间填充曲线,但不是那么明显。您可以搜索ms bings maps quadkey或nick的空间索引hilbert曲线。你也可以下载我的php class hilbert curve @ phpclasses.org。您可以将它与许多不同的空间填充曲线一起使用并生成四元组。一个好的开始也是黑客的食谱。有一整章致力于希尔伯特曲线。