【问题标题】:LeafletJS - Cached tiles with local filesystemLeafletJS - 具有本地文件系统的缓存切片
【发布时间】:2014-06-18 07:33:07
【问题描述】:

我正在实现一个 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) 方法并从本地文件存储返回缓存的切片(此实现实际工作正常,所以这不是问题)或远程 url 但在后台下载切片,以便下次调用时可以从本地文件存储中使用它。

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

有谁知道我做错了什么以及我必须在我的StorageTileLayer 中覆盖什么以防止对远程的调用?真正的问题是,地图也应该在离线模式下工作,但事实并非如此。

感谢您的帮助。

环境中的库:

  • 传单 (0.7.3)
  • angularJS (1.2.16)
  • 科尔多瓦 (3.2)

【问题讨论】:

  • 嗨,我正在处理一个 Chrome 应用程序上的一个非常类似的问题,该应用程序不允许远程图像调用。我需要停止远程调用,检查它是否已经下载到本地文件系统,如果没有,则执行 XhrHttpRrequest 来获取磁贴。你有什么运气可以让你的版本正常工作吗?

标签: android html cordova leaflet html5-filesystem


【解决方案1】:

我基本上用这段代码(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-defer,它可以通过本地可用文件解决。如果文件在本地存储中不可用,则将下载该文件,然后解决 Promise。

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

但我希望这对你有所帮助。

【讨论】:

  • 如何将瓦片图层链接到传单地图?
  • 你做的方式永远是:layer.addTo(map);如何创建图层可以看上面的帖子。
  • 啊,谢谢 - 我正在使用 angular 指令,所以花了一段时间才弄清楚如何获取地图:leafletData.getMap().then(function(map) { ...跨度>
猜你喜欢
  • 2011-10-30
  • 1970-01-01
  • 2011-03-21
  • 2012-06-05
  • 2019-03-13
  • 2017-11-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多