오픈레이어스의 이미지 저장 및 프린트를 하기 위해서는 별도의 코드 구현이 필요하다.
구글 검색을 해보면 여러 케이스가 나오지만 제대로 작동되지 않는 코드가 많이 있었다.
공식 홈페이지에서 정상작동하는 코드를 확인할 수 있다.
현재시간 기준으로 6.5.0 버전에서 정상작동하는 코드를 정리하였다.
- 이미지 저장
map.once('rendercomplete', function(event) {
const mapCanvas = document.createElement("canvas");
const size = map.getSize();
mapCanvas.width = size[0];
mapCanvas.height = size[1];
const mapContext = mapCanvas.getContext("2d");
Array.prototype.forEach.call(
map.getViewport().querySelectorAll('.ol-layer canvas, canvas.ol-layer'),
canvas => {
if (canvas.width > 0) {
let matrix;
const transform = canvas.style.transform;
if (transform) {
matrix = transform
.match(/^matrix\(([^\(]*)\)$/)[1]
.split(',')
.map(Number);
} else {
matrix = [
parseFloat(canvas.style.width) / canvas.width,
0,
0,
parseFloat(canvas.style.height) / canvas.height,
0,
0,
];
}
CanvasRenderingContext2D.prototype.setTransform.apply(mapContext, matrix);
mapContext.drawImage(canvas, 0, 0);
}
}
);
if (navigator.msSaveBlob) {
navigator.msSaveBlob(mapCanvas.msToBlob(), 'map.png');
} else {
const link = document.getElementById('image-download');
link.href = mapContext.canvas.toDataURL("image/jpeg");
link.click();
}
});
map.renderSync();
- 프린트
map.once('rendercomplete', function(event) {
const mapCanvas = document.createElement("canvas");
const size = map.getSize();
mapCanvas.width = size[0];
mapCanvas.height = size[1];
const mapContext = mapCanvas.getContext("2d");
Array.prototype.forEach.call(
map.getViewport().querySelectorAll('.ol-layer canvas, canvas.ol-layer'),
canvas => {
if (canvas.width > 0) {
let matrix;
const transform = canvas.style.transform;
if (transform) {
matrix = transform
.match(/^matrix\(([^\(]*)\)$/)[1]
.split(',')
.map(Number);
} else {
matrix = [
parseFloat(canvas.style.width) / canvas.width,
0,
0,
parseFloat(canvas.style.height) / canvas.height,
0,
0,
];
}
CanvasRenderingContext2D.prototype.setTransform.apply(mapContext, matrix);
mapContext.drawImage(canvas, 0, 0);
}
}
);
let windowContent = `<img src="${mapContext.canvas.toDataURL("image/jpeg")}">`;
const printWin = window.open('', '', `width=${screen.availWidth},height=${screen.availHeight}`);
printWin.document.open();
printWin.document.write(windowContent);
printWin.document.addEventListener('load', function() {
printWin.focus();
printWin.print();
printWin.document.close();
printWin.close();
}, true);
});
map.renderSync();
- 이미지 저장 및 프린트 함수 구현
/**
* image save & print
* @param sx start x
* @param sy start y
* @param dw width
* @param dh height
* @param isPrint
*/
export = (sx, sy, dw, dh, isPrint = false) => {
const map = this.map;
map.once('rendercomplete', (evt) => {
const mapCanvas = document.createElement("canvas");
mapCanvas.width = dw;
mapCanvas.height = dh;
const mapContext = mapCanvas.getContext("2d");
Array.prototype.forEach.call(
map.getViewport().querySelectorAll('.ol-layer canvas, canvas.ol-layer'),
canvas => {
if (canvas.width > 0) {
let matrix;
const transform = canvas.style.transform;
if (transform) {
matrix = transform
.match(/^matrix\(([^\(]*)\)$/)[1]
.split(',')
.map(Number);
} else {
matrix = [
parseFloat(canvas.style.width) / canvas.width,
0,
0,
parseFloat(canvas.style.height) / canvas.height,
0,
0,
];
}
CanvasRenderingContext2D.prototype.setTransform.apply(mapContext, matrix);
mapContext.drawImage(canvas, 0, 0);
}
}
);
if(isPrint) {
let windowContent = `<img src="${mapContext.canvas.toDataURL("image/jpeg")}">`;
const printWin = window.open('', '', `width=${screen.availWidth},height=${screen.availHeight}`);
printWin.document.open();
printWin.document.write(windowContent);
printWin.document.addEventListener('load', function() {
printWin.focus();
printWin.print();
printWin.document.close();
printWin.close();
}, true);
} else {
if (navigator.msSaveBlob) {
navigator.msSaveBlob(mapCanvas.msToBlob(), 'map.png');
} else {
const link = document.getElementById('image-download');
link.href = mapContext.canvas.toDataURL("image/jpeg");
link.click();
}
}
});
map.renderSync();
}
주의할 점 !!
아래와 같이 클릭 가능한 범위안에 download 링크를 같이 넣게 되면 rendercomplete가 무한으로 재 호출되는 현상을 보게 될 것이다.
<span onclick="saveImage();">
<i class="icon icon-export-save"></i>
<a id="image-download" download="map.png"></a>
</span>
따라서 a태그는 클릭 범위 밖으로 이동시켜야 한다.
a태그를 이동시키고 테스트 해보니 여러번 호출되던 현상이 사라졌다.
<span onclick="saveImage();">
<i class="icon icon-export-save"></i>
</span>
<a id="image-download" download="map.png"></a>
'웹 > 오픈레이어스' 카테고리의 다른 글
오픈레이어스 카카오맵(타일) 사용하기 (6) | 2023.01.19 |
---|---|
오픈레이어스 버전 확인 (6) | 2022.02.15 |
댓글