본문 바로가기

위치 기반 서비스 사용하기/구글 지도 (Google Maps)

구글맵 API 활용하기 - (3) 지도에 확대/축소 기능 추가하기

강좌 작성환경
SDK Version : Android SDK 2.0, release 1
ADT Version : 0.9.4

추후 SDK업데이트로 인해 글의 내용과 최신 SDK 내용간 차이가 있을 수 있습니다.

* SDK 2.0 기준 업데이트 완료됨 : 2009/11/12

저번 강좌 이후로 공백이 좀 길었네요.
이래저래 제가 자유롭게(?) 글을 쓸 환경이 되질 않다보니 -_-... 이렇게 띄엄~띄엄 포스팅을 하게 되네요.
(물론 최근에 렌즈 구한다고 장터매복 했던 이유도 없지않게 있겠지만요, ㅎㅎ;;;)

긴 이야기는 이쯤에서 접어두고, 오늘은 저번에 예고했던 대로, 맵을 컨트롤하는 기능을 추가해보도록 하겠습니다.
맵을 컨트롤하려면, 깜찍이님 강좌에서처럼 할 수도 있지만, 저 방법은 제가 보는 책 (Professional Android Application Development)에 나와있는 방법인데다가, 제 실력이 딸려서인지는 몰라도 잘 이해가 가지 않아서, 메뉴 이용법 및 Toast 이용법까지 익힐 수 있도록 다른 방식으로 작성하는 법에 대해서 강좌를 진행하도록 하겠습니다.

일단, 메뉴를 이용해서 지도 확대/축소 버튼을 추가할 것입니다. 다음과 같이 말이죠.



사실, 메뉴 아이템(지도 확대, 축소 버튼)에 아이콘도 넣을 수 있지만, 이번 강좌에서는 사정상(...) 아이콘 넣는 것은 생략하고 지나가도록 하겠습니다.

일단, 메뉴부터 넣어보도록 하죠. 메뉴를 넣으려면 onCreateOptionsMenu()와 onOptionsItemSelected() 메소드를 오버라이드 해야 합니다. onCreateOptionsMenu()에서는 메뉴에 항목들을 추가해주고, onOptionsItemSelected()에서는 사용자가 실제로 메뉴 항목을 눌렀을 경우 처리할 작업을 입력해줍니다.

다음과 같이 onCreateOptionsMenu()메소드와 onOptionsItemSelected() 메소드를 추가합니다.
package com.androidhuman.HelloMaps;

import com.google.android.maps.MapActivity; // Activity가 아닌 MapActivity를 추가합니다.

import android.os.Bundle;
import android.view.Menu; // 메뉴를 사용하기 위해 import합니다.
import android.view.MenuItem; // 메뉴를 사용하기 위해 import 합니다.

public class HelloMaps extends MapActivity { // MapActivity를 상속합니다.
	 /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
                
    }
        

@Override 
protected boolean isRouteDisplayed() { // MapActivity를 상속하면, 이 메소드를 추가해줘야 합니다.
	// TODO Auto-generated method stub
	return false;
}
public boolean onCreateOptionsMenu(Menu menu){
	super.onCreateOptionsMenu(menu);
	// 메뉴에 항목을 추가하려면 이 메소드에서 추가해줍니다. 	
	return true;
}

public boolean onOptionsItemSelected(MenuItem item){
	super.onOptionsItemSelected(item);
		
	return true;
}
onCreateOptionsMenu() 메소드 오버라이드하고, 이를 수정함으로써 메뉴를 눌렀을 때 나오는 항목들을 변경할 수 있으며, onOptionsItemSelected() 메소드를 오버라이드하고 수저암으로써 메뉴의 각 항목을 눌렀을 때 나오는 항목들을 변경할 수 있습니다.

그럼, 먼저 메뉴 항목을 추가해볼까요??

아까 오버라이드한 onCreateOptionsMenu() 메소드를 다음과 같이 수정합니다.

public boolean onCreateOptionsMenu(Menu menu){
	super.onCreateOptionsMenu(menu);
	MenuItem zoomin = menu.add(0, 1, Menu.NONE, "지도 확대"); // 메뉴에 항목 추가
	MenuItem zoonout = menu.add(0, 2, Menu.NONE, "지도 축소"); // 메뉴에 항목 추가
	
	return true;
}

메뉴의 항목을 추가해주기 위해서는 add()메소드를 사용하면 됩니다.

public abstract MenuItem add (int groupId, int itemId, int order, CharSequence titleRes)
- groupid : 메뉴 항목의 그룹을 지정합니다.
- itemId : 각 메뉴 항목의 고유의 번호입니다.
- order : 각 항목의 정렬 방식입니다.
- titleRes : 메뉴 항목의 이름입니다.


