leaflet-headless icon indicating copy to clipboard operation
leaflet-headless copied to clipboard

Error: Image given has not completed loading

Open danidev opened this issue 6 years ago • 9 comments
trafficstars

Hello,

I've seen that this repo has been not actively developed since 2017 but I'm using it and eventually I could try to fix it if someone could help me to understand this issue, because apart of this issue this library works very well.

Basically, what happen is that if I zoom out too much, I get this exception:

uncaughtException: Error: Image given has not completed loading
    at CanvasRenderingContext2D.ctx.(anonymous function) [as drawImage] (.../node_modules/leaflet-headless/node_modules/jsdom/lib/jsdom/living/nodes/HTMLCanvasElement-impl.js:128:17)
    at drawTile (.../node_modules/leaflet-image/index.js:174:17)
    at Array.forEach (<anonymous>)
    at Queue.tileQueueFinish [as _call] (.../node_modules/leaflet-image/index.js:169:18)
    at maybeNotify (/home/daniele/git/print.nextatlas.com/node_modules/d3-queue/build/d3-queue.js:109:34)
    at .../node_modules/d3-queue/build/d3-queue.js:85:14
    at Image.im.onload .../node_modules/leaflet-image/index.js:146:17)
    at buffer2image (.../node_modules/leaflet-headless/src/image.js:29:25)
    at Request._callback (.../node_modules/leaflet-headless/src/image.js:41:13)
    at Request.self.callback (.../node_modules/request/request.js:185:22)
    at Request.emit (events.js:160:13)
    at Request.<anonymous> (.../node_modules/request/request.js:1161:10)
    at Request.emit (events.js:160:13)
    at IncomingMessage.<anonymous> (.../node_modules/request/request.js:1083:12)
    at Object.onceWrapper (events.js:255:19)
    at IncomingMessage.emit (events.js:165:20)

To be more precise, this is the configuration I use:

maxBounds = {
    northEast: {lat: 80.297927149974, lng: 180.94482421874997},
    southWest: {lat: -50.736455137010644, lng: -178.35205078125}
};

center = [45, 8];

mapConfig = {
    zoomControl: false,
    attributionControl: false,
    worldCopyJump: true,
    dragging: false,
    touchZoom: false,
    scrollWheelZoom: false,
    doubleClickZoom: false,
    boxZoom: false,
    tap: false,
    trackResize: false,
    minZoom: 0,
    maxBounds: L.latLngBounds(
    L.latLng(maxBounds.southWest.lat, maxBounds.southWest.lng),
        L.latLng(maxBounds.northEast.lat, maxBounds.northEast.lng))
};

tilesConfig = {
    attribution: '&copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, ' + '<a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>',
    maxZoom: 14,
    minZoom: 0,
    detectRetina: true,
    continuousWorld: true
}

const map = L.map(global.document.createElement('div'), mapConfig);
L.tileLayer('mapbox-url', tilesConfig).addTo(map);

To export the map I use this code:

map.setView(center, 1);             /* if the zoom is more than 1 it doesn't break */
this.map.setSize(width, height);    /* width = 572 height = 354 */

map.saveImage('test_map.png', (filename) => {
   /* callback when the export finishes */
});

Any hints will be very appreciated.

Daniele

danidev avatar Jan 04 '19 10:01 danidev

How many times does the layer have at zoom level 1? Do they cover the extent of the image you are trying to save?

jieter avatar Jan 17 '19 16:01 jieter

Hello, I have the same problem.

ablaye avatar Jun 06 '19 12:06 ablaye

Hi @jieter , the same error occurs when running the examples. F.i. doing the following:

npm install
cd examples/leaflet-image
node index.js

Returns the following:

Saving an image using leaflet-image...
/home/me/leaflet-headless/node_modules/jsdom/lib/jsdom/living/nodes/HTMLCanvasElement-impl.js:128
    return prev.apply(ctx, arguments);
                ^

Error: Image given has not completed loading
    at CanvasRenderingContext2D.ctx.(anonymous function) [as drawImage] (/home/me/leaflet-headless/node_modules/jsdom/lib/jsdom/living/nodes/HTMLCanvasElement-impl.js:128:17)
    at drawTile (/home/me/leaflet-headless/node_modules/leaflet-image/index.js:174:17)
    at Array.forEach (<anonymous>)
    at Queue.tileQueueFinish [as _call] (/home/me/leaflet-headless/node_modules/leaflet-image/index.js:169:18)
    at maybeNotify (/home/me/leaflet-headless/node_modules/d3-queue/build/d3-queue.js:109:34)
    at /home/me/leaflet-headless/node_modules/d3-queue/build/d3-queue.js:85:14
    at Image.im.onload (/home/me/leaflet-headless/node_modules/leaflet-image/index.js:146:17)
    at buffer2image (/home/me/leaflet-headless/src/image.js:29:25)
    at Request._callback (/home/me/leaflet-headless/src/image.js:41:13)
    at Request.self.callback (/home/me/leaflet-headless/node_modules/request/request.js:185:22)

Now, I'm very sure, that I didn't have this problem previously. I'm not sure what changed. I'm using node v10.16.1 and installed all the ubuntu libraries specified in the README.md.

Any ideas?

janbols avatar Jan 25 '20 13:01 janbols

@janbols Did you find a solution, i'm running into this problem aswell, on a system that has always been running fine.

mrcbk avatar Jan 30 '20 21:01 mrcbk

@janbols no idea, I have not used it touched this codebase in a while...

jieter avatar Jan 30 '20 21:01 jieter

@janbols @jieter Only thing I've managed to find out so far is that polygons (outlines, roads etc) are rendered ok and work, but as soon as I add a tilelayer the error occurs. Edit: only occurs when using openstreetmaps, i switched to thunderforest which works fine.

mrcbk avatar Jan 30 '20 23:01 mrcbk

@mrcbk, indeed using thunderforest also works for me. Hmmm, what could be different between both providers?

janbols avatar Jan 31 '20 20:01 janbols

There can be a multitude of differences between providers, for example CORS headers and response times.

jieter avatar Feb 01 '20 12:02 jieter

I'm just making a note here in case it helps anybody.

It seems that the osm xyz server has some weird CORS set up that prevents this library from working with it.

I spent nearly a day pulling my hair out trying to figure out what was going on but when I tried some different tiles everything worked.

Here's a few I tested that worked perfectly fine:

// mapbox works
let mapId = 'mapbox/streets-v11';
// let mapId = 'mapbox/outdoors-v11';
let token = "pk.yourmapboxtoken";
const tileLayer = L.tileLayer(
  `https://api.mapbox.com/styles/v1/${mapId}/tiles/{z}/{x}/{y}?access_token=${token}`
).addTo(map);

const tileLayer = L.tileLayer(
  `https://stamen-tiles.a.ssl.fastly.net/watercolor/{z}/{x}/{y}.jpg`
).addTo(map);

const tileLayer = L.tileLayer(
  `https://a.basemaps.cartocdn.com/rastertiles/voyager_labels_under/{z}/{x}/{y}.png`
).addTo(map);

const tileLayer = L.tileLayer(
  `https://a.basemaps.cartocdn.com/rastertiles/light_all/{z}/{x}/{y}.png`
).addTo(map);

It was only the OSM xyz server that was giving me the issue but realistically, it could be any server that doesn't send back CORS headers as expected.

DazDotOne avatar Dec 14 '21 11:12 DazDotOne