LeafletJS - 具有本地文件系统的缓存切片

时间:2014-06-18 07:33:08

标签: android html5 cordova leaflet html5-filesystem

我正在实现Cordova应用程序(3.2),我希望将LeafletJS和地图图块提供程序与图块的本地文件系统缓存一起使用。

我在概述中的方法如下:

  • 扩展Leaflet TileLayer
  • 覆盖_loadTile方法以从本地文件系统或远程
  • 检索磁贴

我的代码:

var StorageTileLayer = L.TileLayer.extend({
log: function (text) {
  if (this.options.log)
    this.options.log(text);
  else
    console.log("[StorageTileLayer]: " + text);
},
_setUpTile: function (tile, key, value, cache) {
  try {
    tile._layer = this;
    tile.onload = this._tileOnLoad;
    tile.onerror = this._tileOnError;

    this._adjustTilePoint(tile);
    tile.src = value;
    this.fire('tileloadstart', {
      tile: tile,
      url: tile.src
    });

    this.log("Setting url to " + tile.src);
  }
  catch (e) {
    this.log("ERROR in setUpTile: " + e.message);
  }
},

_loadTile: function (tile, tilePoint) {
  this._adjustTilePoint(tilePoint);
  var key = tilePoint.z + ',' + tilePoint.y + ',' + tilePoint.x;
  var self = this;
  var tileUrl = self.getTileUrl(tilePoint);
  console.log(tileUrl);
  console.log(typeof tileUrl);
  if (this.options.storage) {
    this.log("Load Tile with storage");
    this.options.storage.get(key, tileUrl).then(function (value) {
      self.log("Tile URL to load: " + value.url);
      self._setUpTile(tile, key, value.url, true);
    });
  } else {
    this.log("Load Tile without storage");
    self._setUpTile(tile, key, tileUrl, false);
  }
}

});

options.storage是一个存储方法,它具有方法get(key, remoteUrl),并返回本地文件存储区中的缓存区块(此实现实际工作正常,所以这里不是问题)或远程网址但是下载了在后台平铺,以便下次调用时可以从本地文件存储中获取。

不幸的是,当我使用Charles(Web调试代理)时,我可以在我的设备上看到虽然加载了本地地图图块(我可以从日志中看到它),但仍然有一些对地图图块提供程序的请求。

有没有人知道我做错了什么以及我在StorageTileLayer覆盖了什么以阻止对遥控器的调用?真正的问题是,地图也应该在离线模式下工作,但事实并非如此。

感谢您的帮助。

环境中的图书馆:

  • 宣传单(0.7.3)
  • angularJS(1.2.16)
  • Cordova(3.2)

1 个答案:

答案 0 :(得分:3)

我基本上用这个代码修改了它(angular js):

(function (window, L) {
  var isDebug = false;
  var StorageTileLayer = L.TileLayer.extend({

    log: function (text) {
      if (!isDebug)
        return;
      if (this.options.log)
        this.options.log(text);
      else
        console.log("[StorageTileLayer]: " + text);
    },
    _setUpTile: function (tile, key, value, cache) {
      try {
        tile._layer = this;
        tile.onload = this._tileOnLoad;
        tile.onerror = this._tileOnError;

        this._adjustTilePoint(tile);
        tile.src = value;
        this.fire('tileloadstart', {
          tile: tile,
          url: tile.src
        });
      }
      catch (e) {
        this.log("ERROR in setUpTile: " + e.message);
      }
    },

    _loadTile: function (tile, tilePoint) {
      this._adjustTilePoint(tilePoint);
      var key = tilePoint.z + ',' + tilePoint.y + ',' + tilePoint.x;
      var self = this;
      var tileUrl = self.getTileUrl(tilePoint);
      if (isNaN(tilePoint.x) || isNaN(tilePoint.y)) {
        this.log("TilePoint x or y is nan: " + tilePoint.x + "-" + tilePoint.y);
        return;
      }
      if (this.options.storage) {
        this.options.storage.get(key, tileUrl).then(function (value) {
          self.log("Tile URL to load: " + value.url);
          self._setUpTile(tile, key, value.url, true);
        });
      } else {
        this.log("Load Tile without storage");
        self._setUpTile(tile, key, tileUrl, false);
      }
    }
  });

  window.StorageTileLayer = StorageTileLayer;
})(window, L);

将图块层添加到传单图中是重要的部分!您必须防止负载均衡器为每个磁贴获取不同的URL。我通过将tole层的url设置为固定值来实现:

var url = 'https://a.tiles.mapbox.com/v3/<<YOUR ACCESS CODE>>/{z}/{x}/{y}.png';
    var layer = new StorageTileLayer(url, {
      storage: TileStorage
    });

当然,在我的情况下,你仍然需要实现TileStorage它有一个方法get(key, url)并返回一个$q - 延迟,它可以使用本地可用文件解析。如果该文件在本地存储中不可用,则将下载该文件,然后解析承诺。

不幸的是,这个TileStorage不公开,因为它是我公司的内部开发,所以我无法分享它。

尽管如此,我希望这会对你有所帮助。