[C++] XML 파서, CMarkup

XML 데이터를 쓰고 읽기 위해서 인터넷을 검색하던 차에 속도를 강점으로 내세우면서 STL 만을 사용하여 플랫폼 이식에도 뛰어난 오픈소스를 찾았는데요. 바로 CMarkup 입니다. 다운로드 사이트는 http://www.firstobject.com/ 이구요. 사용해 보니 XML의 charset도 지원하여 더욱 믿음이 가는 오픈소스였습니다. XML을 처리할 일이 있다면 한번 사용해 보시기 바랍니다.

추후 이 오픈소스를 다시 사용할 때를 대비하여 사용 방법을 정리해 정리차원에서 올려봅니다.

컴파일 시 주의할 사항은… CMarkup은 MFC의 CString와 STL의 string에 대한 문자열 타입을 사용하며 기본적으로 CString을 사용합니다. 플랫폼에 독립적인 구성을 위해서 STL을 사용하는것이 좋기 때문에 전처리에서 MARKUP_STL를 정의해줘야 합니다. 이 전처리 정의는 프로젝트의 속성 페이지에서 해줌으로써 전역적으로 적용되도록 해야 합니다. 아래의 코드는 XML을 쓰는 예제 코드입니다. 윈도우즈 계열의 개발툴인 VS2008로 작성했습니다.

#include "stdafx.h"
#include "../Markup.h"

int _tmain(int argc, _TCHAR* argv[])
{
    CMarkup xml;

    xml.AddElem( "ORDER" );
    xml.AddChildElem( "ITEM" );
    xml.IntoElem();
    xml.AddAttrib("type", "A");
    xml.AddChildElem( "SN", "132487A-J" );
    xml.AddChildElem( "NAME", "crank casing" );
    xml.AddChildElem( "QTY", "1" );
    xml.OutOfElem();

    xml.AddChildElem( "ITEM" );
    xml.IntoElem();
    xml.AddAttrib("type", "C");
    xml.AddChildElem( "SN", "434417F-Y" );
    xml.AddChildElem( "NAME", "kully casing" );
    xml.AddChildElem( "QTY", "2" );
    xml.OutOfElem();

    std::string csXML = xml.GetDoc();

    printf("%s", csXML.c_str());

    return 0;
}

결과는 다음과 같습니다.

사용자 삽입 이미지
AddElement를 통해 엘리먼트를 만들고, 해당 엘리먼트의 자식을 추가하기 위해 AddChildElem을 사용하거나 먼저 IntoElem을 호출한 후 다시 AddElement를 사용합니다.

이제 반대로 위와 같은 XML 데이터를 읽어 보도록 하겠습니다. 먼저 위의 결과를 파일로 저장해 놓고 그 파일을 읽어 데이터를 추출하는 예제를 들어 보겠습니다. 예를 들어… 아이템(ITEM)의 이름(NAME)과 수량(QTY)을 읽어 보도록 하겠습니다. 위의 XML 문자열의 경우 아이템의 개수는 총2개이므로 2개가 검색될 것입니다. 다음이 이 예제와 부합되는 코드입니다.

CMarkup xml;
xml.Load("d:/data.xml");

while ( xml.FindChildElem("ITEM") )
{
    xml.IntoElem();

    xml.FindChildElem( "NAME" );
    std::string csSN = xml.GetChildData();
    xml.FindChildElem( "QTY" );
    int nQty = atoi(xml.GetChildData().c_str());

    xml.OutOfElem();

    printf("%s, %d\n", csSN.c_str(), nQty);
}

먼저 XML 데이터를 가지고 있는 파일을 Load 매서드를 이용해 읽습니다. 다시 반복문을 사용하여 루트 엘리먼트의 자식 ITEM 엘리먼트를 검색하기 위해 FindChildElem을 사용합니다. 그러면 해당되는 자식 엘리먼트가 추출됩니다. 해당되는 자식 엘리먼트의 자식 엘리먼트를 읽기 위해 IntoElem() 함수를 사용한 뒤에 원하는 엘리먼트(NAME, QTY)를 검색하기 위해 FindChildElem을 호출하고 실제로 값을 읽기 위해서 GetChildData 매서드를 호출합니다. 다 읽은 후 OutOfElem()을 호출합니다. 결과는 아래와 같습니다.

사용자 삽입 이미지

타원의 방정식

이 얼마나 오랜만에 써보는 포스팅인지 모르겠습니다. 요즘 이러 저런 일로 바쁘다보니 블로그 관리에 매우 소홀했습니다. 이제 부터라도 짬짬히 시간을 내어.. 일상 업무에서 찾은 내용을 올리도록 노력 해야겠습니다. 해서… 알고보면 매우 간단한 내용이지만 포스팅 하나 올려봅니다.

