2010년 10월 29일 금요일

구글맵 API - GPS로 현재위치 받아와서 표시하기

 

 

 

 

현재 위치 표시

 

지도 위에 겹쳐서 표시되는 정보 중 가장 실용적인 것은 사용자의 현재 위치이다. 사용자는 자신의 위치로부터 정보를 얻으므로 현재 위치가 어디인가는 항상 표시해야 할 중요한 정보이다. 현재 위치를 표시하는 방법은 아주 원론적인데 위치 제공자로부터 위치를 조사하고 해당 좌표에 표식을 추가하면 된다. 그러나 앞에서 연구해 봤다시피 다량의 코드가 필요하다.

다행히 이 번거로운 작업을 대신 해 주는 오버레이가 제공된다. MyLocationOverlay 클래스는 이름이 의미하는 바대로 현재 위치를 조사하여 오버레이로 표시까지 해 준다. 이 객체를 생성하여 맵뷰의 오버레이로 추가해 놓기만 하면 내부적으로 위치 정보를 수신하여 현재 위치를 보여주며 더불어 나침반이 있는 장비인 경우 방향 정보까지도 같이 표시한다.

개발자가 해야할 잡스러운 처리를 모두 대신 해 주므로 굉장히 편리한 클래스이다. 그러나 이 기능들이 동작하려면 백그라운드에서 여분의 코드를 계속 실행해야 하므로 배터리 성능에는 부정적이다. 그래서 기능을 켜고 끌 수 있는 메서드들을 제공한다. 액티비티가 실행중일 때만 이 기능들이 필요하므로 onResume에서 켜고 onPause에서 정지시키는 것이 합리적이다.

 

boolean enableMyLocation()

void disableMyLocation()

boolean enableCompass()

void disableCompass()

 

 다음 메서드는 처음 위치가 조사될 때 실행될 러너블을 등록한다. 이 러너블은 분리된 스레드에서 실행되며 첫 조사된 위치로 이동하는 등의 처리를 할 수 있다.

 

boolean runOnFirstFix(Runnable runnable)

 

현재 위치는 파란색의 반짝거리는 원으로 표시되는데 이 표식을 탭하면 다음 메서드가 호출된다. 이 메서드를 재정의하면 현재 위치를 탭 했을 때의 처리를 수행할 수 있된 단, 메서드를 재정의하려면 상속을 받아야 한다는 점에서 약간 번거롭기는 하다.

 

boolean dispatchTap()

 

모든 것이 자동화되어 있으므로 이 클래스를 사용하는 것은 굉장히 쉽다. 객체 만들어 오버레이에 추가하고 적당한 때에 기능을 켜 주기만 하면 나머지는 내부에서 알아서 처리한다.

 

location/MyLocationOverlay

public class OverlayLocation extends MapActivity {

     MapView mMap;

     MyLocationOverlay2 mLocation;

 

     protected boolean isRouteDisplayed() {

          return false;

     }

 

     public void onCreate(Bundle savedInstanceState) {

          super.onCreate(savedInstanceState);

          setContentView(R.layout.location_mapviewtest);

 

          mMap = (MapView)findViewById(R.id.mapview);

          MapController mapControl = mMap.getController();

          mapControl.setZoom(13);

          mMap.setBuiltInZoomControls(true);

 

          GeoPoint pt = new GeoPoint(37881311, 127729968);

          mapControl.setCenter(pt);

 

          mLocation = new MyLocationOverlay2(this, mMap);

          List<Overlay> overlays = mMap.getOverlays();

          overlays.add(mLocation);

 

          mLocation.runOnFirstFix(new Runnable() {

              public void run() {

                   mMap.getController().animateTo(mLocation.getMyLocation());

              }

          });

     }

 

     public void onResume() {

          super.onResume();

          mLocation.enableMyLocation();

          mLocation.enableCompass();

     }  

 

     public void onPause() {

          super.onPause();

          mLocation.disableMyLocation();

          mLocation.disableCompass();

     }

 

     class MyLocationOverlay2 extends MyLocationOverlay {

          public MyLocationOverlay2(Context context, MapView mapView) {

              super(context, mapView);

          }

         

          protected boolean dispatchTap() {

              Toast.makeText(OverlayLocation.this, "여기가 현재 위치입니다.",

                        Toast.LENGTH_SHORT).show();

              return false;

          }

     }

}

 

춘천 시청을 지도 중앙에 표시했으며 현재 위치 오버레이를 생성하여 살짝 얹어 놓았다. onResume에서 현재 위치와 나침반 기능을 활성화시키고 onPause에서는 두 기능을 정지시킨다. 현재 위치가 처음 확인될 때 해당 좌표로 이동하는 러너블을 등록해 놓았으므로 위치 정보가 수신되는 즉시 현재 위치가 화면 중앙에 올 것이다.

현재 위치는 위치 제공자로부터 수신되는데 알다시피 에뮬레이터에서는 불가능하다. 그래서 DDMS로 가짜 좌표를 던져 주어야 이 예제가 동작하는 것을 볼 수 있다. 위도를 37.9로 살짝 수정해서 보내면 다음과 같이 지도가 이동한다. 실 장비에서는 장비를 들고 이동해야 현재 위치가 조사될 것이다.

 

 

dispatchTap 메서드에서는 현재 위치를 탭했을 때 토스트로 클릭을 받았음만 확인해 보았다. 이 메서드에서 true를 리턴하면 현재 위치에 대한 처리가 완료된 것으로 인식하여 현재 위치 표식이 사라져 버리므로 표식을 계속 유지하려면 false를 리턴해야 한다. 이 메서드를 재정의하기 위해 MyLocationOverlay2 클래스를 상속받았다.

나침반 기능도 켜 두기는 했지만 에뮬레이터에서는 나침반이 없을 뿐더러 DDMS에도 나침반 흉내 기능이 제공되지 않으므로 이 기능을 확인해 볼 방법이 없다. 실장비가 있어야만 방향 정보를 확인해 볼 수 있다. 실장비에서 실행하면 화면 우 하단에 빨간색 바늘을 가진 나침반이 나타나 현재 방향을 표시하며 장비를 회전시키면 나침반이 따라 움직인다.

 

 

[출처] - http://www.winapi.co.kr/android/

 

댓글 없음:

댓글 쓰기