.NET ListView 컨트롤의 가상모드(VirtualMode) 사용하기

.NET의 리스트뷰에는 가상모드를 지원합니다. 상당히 많은 수의 데이터를 리스트뷰의 항목으로 추가할때 속도면에서, 메모리 면에서 효율적으로 화면에 표시하기 위한 목적으로 사용할만한 매우 좋은 방법입니다.

사용자 삽입 이미지
위의 화면은 리스트뷰 컨트롤의 View 속성을 Details로 하여 그리드(Grid) 형태로 데이터를 표시하고 있습니다. 좀더 자세히 설명하면 SHP 파일에 대한 속성을 전체적으로 살펴볼 목적으로 만들어진 UI 입니다.

일반적으로 SHP 파일을 구성하는 레코드의 개수는 적게는 수십개에서 많게는 수천만개 정도됩니다. 개수가 매우 많을 경우 레코드를 한번에 리스트뷰 컨트롤에 올려 놓을 경우 UI이 얼어버리는(Freeze) 현상이 발생하고 스크롤시 매우 느린 경험을 하게 됩니다.

이럴때 가상모드를 활용해 언급한 문제를 말끔히 해결할 수 있습니다. 리스트뷰에서 가상모드를 사용하기 위해서 최소한 3가지 작업을 해줘야 합니다. 먼저 리스트뷰 컨트롤의 VirtualMode를 true로 지정하기와 다음으로 리스트뷰에서 표시할 항목의 정확한 개수를 지정하기 위한 리스트뷰 컨트롤의 VirtualListSize 값의 지정입니다. 사용자에게 제공해야할 항목의 개수가 백만개라면 이 VirtualListSize의 값을 백만으로 주면됩니다. 그리고 끝으로 실제 제공할 데이터를 필요할때 마다 그때 그때 제공해주는 RetrieveVirtualItem 이벤트 함수입니다.

private void lvAttributes_RetrieveVirtualItem(object sender, 
    RetrieveVirtualItemEventArgs e)
{
    Xr.StopMapDrawing();

    int FID = e.ItemIndex;
    XrMapLib.AttributeRow Row = SML.AttributeTable.GetRow(FID);

    if (Row != null && Row.Load())
    {
        e.Item = new ListViewItem();
        e.Item.Text = FID.ToString();
        int ToIndex = (lvAttributes.Columns.Count - 1);

        for (int iField = 0; iField < ToIndex; iField++)
        {
            String FieldValue = Row.GetValueAsString(iField);
            e.Item.SubItems.Add(FieldValue);
        }

        Row.Unload();
    }
}

위의 코드 중 중요한 부분은 e.Item에 제공할 리스트뷰의 항목을 생성해 할당한다는 것입니다. 이정도의 코드만으로도 가상모드를 충분히 실무에서 적용해 활용할 수 있지만 이에더해 캐쉬 기법을 제공함으로써 더욱 속도를 향상시킬 수 있는 방법을 제공합니다.

끝으로, 가상모드가 항상 모든 경우에서 좋은 것은 아닙니다. 필요할때마다 그때 그때 데이터를 가져오므로 전체 항목에 대한 정렬과 같은 기능을 제공할 수 없다는 점 역시 주의하시기 바랍니다.

[JavaScript] 주의해야 할 ‘변수에 대한 호이스팅(hoisting)’

자바스크립트에서 변수에 대한 호이스팅이라는 개념이 있습니다. 함수 안에 정의된 모든 변수는 선언된 그 위치에 상관없이 함수의 윗부분으로 끌어올려(hoist)된다라는 개념입니다. 여기서 주의할 점은 자바스크립트에서 함수도 객체 변수이며 이 함수가 호이스팅될때입니다.. 함수를 정의하고 선언하는 방법을 크게 2가지로 구분할 수 있습니다.

  • 표현식에 의한 정의
  • 선언문에 의한 정의

