FingerEyes-Xr에서 코드를 통한 지도 이동시 깜빡거리는 현상 제거

FingerEyes-Xr은 웹 기반에서 공간 데이터를 편집할 수 있도록 도형 데이터를 클라이언트에서 직접 렌더링하여 표시합니다. 즉 배경지도는 Image로 표시하고 그외 수치지도 레이어는 SVG와 같은 그래픽 요소로 표시됩니다.

이러한 구조로 인해 마우스 등을 통한 지도 이동 시에는 문제가 없으나, 코드를 통한 지도 이동시에 수치지도 레이어가 깜빡 거리는 현상이 발생할 수 있습니다. 그러나 움직이는 물체를 지도에서 추적하거나 GPS 등을 이용해 내 위치를 중심으로 지도를 이동시키는 등의 기능을 개발할때 이러한 깜빡거리는 현상은 사용자에게 좋지 않은 경험을 제공합니다.

그러나 FingerEyes-Xr에서도 움직이는 물체나 GPS 등을 통한 지도 이동 등과 같은 기능에서 자연스럽게 지도를 깜빡임없이 이동시키는 기능의 구현이 가능합니다. 이럴때 사용할 수 있는 코드는 아래와 같습니다.

function smoothMapMoveByPixel(map, px, py) {
    var cm = map.coordMapper();

    cm.moveMapByViewOffset(px, py);
    map.update(Xr.MouseActionEnum.MOUSE_DRAG_END, px, py);
}
                        
function smoothMapMove(map, newX, newY) {
    var cm = map.coordMapper();
    var prePt = cm.currentCenter();

    cm.moveTo(newX, newY);

    var deltaX = cm.viewLength(newX - prePt.x);
    var deltaY = cm.viewLength(newY - prePt.y);

    if (newX > prePt.x) deltaX = -deltaX;
    if (newY < prePt.y) deltaY = -deltaY;

    map.update(Xr.MouseActionEnum.MOUSE_DRAG_END, deltaX, deltaY);
}

함수가 2개인데요. 먼저 smoothMapMoveByPixel는 픽셀 단위값 만큼 지도를 자연스럽게 이동시키는 함수이고, smoothMapMove는 이동하고자 하는 위치를 지도의 절대좌표값으로 해서 자연스럽게 이동하는 함수입니다. 이중 smoothMapMove 함수의 사용예는 아래와 같습니다.

setInterval(function () {
    var map = ...;
    var cm = map.coordMapper();
    var prePt = cm.currentCenter();
    var newX = prePt.x + 2; 
    var newY = prePt.y - 2;

    smoothMapMove(map, newX, newY);
}, 100);

위의 코드는 0.1초마다 지도를 우측하단으로 x와 y축 모두에 대해 2미터만큼 이동시키는 것으로, 실제 시스템에 적용한 결과 화면은 아래와 같습니다.

보시는 것처럼 깜빡거림없이 자연스럽게 지도가 이동하는 것을 볼 수 있는데요. 만약, 구성 레이어가 많거나 해서 깜빡거림이 여전이 발생한다면 지도 이동 반복 주기에 대한 시간을 늘려 테스트 해보기 바랍니다.

jQuery UI의 draggable 기능에서 Scroll 오류 해결 방법

jQuery UI에서는 dom 요소에 대해 마우스로 쉽게 이동할 수 있도록 draggable 기능을 제공합니다. Windows 10에서는 문제가 없는데, Windows 7 등과 같은 버전에서는 이 draggable 기능 적용시 Scroll 기능에 오류가 있습니다. 즉, Scroll 기능이 작동하면 해당 dom이 계속 마우스에 붙어 따라다니는 기이한 현상이 발생합니다. 이에 대한 해결책은 아래의 코드와 같습니다.

var containerDiv = $("#layerManager");
containerDiv.draggable({ handle: "#layerManagerTitle" });