오늘, 열심히 코드를 작성하던 중에.. 2차원에서 타원을 구성하는 좌표를 뽑아 낼 필요가 있었습니다. Needs는 하나의 타원과 또 다른 하나의 폴리곤을 하나의 도형으로 합(Union)하는 연산이 필요할듯 한데… 타원에 대한 정보는 단순히 중심점과 장반경 그리고 단반경만을 가지고 있음으로 폴리곤에 바로 합할 수 없는지라.. 일단 타원을 구성하는 정점을 이용하여 폴리곤으로 만들고.. 폴리곤과 폴리곤의 합 연산을 통해 원하는 결과를 얻고자 함이였습니다.

간단히 타원의 공식은 인터넷(http://en.wikipedia.org/wiki/Ellipse)을 통해 아래처럼 얻었습니다. 물론 프로그래밍에서 쉽게 사용할 수 있는 매개변수방정식으로 말입니다.

사용자 삽입 이미지
위의 식에서 Xc와 Yc는 타원의 중심입니다. 그리고 A와 B는 각각 X축과 Y축에 대한 타원의 반경이며 각각을 장축과 단축이라고 하겠습니다. 그리고 t는 0도에서 360도까지의 범위입니다. 물론 0도와 360도는 동일하므로 둘 중 하나는 포함되지 않아야 합니다.  마지막으로 ∅는 장축과 X축이 이루는 각도 입니다. 즉 ∅를 통해 기울어진 타원을 구성하는 좌표를 정의할 수가 있습니다. ∅에 대한 이해를 돕기 위해 아래 그림을 참고 하시기 바랍니다.

사용자 삽입 이미지

“안된다”는 말은 언제 써야 하나…

만약 무언가를 하고자할때.. 하고자 하는 일에 대한 가능성을 고민하면서, 되는 이유와 되지 않는 이유로 나눠서 생각하게 된다. 되지 않는 이유보다 되는 이유가 많을 때…. 그 일에 대해 “된다”라고 판단하고 실행에 옮길 것이다. 하지만 말이다… 만약 모든 사람이 이런 논리로 무언가를 생각하고 행동하려 한다면… 이 기타 리스트를 이해할 수 있을까?

기타를 칠 수 있는.. 되는 이유보다 “안된다”는 이유가 치명적인 이 사람은 어떤 마음으로 기타를 잡게 되었을까… 그건.. 머리가 아닌 가슴으로 생각했기에 가능하지 않았을까……. 가슴속 간절하게 기타를 연주하고 싶었던… 간절히 원하는 것을 이루고 싶다면… 말이다.. “안된다”는 이유로 인해 더 이상 망서리지 말고.. 한단계 한단계 결과를 향한 과정을 느껴보면 될 뿐이다… 마치 이 기타리스트가 지금 이노래를 연주하기 위해 격었을 과정처럼 말이다…

네이버 GIS 개발자 카페 오프라인 모임에서..

사용자 삽입 이미지
얼마전에 가진 네이버 카페의 GIS 개발자 모임입니다. 참여 하신 분들이 가장 많이 나온 사진을 올려 봅니다. 이날 회사 일로 조금 늦게 갔는데요… 이미 많은 분들이 즐겁게 술잔을 기울이고 계시더군요.. 다들 자신의 꿈을 향해 전진하는 열정은… 많은 말은 나누지 않아도 느낄 수 있었습니다. 문득… 난 지금 어디에서 무엇을 지키기만 하며 정체하고 있나… 하는 생각이 들더군요.. 처음 만나는 분들이였지만, GIS라는 공통된 주제를 통해 이런 저런 이야기를 나누며… 늦은 시간까지 함께 했는데요…. 무척 즐거웠습니다.. 다들, 자신의 꿈에 대해서 한발 한발 다가서며.. 그 꿈을 꼭 이루셨으면 좋겠습니다..

[GIS] 분석 결과와 배경 지도

오늘 급작스레 구현해 본 기능인데… 어떤 공간 위에 여러가지 데이터를 가지고 분석한 결과를 표출할때… 배경이 되는 지도와 분석 결과가 뒤섞여… 분석 결과가 한눈에 들어오지 않는 경우가 있는 듯합니다.

사용자 삽입 이미지

그래서 배경이 되는지도의 색상을 빼고, 분석 결과만 색상을 적용하도록 했습니다. 물론.. 사용자가 원하는 시점에서 배경 지도의 색상을 적용하고 뺄 수 있도록 한 것이구요. 매우 단순한 아이디어지만… 사용자에게는 매우 좋은 기능으로 생각됩니다..

위의 이미지는 배경지도위에 어떤 주제를 가지는 밀도 분석 결과를 함께 표현한 것입니다. 지도 엔진은 오픈메이트의 지도 엔진인 XGE를 이용해서 밀도 분석은 XGE에 플러그인할 수 있는 확장 기능으로 수행했습니다.

참고로… 위의 이미지에 해당하는 프로그램인 Clone은 XGE를 이용해 만든 간단한 C/S 프로그램입니다. 여러가지 공간분석기능을 기본도 위에서 수행할 수 있는 GIS 분석용 프로그램입니다. 언제 시간이 되면… XGE를 이용해 만든 여느 프로그램처럼… 소스를 공개할 예정입니다.