먼저 표현식에 의한 정의의 예는 다음과 같습니다.

var bar = function() {
     // 표현식에 의한 함수 정의 
}; 

다음은 선언문에 의한 정의의 예입니다.

function foo() { 
    // 선언문에 의한 함수 정의
} 

이러한 함수 정의가 함수 안에서 이루어질때 호이스팅에 차이가 발생하게 됩니다.

function test() { 
    alert(typeof foo); 
    alert(typeof bar); 

    function foo() { 
        // 선언문에 의한 함수 정의 
    } 
    
    var bar = function() {
         // 표현식에 의한 함수 정의 
    }; 
} 

test();

위의 코드를 실행해 보면 처음에는 “function”이라는 메세지가 표시되고 다음에는 “undefined”라는 메세지가 표시됩니다. 이는 표현식에 대한 함수 정의시에 함수 객체가 호이스팅될때 함수의 코드부분은 호이스팅되지 않지만 선언문으로 함수가 정의될 경우에는 함수의 코드부분까지도 호이스팅된다는 것을 알 수 있습니다. 

[Android] ProgressDialog의 메세지(Message) 폰트 크기 키우기

안드로이드에서 사용자에게 잠시 기다려 줄 것을 요청하는 방법 중 하나로 ProgressDialog를 사용합니다. 그런데 이 ProgressDialog에 표시되는 메세지의 폰트가 쥐불알만합니다..

사용자 삽입 이미지
해서 이 폰트를 전체적인 화면과 어울리게 좀 키워보려고 했고, 그 방법 중에 가장 간단한 방법은 다음과 같습니다.

inkTaskProgressDlg = ProgressDialog.show(
    DASSActivity.this, 
    "펜 메모 준비",
    Html.fromHtml("지도 이미지에 대한 펜 메모를 준비 중입니다. 잠시만 기다려 주세요.."), 
    true, 
    false);

네, 바로 Html.fromHtml를 이용해 텍스트에 스타일을 지정하는 방법입니다. HTML 방식으로 문자 스타일을 지정하니 색상이며 굵기등도 지정이 가능합니다. 안드로이드… 상당히 쓸만한 물건이라는 생각입니다. 위의 코드에 대한 결과는 아래와 같습니다.

사용자 삽입 이미지
다음 주 정도 지자체에 안드로이드 기반의 현장지원시스템을 납품합니다(담당자 분의 납품 승인을 받아야 할텐데.. -_-;). 거즘… 마무리하고 소소하지만 중요한 사용자 편의성을 다듬어 보면서 얻은 내용을 정리해 봅니다.

geos3.2.2에서 intersects 연산에서 주의할 것

듀라맵이 GEOS 라이브러리를 사용합니다. 공간연산을 위해 사용하는 라이브러리인데.. 공간데이터를 가공하기 위해 듀라맵으로 툴을 만들어 사용하고 있었는데.. 이상한 현상이 발생해서 문제를 쫓다 쫓다.. 쫓다가.. 또 쫓다가.. 쫓다가.. 쫓다가.. 결국 GEOS에서 문제를 발견하여 그 내용을 정리해 봅니다. 나중에 잊을 소지가 다분하므로…

아래와 같은 도형이 있습니다. 사각형 폴리곤 하나와 4개의 포인트라고 할때 이 4개의 포인트는 사각형 폴리곤 가장자리에 정확히 일치해서 놓입니다. 4개는 각각 사각형 폴리곤의 왼쪽 모서리, 오른쪽 모서리, 위쪽 모서리, 아래쪽 모서리에 놓입니다.
사용자 삽입 이미지사각형에 대한 지오메트리에 대해서 포인트 1, 2, 3, 4에 대해 intersets 연산을 수행하면 희한하게도 1과 2는 intersets가 false를 반환하고 3과 4는 true를 반환합니다. 제가 사용하는 GEOS의 버전이 3.2.2인데.. 오늘 오랜만에 GEOS의 공식 배포 사이트에 보니 올해 1월말에 3.3.7로 올랐군요. 아마도 분명… 새로운 버전에서는 이러한 문제가 해결되었다고 생각합니다. 언제 시간을 내서 GEOS의 새로운 버전으로 변경해서 듀라맵을 배포해야겠습니다.

