|
Android 내 위치 찾기 지도표기 기능 넣기 |
작 성 일 : 2011-11-14 |
작 성 자 : 이혁 |
내 위치 찾기 프로젝트를 확장하여 기존 액티비티에 맵 액티비티로 바꿔 지도 표시 기능을 추가한다. 이 기능은 기기의 위치가 바뀜에 따라 중신이 새 위치로 자동 재설정 될 것이다.
내 위치찾기 링크 : http://cafe.daum.net/smbitpro/TjwF/28
application 태그 안에 아래. 안드로이드 지도 라이브러리를 임포트한다.
androidManifest.xml
<uses-library android:name="com.google.android.maps"/> |
인터넷 권한을 준다.
<uses-permission android:name="android.permission.INTERNET"/> |
이 두 부분은 “내 위치 찾기” 프로젝트에서 이미 추가 했을 것이다.
main.java
public class DddfActivity extends MapActivity { [......기존 액티비티 코드......]
@Override protected boolean isRouteDisplayed() { // TODO Auto-generated method stub return false; } } |
기존 코드에서 Activity가 아닌 MapActivity를 상속하도록 바꾼다. isRouteDisplayed 메소드를 제정의 한다. 경로 안내를 보여주지 않을 것이므로 false를 리턴한다.
tip… 코드를 작성하다 보면 임포트를 해야 할 일이 있다. 작성 중 Ctrl+Shift+o를 누르면 자동으로 import를 해준다.
main.xml
<com.google.android.maps.MapView android:id="@+id/myMapView" android:layout_width="fill_parent" android:layout_height="fill_parent" android:enabled="true" android:clickable="true" android:apiKey="키값" />
|
TextView아래에 위의 코드를 작성한다.
키값을 얻는 부분은 따로 기술 문서를 참조 바란다.
main.java
private MapController mcon; private MapView mapView;
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main);
mapView = (MapView)findViewById(R.id.myMapView); mcon = mapView.getController();
//지도 표시 옵션을 구성한다. mapView.setSatellite(false);//위성모드옵션 mapView.displayZoomControls(true);
//지도 확대 mcon.setZoom(17);
LocationManager locationmanager; String context = Context.LOCATION_SERVICE; locationmanager=(LocationManager)getSystemService(context);
criteria=new Criteria(); criteria.setAccuracy(Criteria.ACCURACY_FINE); criteria.setAltitudeRequired(false); criteria.setBearingRequired(false); criteria.setCostAllowed(true); criteria.setPowerRequirement(Criteria.POWER_LOW);
String provider = locationmanager.getBestProvider(criteria, true);
Location location = locationmanager.getLastKnownLocation(provider);
updateWithNewLocation(location);
locationmanager.requestLocationUpdates(provider, 2000, 10, locationListener);
} |
글씨가 진한 부분을 추가한다.
맵뷰를 구성하고 맵 뷰가 가진 Map Controller의 레퍼런스를 얻어와 인스턴스 변수에 저장한다. 옵션으로 위성모드를 false, 줌 컨트롤을 true로 설정한다.
private void updateWithNewLocation(Location location) { String latlng; mylocationText = (TextView)findViewById(R.id.myLocationText); if(location!=null) { //내위치 마커를 업데이트 한다. mol.setLocation(location);
double lat = location.getLatitude(); double lng = location.getLongitude();
GeoPoint point = new GeoPoint((int)(lat*1E6), (int)(lng*1E6)); //지도 이동한다. mcon.animateTo(point);
latlng = "위도 : "+lat+" \n경도 : "+lng; } else { latlng="위치를 찾을수 없습니다."; } mylocationText.setText("현재위치 : \n" + latlng); } |
맵 컨트롤을 이용하여 지도의 중심을 현재 위치로 재설정 한다.
오버레이 만들고 이용하기
오버레이를 이용하면 MapView에 원하는 정보를 추가해 넣을 수 있고, 또한 클릭을 처리할 수 있다.
하나의 지도 위에는 여러 개의 오버레이가 추가될 수 있다. MapView에 할당된 모든 오버레이는 레이어 형태로 추가되며 나중에 추가된 레이어가 먼저 추가된 레이어를 가리게 된다. 사용자의 클릭 이벤트는 오버레이에 의해 처리되거나 맵뷰 자체에 대한 클릭으로 등록될 때 까지 스택을 통해 전달 된다.
프로젝션
Projction클래스는 GeoPoint형태로 저장되는 위도/경도 좌표와 point형태로 저장되는 x/y 화면 픽셀 좌표 간을 변환할 수 잇게 해준다.
지도의 프로젝션은 draw호출 시마다 달라질 수 있으므로 매번 새로운 인스턴스를 얻는 것이 좋다. 맵 뷰의 프로젝션은 getProjection을 호출해 얻는다.
Projection projection = mapView.getProjection();
GeoPoint와 Point 간을 상호 변환하려면 fromPixel과 toPixel 메서드를 이용한다.
새로운 오버레이 클래스를 만든다.
MyOverlay.java
package com.oaie;
import android.graphics.*; import android.location.*;
import com.google.android.maps.*;
public class MyOverlay extends Overlay{
Location location; public Location getLocation() { return location; } public void setLocation(Location _location) { location=_location; }
private final int mRadius =5;
@Override public void draw(Canvas canvas, MapView mapView, boolean shadow) {
Projection projection = mapView.getProjection();
if(shadow==false && location != null) { //메인 지도 레이어 위에 원하는 내용을 그린다.
//현재 위치를 얻는다. double lat=location.getLatitude()*1E6; double lng = location.getLongitude()*1E6; GeoPoint geoPoint = new GeoPoint((int)lat,(int)lng);
//현재 위치를 화면 픽셀로 변환한다. Point point = new Point(); projection.toPixels(geoPoint, point);
RectF oval = new RectF(point.x-mRadius, point.y-mRadius, point.x+mRadius, point.y+mRadius);
//페인트를 설정한다. Paint paint = new Paint(); paint.setARGB(250, 255, 255, 255); paint.setAntiAlias(true); paint.setFakeBoldText(true);
Paint backPaint = new Paint(); backPaint.setARGB(175, 50, 50, 50); backPaint.setAntiAlias(true);
RectF backRect = new RectF(point.x+2+mRadius, point.y-3*mRadius, point.x+65, point.y+mRadius);
//마커를 그린다.
canvas.drawOval(oval, paint); canvas.drawRoundRect(backRect, 5, 5, backPaint); canvas.drawText("현재위치 : ", point.x+2*mRadius, point.y, paint); }
super.draw(canvas, mapView, shadow); }
@Override public boolean onTap(GeoPoint p, MapView mapView) {//오버레이가 탭 이벤트를 처리한 경우 true를 리턴한다.
return super.onTap(p, mapView); }
} |
Overlay를 상속받는다. 현재위치를 저장하기 위한 Location 변수를 만들고 게터와 세터 메서드를 추가한다. draw메서드를 재정의하여 현재 위치에 작은 하얀색 원을 그린다.
main.java
private MyOverlay mol;//오버레이
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main);
[…기존 코드…] //지도 확대 mcon.setZoom(17);
//MyOverlay추가 mol = new MyOverlay(); List<Overlay> overlays = mapView.getOverlays(); overlays.add(mol);
|
MyOverlay를 저장하기 위한 새로운 인스턴스 변수를 추가한다음 onCreate에서 이 클래스의 새로운 인스턴스 하나를 만들어 MapView의 오버레이 리스트에 추가한다.
private void updateWithNewLocation(Location location) { String latlng; mylocationText = (TextView)findViewById(R.id.myLocationText); if(location!=null) { //내위치 마커를 업데이트 한다. mol.setLocation(location); } […기존 코드…]
} |
새로운 위치를 오버레이에 전달하도록 업데이트 한다.
결과물