위의 과정까지 추가하고 프로젝트를 실행한 후, 메뉴를 눌러보면 위 스크린샷과 같이 메뉴가 뜨는 것을 볼 수 있습니다. 하지만, 아직까지는 메뉴를 눌러도 아무런 동작을 하지 않을 것입니다. 메뉴 항목을 누름에 따라 어떻게 반응할지 지정해 주지 않았기 때문이죠.

그럼, 이제부터 메뉴 항목에 따라 어떤 동작을 할 지 지정해 주도록 하겠습니다.

그 전에, 우리가 하고싶은 일이 지도의 확대/축소, 즉 MapView를 컨트롤하는 일이므로 MapView의 컨트롤러를 받아와야 합니다. MapView의 컨트롤러는 MapView 객체를 받아온 후, getController() 메소드를 통해 받아올 수 있습니다.

우리는 여기에서 지도의 확대/축소를 구현하고, 확대/축소 레벨이 최대에 도달했을 경우 사용자에게 이를 알려주는 기능까지 구현해보도록 합시다. 지도를 확대/ 축소하는 등 지도를 '컨트롤' 하려면 MapView의 컨트롤러를 받아야 하는데, 이를 위해 MapView에 id를 지정해주어야 합니다. 그래야 findViewById()를 통해 MapView 객체를 받아올 수 있게 되겠죠. 다음과 같이 MapView의 ID를 지정해주도록 합니다.

<com.google.android.maps.MapView
	android:id="@+id/mapview"
	android:layout_width="fill_parent"
	android:layout_height="fill_parent"
        android:focusable="true" 
	android:clickable="true"
        android:apiKey="내 API KEY" />


MapView 객체과 그의 컨트롤러인 MapController를 사용하기 위해, 필요한 요소들을 import 하고 다음과 같이 코드를 수정합니다.

package com.androidhuman.HelloMaps;

import com.google.android.maps.MapActivity; // Activity가 아닌 MapActivity를 추가합니다.
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;

import android.content.Context;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

public class HelloMaps extends MapActivity { // MapActivity를 상속합니다.
	MapView v; // MapView를 연결해줄 객체를 생성합니다.
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        v = (MapView)findViewById(R.id.mapview);
        
    }
        

@Override 
protected boolean isRouteDisplayed() { // MapActivity를 상속하면, 이 메소드를 추가해줘야 합니다.
	// TODO Auto-generated method stub
	return false;
}
public boolean onCreateOptionsMenu(Menu menu){
	super.onCreateOptionsMenu(menu);
	MenuItem zoomin = menu.add(0, 1, Menu.NONE, "지도 확대");
	MenuItem zoomout = menu.add(0, 2, Menu.NONE, "지도 축소");
	
	return true;
}

public boolean onOptionsItemSelected(MenuItem item){
	super.onOptionsItemSelected(item);
	MapController control = v.getController(); // 맵 컨트롤러를 받아옵니다.
	Context context = getApplicationContext(); // Toast를 띄우기 위해 Context를 받아옵니다.
	
	switch(item.getItemId()){
	case 1: // 지도 확대
		if(!control.zoomIn()){
			Toast toast = Toast.makeText(context, "최대 줌 레벨에 도달했습니다.", Toast.LENGTH_SHORT);
			toast.show(); // Toast를 표시
			break;
		}
		break;
	case 2: // 지도 축소
		if(!control.zoomOut()){
			Toast toast = Toast.makeText(context, "최소 줌 레벨에 도달했습니다.", Toast.LENGTH_SHORT);
			toast.show(); // Toast를 표시
			break;
		}
		
		
	}
	return true;
}

}


메뉴 항목을 선택했을 때, 이를 처리해주는 onOptionsItemSelected()메소드를 보시면, switch구문에 getId()메소드로 각 메뉴 항목의 id를 가지고 처리하는 것을 볼 수 있습니다. 때문에, 메뉴 항목을 추가할 때 이 id가 겹치지 안도록 하는 것이 중요합니다.

지도의 확대/축소는 각각 MapController 객체의 zoomIn(), zoomOut() 메소드를 사용합니다. 이 메소드들은 지도를 확대/축소하는 기능 뿐만 아니라 만약 더이상 확대/축소가 가능하지 않다면 false를 반환합니다. 따라서, 이러한 특성을 이용하여 확대/축소가 최대 레벨에 도달하였을 대 사용자에게 이를 알려주도록 작성하였습니다.



코드를 보면, 사용자에게 최대 / 최소 줌 레벨 여부를 알려주는 수단으로 Toast를 이용하였습니다.
Toast는 간단한 메시지 등을 사용자에게 전달할 때 많이 사용하는데요, 마치 그 특성이 토스터기에서 나오는 빵처럼 '톡' 튀어나오는것과 비슷합니다. ^^;;;

Toast에 관한 내용은 다음 강좌에서 다루도록 하겠습니다. :)