[OpenLayers] 현재 지도 화면 영역 얻기

지도를 이동 또는 확대 후에 지도가 표시되는 화면의 영역을 얻어야할 때가 있습니다. 여기서의 화면 영역의 좌표는 지도 좌표입니다. 이 글은 지도가 이동 또는 확대 시 발생되는 이벤트를 통해서.. 변경된 지도 화면에 대한 지도 좌표 영역을 얻어서 지도 상에 사각형으로 그려주는 예를 소개합니다.

먼저 필요한 index.html 파일의 내용입니다.



    
        
        OpenLayers
        
    
                    
        

그리고 index.js 파일에 대한 내용인데, 순차적으로 하나씩 언급하면.. 먼저 필요한 모듈의 추가입니다.

import 'ol/ol.css';
 
import Map from 'ol/Map.js';
import View from 'ol/View.js';
import {getBottomLeft, getTopRight, getBottomRight, getTopLeft} from 'ol/extent.js';
import {toLonLat} from 'ol/proj.js';
import OSM from 'ol/source/OSM.js';
import {Vector as VectorSource} from 'ol/source.js';
import Feature from 'ol/Feature.js';
import {LineString} from 'ol/geom.js';
import {Stroke, Style} from 'ol/style.js';
import {Tile as TileLayer, Vector as VectorLayer} from 'ol/layer.js';
import {get as getProjection} from 'ol/proj.js';

현재 화면 영역에 대한 사각형 도형을 추가하기 위한 벡터 레이어가 필요하므로 이를 위한 레이어 생성과 이 레이어로 구성된 지도를 생성하는 코드입니다.

var vectorsource = new VectorSource();

var vectorlayer = new VectorLayer({
    source: vectorsource,
    style: new Style({
        stroke: new Stroke({
            width: 2,
            color: [0, 0, 255, 1]
        })
    })
});

var map = new Map({
    layers: [
        new TileLayer({
            source: new OSM()
        }),
        vectorlayer
    ],
    target: 'map',
    view: new View({
        center: [0, 0],
        zoom: 18
    })
});

사용자가 지도를 확대 또는 이동하면 지도에 대해서 moveend 이벤트가 발생하는데, 이 이벤트에 대한 콜백 함수를 지정합니다.

map.on('moveend', onMoveEnd);

function onMoveEnd(evt) {
    var map = evt.map;
    var size = map.getSize();
    var extent = map.getView().calculateExtent(size);
    var bottomLeft = toLonLat(getBottomLeft(extent));
    var topRight = toLonLat(getTopRight(extent));
    var bottomRight = toLonLat(getBottomRight(extent));
    var topLeft = toLonLat(getTopLeft(extent));

    var box = new Feature(new LineString(
        [
            [bottomLeft[0], bottomLeft[1]], 
            [bottomRight[0], bottomRight[1]], 
            [topRight[0], topRight[1]],
            [topLeft[0], topLeft[1]],
            [bottomLeft[0], bottomLeft[1]]
        ])
    );

    var current_projection = getProjection('EPSG:4326');
    var new_projection = getProjection('EPSG:3857');
 
    box.getGeometry().transform(current_projection, new_projection);

    vectorsource.addFeatures([box]);
}

이 글의 핵심적인 내용이니 하나씩 파악해보면… 5번 코드의 map에 대한 getSize()를 통해 얻어올 수 있는 것은 현재 지도에 대한 픽셀 단위의 화면 크기입니다. 이 화면 크기를 이용해 map의 view에 대한 calculateExtent 함수의 인자로 전달해 해당 크기만큼의 현재 지도 화면의 지도 좌표의 경계(MinX, MinY, MaxX, MaxY)를 얻는 코드가 6입니다. 이렇게 얻은 지도 좌표 경계는 사각형 형태인데 각 4개의 모서리 좌표를 얻는 것이 7-10번 코드입니다. 그런데 이 코드들을 보면 좌표를 경위도로 변경하고 있는데.. 이는 OSM의 좌표계인 EPSG:4326으로 넘어오기 때문에 이를 WGS84 타원체의 경위도 좌표계(EPSG:3857)로 변환하는 것입니다. 사실 그냥 표현만을 위한 것이라면 OSM 좌표계로 그대로 사용해도 되지만 DBMS에 저장시에는 경위도 좌표계가 필요한 경우가 많아 소개해 봅니다. 이렇게 얻은 좌표를 이용해 Feature를 생성하고, 이를 다시 화면에 표시하기 위해 EPSG:3857에서 EPSG:4326으로 변환합니다. ^^; 역시 좌표계 변환을 방법을 소개 및 정리하기 위해 추가해본 코드입니다. 이처럼 좌표변환까지 완료된 Feature를 소스에 추가해 주면 됩니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 항목은 *(으)로 표시합니다