无法访问方法下载图像

时间:2018-04-18 15:48:55

标签: javascript reactjs openlayers-3

我试图调用方法来下载地图图片,但我不知道如何等待

如果我只使用这部分代码,我可以完美地下载图像

handleGetImage = () => {

    this.setState({ imageButtonDisabled: true, cancelButtonDisabled: true, isLoading: true });

    this.checkIfStatusEnd();

    if (this.state.radioArea === true) {
        this.hideLayerArea();
        var size = /** @type {ol.Size} */ (this.map.getSize());
        this.map.getView().setCenter(this.state.center);
        this.map.getView().fit(this.state.extent, size);
    } 

    window.setTimeout( () => {
        var canvas = document.getElementsByTagName("canvas")[0];

        this.map.once('precompose', (event) => {
            this.setDPI(canvas,300);
        });

        this.map.once('postcompose', (event) => {
            var canvas = event.context.canvas;
            canvas.toBlob( (blob) => {
                this.showLayerArea();
                FileSaver.saveAs(blob, "map.png");
                this.setState({ imageButtonDisabled: false, cancelButtonDisabled: false, isLoading: false });
                // this.props.closePopup();
            });
        });
    }, 400 );
}

setDPI = (canvas, dpi) => {
    var scaleFactor = dpi / 96;
    canvas.width = Math.ceil(canvas.width * scaleFactor);
    canvas.height = Math.ceil(canvas.height * scaleFactor);
    var ctx=canvas.getContext("2d");
    ctx.scale(scaleFactor, scaleFactor);
}

但是当我尝试在downloadImage方法中调用方法hide时,不行。如何正确调用该方法?

地图渲染完成后调用

hide方法。

我不知道很多javascript,我正在学习..有人可以解释我或者如何做出更好的实现,当this.loading === this.loaded调用方法downloadImage?回调或其他什么?

由于

handleGetImage = () => {

    this.setState({ imageButtonDisabled: true, cancelButtonDisabled: true, isLoading: true });

    this.checkIfStatusEnd();

    if (this.state.radioArea === true) {
        this.hideLayerArea();
        var size = /** @type {ol.Size} */ (this.map.getSize());
        this.map.getView().setCenter(this.state.center);
        this.map.getView().fit(this.state.extent, size);
    }
}

downloadImage = () => {

    setTimeout( () => {
        var canvas = document.getElementsByTagName("canvas")[0];
        this.map.once('precompose', (event) => {
            this.setDPI(canvas,300);
        });

        this.map.once('postcompose', (event) => {
            var canvas = event.context.canvas;
            canvas.toBlob( (blob) => {
                this.showLayerArea();
                FileSaver.saveAs(blob, "map.png");
                this.setState({ imageButtonDisabled: false, cancelButtonDisabled: false, isLoading: false });
                // this.props.closePopup();
            });
        });
    }, 400 );
}

setDPI = (canvas, dpi) => {
    var scaleFactor = dpi / 96;
    canvas.width = Math.ceil(canvas.width * scaleFactor);
    canvas.height = Math.ceil(canvas.height * scaleFactor);
    var ctx=canvas.getContext("2d");
    ctx.scale(scaleFactor, scaleFactor);
}

checkIfStatusEnd = () => {
    this.map.getLayers().forEach( (layer) => {
        if (layer.getVisible() === true) {
            if (layer.values_.name !== 'custom-area') {
                this.layersCached.push(layer);

                if ((layer.getType() === 'TILE') || (layer.getType() === 'VECTOR_TILE')) {

                    layer.getSource().on('tileloadstart', () => {
                        this.addLoading();
                    });

                    layer.getSource().on('tileloadend', () => {
                        this.addLoaded();
                    });

                    layer.getSource().on('tileloaderror', () => {
                        this.addLoaded();
                    });

                } else if (layer.getType() === 'IMAGE') {
                    layer.getSource().on('imageloadend', () => {
                        // TO-DO
                    });
                }
            }
        }
    });
}

unsubscribeLayerEvent = () => {
    this.layersCached.forEach( (layer) => {
        if ((layer.getType() === 'TILE') || (layer.getType() === 'VECTOR_TILE')) {
            layer.getSource().un('tileloadend', null);
            layer.getSource().un('tileloadend', null);
            layer.getSource().un('tileloadend', null);
        } else if (layer.getType() === 'IMAGE') {
            layer.getSource().un('imageloadend', null);
        }
    });
}

/* Status Layer */
addLoading = () => {
    if (this.loading === 0) {
        this.show();
    }
    ++this.loading;
    this.update();
}

addLoaded = () => {
    var this_ = this;
    setTimeout( () => {
        ++this_.loaded;
        this_.update();
    }, 100);
}

