'mfc google earth'에 해당되는 글 2건

  1. 2009.08.27 [MFC]Google Earth Interface with MFC 원하는 아이콘 출력
  2. 2009.08.27 [MFC]Google Earth Interface with MFC (1)

 

자 이제는 원하는 위치에 원하는 아이콘을 출력시키는 기능을 추가해 보겠다.

간단히 타이머를 이용 DB에서 좌표를 읽어와서 아이콘을 출력시킨다물론 타이머 간격을 짧게 하고

좌표가 계속 변한다면 화면에서 아이콘이 자연스럽게 움직이는 애니메이션을 구현하게 된다.

 

최종 작성된 KML파일은 내용은 아래와 같다.

 

<?xml version="1.0" encoding="UTF-8"?>  <kml xmlns="http://earth.google.com/kml/2.1">  <Document><name>CowellTech_GPS_POS</name><Style id="hiker-icon"> <IconStyle><Icon><href>http://maps.google.com/mapfiles/kml/shapes/man.png</href> 
</Icon></IconStyle></Style><Style id="alarm-icon"> <IconStyle><Icon><href>http://maps.google.com/mapfiles/kml/shapes/caution.png</href> </Icon></IconStyle></Style><Style id="info-icon"> 
<IconStyle><Icon><href>http://maps.google.com/mapfiles/kml/shapes/info.png</href> </Icon></IconStyle></Style><Style id="device-icon"> <IconStyle><Icon><href>http://maps.google.com/mapfiles/kml/shapes/camera.png</href> 
</Icon></IconStyle></Style><Style id="device_sel-icon"> <IconStyle><Icon><href>http://maps.google.com/mapfiles/kml/shapes/movies.png</href> </Icon></IconStyle></Style><Placemark><name>1001</name><description>
<![CDATA[<img src="C:/DownLoad/1002.jpg"]]>

</description><styleUrl>#hiker-icon</styleUrl> <Point><coordinates>126.953570,37.393616,0 </coordinates></Point></Placemark><Placemark><name>1002</name><description><![CDATA[<img src="C:/DownLoad/1002.jpg"]]>

</description><styleUrl>#hiker-icon</styleUrl> <Point><coordinates>126.953575,37.393617,0 </coordinates></Point></Placemark><Placemark><name>1003</name><description><![CDATA[<img src="C:/DownLoad/1002.jpg"]]>

</description><styleUrl>#hiker-icon</styleUrl> <Point><coordinates>126.954347,37.393117,0 </coordinates></Point></Placemark><Placemark><name>1004</name><description><![CDATA[<img src="C:/DownLoad/1002.jpg"]]>

</description><styleUrl>#hiker-icon</styleUrl> <Point><coordinates>126.954147,37.393799,0 </coordinates></Point></Placemark><Placemark><name>1005</name><description><![CDATA[<img src="C:/DownLoad/1002.jpg"]]>

</description><styleUrl>#hiker-icon</styleUrl> <Point><coordinates>126.955347,37.393717,0 </coordinates></Point></Placemark><Placemark><name>2001</name><description><![CDATA[<img src="C:/DownLoad/1002.jpg"]]>

</description><styleUrl>#hiker-icon</styleUrl> <Point><coordinates>126.954347,37.393317,0 </coordinates></Point></Placemark><Placemark><name>2002</name><description><![CDATA[<img src="C:/DownLoad/1002.jpg"]]>

</description><styleUrl>#hiker-icon</styleUrl> <Point><coordinates>126.953347,37.393917,0 </coordinates></Point></Placemark><Placemark><name>2003</name><description><![CDATA[<img src="C:/DownLoad/1002.jpg"]]>

</description><styleUrl>#hiker-icon</styleUrl> <Point><coordinates>126.954147,37.393217,0 </coordinates></Point></Placemark><Placemark><name>3001</name><description><![CDATA[<img src="C:/DownLoad/1002.jpg"]]>

</description><styleUrl>#hiker-icon</styleUrl> <Point><coordinates>126.954447,37.393878,0 </coordinates></Point></Placemark><Placemark><name>3002</name><description><![CDATA[<img src="C:/DownLoad/1002.jpg"]]>

</description><styleUrl>#hiker-icon</styleUrl> <Point><coordinates>126.954357,37.393817,0 </coordinates></Point></Placemark><Placemark><name>257</name><description>테스트ID 257상태 : 정상동작
     
</description><styleUrl>#device_sel-icon</styleUrl> <Point><coordinates>126.954105,37.392958,0 </coordinates></Point></Placemark><Placemark><name>258</name><description>테스트ID 258상태 : 정상동작
  
