[OpenLayers] Canvas를 활용한 ImageLayer

ol에서 제공하는 레이어중 개발자가 직접 Canavs를 생성하고, 이 Canvas에 도형을 그려 넣을 수 있는 기능을 가진 ImageLayer가 있습니다. 이 레이어는 지도 좌표를 가진 도형을 원하는 스타일로 자유롭게 다른 레이어와 어색하지 않게 표현해 줍니다. 이 글은 ImageLayer를 이용해 지도 좌표를 갖는 간단한 사각형을 표현하는 예제를 소개합니다.

먼저 index.html은 다음과 같습니다.



    
        
        OpenLayers
        
    
                    
        

그리고 위에서 언급된 index.js 파일인데, 하나씩 살펴보면.. 먼저 필요한 모듈에 대한 코드입니다.

import 'ol/ol.css';

import Map from 'ol/Map.js';
import View from 'ol/View.js';
import {Image as ImageLayer, Tile as TileLayer} from 'ol/layer.js';
import {ImageCanvas as ImageCanvasSource, Stamen} from 'ol/source.js';

그리고 지도 객체와 배경으로 사용할 레이어를 생성합니다.

var map = new Map({
    layers: [
        new TileLayer({
            source: new Stamen({
                layer: 'watercolor'
            })
        })
    ],
    target: 'map',
    view: new View({
        center: [50000, -50000],
        zoom: 9
    })
});

다음은 ImageLayer 객체를 생성하고 이 객체를 지도 객체에 추가하는 코드입니다.

var layer = new ImageLayer({
        source: new ImageCanvasSource({
        canvasFunction: canvasFunction,
        projection: 'EPSG:3857'
    })
});

map.addLayer(layer);

위의 코드 중 canvasFunction이 보이는데, 이 함수는 ImageLayer에서 Canvas 요소에 어떤 도형을 표현할 것인지에 대한 정의가 있습니다. 예를들어 다음과 같습니다.

function canvasFunction(extent, resolution, pixelRatio, size, projection) {
    var canvasWidth = size[0];
    var canvasHeight = size[1];

    var canvas = document.createElement('canvas');
    canvas.width = canvasWidth;
    canvas.height = canvasHeight;

    var ctx = canvas.getContext('2d');

    var canvasOrigin = map.getPixelFromCoordinate([extent[0], extent[3]]);
    var mapExtent = map.getView().calculateExtent(map.getSize())
    var mapOrigin = map.getPixelFromCoordinate([mapExtent[0], mapExtent[3]]);
    var delta = [mapOrigin[0] - canvasOrigin[0], mapOrigin[1] - canvasOrigin[1]]

    var a1 = map.getPixelFromCoordinate([0, 0]); // [0, 0] -> EPSG:3857
    var a2 = map.getPixelFromCoordinate([100000, 100000]); // [100000, 100000] -> EPSG:3857
    
    ctx.fillStyle = "rgba(0,0,255,0.4)";
    ctx.fillRect(
        a1[0] + delta[0], a1[1] + delta[1], 
        Math.abs(a2[0]-a1[0]), Math.abs(a1[1]-a2[1])
    );

    return canvas;
};        

인자를 5개를 갖는 함수로 extent는 현재 지도의 extent, resolution은 현재 지도의 DPI, PixelRatio는 픽셀 비율값, 지도에 대한 DOM 요소의 크기, projection은 좌표계 정보인데 앞서 ImageLayer 생성시 projection을 ‘EPSG:3857’로 지정했으므로 이에 대한 제원정보를 갖는 투영객체가 할당됩니다. 코드를 보면 Canvas를 생성하기 위한 크기를 계산하여 지정하는 코드가 1-7번까지의 코드이고 11-14번은 도형의 좌표를 화면 좌표로 변환했을 시에 Canvas에 적용해야할 Offset값을 계산합니다. 이 값은 14번 코드의 delta에 저장됩니다. 16-17은 지도 좌표 (0,0)과 (100000, 100000) 좌표를 화면 좌표로 계산하여 a1, a2에 저장합니다. 이렇게 저장된 a1, a2를 이용해 Canvas에 사각형으로 그리는 코드가 19-23번 코드입니다. 최종적으로 처음 생성한 Canvas 객체를 반환해 줍니다. 실행해 보면 아래처럼 지도에 좌상단 좌표가 (0,0)이고 너비와 높이가 100000미터인 사각형이 그려진 것을 볼 수 있습니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다