<div dir="ltr"><div dir="ltr">The easiest way to achieve this is to configure a custom tileLoadFunction for the VectorTile source. That function, when it receives a 404, has to request the tile for the next lower zoom, until it receives a 200, and call `setFeatures` with the result. Something like this (untested):<div><br></div><div><div style="line-height:18px"><div style="color:rgb(0,0,0);font-family:Menlo,Monaco,"Courier New",monospace;font-size:12px;white-space:pre"><span style="color:rgb(175,0,219)">import</span> {<span style="color:rgb(0,16,128)">getCenter</span>} <span style="color:rgb(175,0,219)">from</span> <span style="color:rgb(163,21,21)">'ol/extent'</span>;</div><div style="color:rgb(0,0,0);font-family:Menlo,Monaco,"Courier New",monospace;font-size:12px;white-space:pre"><span style="color:rgb(175,0,219)">import</span> <span style="color:rgb(0,16,128)">MVT</span> <span style="color:rgb(175,0,219)">from</span> <span style="color:rgb(163,21,21)">'ol/format/MVT'</span>;</div><br><div style="color:rgb(0,0,0);font-family:Menlo,Monaco,"Courier New",monospace;font-size:12px;white-space:pre"><span style="color:rgb(0,0,255)">const</span> <span style="color:rgb(0,112,193)">source</span> = <span style="color:rgb(0,0,255)">new</span> <span style="color:rgb(38,127,153)">VectorTileSource</span>({</div><div style="color:rgb(0,0,0);font-family:Menlo,Monaco,"Courier New",monospace;font-size:12px;white-space:pre">  <span style="color:rgb(0,16,128)">format:</span> <span style="color:rgb(0,0,255)">new</span> <span style="color:rgb(38,127,153)">MVT</span>(),</div><div style="color:rgb(0,0,0);font-family:Menlo,Monaco,"Courier New",monospace;font-size:12px;white-space:pre">  <span style="color:rgb(0,16,128)">url:</span> <span style="color:rgb(163,21,21)">'<a href="https://my.tiles/{z}/{x}/{y}.pbf">https://my.tiles/{z}/{x}/{y}.pbf</a>'</span>,</div><div style="color:rgb(0,0,0);font-family:Menlo,Monaco,"Courier New",monospace;font-size:12px;white-space:pre">  <span style="color:rgb(121,94,38)">tileLoadFunction</span>(<span style="color:rgb(0,16,128)">tile</span>, <span style="color:rgb(0,16,128)">url</span>) {</div><div style="color:rgb(0,0,0);font-family:Menlo,Monaco,"Courier New",monospace;font-size:12px;white-space:pre">    <span style="color:rgb(0,16,128)">tile</span>.<span style="color:rgb(121,94,38)">setLoader</span>(<span style="color:rgb(0,0,255)">async</span> (<span style="color:rgb(0,16,128)">extent</span>, <span style="color:rgb(0,16,128)">resolution</span>, <span style="color:rgb(0,16,128)">projection</span>) <span style="color:rgb(0,0,255)">=></span> {</div><div style="color:rgb(0,0,0);font-family:Menlo,Monaco,"Courier New",monospace;font-size:12px;white-space:pre">      <span style="color:rgb(0,0,255)">let</span> <span style="color:rgb(0,16,128)">response</span> = <span style="color:rgb(175,0,219)">await</span> <span style="color:rgb(121,94,38)">fetch</span>(<span style="color:rgb(0,16,128)">url</span>);</div><div style="color:rgb(0,0,0);font-family:Menlo,Monaco,"Courier New",monospace;font-size:12px;white-space:pre">      <span style="color:rgb(0,0,255)">let</span> <span style="color:rgb(0,16,128)">status</span> = <span style="color:rgb(0,16,128)">response</span>.<span style="color:rgb(0,16,128)">status</span>;</div><div style="color:rgb(0,0,0);font-family:Menlo,Monaco,"Courier New",monospace;font-size:12px;white-space:pre">      <span style="color:rgb(0,0,255)">let</span> <span style="color:rgb(0,16,128)">tileCoord</span> = <span style="color:rgb(0,16,128)">tile</span>.<span style="color:rgb(0,16,128)">tileCoord</span>;</div><div style="color:rgb(0,0,0);font-family:Menlo,Monaco,"Courier New",monospace;font-size:12px;white-space:pre">      <span style="color:rgb(0,0,255)">const</span> <span style="color:rgb(0,112,193)">tileGrid</span> = <span style="color:rgb(0,16,128)">source</span>.<span style="color:rgb(121,94,38)">getTileGrid</span>();</div><div style="color:rgb(0,0,0);font-family:Menlo,Monaco,"Courier New",monospace;font-size:12px;white-space:pre">      <span style="color:rgb(175,0,219)">while</span> (<span style="color:rgb(0,16,128)">status</span> !== <span style="color:rgb(9,134,88)">200</span> && <span style="color:rgb(0,16,128)">tileCoord</span>[<span style="color:rgb(9,134,88)">0</span>] > <span style="color:rgb(0,16,128)">tileGrid</span>.<span style="color:rgb(121,94,38)">getMinZoom</span>()) {</div><div style="color:rgb(0,0,0);font-family:Menlo,Monaco,"Courier New",monospace;font-size:12px;white-space:pre">        <span style="color:rgb(0,0,255)">const</span> <span style="color:rgb(0,112,193)">z</span> = <span style="color:rgb(0,16,128)">tileCoord</span>[<span style="color:rgb(9,134,88)">0</span>];</div><div style="color:rgb(0,0,0);font-family:Menlo,Monaco,"Courier New",monospace;font-size:12px;white-space:pre">        <span style="color:rgb(0,16,128)">tileCoord</span> = <span style="color:rgb(0,16,128)">tileGrid</span>.<span style="color:rgb(121,94,38)">getTileCoordForCoordAndZ</span>(</div><div style="color:rgb(0,0,0);font-family:Menlo,Monaco,"Courier New",monospace;font-size:12px;white-space:pre">          <span style="color:rgb(121,94,38)">getCenter</span>(<span style="color:rgb(0,16,128)">tileGrid</span>.<span style="color:rgb(121,94,38)">getTileCoordExtent</span>(<span style="color:rgb(0,16,128)">tileCoord</span>)), <span style="color:rgb(0,16,128)">z</span> - <span style="color:rgb(9,134,88)">1</span></div><div style="color:rgb(0,0,0);font-family:Menlo,Monaco,"Courier New",monospace;font-size:12px;white-space:pre">        );</div><div style="color:rgb(0,0,0);font-family:Menlo,Monaco,"Courier New",monospace;font-size:12px;white-space:pre">        <span style="color:rgb(0,16,128)">response</span> = <span style="color:rgb(175,0,219)">await</span> <span style="color:rgb(121,94,38)">fetch</span>(<span style="color:rgb(0,16,128)">source</span>.<span style="color:rgb(121,94,38)">getTileUrlFunction</span>()(<span style="color:rgb(0,16,128)">tileCoord</span>, <span style="color:rgb(0,16,128)">devicePixelRatio</span>, <span style="color:rgb(0,16,128)">projection</span>));</div><div style="color:rgb(0,0,0);font-family:Menlo,Monaco,"Courier New",monospace;font-size:12px;white-space:pre">      }</div><div style="color:rgb(0,0,0);font-family:Menlo,Monaco,"Courier New",monospace;font-size:12px;white-space:pre">      <span style="color:rgb(0,0,255)">const</span> <span style="color:rgb(0,112,193)">data</span> = <span style="color:rgb(175,0,219)">await</span> <span style="color:rgb(0,16,128)">response</span>.<span style="color:rgb(121,94,38)">arrayBuffer</span>();</div><div style="color:rgb(0,0,0);font-family:Menlo,Monaco,"Courier New",monospace;font-size:12px;white-space:pre">      <span style="color:rgb(0,0,255)">const</span> <span style="color:rgb(0,112,193)">format</span> = <span style="color:rgb(0,16,128)">tile</span>.<span style="color:rgb(121,94,38)">getFormat</span>()</div><div style="color:rgb(0,0,0);font-family:Menlo,Monaco,"Courier New",monospace;font-size:12px;white-space:pre">      <span style="color:rgb(0,0,255)">const</span> <span style="color:rgb(0,112,193)">features</span> = <span style="color:rgb(0,16,128)">format</span>.<span style="color:rgb(121,94,38)">readFeatures</span>(<span style="color:rgb(0,16,128)">data</span>, {</div><div style="color:rgb(0,0,0);font-family:Menlo,Monaco,"Courier New",monospace;font-size:12px;white-space:pre">        <span style="color:rgb(0,16,128)">extent:</span> <span style="color:rgb(0,16,128)">extent</span>,</div><div style="color:rgb(0,0,0);font-family:Menlo,Monaco,"Courier New",monospace;font-size:12px;white-space:pre">        <span style="color:rgb(0,16,128)">featureProjection:</span> <span style="color:rgb(0,16,128)">projection</span></div><div style="color:rgb(0,0,0);font-family:Menlo,Monaco,"Courier New",monospace;font-size:12px;white-space:pre">      });</div><div style="color:rgb(0,0,0);font-family:Menlo,Monaco,"Courier New",monospace;font-size:12px;white-space:pre">      <span style="color:rgb(0,16,128)">tile</span>.<span style="color:rgb(121,94,38)">setFeatures</span>(<span style="color:rgb(0,16,128)">features</span>);</div><div style="color:rgb(0,0,0);font-family:Menlo,Monaco,"Courier New",monospace;font-size:12px;white-space:pre">    });</div><div style="color:rgb(0,0,0);font-family:Menlo,Monaco,"Courier New",monospace;font-size:12px;white-space:pre">  }</div><div style="color:rgb(0,0,0);font-family:Menlo,Monaco,"Courier New",monospace;font-size:12px;white-space:pre">});</div><br>I hope this helps.<br><br>Andreas.</div></div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Aug 4, 2020 at 2:45 PM Daniel Urda <<a href="mailto:daniel.urda.ct@gmail.com">daniel.urda.ct@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir="ltr">
<div>Hello,</div><div><br></div><div>I am resending this since the mail requiring confirmation of registration to the mailing list went to my spam folder. Sorry if this results in a duplicate mail.<br></div><div><br></div><div>I am trying to consume a vector tiles as provide by an ArcGIS Enterprise Server. I successfully managed to hijack the MapboxVector layer in order to display the tiles in OpenLayers (fortunately style description is more or less compatible with MapboxVector). <br></div><div>The issue is that ESRI Vector Tile Services randomly decide to drop lower level tiles. Thus, if ESRI somehow decides that for a certain area level X+1 does not provide significantly more information than level X, tiles on level X+1 are not generated 
 (requests result in 404)

 and the client is expected to display the data on level X. ArcGIS JS does have a mechanism to make sure it never gets 404 (making use of <a href="https://developers.arcgis.com/rest/services-reference/tile-map.htm" target="_blank">https://developers.arcgis.com/rest/services-reference/tile-map.htm</a> ), however it seems to me that implementing that in OL would need significant effort with low benefits. Setting maxZoom on the vector tile is not really helpful, since better zoom levels may exist in some regions (detecting the max level that has tiles for all areas is cumbersome, but doable using the API in the provided link). <br></div><div>Therefore, I was thinking I could somehow convince OL to render the tile at best available resolution when it gets 404s at better resolution. Any hint to where exactly in the code I could do that?</div><div><br></div><div>Thanks,</div><div>Daniel Urda</div>

</div>
_______________________________________________<br>
Users mailing list<br>
<a href="mailto:Users@lists.osgeo.org" target="_blank">Users@lists.osgeo.org</a><br>
<a href="https://lists.osgeo.org/mailman/listinfo/openlayers-users" rel="noreferrer" target="_blank">https://lists.osgeo.org/mailman/listinfo/openlayers-users</a></blockquote></div>