如何检测Tile Server正确返回的tile,但是说没有地图数据"

时间:2018-03-30 11:14:14

标签: javascript leaflet

我知道Leaflet Tile Layer的tileerror事件,但是如果该图块只是一个虚拟的,并且没有地图数据,那么它就不会触发。免责声明。



var map = L.map("map").setView([52.21581894148382, 2.74709701538086], 14);

var layer = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
	attribution: 'Tiles © Esri — Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community'
});

layer.addTo(map);

layer.on("tileerror", function() {
  console.log("An error occurred while trying to load a tine...");
});

#map { height: 98vh; }

<link href="https://unpkg.com/leaflet@1.3.1/dist/leaflet.css" rel="stylesheet"/>
<script src="https://unpkg.com/leaflet@1.3.1/dist/leaflet.js"></script>

 <div id="map"></div>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:3)

如果我理解正确,你有一个Tile Server有时会返回一个技术上正确的平铺图像,但它的内容显示实际上没有有效的数据呈现在它上面,如下那个:

Example of tile without useful rendered data Tiles©Esri - 来源:Esri,i-cubed,USDA,USGS,AEX,GeoEye,Getmapping,Aerogrid,IGN,IGP,UPR-EGP和GIS用户社区

您希望在传单图块层获得此类图块时收到通知,其方式与"tileerror"事件类似。

由于图块在技术上是正确的,不幸的是Leaflet无法理解实际上没有渲染有用的数据。

但是,假设Tile Server始终返回完全相同的内容,您可以很好地与您知道没有数据的图块进行图像比较。

  1. 收听Tile Layer的"tileload"事件,以便在加载新图块时附加回调。
  2. 将平铺图像与您知道的平铺图像对应于“无用数据”状态进行比较。例如。您可以使用js-imagediff,但还有许多其他库可用于此类任务。
  3. 如果图像相同,则执行一些操作,例如发起新事件。
  4. (打开浏览器开发者控制台以查看以下代码段的效果)

    var map = L.map("map").setView([52.21581894148382, 2.74709701538086], 14);
    
    var layer = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
      attribution: 'Tiles &copy; Esri &mdash; Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community',
      crossOrigin: true // Required to be able to analyze the image in a canvas context.
    }).addTo(map);
    
    var nodatatile = document.getElementById('nodatatile');
    
    // 1. Listen to the Tile Layer's "tileload" event.
    // http://leafletjs.com/reference-1.3.0.html#gridlayer-tileload
    // http://leafletjs.com/reference-1.3.0.html#tileevent
    layer.on('tileload', function(tileEvent) {
      var tile = tileEvent.tile;
      var c = tileEvent.coords;
      // 2. Compare the tile with a known tile that has no useful data.
      // https://github.com/HumbleSoftware/js-imagediff/
      var isEqualToNoData = imagediff.equal(nodatatile, tile);
    
      // 3. Perform some action if they are equal, e.g. fire a new event.
      if (isEqualToNoData) {
        layer.fire('tilenodata', tileEvent);
      }
    });
    
    // Listen to the new event.
    layer.on('tilenodata', function(tileEvent) {
      var c = tileEvent.coords;
      console.log('Tile no data at ' + c.x + '/' + c.y + '/' + c.z);
    });
    #map {
      height: 98vh;
    }
    <link href="https://unpkg.com/leaflet@1.3.1/dist/leaflet.css" rel="stylesheet" />
    <script src="https://unpkg.com/leaflet@1.3.1/dist/leaflet.js"></script>
    <script src="https://unpkg.com/imagediff@1.0.8/imagediff.js"></script>
    
    <div id="map"></div>
    
    <img id="nodatatile" src="https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/14/5395/8316" crossorigin="" />