모바일 GIS 실습 A. 실습할프로젝트소개 첫째, 스마트폰또는태블릿 PC의화면에지도를표시하고둘째, 지도를레이어 (Layer) 단위로구성하며셋째, 구성된레이어의색상등의심벌을지정하고넷째, 구성된레이어의라벨을표시하며다섯째, 표시된건물을터치하면터치된건물의속성정보를제공하고여섯째, 현재내위치로지도를이동함 B. 사용할지도데이터살펴보기 레이어이름 설명 형상 SJ _EMD 세종시의 읍면동 단위행정구역 Polygon SJ _LI 세종시의 리 단위행정구역 Polygon SJ _MANAGE 세종시의전체도로중심선 Polyline SJ _RW 세종시의전체실폭도로 Polygon SJ _BULD 세종시의전체건물 Polygon SJ_EMD의속성구조필드명 설명 타입 EMD_CD 읍면동코드 VARCHAR2(10) EMD_KOR_NM 읍면동명 _ 한글 VARCHAR2(40) EMD_ENG_NM 읍면동명 _ 영문 VARCHAR2(40) SJ _LI의속성구조필드명 설명 타입 LI_CD 리코드 VARCHAR2(10) LI_KOR_NM 리명 _ 한글 VARCHAR2(40) LI_ENG_NM 리명 _ 영문 VARCHAR2(40) SJ_BULD의속성구조필드명 설명 타입 SIG_CD 시군구코드 VARCHAR2(5) BUL_MAN_NO 건물일련번호 NUMBER(7) RN_CD 도로명코드 VARCHAR2(7)
RDS_MAN_NO 도로구간일련번호 NUMBER(12) BSI_INT_SN 기초구간일련번호 NUMBER(10) EQB_MAN_SN 건물군일련번호 NUMBER(10) BULD_SE_CD 건물구분코드 VARCHAR2(1) BULD_MNNM 건물본번 NUMBER(5) BULD_SLNO 건물부번 NUMBER(5) BULD_NM 건물명 VARCHAR2(40) BUL_ENG_NM 건물영문명 VARCHAR2(40) BULD_NM_DC 상세건물명 VARCHAR2(100) BULD_STTUS 건물상태코드 VARCHAR2(40) BDTYP_CD 건물용도코드 VARCHAR2(5) BUL_DPN_SE 건물종속구분 VARCHAR2(1) GRO_FLO_CO 지상층수 NUMBER(3) UND_FLO_CO 지하층수 NUMBER(3) ZIP 우편번호 VARCHAR2(7) POS_BUL_NM 다량배달처건물명 VARCHAR2(40) POS_BUL_YN 다량배달처여부 VARCHAR2(1) REG_PUB_NM 등록공공문서명 VARCHAR2(20) EMD_CD 읍면동코드 VARCHAR2(3) LI_CD 리코드 VARCHAR2(2) MNTN_YN 산여부 VARCHAR2(1) LNBR_MNNM 지번본번 NUMBER(4) LNBR_SLNO 지번부번 NUMBER(4) COMPET_DE 완료일자 VARCHAR2(8) NTFC_DE 고시일자 VARCHAR2(8) MVM_RES_CD 이동사유코드 VARCHAR2(10) MVMN_RESN 이동사유 VARCHAR2(254) MVMN_DE 이동일자 VARCHAR2(8) OPE_MAN_ID 작업자아이디 VARCHAR2(20) OPERT_DE 작업일시 VARCHAR2(14) IMA_FIL_SN 이미지파일일련번호 NUMBER(11) BSI_ZON_NO 기초구역번호 NUMBER(5) NTI_TRG_YN 고지대상여부 VARCHAR2(1) INPUT_MTHD 입력방법 VARCHAR2(1) BD_MGT_SN 이전건물관리번호 VARCHAR2(25) ISSU_YN 발급여부 VARCHAR2(1) XGEOMETRY 도형정보 LONG RAW ZIP_BUL_NM 다량배달처건물명 VARCHAR2(1)
ETC_BUL_NM 기타상세건물명 VARCHAR2(40) ZIP_NO 우편번호일련번호 VARCHAR2(3) RDS_SIG_CD 도로구간시군구코드 VARCHAR2(5) SJ_MANAGE의속성구조필드명 설명 타입 SIG_CD 시군구코드 VARCHAR2(5) RDS_MAN_NO 도로구간일련번호 NUMBER(12) RN 도로명 VARCHAR2(80) RN_CD 도로명코드 VARCHAR2(7) ENG_RN 영문도로명 VARCHAR2(80) NTFC_DE 고시일자 VARCHAR2(8) RN_DLB_DE 도로명심의일자 VARCHAR2(8) ROA_MAN_ES 도로제정권자 VARCHAR2(20) WDR_RD_CD 광역도로구분코드 VARCHAR2(10) ROA_CLS_SE 도로위계기능구분 VARCHAR2(2) RDS_DPN_SE 도로구간종속구분 VARCHAR2(1) RBP_CN 기점 VARCHAR2(80) REP_CN 종점 VARCHAR2(80) ROAD_BT 도로폭 NUMBER(10,3) ROAD_LT 도로길이 NUMBER(10,3) BSI_INT 기초간격 VARCHAR2(2) NLR_LCL_NO 국도 / 지방도번호 VARCHAR2(10) ALWNC_RESN 부여사유 VARCHAR2(254) ALWNC_DE 부여일자 VARCHAR2(8) MVM_RES_CD 이동사유코드 VARCHAR2(10) MVMN_RESN 이동사유 VARCHAR2(254) MVMN_DE 이동일자 VARCHAR2(8) OPE_MAN_ID 작업자아이디 VARCHAR2(20) OPERT_DE 작업일시 VARCHAR2(14) PAR_SIG_CD 분기시군구코드 VARCHAR2(5) PAR_RDS_NO 분기도로구간일련번호 NUMBER(12) INPUT_MTHD 입력방법 VARCHAR2(1) CRSRD_CNT 교차로수 NUMBER(3) ISSU_YN 발급여부 VARCHAR2(1) SJ_RW 의속성구조 필드명설명타입
SIG_CD 시군구코드 VARCHAR2(5) RW_SN 실폭도로일련번호 NUMBER(12) ROA_CLS_SE 도로위계기능구분 VARCHAR2(2) RDS_MAN_NO 도로구간일련번호 NUMBER(12) OPE_MAN_ID 작업자아이디 VARCHAR2(20) OPERT_DE 작업일시 VARCHAR2(14) C. 개발프로젝트구성 가장먼저모바일 GIS 엔진인블랙포인트를아래의 URL 을통해다운로드받습니다. http://www.geoservice.co.kr/upload/20131101/blackpoint_v3.1.20131101.zip 다운로드받은압축파일을 C 드라이브의 mobilegis 폴더의서브폴더인 engine 에 압축을풉니다. ( 폴더가없으면생성합니다 ) 개발툴인이클립스 (Eclipse) 를실행하고 New Project 에서 Android Application Project 를선택하고 Next 버튼을클릭합니다.
새롭게나타나는대화창에서아래와같이입력하고 Next 버튼을클릭합니다. 새롭게표시되는대화창에서아래와같이입력하고 Next 버튼을클릭합니다.
새롭게표시되는대화창에서아래와같이입력 ( 기본값 ) 하고 Next 버튼을클릭합니다. 새롭게표시되는대화창에서아래와같이입력 ( 기본값 ) 하고 Finish 버튼을클릭합니 다.
실행을위해 F11 키를누르면아래와같은대화창이표시되는데여기서 Android Application 을선택하고 OK 버튼을클릭합니다. 아래와같은대화창이표시되는데안드로이드가상단말기 (Android Virtual Device, 이하 AVD 라함 ) 를생성할것을묻는것으로 Yes 를클릭합니다.
아래와같은대화창이표시되며, Launch a new Android Virtual Device 를선택하고 Manager 버튼을클릭합니다. 아래와같은대화창이표시되며 New 버튼을클릭합니다. 새롭게표시되는대화창에서다음처럼입력합니다.
다음처럼 MyDevice 라는이름의 AVD 가추가된것을확인할수있습니다. MyDevice 를선택하고 Start 버튼을클릭합니다.
다음처럼새로운대화창이표시되며 Launch 버튼을클릭합니다. 다음처럼 AVD 가실행되는것을볼수있습니다. 앞서 F11 키를눌러표시된 Android Device Chooser 대화창으로돌아왔으며아래 처럼 MyDevice 를선택하고 OK 버튼을클릭합니다.
실행결과는다음과같습니다. ( 위의화면은 AVD 에서 Ctrl+F11 를눌러화면을회전시켰습니다 ) D. 모바일 GIS 엔진블랙포인트라이브러리참조 이제모바일 GIS 엔진을사용하기위해프로젝트의 libs 폴더에블랙포인트의 lib 파 일을모두복사합니다.
그리고 AndroidManifest.xml 파일에다음과같이 6 개의퍼미션 (Permission) 을추가합 니다. <uses-permission android:name="android.permission.access_fine_location" /> <uses-permission android:name="android.permission.get_accounts" /> <uses-permission android:name="android.permission.get_tasks" /> <uses-permission android:name="android.permission.internet" /> <uses-permission android:name="android.permission.access_network_state" /> <uses-permission android:name="android.permission.write_external_storage" /> E. 화면에지도뷰배치 activity_main.xml 파일을열어다음처럼변경합니다. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".mainactivity" > <geoservice.blackpoint.xrmap android:id="@+id/map" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </RelativeLayout> MainActivity.java 파일을다음처럼변경합니다.
package com.example.mobilegis; import geoservice.blackpoint.xrmap; import android.app.activity; import android.os.bundle; import android.util.displaymetrics; import android.view.menu; import android.view.window; public class MainActivity extends Activity { private XrMap map = null; @Override protected void oncreate(bundle savedinstancestate) { requestwindowfeature(window.feature_no_title); super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); map = (XrMap)findViewById(R.id.map); DisplayMetrics outmetrics = new DisplayMetrics(); getwindowmanager().getdefaultdisplay().getmetrics(outmetrics); int DPI = outmetrics.densitydpi; map.setdpi(dpi); @Override public boolean oncreateoptionsmenu(menu menu) { getmenuinflater().inflate(r.menu.main, menu); return true; 이제 F11 를눌러실행하면다음과같은화면이표시됩니다. F. 레이어구성 모바일 GIS 엔진인블랙포인트는지도데이터에대해서 ESRI 사의 SHP 파일과모바 일환경에최적화된 XrS 파일을지원함은물론공간서버로부터공간데이터를받아
사용할수있습니다. 이교육에서는공간서버로부터공간데이터를받아사용하는 것을위주로사용하겠습니다. 지도데이터를추가하는작업은연산시간이많이소요될수있으므로별도의스레 드 (Thread) 를사용합니다. 아래처럼 Thread 로부터상속을받는 MapLoadThread.java 파일을추가합니다. 그리고 MapLoadThread.java 파일을다음처럼입력합니다. package com.example.mobilegis; import geoservice.blackpoint.mousemode; import geoservice.blackpoint.xrmap; import geoservice.blackpoint.base.coordmapper; import geoservice.blackpoint.managers.layermanager; import geoservice.blackpoint.view.layers.shapelayer; import android.os.handler; import android.os.message; public class MapLoadThread extends Thread { private XrMap map = null; public MapLoadThread(XrMap map) { this.map = map; public void run() { map.getrenderermanager().waitfordrawing(true);
map.setmousemode(mousemode.nonemode); LayerManager layerman = map.getlayermanager(); ShapeLayer lyremd = new ShapeLayer(" 읍면동 ", "http://www.geoservice.co.kr:8080/xr?layername=sj_emd"); layerman.addlayer(lyremd); map.setmousemode(mousemode.mapviewmode); handler.sendemptymessage(0); private Handler handler = new Handler() { public void handlemessage(message msg) { if(msg.what == 0) { CoordMapper coordmapper = map.getcoordmapper(); LayerManager layerman = map.getlayermanager(); coordmapper.zoombymbr(layerman.getlayerbyname(" 읍면동 ").getmbr()); ; map.update(); 이제 MapLoadThread 에서제공하는스레드를실행하기위해 MainActivity.java 파일 에서제공하는 MainActivity 클래스가다음처럼 OnMapReadyEventListener 인터페이 스를구현하도록지정합니다. public class MainActivity extends Activity implements OnMapReadyEventListener { 그리고 oncreate 의마지막줄에다음코드를추가합니다. map.setonmapreadylistener(this); OnMapReadyEventListener 인터페이스에대해서 onmapready 라는함수를구현해야 하며다음처럼입력합니다. @Override public void onmapready(mapevent arg0) { MapLoadThread dataloadthread = new MapLoadThread( map); dataloadthread.start(); 실행하면다음과같은결과를볼수있습니다.
지도에대해서확대, 축소를위한메뉴를추가합니다. 이를위해서 main.xml 파일을 열어다음처럼입력합니다. <menu xmlns:android="http://schemas.android.com/apk/res/android" > <item android:id="@+id/zoomin" android:showasaction="never" /> android:title=" 확대 " <item android:id="@+id/zoomout" android:showasaction="never" /> android:title=" 축소 " /> <item android:id="@+id/identifyattribute" android:showasaction="never" android:title=" 건물속성 " <item android:id="@+id/movegps" android:showasaction="never" android:title=" 내위치 " /> </menu> 이제이메뉴에대한코드를위해 MainActivity.java 에서 onoptionsitemselected 함수 를다음처럼추가합니다. @Override public boolean onoptionsitemselected(menuitem item) { switch(item.getitemid()) { case R.id.zoomIn: { double scale = map.getcoordmapper().getscale(); map.getcoordmapper().setscale(scale * 2); map.update();
break; case R.id.zoomOut: { double scale = map.getcoordmapper().getscale(); map.getcoordmapper().setscale(scale * 0.5); map.update(); break; return true; 실행하여 MENU 를통해지도를확대하고축소할수있습니다. 이제제주도의 도 에대한행정구역뿐만아니라시, 읍면동, 리, 도로, 건물에대한 레이어를구성하기위해 MapLoadThread 의 run 함수를다음처럼변경합니다. 이와 함께축척에따라각레이어를보이고감추는기능을추가합니다. 레이어이름 축척범위 읍면동 1:2000000 ㅡ 1:200000 리 1:200000 ㅡ 1:1 도로 _ 중심선 1:100000 ㅡ 1:1 도로 _ 실폭 1:50000 ㅡ 1:1 건물 1:25000 ㅡ 1:1 public void run() { map.getrenderermanager().waitfordrawing(true); map.setmousemode(mousemode.nonemode); LayerManager layerman = map.getlayermanager(); ShapeLayer lyremd = new ShapeLayer(" 읍면동 ", "http://www.geoservice.co.kr:8080/xr?layername=sj_emd"); layerman.addlayer(lyremd); ShapeLayer lyrli = new ShapeLayer(" 리 ", "http://www.geoservice.co.kr:8080/xr?layername=sj_li"); layerman.addlayer(lyrli); ShapeLayer lyrmanage = new ShapeLayer(" 도로 _ 중심선 ", "http://www.geoservice.co.kr:8080/xr?layername=sj_manage"); layerman.addlayer(lyrmanage); ShapeLayer lyrrw = new ShapeLayer(" 도로 _ 실폭 ", "http://www.geoservice.co.kr:8080/xr?layername=sj_rw"); layerman.addlayer(lyrrw); ShapeLayer lyrbuld = new ShapeLayer(" 건물 ", "http://www.geoservice.co.kr:8080/xr?layername=sj_buld"); layerman.addlayer(lyrbuld);
Visibility visbemd = lyremd.getvisibility(); visbemd.setvisiblebyscale(true); visbemd.setfromscale(1); visbemd.settoscale(2000000); Visibility visbli = lyrli.getvisibility(); visbli.setvisiblebyscale(true); visbli.setfromscale(1); visbli.settoscale(200000); Visibility visbmanage = lyrmanage.getvisibility(); visbmanage.setvisiblebyscale(true); visbmanage.setfromscale(1); visbmanage.settoscale(100000); Visibility visbrw = lyrrw.getvisibility(); visbrw.setvisiblebyscale(true); visbrw.setfromscale(1); visbrw.settoscale(50000); Visibility visbbuld = lyrbuld.getvisibility(); visbbuld.setvisiblebyscale(true); visbbuld.setfromscale(1); visbbuld.settoscale(25000); map.setmousemode(mousemode.mapviewmode); handler.sendemptymessage(0); G. 레이어의그리기심벌지정 이제레이어의그리기심벌을지정해합니다. MapLoadThread 의 run 함수에다음코 드를추가합니다. SimpleDrawShapeTheme themeemd = (SimpleDrawShapeTheme)lyrEMD.getTheme(); themeemd.getstrokesymbol().setwidth(3); SimpleDrawShapeTheme themeli= (SimpleDrawShapeTheme)lyrLI.getTheme(); themeli.getstrokesymbol().setwidth(1); themeli.getfillsymbol().sethollow(true); SimpleDrawShapeTheme thememanage = (SimpleDrawShapeTheme)lyrMANAGE.getTheme(); thememanage.getstrokesymbol().setcolor(color.dkgray); SimpleDrawShapeTheme themerw = (SimpleDrawShapeTheme)lyrRW.getTheme(); themerw.getstrokesymbol().setcolor(color.dkgray); themerw.getfillsymbol().setcolor(color.dkgray); SimpleDrawShapeTheme themebuld = (SimpleDrawShapeTheme)lyrBULD.getTheme(); themebuld.getstrokesymbol().setcolor(color.red); themebuld.getfillsymbol().setcolor(color.yellow); 실행하여지도를확대해보면다음과같습니다.
H. 레이어의라벨지정 레이어의라벨을표시하도록합니다. 먼저읍면동에대한행정구역명칭을표시하기 위해 MapLoadThread 의 run 함수에다음코드를추가합니다. ShapeLayerLabel lblemd = (ShapeLayerLabel)lyrEMD.getLabel(); lblemd.setfieldname("emd_kor_nm"); lblemd.setenable(true); lblemd.getfontsymbol().settextsize(14); lblemd.getfontsymbol().settextcolor(color.white); Visibility visblblemd = lblemd.getvisibility(); visblblemd.setvisiblebyscale(true); visblblemd.setfromscale(1); visblblemd.settoscale(2000000); 실행해보면다음과같은화면을볼수있습니다. 이제나머지레이어인 리 레이어와도로중심선에대한라벨도지정합니다. 아래처 럼코드를추가합니다.
ShapeLayerLabel lblli= (ShapeLayerLabel)lyrLI.getLabel(); lblli.setfieldname("li_kor_nm"); lblli.setenable(true); lblli.getfontsymbol().settextsize(11); lblli.getfontsymbol().settextcolor(color.ltgray); Visibility visblblli= lblli.getvisibility(); visblblli.setvisiblebyscale(true); visblblli.setfromscale(1); visblblli.settoscale(200000); ShapeLayerLabel lblmanage = (ShapeLayerLabel)lyrMANAGE.getLabel(); lblmanage.setfieldname("rn"); lblmanage.setenable(true); lblmanage.getfontsymbol().settextsize(10); lblmanage.getfontsymbol().settextcolor(color.white); Visibility visblblmanage = lblmanage.getvisibility(); visblblmanage.setvisiblebyscale(true); visblblmanage.setfromscale(1); visblblmanage.settoscale(20000); 실행하고지도를확대해보면다음과같은화면을볼수있습니다. I. 건물을터치하여속성확인 이제화면에표시된건물을선택하면선택된건물의속성정보를제공하는기능을추가하겠습니다. 먼저건물의속성정보가필요하므로 MapLoadThread의 run 함수에서건물레이어를추가하는코드인 layerman.addlayer(lyrbuld); 바로밑에다음코드를추가합니다. ((ShapeServiceAccess)lyrBULD.getAccess()).bAlwaysRequestAttribute = true; 그리고선택된건물에대해서시각적으로다르게표시하기위해그래픽레이어를하나추가합니다. MapLoadThread의 run 함수에서 map.setmousemode(mousemode.mapviewmode); 코드바로위에다음코드를추가합니다.
GraphicLayer grplyr = new GraphicLayer("gl"); layerman.addlayer(grplyr); grplyr.settoplayer(true); 그리고지도에서화면터치에대해이벤트를추가하기위해 MainActivity 클래스에 대해서 OnTapUpEventListener 인터페이스를구현하도록다음처럼지정합니다. public class MainActivity extends Activity implements OnMapReadyEventListener, OnTapUpEventListener { 그리고 oncreate 에다음코드를추가합니다. map.setontapuplistener(this); OnTapUpEventListener 인터페이스에대해구현해야할함수를추가합니다. @Override public void ontapup(motionevent arg0) { // TODO Auto-generated method stub 건물에대해서속성정보를확인하겠다는명령은메뉴중에건물속성을선택하는것 으로시작합니다. onoptionsitemselected 함수에서 switch 문에다음 case 문을추가 합니다. case R.id.identifyAttribute: { if(mousemode.pickingmode!= map.getmousemode()) { map.setmousemode(mousemode.pickingmode); Toast.makeText(this, " 정보를확인할건물을선택하세요.", Toast.LENGTH_LONG).show(); else { map.setmousemode(mousemode.mapviewmode); ontapup 이벤트는 map 의 MouseMode 값이 MouseMode.PickingMode 일때만발생 합니다. ontapup 이벤트함수를다음처럼입력합니다. @Override public void ontapup(motionevent arg0) { boolean bdrawing = map.getrenderermanager().isworking(); map.getrenderermanager().waitfordrawing(true); ShapeLayer layer = (ShapeLayer)map.layers().getLayerByName(" 건물 "); ShapeAccess sa = (ShapeAccess)layer.getAccess(); PointD coord = map.getcoordmapper().v2w(new PointD(arg0.getX(), arg0.gety())); try { Vector<Integer> fids = layer.getfidsbymapcoord(coord); if(fids!= null) { int cntfids = fids.size();
if(cntfids > 0) { sa.beginloading(); int FID = fids.get(0); AttributeRow ar = sa.loadattributebyid(fid); AttributeRowSet ars = (AttributeRowSet)sa.getAttributeRowSet(); ShapeRow sr = (ShapeRow)sa.loadById(FID); highlightselected(sr); if(bdrawing) map.update(); else map.refresh(); map.getrenderermanager().waitfordrawing(false); map.finishdrawing(); String strinfo = getattributeinfo(ars, ar); new AlertDialog.Builder(MainActivity.this).setTitle(" 건물정보 ").setmessage(strinfo).setpositivebutton(" 확인 ", new DialogInterface.OnClickListener() { @Override public void onclick(dialoginterface dialog, int which) { ).show(); map.setmousemode(mousemode.mapviewmode); sa.unload(sr); sa.unload(ar); sa.endloading(); return; catch(ioexception e) { e.printstacktrace(); 위의코드는 2개의사용자정의함수를사용하고있습니다. highlightselected 함수는사용자가선택한건물을다른색상으로표시하여사용자에게피드백 (Feedback) 을제공하고 getattributeinfo 함수는선택된건물의속성정보를문자열로구성하여전달하는함수입니다. highlightselected 함수는다음과같이입력합니다. private void highlightselected(shaperow sr) { GraphicLayer gl = (GraphicLayer)map.layers().getLayerByName("gl"); gl.getaccess().getspatialrowset().reset(); PolygonShape polygon = (PolygonShape)sr.getShape(); ArrayList<ArrayList<PointD>> polygons = polygon.getpolygons(); PolygonGraphic grp = new PolygonGraphic(polygons); grp.getstrokesymbol().setcolor(color.cyan); grp.getstrokesymbol().setwidth(4); grp.getstrokesymbol().setantialias(true); grp.getfillsymbol().setcolor(color.cyan);
grp.getfillsymbol().setalpha(60); GraphicRow gr = new GraphicRow(0, grp); gl.addgraphic(gr); 다음과같은 getattributeinfo 함수를입력합니다. private String getattributeinfo(attributerowset ars, AttributeRow ar) { StringBuilder result = new StringBuilder(); FieldSet fs = ars.getfieldset(); int cntfields = fs.getfieldscount(); for(int ifield=0; ifield<cntfields; ifield++) { Field field = fs.getfield(ifield); result.append(field.getfieldname()); result.append(": "); String value = ar.getvalueasstring(ifield); result.append(value); result.append('\n'); return result.tostring(); 이제실행하고건물의속성정보를확인해보면다음과같은결과를볼수있습니다. J. GPS 로현재내위치확인 이제 GPS 를이용하여현재자신의위치로지도를이동하는기능을추가하겠습니다. 이 GPS 연동기능을위해서기본적인 GPS 의원리와좌표계에대해알고있어야합 니다. i. GPS 의원리 안드로이드기반의디바이스는 GPS 수신기가기본적으로장착되어있습니다.
GPS 수신기는우주에배치된여러대의 GPS 인공위성으로부터신호를받아해 석하고계산하여현재의위치를취득합니다. GPS 수신기 1대를가지고위치를얻는것을단독측위라고하며오차는수미터ㅡ수십미터정도됩니다. 이러한단독측위로수mm 또는수cm의정밀한위치를측정할수없으나선박, 비행기, 자동차등과같은네비게이션분야에매우효과적으로활용되고있습니다. ii. 좌표계의원리 GPS의좌표계는 WGS84 타원체의경위도로써 3차원좌표계입니다. 이를종이지도나컴퓨터와같은화면에나타내기위해서 2차원으로투영 (Projection) 하여야하는데본교육에서사용하는세종시의행정구역도및도로, 건물은 Bessel1841 타원체의 TM 좌표계이며 2차원좌표계입니다. 즉, GPS에서로부터측정된 3차원좌표를 2차원상에표시하기위해서는좌표의변환이필요합니다. 블랙포인트는기본적으로 GPS 좌표를 2 차원의화면에표시하기위한좌표변환 기능을제공하여개발자가쉽게 GPS 좌표와지도를연동할수있도록돕고있 습니다. 이제기본적인 GPS 의원리와좌표계에대하파악했으므로코드를작성해보도 록하겠습니다. 먼저모바일 GIS 엔진에서위치기능을위해 MainActivity 클래스의 oncreate 에 다음코드를추가합니다. IGPSProjection proj = new BesselUTMKProjection(); LocationManager lm = map.getlocationmanager(); lm.setprojection(proj);
lm.start(); 그리고내위치 MENU 에대한실행코드를 onoptionsitemselected 함수에서 switch 문에다음 case 문을추가합니다. case R.id.moveGPS: { LocationManager lm = map.getlocationmanager(); Values3 pt = map.getlocationmanager().getprojectedpoint(); if(pt == null) { Toast.makeText(this, "GPS 위치신호가없습니다.", Toast.LENGTH_LONG).show(); else { lm.settrackingenable(!lm.istrackingmode()); if(lm.istrackingmode()) { Toast.makeText(this, " 내위치를추적합니다.", Toast.LENGTH_LONG).show(); else { Toast.makeText(this, " 내위치를추적하지않습니다.", Toast.LENGTH_LONG).show(); break; 이제실행하고내위치메뉴를실행합니다. 그리고 AVD에서 GPS 좌표를입력해주기위해서 DDMS의 Emulator Control에서 Longitude와 Latitude를각각 127.298096과 36.601293을입력해줍니다. 결과는다음과같이현재의위치 ( 에뮬레이터와같은 AVD에서는앞서입력한좌표위치 ) 로이동하여지도를표시합니다. 블랙포인트의보다자세한내용은도서출판사지앤서의 모바일 GIS 프로그래밍 ㅡ김형준, 이근상, 박진호공저 을참고하시기바랍니다.