update = () => {

    if (this.loading === this.loaded) {
        this.loading = 0;
        this.loaded = 0;
        var this_ = this;
        setTimeout( () => {
            this_.hide();
        }, 500);
    }
}

hide = () => {
    if (this.loading === this.loaded) {
        console.log('hide');
        this.downloadImage();
    }
}

show = () => {
    console.log('show');
}

1 个答案:

答案 0 :(得分:0)

<强>解决方案

问题是与postcompose方法发生冲突,事件添加了checkIfStatusEnd以捕获所有切片是否已完成。

handleGetImage = () => {

    this.setState({ imageButtonDisabled: true, cancelButtonDisabled: true, isLoading: true });

    this.hideLayerArea()
    .then( () => {
        if (this.state.radioArea === true) {
            this.checkIfStatusEnd();
            var size = /** @type {ol.Size} */ (this.map.getSize());
            this.map.getView().setCenter(this.state.center);
            this.map.getView().fit(this.state.extent, size);
            this.canvas = document.getElementsByTagName("canvas")[0];
            this.map.once('precompose', (event) => {
                this.setDPI(this.canvas,300);
            });
        } 

    });
}

setDPI = (canvas, dpi) => {
    var scaleFactor = dpi / 96;
    canvas.width = Math.ceil(canvas.width * scaleFactor);
    canvas.height = Math.ceil(canvas.height * scaleFactor);
    var ctx=canvas.getContext("2d");
    ctx.scale(scaleFactor, scaleFactor);
}

checkIfStatusEnd = () => {
    this.map.getLayers().forEach( (layer) => {
        if (layer.getVisible() === true) {
            if (layer.values_.name !== 'custom-area') {
                this.layersCached.push(layer);

                if ((layer.getType() === 'TILE') || (layer.getType() === 'VECTOR_TILE')) {

                    layer.getSource().on('tileloadstart', () => {
                        this.addLoading();
                    });

                    layer.getSource().on('tileloadend', () => {
                        this.addLoaded();
                    });

                    layer.getSource().on('tileloaderror', () => {
                        this.addLoaded();
                    });

                } else if (layer.getType() === 'IMAGE') {
                    layer.getSource().on('imageloadstart', () => {
                        this.addLoading();
                    });

                    layer.getSource().on('imageloadend', () => {
                        this.addLoaded();
                    });

                    layer.getSource().on('imageloaderror', () => {
                        this.addLoaded();
                    });
                }
            }
        }
    });
}

unsubscribeLayerEvent = () => {
    this.layersCached.forEach( (layer) => {
        if ((layer.getType() === 'TILE') || (layer.getType() === 'VECTOR_TILE')) {
            layer.getSource().removeEventListener('tileloadend', null);
            layer.getSource().removeEventListener('tileloadend', null);
            layer.getSource().removeEventListener('tileloadend', null);
        } else if (layer.getType() === 'IMAGE') {
            layer.getSource().removeEventListener('imageloadstart', null);
            layer.getSource().removeEventListener('imageloadend', null);
            layer.getSource().removeEventListener('imageloaderror', null);
        }
    });
}

/* Status Layer */
addLoading = () => {
    ++this.loading;
    this.update();
}

addLoaded = () => {
    setTimeout( () => {
        ++this.loaded;
        this.update();
    }, 100);
}

update = () => {

    if (this.loading === this.loaded) {
        this.loading = 0;
        this.loaded = 0;
        setTimeout( () => {
            this.hide();
        }, 500);
    }
}

hide = () => {
    if (this.loading === this.loaded) {
        console.log('finish');
        this.downloadImage();
    }
}

downloadImage = () => {

    var dims = {
        a0: [1189, 841],
        a1: [841, 594],
        a2: [594, 420],
        a3: [420, 297],
        a4: [297, 210],
        a5: [210, 148]
    };

    var format = this.state.format;
    var dim = dims[format];

    var imgData = this.canvas.toDataURL("image/jpeg", 1.0);
    var pdf;
    if (this.state.orientation === 'portrait') {
        this.resize(this.canvas, dim[1], dim[0]);
        pdf = new jsPDF('portrait', undefined, format);
        pdf.addImage(imgData, 'JPEG', 0, 0, dim[1], dim[0]);
    } else {
        this.resize(this.canvas, dim[1], dim[0]);            
        pdf = new jsPDF('landscape', undefined, format);
        pdf.addImage(imgData, 'JPEG', 0, 0, dim[0], dim[1]);
    }

    pdf.save(`map-${format}-${this.state.orientation}.pdf`);
    this.setState({ imageButtonDisabled: false, cancelButtonDisabled: false, isLoading: false });
    this.props.closePopup();
}