为离线使用提供地图瓦片包套餐

3
我正在制作一个需要离线工作的Web应用程序。目前一切正常,我的最后一步是将地图瓦片离线。幸运的是,我知道用户需要访问地图的确切区域,因此我不必允许缓存数百万个瓦片。
地图被分成多个区域,所以想法是提供这些区域的瓦片作为可下载的“包”。
例如,当我在线时,我会进入“瓦片包”页面,该页面提供几个区域的下载。我选择我感兴趣的区域,下载瓦片,然后当我离线时,我就可以使用这些瓦片。我只需要大约两个缩放级别,一个远距离用于快速导航,一个更近距离用于更详细的信息。
我正在使用Leaflet来提供地图服务。是否有人做过类似的事情并能给我一些指导?我真的不知道如何开始处理这个问题,这是拼图的最后一块。

1
我不确定你的实际问题是什么。你想知道如何为两个缩放级别生成瓦片吗? - scai
3
你可能会发现MBTiles很有用——它是一种基于 SQLite 的格式,可以从单个文件中提供一组瓷砖。 - Dan Stowell
3个回答

5
很遗憾您没有指出具体的问题或失败步骤。因此,我将尝试给出一个一般性的答案:
Leaflet使用不同供应商提供的图块来创建JavaScript滑动地图。地图瓦片(也称为光栅图像)可以通过Tile Map Service(TMS)或略微不同的方法(例如OSM中描述的编号here described)提供。
因此,您可以创建一个图像列表,并通过遵守法律和技术条款进行传输。例如,对于OSM:

因此,您需要创建一个能够执行这种批量传输的服务器/客户端脚本(可能以打包的归档文件形式?),并请求将其放置在特定位置以供用户使用。我在Leaflet方面没有足够的经验,无法告诉您如何提供它们,但是您可以将它们添加到浏览器缓存本身,或者使用本地服务器将它们提供为localhost。

无论如何,如果您有更多问题,请随时问我。


2

这是我想到的方法。我将地图区域导入数据库,然后将该区域作为可下载的套餐提供给用户。当用户下载该套餐时,查询数据库并以JSON格式返回与该区域相关联的所有瓷砖。这些图像存储为BLOB。然后,我将这个瓷砖数组传递给一个自定义的Leaflet层,它解析数据。以下是该层的代码:

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;
        }
    });
});

0

我认为你可以使用四叉树,即空间填充曲线。MS Bing Map使用最简单的瓦片地图:http://bcdcspatial.blogspot.de/2012/01/onlineoffline-mapping-map-tiles-and.html?m=1。我认为其他地图服务器也使用了空间填充曲线,但不是那么明显。你可以搜索ms bings maps quadkey或nick's spatial index hilbert curve。你也可以在phpclasses.org上下载我的php类hilbert curve。你可以将它与许多不同的空间填充曲线一起使用,并生成一个quadkey。一个好的开始也是黑客的食谱。有一个专门介绍hilbert曲线的整章。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接