</description><styleUrl>#device_sel-icon</styleUrl> <Point><coordinates>126.955105,37.393558,0 </coordinates></Point></Placemark><Placemark><name>1538</name><description>테스트D 1538상태 : 정상동작
   
</description><styleUrl>#device_sel-icon</styleUrl> <Point><coordinates>126.951356,37.393157,0 </coordinates></Point></Placemark><Placemark><name>1793</name><description>테스트 ID 1793 상태 : 정상동작
  
</description><styleUrl>#device_sel-icon</styleUrl> <Point><coordinates>126.953699,37.394536,0 </coordinates></Point></Placemark><flyToView>0</flyToView></Document></kml>

 

윗부분에 기본적이 헤더와 앞으로 사용하게 될 icon들에 대한 정보를 기술 했고 아래 태그 들을 보면

아이콘이름을 선택하고 경도 위도를 기술한 것이 보일 것이다.

 

자 이제 남은 것은 위도 경도 값들을 받아서 (DB에서 읽어 들이든 소켓이나 시리얼로 받았던 간에위의 파일을 만들어 주는 일인데

단순노동을 대신 해주는 간단한 클래스를 하나 만들었다.

 

class CMakeKML

{

             public:

             CMakeKML(void) {};

             ~CMakeKML(void) {};

 

             CString makeHeader (CString strDocName)

             {

                           CString strKML;

                           strKML.Format ("%s%c%s%c%s%c%s%c%s  %s%c%s%c%s  %s%s%s",

                                                     "<?xml version=", '"', "1.0", '"', " encoding=", '"', "UTF-8", '"', "?>",

                                                     "<kml xmlns=",  '"', "http://earth.google.com/kml/2.1", '"',  ">",

                                                     "<Document><name>", strDocName, "</name>");

                           return strKML;

             }

 

             CString makeLookAt (double longit, double lat, int alt, double range, double tilt, double head) //경도,위도 ...

             {

                           CString strKML;

                           strKML.Format ("%s%f%s %s%f%s %s%d%s %s%f%s %s%f%s %s%f%s %s",

                                        "<LookAt><longitude>",longit, "</longitude>",

                                        "<latitude>",lat, "</latitude>",

                                        "<altitude>",alt, "</altitude>",

                                        "<range>",range, "</range>",

                                        "<tilt>",tilt, "</tilt>",

                                        "<heading>",head, "</heading>",

                                        "</LookAt>");

                                        //TRACE ("%s\r\n", strKML);

                           return strKML;

             }

 

             CString makeIconStyle (CString strID, CString strHref)

             {

                           CString strKML;

                           strKML.Format ("%s%c%s%c%s %s%s%s %s",

                                        "<Style id=", '"', strID, '"', ">",

                                        "<IconStyle><Icon><href>", strHref, "</href>",

                                        "</Icon></IconStyle></Style>");

                           return strKML;

             }

 

             CString makePlacemark (CString strID, double longit, double lat, int alt, CString strStyleUrl, CString strDesc) //

             {

                           CString strKML;

                           strKML.Format ("%s%s%s%s%s%s%s %s%f%,%f,%d %s",

                                                     "<Placemark><name>",strID, "</name><description>",

                                                     strDesc,"</description><styleUrl>#",strStyleUrl, "</styleUrl>",

                                                     , "</styleUrl>",

                                                     "<Point><coordinates>",longit, lat, alt, "</coordinates></Point></Placemark>");

                           return strKML;

             }

};


 

내용은 간단하니 뭐 설명은 필요 없을듯 하고 이 클래스는 그대로 복사 해서 컴파일 해서 사용하면 된다, 혹 안되면 리플 이나

연락 부탁한다. 자 이제 이 녀석을 이용 해서

 

CString CXXXXView::MakeKML_DB (int nType)

{

             CString strKML;

             CMakeKML kml;

 

             strKML = kml.makeHeader ("TEST_GPS_POS");

              strKML += kml.makeIconStyle ("hiker-icon", "http://maps.google.com/mapfiles/kml/shapes/man.png");

             strKML += kml.makeIconStyle ("alarm-icon", "http://maps.google.com/mapfiles/kml/shapes/caution.png");

             strKML += kml.makeIconStyle ("info-icon", "http://maps.google.com/mapfiles/kml/shapes/info.png");

             strKML += kml.makeIconStyle ("device-icon", "http://maps.google.com/mapfiles/kml/shapes/camera.png");

             strKML += kml.makeIconStyle ("device_sel-icon", "http://maps.google.com/mapfiles/kml/shapes/movies.png");

 

             CString strItem, strID;

             CString strIcon, strDesc;

 

             double x, y;

             CString str = "Select * From TB_CURRENT_TAG_POS";

             if (g_App.m_adoDatabase.OpenQuery (str , (CADORecordBinding *)NULL))

             {

                           int nCount = g_App.m_adoDatabase.GetRecordCount ();

                           for (int i = 0 ; i < nCount ; i++)

                           {

                                        strIcon = "info-icon";

                                        strDesc.Format ("<![CDATA[<img src=%c%s%c]]>\r\n\r\n", '"', "C:/DownLoad/1001.jpg", '"');

                                        strKML += kml.makePlacemark (strID, x, y, 0, strIcon, strDesc);

                                        if (FAILED (g_App.m_adoDatabase.MoveNext ()))

                                        {

                                                     TRACE ("FAILED ( g_App.m_adoDatabase.MoveNext()\n");

                                                     break;

                                        }

                           }

                           g_App.m_adoDatabase.RSClose ();

             }

              strKML += "<flyToView>0</flyToView>";

             strKML += "</Document></kml>";

             return strKML;

}

 

대충 이런 모습의 함수 하나 작성해서 타이머등에서 불러 주기만 하면 끝이다. 위 코드에서

DB관련 코드들은 일단 샘플이니 일단 신경 쓰지 말고 CMakeKML의 인스턴스인 kml만 주목하고 뽑아서 사용 하면 된다.

위 코드의 5가지의 아이콘들을 미리 서술하고 makePlacemark 에서 아이콘을 선택 하고 있다.간단한 코드이니 더 이상 설명은

필요 없을 듯 하다. 이말 참 자주 하는 것 같은데 앞으로도 그렇듯 하다.

이렇게 완성된 KML 문자열을  이전 포스트 에서 이미 언급했던 코드

 

 pMainFrm->m_GE.OpenKmlFile((LPCTSTR)GetFullPath (strFile), 1);  

를 다시 불러주면 끝이다.

 

KML GoogleEarth API를 좀더 보고 싶은 분들은 아래 링크를 참고 하시길

 

http://earth.google.com/comapi/annotated.html

http://code.google.com/intl/ko/apis/kml/documentation/kml_tut.html

http://groups.google.com/group/kml-support

 

끝으로 혹 버그가 있거나 질문 또는 다른 의견 등에 관한 리플이든 쪽지든 메일이든 언제든지 대환영이다부담 가질 필요도 없다.

다행히 내가 겪어봐서 조금 아는 내용이면 빠르게 피드백 될 것이고 모르는 거면 바로 모른다 라고 일단 피드백 할 것이다.

 

개인적으로 관심 있는 분야 이거나 미래에 내가 겪을 내용이면 언젠가는 답을 하려 노력하겠다물론 내가 질문을 하거나

도움을 받을 수 있으면 더 좋겠다.

 

또 주말에 비가 내린다... 비가 지겹다.....



출처 :  http://blog.daum.net/mrprogrammer

태그 : mfc google earth

댓글을 달아 주세요

[MFC]Google Earth Interface with MFC

Posted by 춘자 Windows/MFC : 2009.08.27 01:25

벌써2년이 지난 일이지만 필자의 회사에서 GPS관련 프로젝트를 진행한적이 있다.

그때 마침 GoogleEarth를 한번 접해 보고 관련자료를 조금 찾아보았더니 역시 인터페이스를 제공하기에 (COM)

회사 내 GPS관련 프로젝트에서 생성된 GPS데이터를 구글어쓰 위에 출력해볼 생각으로 간단한 데모용으로 만들어 보았던 프로그램이다.

 

 

 

 

프로그램자체의 코딩 량이야 몇 시간 분량이지만 KML의 태그와 내용도 대충 찾아 보고

DB를 읽어 KML파일로 변환하여 DB상의 GPS위치에 원하는 ICON을 출력하는데 이틀 정도 소요된 듯 하다.

 

모든것이 그렇듯 알고 나면 별것 아니지만... 암튼....

 

그런데 오랜만에 실행해 보니 일단 GoogleEarth를 요즘의 최신버젼으로 업데이트 해버렸더니 좀더 사용해보면 모르겠지만

왠지 예전 보다 맘에 안든다. (후회 하는 중..)

인터페이스도 조금 변화된 듯 하며 손봐야 할부 분도 눈에 보이지만 언젠가 시간이 나면  이것 저것 기능도 추가 하고

업데이트 해볼 계획이다뭐 그래도 KML은 잘 동작 한다.

 

서론이 길어졌는데 프로그램 기능을 요약하면 GoogleEarth를 내 원도 안에 집어 넣고

내가 원하는 지점에 원하는 높이로 이동 시키는 기능과 역시 내가 원하는 지점에 icon을 표시하는 기능 정도만 설명 해보겠다.

 

일단 MFC로 기본적인 ViewDocument방식의 SDI MDI든 프로젝트 하나 만들고,

프로젝트의 팝업메뉴에서 추가 -> 클래스추가 를 선택하면 DialogBox가 하나 열린다.

 

오른쪽 탬플릿리스트에서 TypeLib MFC클래스를 선택 하면 상단 콤보에

사용가능한 형식 라이브러리를 펼쳐서 GoogleEarth 1.0 Type Library를 선택 하면

왼쪽아래 리스트에 인터페이스들이 보인다 이중에서 ApplicationGE 만 사용해도 되지만

확장을 위하여 일단 모든 인터페이스들을 선택래퍼클래스를 준비 하면 좋을듯....

 

일단 CMainFrame의 멤버로

CApplicationGE m_GE;  이렇게 선언하고 생성된 래퍼 클래스 헤더들 적당한 곳에

include 하고  아래 2라인 추가 하고

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)

