Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ol.layer.Tile 'drawImage' on 'CanvasRenderingContext2D' exception when zoom out #8700

Closed
ChrisHSandN opened this issue Sep 24, 2018 · 3 comments · Fixed by #8805
Closed

ol.layer.Tile 'drawImage' on 'CanvasRenderingContext2D' exception when zoom out #8700

ChrisHSandN opened this issue Sep 24, 2018 · 3 comments · Fixed by #8805

Comments

@ChrisHSandN
Copy link

If I add a XYZ Image Tile layer with a small extent and then zoom out a long way I get fatal JS errors which cause the map to stop responding to interactions.

Example

https://jsfiddle.net/chris_h/scom9yv5/10/ (zoom out to < level 6 in Chrome or Firefox)

In the example I am mis-using a static image as a tile source however in my real code I have a proper tile set and still experience the same issues.

Chrome 69:

Uncaught DOMException: Failed to execute 'drawImage' on 'CanvasRenderingContext2D': The image argument is a canvas element with a width or height of 0.
    at CanvasTileLayerRenderer.composeFrame 
    at CanvasMapRenderer.renderFrame 
    at Map.renderFrame_ 
    at Map.<anonymous>

Firefox 61

InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable IntermediateCanvas.js:66
composeFrame  IntermediateCanvas.js:66
renderFrame  Map.js:161
renderFrame_PluggableMap.js:1224
PluggableMap/this.animationDelay_<PluggableMap.js:189
<anonymous> self-hosted:983:17

Edge

No issue

The line of failing code is:

context.drawImage(image, 0, 0, +image.width, +image.height,
        Math.round(dx), Math.round(dy), Math.round(dw), Math.round(dh));
@ahocevar
Copy link
Member

Confirmed. This happens when the tile gets downscaled to a width or height of 0 pixels. A fix would be to only call drawImage when dh or dw is greater than or equal to 0.5. Would you be willing and able to submit a pull request?

@ChrisHSandN
Copy link
Author

Would you be willing and able to submit a pull request?

Sorry, I don’t have any experience with the ol codebase beyond using it, so fixing it would be a bit beyond me.

For anyone finding this bug in the future: My temporary fix is to set the maxResolution of the layer to the same as the shortest size (in meters) of the tile set extent. My logic being that if resolution is defined in meters per pixel then this will be the resolution where the rendered image becomes <=1px wide and is of no use showing anyway.

var extent = [x1, y1, x2, y2]; //in lat/lng

new ol.Layer.Tile({
    ...
    maxResolution: Math.min(
        ol.sphere.getDistance(
            [extent[0], extent[1]],
            [extent[2], extent[1]]
        ),
        ol.sphere.getDistance(
            [extent[0], extent[1]],
            [extent[0], extent[3]]
        )
    )
});

@phanf
Copy link

phanf commented Mar 6, 2019

I had the same error but it was related to the ol.style.Style and how I assigned the svg image to it. The error was introduced when I updated my npm package from 'npm i openlayers' to 'npm i ol'.

Broken: Original code

    const svgIcon = '<svg...> ... </svg>';
    const mysvg = new Image();
    mysvg.src = 'data:image/svg+xml,' + encodeURI(svgIcon); // broken

FIX: The solution was to base64 the svg image before adding it to the ol.style.Style object.

styleFunction = (feature, resolution) => {
    const svgIcon = '<svg...> ... </svg>';
    const mysvg = new Image();
    mysvg.src = 'data:image/svg+xml;base64,' + btoa(svgIcon);  // base64 image
    return [ 
        new ol.style.Style({
        image: new ol.style.Icon({
          img: mysvg,
          imgSize: [20, 25]
        })
      })
    ];

 };

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants