현재 위치 표시
지도 위에 겹쳐서 표시되는 정보 중 가장 실용적인 것은 사용자의 현재 위치이다. 사용자는 자신의 위치로부터 정보를 얻으므로 현재 위치가 어디인가는 항상 표시해야 할 중요한 정보이다. 현재 위치를 표시하는 방법은 아주 원론적인데 위치 제공자로부터 위치를 조사하고 해당 좌표에 표식을 추가하면 된다. 그러나 앞에서 연구해 봤다시피 다량의 코드가 필요하다.
다행히 이 번거로운 작업을 대신 해 주는 오버레이가 제공된다. 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/