{

             

             ..

             static CLSID const clsid = { 0x8097D7E9,0xDB9E,0x4AEF, {0x9B,0x28,0x61,0xD8,0x2A,0x1D,0xF7,0x84}};

             m_GE.CreateDispatch (clsid);

}

 

View의 OnInitialUpdate() 에서

             CMainFrame *pMainFrm = (CMainFrame *)AfxGetMainWnd();

             m_hwndGEFrame = (HWND)pMainFrm->m_GE.GetMainHwnd ();

             ::ShowWindow (m_hwndGEFrame, SW_HIDE); // 테스트를 위해 구글을 보이게 할려면 여기만 막으면 된다.

 

             if (pMainFrm->m_GE.IsInitialized () == S_OK);

             if (pMainFrm->m_GE.IsOnline() == S_OK);

 

             m_hwndGE = (HWND)pMainFrm->m_GE.GetRenderHwnd ();

             m_hwndOldParent = ::SetParent (m_hwndGE, m_hWnd);

 

이렇게 추가 한다뭐 보면 알겠지만 구글어쓰의 원도핸들을 가져와 View Child로 변경 하고

 

View OnSize에서

if (m_hwndGE) ::SetWindowPos (m_hwndGE, NULL, 0, 0, cx, cy, SWP_SHOWWINDOW);

 

