tangrams / heightmapper

interactive heightmaps from terrain data
http://tangrams.github.io/heightmapper
MIT License
414 stars 120 forks source link

Issues with rendering #44

Open azrellie opened 1 year ago

azrellie commented 1 year ago

Rendering with "render multiplier" values 1.5 and over has these unloaded white tiles in the rendered image (and it happens every single time, with the same result, no matter how many times I render the same place).

Multiplier: 1.5 render (1)

Multiplier: 8 (compressed to upload) render (2)

Casqade commented 1 year ago

In my case the problem was due to tile.nextzen.org (that's where tiles are downloaded from) anti-DDoS protection: server returns 429 status code (too many requests).

As a quick-time dirty hack I just added an artificial delay between tile requests in main.js:

logRenderStep("Rendering cells");

// Render each cell:
let count = 0;
for(const bounds of cells) {
  // wait for Leaflet moveend + zoomend events
  await new Promise(r => setTimeout(r, 2000)); // <--- wait 2 seconds
  await async function() {
    return new Promise(resolve => {
      map.once('moveend zoomend', resolve);
      map.fitBounds(bounds);
    });
  }();

You can override main.js source code in your browser DevTools.

Delay time can be decreased as long as it doesn't go above the server threshold for request frequency. This threshold may change in the time being, so my initial delay of 2 seconds won't work forever. Ideally, the code should automatically reload failed tile download requests after some delay to prevent white boxes in the final render. Unfortunately, I'm not a JS developer so solving it properly is up to repository maintainers or other contributors :)

quentinjeanningros commented 8 months ago

I have the same issue, merged to CORS issue,

I use this app often I will be glad to make a PR, but I can't manage to run this app locally : I can't understand why but everything is white, and no tiles are loaded

However, your fix @Casqade help a lot, I tryed to implement a try/catch on this part

map.once('moveend zoomend', resolve);
map.fitBounds(bounds);

but it's not look like the throw errors so it can't loop on error to make it work anyway

Allakazan commented 3 months ago

In my case the problem was due to tile.nextzen.org (that's where tiles are downloaded from) anti-DDoS protection: server returns 429 status code (too many requests).

As a quick-time dirty hack I just added an artificial delay between tile requests in main.js:

logRenderStep("Rendering cells");

// Render each cell:
let count = 0;
for(const bounds of cells) {
  // wait for Leaflet moveend + zoomend events
  await new Promise(r => setTimeout(r, 2000)); // <--- wait 2 seconds
  await async function() {
    return new Promise(resolve => {
      map.once('moveend zoomend', resolve);
      map.fitBounds(bounds);
    });
  }();

You can override main.js source code in your browser DevTools.

Delay time can be decreased as long as it doesn't go above the server threshold for request frequency. This threshold may change in the time being, so my initial delay of 2 seconds won't work forever. Ideally, the code should automatically reload failed tile download requests after some delay to prevent white boxes in the final render. Unfortunately, I'm not a JS developer so solving it properly is up to repository maintainers or other contributors :)

Bro you just saved my day ! I think i'm going to fork this app and implement this new features

quentinjeanningros commented 3 months ago

In my case the problem was due to tile.nextzen.org (that's where tiles are downloaded from) anti-DDoS protection: server returns 429 status code (too many requests). As a quick-time dirty hack I just added an artificial delay between tile requests in main.js:

logRenderStep("Rendering cells");

// Render each cell:
let count = 0;
for(const bounds of cells) {
  // wait for Leaflet moveend + zoomend events
  await new Promise(r => setTimeout(r, 2000)); // <--- wait 2 seconds
  await async function() {
    return new Promise(resolve => {
      map.once('moveend zoomend', resolve);
      map.fitBounds(bounds);
    });
  }();

You can override main.js source code in your browser DevTools. Delay time can be decreased as long as it doesn't go above the server threshold for request frequency. This threshold may change in the time being, so my initial delay of 2 seconds won't work forever. Ideally, the code should automatically reload failed tile download requests after some delay to prevent white boxes in the final render. Unfortunately, I'm not a JS developer so solving it properly is up to repository maintainers or other contributors :)

Bro you just saved my day ! I think i'm going to fork this app and implement this new features

Let me know if it work, i tried but I don't acheive make it work