위의 코드가 적용된 dom 요소의 구성은 아래 이미지와 같습니다.

즉, ID가 layerManager인 DIV에 draggable 기능을 적용어 이동시키되, ID가 layerManagerTitle인 DIV에 대해서만 draggable 적용을 받도록 하는 것입니다.

GeoService-Xr의 SQL 실행 서비스

GeoService-Xr은 연결된 DBMS에 대해 SQL문 실행을 대신해 주고 그 결과를 클라이언트에게 JSON 형식으로 전송해 주는 기능을 제공합니다. 이를 위해서 실행할 SQL 문이 정의된 파일이 서버측에 필요한데요. 아래는 그 한가지 예입니다.

{
    "metadata": {
        "startToken": "{$",
        "endToken": "}"
    },
	
    "sql": {
        "getLayers": "SELECT layers FROM core_users LIMIT 1",
        "getBuildingsByRoadCode": "SELECT ST_AsText(the_geom) FROM buld_a WHERE rn_cd ='{$road_cd}' LIMIT 1",
        "addUseLog": "INSERT INTO core_uselog (systemname, username) VALUES('{$systemName}', '{$userName}')" 	
    }
}

위의 내용에 규칙이 존재하는데요. sql 문의 id가 get으로 시작하는 getLayers나 getBuildingsByRoadCode는 반드시 SELECT 문이여야 하고, add로 시작한다면 INSERT 문, del로 시작하면 DELETE 문, set으로 시작하면 UPDATE 문이어야 합니다. 위의 SQL 정의 파일의 이름이 SQL.json이라고 한다면, GeoService-Xr의 환경설정 파일인 XrConfig.xml에 다음처럼 기술되어져야 GeoService-Xr이 실행될때 SQL 문이 로딩되어 실행할 준비가 완료됩니다..


    ....

    d:/config/SQL.json

위와 같은 준비가 되면, 클라이언트 측에서 SQL 문을 호출할 수 있는데요. 아래는 javascript 문을 통해 실행한 내용의 예입니다.

var road_cd = this._CodeMap_Road[name];

$.ajax({
    url: url = ConfigValues.GIS_SERVER + "/Xr?rsql|getBuildingsByRoadCode|" + ConfigValues.DB_NAME,
    type: "POST",
    crossDomain: true,
    data: "road_cd:=" + road_cd + "\nparam2:=param2", // 파라메터의 구분은 \n 문자로 함
    dataType: "text",
    success: function (response) {
        // Java, C/C++ 등과 같은 언어의 편의성을 위해 결과의 끝에 \0이 붙음
        // javascript에서 json으로 파싱하기 위해 response 문자열 끝에 \0 문자를 제거해야 함
        response = response.substr(0, response.length - 1); 
        response = JSON.parse(response);
        
        ...
    },

    error: function (xhr, status) {
        alert("ERROR");
    }
});

MySQL, MariaDB의 INSERT INTO … ON DUPLICATE KEY UPDATE …

MySQL(MariaDB)에서 동일한 Key 값이 이미 존재한다면 UPDATE 문을 호출하여 기존의 Row의 값을 변경하고, 동일한 Key 값을 가진 Row가 없다면 INSERT를 호출하는 SQL 문의 예입니다.

INSERT INTO 
    current_load_powerfactor 
    (ref_mRID, update_timeStamp, value) 
VALUES
    ("_1e1ccab5-250a-44a3-89d8-177e2d53e071", NOW(), 99) 
ON DUPLICATE KEY UPDATE 
    update_timeStamp=NOW(), value=99

위의 SQL은 current_load_powerfactor라는 테이블에 대해서, Primary Key로 잡힌 ref_mRID가 중복된 이미 존재하는 Row가 있다면, 중복된 Row의 값을 변경(UPDATE 문 실행)하고, 중복된 Row가 없다면 새로운 Row를 추가(INSERT)하라는 내용입니다.