[OpenLayers] 사용자 정의 Interaction

ol에서 마우스나 키보드 등을 통한 사용자의 행위에 대한 처리를 위한 Interaction를 정의하는 내용에 대한 정리이다. 이 글은 [OpenLayers] 직접 좌표를 지정하여 구성하는 벡터 레이어에서 작성된 코드를 기반으로 작성되었으므로, 실제 실행하기 위해서는 해당 글에 대한 코드를 먼저 작성한 후 이 글의 코드를 반영하기 바란다.

사용자의 조작에 대한 Interaction을 정의하기 위한 예로써 사용자가 지도에 표시된 Feature를 마우스로 드레그하여 이동하는 경우에 대한 코드를 작성한다.

먼저 아래처럼 필요한 모듈을 하나 추가한다.

import {defaults as defaultInteractions, Pointer as PointerInteraction} from 'ol/interaction.js';

PointInteraction 클래스를 상속받도록 하여, Drag라는 클래스로 하여 아래처럼 생성한다.

/**
 * @constructor
 * @extends {module:ol/interaction/Pointer}
 */
var Drag = (function (PointerInteraction) {
    function Drag() {
        PointerInteraction.call(this, {
            handleDownEvent: handleDownEvent,
            handleDragEvent: handleDragEvent,
            handleMoveEvent: handleMoveEvent,
            handleUpEvent: handleUpEvent
        });

        this.coordinate_ = null;
        this.cursor_ = 'pointer';
        this.feature_ = null;
        this.previousCursor_ = undefined;
    }

    if ( PointerInteraction ) Drag.__proto__ = PointerInteraction;
    Drag.prototype = Object.create( PointerInteraction && PointerInteraction.prototype );
    Drag.prototype.constructor = Drag;

    return Drag;
}(PointerInteraction));

14~17번 코드에서 정의된 private 변수는 사용자가 마우스로 Feature를 이동할때 필요한 변수들이다. Interaction은 사용자가 마우스나 키보드 등과 같은 입력 장치을 통한 상호작용으로 6번 코드의 생성자에서 4개의 마우스 이벤트에 대한 호출 함수를 지정하고 있다. 4개의 마우스 이벤트는 각각 버튼 Down 이벤트, Drag 이벤트, Move 이벤트, 버튼 Up 이벤트이다. 이들 호출 함수는 아래와 같으며
14~17번 코드에서 정의된 private 변수들에 대해 처리하고 있는 것을 볼 수 있다.

function handleDownEvent(evt) {
    var map = evt.map;

    var feature = map.forEachFeatureAtPixel(evt.pixel,
        function(feature) { return feature; });

    if (feature) {
        this.coordinate_ = evt.coordinate;
        this.feature_ = feature;
    }

    return !!feature;
}

function handleDragEvent(evt) {
    var deltaX = evt.coordinate[0] - this.coordinate_[0];
    var deltaY = evt.coordinate[1] - this.coordinate_[1];

    var geometry = this.feature_.getGeometry();
    geometry.translate(deltaX, deltaY);

    this.coordinate_[0] = evt.coordinate[0];
    this.coordinate_[1] = evt.coordinate[1];
}

function handleMoveEvent(evt) {
    if (this.cursor_) {
        var map = evt.map;
        var feature = map.forEachFeatureAtPixel(evt.pixel,
        
            function(feature) {
            return feature;
        });

        var element = evt.map.getTargetElement();
        
        if (feature) {
            if (element.style.cursor != this.cursor_) {
                this.previousCursor_ = element.style.cursor;
                element.style.cursor = this.cursor_;
            }
        } else if (this.previousCursor_ !== undefined) {
            element.style.cursor = this.previousCursor_;
            this.previousCursor_ = undefined;
        }
    }
}

function handleUpEvent() {
    this.coordinate_ = null;
    this.feature_ = null;
    return false;
}

지도에 대해 위에서 정의한 Interaction을 반영하기 위해 지도를 생성 코드에서 아래처럼 반영한다.

var map = new Map({
    // 아래의 한줄이 반영된 코드임
    interactions: defaultInteractions().extend([new Drag()]),
    target: 'map',

    ...

});

실행하여 Feature를 마우스로 드레그 하면 이동되는 것을 확인할 수 있다.

답글 남기기

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