이렇게 하면 내 view의 클라이언트 영역에 딱 들어갔었는데.

2년 만에 실행해보니 GoogleEarth가 버전업 되면서 뭔가 변화가 있는 듯 정확히 View의 클라이언트 영역에 위치하지 않고

TOP이 아닌 Bottom을 기준으로 위치 시키는 현상이 있는듯 하다이건 언제 함 찾아봐야겠지만 누구 아는 분 있으면

리플 부탁 드린다. ^^

 

뭐 간단히 GoogleEarth를 내 프로그램 안에 넣는건 대충 끝이 났다.

메뉴를 선택 하든지 하면 내가 원하는 지점으로 멋있게 회전하면서 찾아 가는 기능을 넣는 건 간단 하다.

 

 우선 아래 보이는 것이 GoogleEarth가 지원하는 MarkUp Language인 KML 이다.

 

<?xml version="1.0" encoding="UTF-8"?>

<kml xmlns="http://earth.google.com/kml/2.1">

              <Document>

                           <name>LookAt</name>

                           <LookAt>

                                        <longitude>126.953790</longitude>   

                                        <latitude>37.393453</latitude>   

                                        <altitude>0</altitude>   

                                        <range>500.882995</range>   

                                        <tilt>45.768762</tilt>

                                        <heading>-20.131493</heading> 

                          </LookAt>

             </Document>

</kml>

 

이렇게 파일을 하나 만들고

 

 if (m_hwndGEFrame && m_hwndGE)
 {
          CMainFrame* pMainFrm = (CMainFrame*)g_App.GetMainWnd ();
          pMainFrm->m_GE.OpenKmlFile((LPCTSTR)GetFullPath (strFile), 1);
 }

OpenKmlFile 이라는 함수에 파일을 넘겨 주면 된다.

 

여기서 위도와 경도만 원하는 좌표를 입력 하면 대충 볼만한 높이의 각도로 찾아 가는 것을 볼수 있을것이다.

위 예제의 위도 경도 위치는 필자의 사무실 근처이다. 앵글도 마음에 안들면 나머지 값들도 맘대로 고치시라

아이콘 출력은 다음 포스트에....

 


출처 : http://blog.daum.net/mrprogrammer

 


태그 : mfc google earth

댓글을 달아 주세요

  1. 2012.02.16 00:40 dam  댓글주소  수정/삭제  댓글쓰기

    좋은자료 감사드립니다 혹시 코드좀 보내주실수 있으신가요? 잘 이해가 안가서요 ㅜㅜ

    damho2003@nate.com

 «이전 1  다음»