在OpenLayers中,为什么在翻译的MVT图层上useInterimTilesOnError行为不同?

时间:2019-06-10 21:42:49

标签: openlayers

渲染平移的MVT图层时,如果useInterimTilesOnError为true,则不会渲染某些图块的某些部分。但是,如果(1)图层未翻译或(2)图层已翻译但useInterimTilesOnError为假,则会渲染完整图块。

如果运行此示例,则第三张地图将显示以下半渲染图块:

var proj3857 = ol.proj.get('EPSG:3857');

var center = ol.proj.fromLonLat([133.9789237, -23.6188074]);
var view = new ol.View({
  center: center,
  maxZoom: 23,
  zoom: 10,
  projection: proj3857
});

var raster = new ol.layer.Tile({
  opacity: .4,
  source: new ol.source.XYZ({
    url: 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',
    maxZoom: 23,
  })
});
createMap('untranslated', 0, true);
createMap('false', 20000, false);
createMap('true', 20000, true);

function createMap(id, dx, useInterimTilesOnError) {

  var map = new ol.Map({
    layers: [raster],
    target: id,
    view: view
  });

  let dy = 0;
  var extent = proj3857.getExtent();
  var offsetExtent = [extent[0] + dx, extent[1] + dy, extent[2] + dx, extent[3] + dy];

  var layer = new ol.layer.VectorTile({
    source: new ol.source.VectorTile({
      format: new ol.format.MVT(),
      wrapX: false,
      url: 'https://basemaps.arcgis.com/v1/arcgis/rest/services/World_Basemap/VectorTileServer/tile/{z}/{y}/{x}.pbf',
      tileGrid: ol.tilegrid.createXYZ({
        extent: offsetExtent,
        maxZoom: 18
      })
    }),
    useInterimTilesOnError: useInterimTilesOnError,
    style: new ol.style.Style({
      stroke: new ol.style.Stroke({
        width: 1,
        color: 'black'
      })
    })
  });

  map.addLayer(layer);

  map.addLayer(new ol.layer.Tile({
    source: new ol.source.TileDebug({
      projection: proj3857,
      tileGrid: ol.tilegrid.createXYZ({
        extent: offsetExtent,
        maxZoom: 18
      })
    })
  }));
}
.map {
  height: 400px;
  width: 100%;
  margin-bottom: 10px;
}
<link href="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/css/ol.css" rel="stylesheet"/>
<script src="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/build/ol.js"></script>
<div>
  <h4>Untranslated plus useInterimTilesOnError: true</h4>
  <div id="untranslated" class="map"></div>
</div>
<div>
  <h4>Translated plus useInterimTilesOnError: false</h4>
  <div id="false" class="map"></div>
</div>
<div>
  <h4>Translated plus useInterimTilesOnError: true</h4>
  <div id="true" class="map"></div>
</div>

如果图块存在问题,我希望它也不会在第一张未翻译的地图中正确绘制。

[顺便说一句,我还希望useInterimTilesOnError仅适用于无法检索的图块。但是,很明显,这些图块正在被检索。我不确定它们还会发生什么其他类型的错误? ]

1 个答案:

答案 0 :(得分:1)

使用void Undo() { if (result.Count==0) { Console.WriteLine("UNDO IS NOT AVAILABLE"); } result.Pop(); //Remove current total from last expression total = result.Peek(); //Take previous total Console.WriteLine("Running total:{0}", total); } 似乎存在一个问题,因为视图投影范围与tilegrid范围不匹配,并且正在根据视图投影裁剪图块。矢量图块无法重新投影,因此具有相同的投影但程度不同似乎是原因。定义转换的范围并将其用于视图似乎可以解决此问题,并且可以“重新投影”栅格图层(尽管坐标之间的唯一差异将接近日期线,因此不太可能涉及很多开销)。

我在您的演示中添加了更多方案:

useInterimTilesOnError: true
var proj3857 = ol.proj.get('EPSG:3857');

proj4.defs('EPSG:3857X', '+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext  +no_defs');

if (ol.proj.proj4 && ol.proj.proj4.register) { ol.proj.proj4.register(proj4); }

var dx = 20000;
var dy = 0;

var extent = ol.proj.get('EPSG:3857').getExtent();
var offsetExtent = [extent[0] + dx, extent[1] + dy, extent[2] + dx, extent[3] + dy];

var proj3857X = ol.proj.get('EPSG:3857X');
proj3857X.setGlobal(true);
proj3857X.setExtent(offsetExtent);

var center = ol.proj.fromLonLat([133.9789237, -23.6188074]);
var view = new ol.View({
  center: center,
  maxZoom: 23,
  zoom: 10,
  projection: proj3857
});

var viewX = new ol.View({
  center: center,
  maxZoom: 23,
  zoom: 10,
  projection: proj3857X
});

  var sync = true;

  view.on(['change:center','change:resolution','change:rotation'], function() {
    if (sync) {
      var center = view.getCenter();
      var zoom = view.getZoom();
      var rotation = view.getRotation();
      sync = false;
      viewX.animate({
        center: center,
        zoom: zoom,
        rotation: rotation,
        duration: 0
      }, function() { sync = true; });
    }
  });

 viewX.on(['change:center','change:resolution','change:rotation'], function() {
    if (sync) {
      var center = viewX.getCenter();
      var zoom = viewX.getZoom();
      var rotation = viewX.getRotation();
      sync = false;
      view.animate({
        center: center,
        zoom: zoom,
        rotation: rotation,
        duration: 0
      }, function() { sync = true; });
    }
  });

var raster = new ol.layer.Tile({
  opacity: .4,
  source: new ol.source.XYZ({
    url: 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',
    maxZoom: 23,
  })
});
createMap('untranslated-false', 0, 0, false, view);
createMap('untranslated-true', 0, 0, true, view);
createMap('false', dx, dy, false, view);
createMap('true', dx, dy, true, view);
createMap('projected-false', dx, dy, false, viewX);
createMap('projected-true', dx, dy, true, viewX);

function createMap(id, dx, dy, useInterimTilesOnError, view) {

  var map = new ol.Map({
    layers: [raster],
    target: id,
    view: view
  });

  var extent = proj3857.getExtent();
  var offsetExtent = [extent[0] + dx, extent[1] + dy, extent[2] + dx, extent[3] + dy];

  var layer = new ol.layer.VectorTile({
    source: new ol.source.VectorTile({
      format: new ol.format.MVT(),
      //wrapX: false,
      projection: view.getProjection(),
      url: 'https://basemaps.arcgis.com/v1/arcgis/rest/services/World_Basemap/VectorTileServer/tile/{z}/{y}/{x}.pbf',
      tileGrid: ol.tilegrid.createXYZ({
        extent: offsetExtent,
        maxZoom: 18
      })
    }),
    useInterimTilesOnError: useInterimTilesOnError,
    style: new ol.style.Style({
      stroke: new ol.style.Stroke({
        width: 1,
        color: 'black'
      })
    })
  });

  map.addLayer(layer);

  map.addLayer(new ol.layer.Tile({
    source: new ol.source.TileDebug({
      projection: proj3857,
      tileGrid: ol.tilegrid.createXYZ({
        extent: offsetExtent,
        maxZoom: 18
      })
    })
  }));
}
.map {
  height: 400px;
  width: 100%;
  margin-bottom: 10px;
}