[GIS] 오픈소스, ‘FingerEyes-Xr’의 적용사례

오픈소스인 핑거아이즈(FingerEyes-Xr)의 적용사례 중 대표적인 것 3가지에 대해 소개해 보고자 합니다. 핑거아이즈는 웹기반의 GIS 엔진으로써 플래시(Flash) 기술로 개발되어 있습니다. GIS는 대용량의 데이터를 처리하고 화면에 표시합니다. 이러한 대용량의 데이터 처리와 화면에 빠르게 표시하고 서버로부터 제공받은 공간 데이터를 원활하고 빠르게 처리하기 위한 기술로 플래시가 가장 적합합니다. (ActiveX 방식은 보안적인 이슈와 특정 플랫폼에 종속적인 문제가 있으며 HTML은 속도에 대한 문제가 발생합니다)

핑거아이즈는 지도를 기본으로 다양한 시설물을 관리하고 조회할 수 있는 시스템을 개발할 수 있습니다. 아래의 시스템은 상수, 하수, 도로 시설물에 대한 GIS 시스템입니다. 25cm 급 항공영상과 지적도를 기반으로 수많은 시설물을 검색하고 그 내용을 쉽게 확인할 수 있습니다. 시설물들은 각기 하나 하나의 수치지도 레이어로 제공됨으로써 쉽게 관리될 수 있고 매우 빠르게 검색될 수 있습니다. 이외에도 지적기반의 주소검색, 도로명 기반의 새주소 검색, 건물명칭 검색등이 가능합니다.

사용자 삽입 이미지
또한 핑거아이즈는 웹에서 공간 데이터를 편집하는 시스템을 개발 할 수 있습니다. 아래의 시스템은 인허가에 대한 인허가에 해당하는 구역을 직접 지도 위에 편집하여 추가하고 변경할 수 있는 시스템입니다. 공간 데이터는 DBMS에 저장됨으로써 안정적으로 관리되며 속성값에 의한 조건 검색 및 버퍼링(Buffering)을 통한 중첩 여부를 조건으로 하는 공간 검색이 가능합니다. 공간 데이터에 대한 편집은 정점 및 선분에 대한 스냅핑 기능을 제공하고 편집에 대한 Undo/Redo가 가능합니다.
사용자 삽입 이미지
또한 핑거아이즈는 웹에서 지도를 기반으로 하는 관제시스템 개발이 가능합니다. 아래의 시스템은 실시간으로 각 운행 차량의 상황을 관제하는 시스템입니다. 해당 차량의 현재 위치, 운행한 경로, 위험행동이 발생한 지도 상의 위치를 실시간으로 제공하고 관제할 수 있는 시스템입니다. 또한 이러한 관제 데이터를 기반으로 다양한 통계정보를 차트, 주제도, 밀집도 등으로 사용자에게 효과적으로 제공할 수 있는 시스템입니다.

사용자 삽입 이미지
이처럼 핑거아이즈는 웹에서 빠르게 지도를 서비스하는 것을 기본으로 지도 위에 다양한 시설물을 관리하고 조회할 수 있으며 웹에서 공간 데이터를 안정적으로 편집할 수 있으면서 기본적인 편집 기능인 스냅핑, Undo/Redo를 제공하여 정확한 편집 및 언제든 편집한 내역을 되돌릴 수 있습니다. 또한 실시간 관제 시스템 개발은 물론 다양한 데이터를 기반으로 통계처리하여 지도 위에 차트, 주제도, 밀집도 등으로 정보를 사용자에게 제공할 수 있는 웹기반 GIS 엔진입니다.