지오코딩 GeoCoding (주소,지명 ↔ 위도,경도 변환) 예제

반응형

안드로이드: 지오코딩 GeoCoding (주소,지명 ↔ 위도,경도 변환)

 

 

지오코딩(GeoCoding) 이란  '주소나 지명' 을 '좌표 (위도, 경도)' 로 변환시키는 작업이다.   혹은 반대로 '좌표(위도, 경도)' 를 '주소나 지명' 으로 변환하는 작업 (역 지오코딩: Reverse GeoCoding) 이라 한다.

 

예를 들면 '서울 시청' 을 지오코딩 하면   좌표가   ( 37.56647, 126.977963 ) 이 튀어 나오는 겁니다.   
사실 이런 서비스는 이미 구글맵 등에서도 제공되었죠.  구글맵에서 특정 지점 위에서 마우스우클릭 - '이곳이 궁금한가요?'  실행하면 위도, 경도 가 나왔죠.

 

 

 

 

 

 

 

 

 

 

지오코딩 서비스는 역시 안드로이드 플랫폼을 만든 구글 답게 구글에서 제공해주는 거고, 안드로이드 API 에 Geocoder 객체 + Address 객체 를 통해 서비스 사용이 가능합니다.

 

 

 

 

안드로이드에서 지오코딩을 구현하는 주요 Step 은 다음과 같습니다.

 

Step1 : 메니페스트 파일에 인터넷(INTERNET) 과 위치정보 서비스(ACCESS_FINE_LOCATION) 권한을 받아옵니다

 

Step2 : Geocoder 객체 생성

 

Step3 : '좌표(위도, 경도)' 를 '주소나 지명' 으로 변환하는 경우
          getFromLocation() 메소드 사용.  결과는 List<Address> 형태

 

        : '주소나 지명' 을 '좌표(위도, 경도)' 으로 변환하는 경우

          getFromLocationName() 메소드 사용.  결과는 List<Address> 형태

 

 

Step4 : Address 객체의 toString(), getCountryName(), getLatitude(), getLongitude(), getPostalCode(), getPhone() 메소드 등을 통해 세부정보 추출 가능

 

 

 

 

 

 

아래 에제에서는 

1)  '좌표(위도, 경도)' 를 '주소나 지명' 변환 

2)  '주소나 지명' 을 '좌표(위도, 경도)' 으로 변환

     두가지를 해볼거고, 각각에 대해 변환된 문자열 출력과,  변환된 위도,경도 좌표를 통해 지도를 보여주는 것을 구현해봅니다.  이때 지도는 묵시적 인텐트 (implicit intent) 로 호출합니다.   (묵시적 인텐트 에 대해서는 지난 포스팅 참조 → 클릭)   

 

 

 

 

 

[AndroidManifest.xml]

 

인터넷(INTERNET) 과 위치정보 서비스(ACCESS_FINE_LOCATION) 권한을 받아옵니다

 

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.INTERNET"/>

 

 

 

 

[activity_main.xml]

 

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >

<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="위도"
android:textAppearance="?android:attr/textAppearanceLarge" />

<EditText
android:id="@+id/editText1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:ems="10"
android:inputType="numberDecimal" />

<EditText
android:id="@+id/editText2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/editText1"
android:layout_alignTop="@+id/textView2"
android:ems="10"
android:inputType="numberDecimal" />

<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@+id/editText2"
android:layout_marginTop="26dp"
android:text="주소"
android:textAppearance="?android:attr/textAppearanceLarge" />

<EditText
android:id="@+id/editText3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/editText2"
android:layout_alignTop="@+id/textView3"
android:ems="10" >

<requestFocus />
</EditText>

<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@+id/editText1"
android:layout_marginTop="22dp"
android:text="경도"
android:textAppearance="?android:attr/textAppearanceLarge" />

<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/editText2"
android:layout_alignBottom="@+id/editText2"
android:layout_alignParentRight="true"
android:text="변환1" />

<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/textView3"
android:layout_alignBottom="@+id/textView3"
android:layout_alignParentRight="true"
android:text="변환2" />

<TextView
android:id="@+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_below="@+id/button2"
android:layout_marginTop="28dp"
android:text="조회한 주소정보 출력"
android:textAppearance="?android:attr/textAppearanceMedium" />

<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/editText2"
android:layout_alignRight="@+id/editText2"
android:text="지도1" />

<Button
android:id="@+id/button4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/editText3"
android:layout_alignBottom="@+id/editText3"
android:layout_alignRight="@+id/editText3"
android:text="지도2" />

</RelativeLayout>

 

 

 

 

 

 

 

 

 

[MainActiviy.java]

 

 

 

 

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

// 지오코딩(GeoCoding) : 주소,지명 => 위도,경도 좌표로 변환
// 위치정보를 얻기위한 권한을 획득, AndroidManifest.xml
// ACCESS_FINE_LOCATION : 현재 나의 위치를 얻기 위해서 필요함
// INTERNET : 구글서버에 접근하기위해서 필요함

final TextView tv = (TextView) findViewById(R.id.textView4); // 결과창
Button b1 = (Button)findViewById(R.id.button1);
Button b2 = (Button)findViewById(R.id.button2);
Button b3 = (Button)findViewById(R.id.button3);
Button b4 = (Button)findViewById(R.id.button4);

final EditText et1 = (EditText)findViewById(R.id.editText1);
final EditText et2 = (EditText)findViewById(R.id.editText2);
final EditText et3 = (EditText)findViewById(R.id.editText3);

final Geocoder geocoder = new Geocoder(this);
b1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 위도,경도 입력 후 변환 버튼 클릭
List<Address> list = null;
try {
double d1 = Double.parseDouble(et1.getText().toString());
double d2 = Double.parseDouble(et2.getText().toString());

list = geocoder.getFromLocation(
d1, // 위도
d2, // 경도
10); // 얻어올 값의 개수
} catch (IOException e) {
e.printStackTrace();
Log.e("test", "입출력 오류 - 서버에서 주소변환시 에러발생");
}
if (list != null) {
if (list.size()==0) {
tv.setText("해당되는 주소 정보는 없습니다");
} else {
tv.setText(list.get(0).toString());
}
}
}
});

b2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
List<Address> list = null;


String str = et3.getText().toString();
try {
list = geocoder.getFromLocationName(
str, // 지역 이름
10); // 읽을 개수
} catch (IOException e) {
e.printStackTrace();
Log.e("test","입출력 오류 - 서버에서 주소변환시 에러발생");
}

if (list != null) {
if (list.size() == 0) {
tv.setText("해당되는 주소 정보는 없습니다");
} else {
tv.setText(list.get(0).toString());
// list.get(0).getCountryName(); // 국가명
// list.get(0).getLatitude(); // 위도
// list.get(0).getLongitude(); // 경도
}
}
}
});

b3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 위도,경도 입력 후 지도 버튼 클릭 => 지도화면으로 인텐트 날리기
double d1 = Double.parseDouble(et1.getText().toString());
double d2 = Double.parseDouble(et2.getText().toString());

Intent intent = new Intent(
Intent.ACTION_VIEW,
Uri.parse("geo:" + d1 + "," + d2));
startActivity(intent);
}
});

b4.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 주소입력후 지도2버튼 클릭시 해당 위도경도값의 지도화면으로 이동
List<Address> list = null;

String str = et3.getText().toString();
try {
list = geocoder.getFromLocationName
(str, // 지역 이름
10); // 읽을 개수
} catch (IOException e) {
e.printStackTrace();
Log.e("test","입출력 오류 - 서버에서 주소변환시 에러발생");
}

if (list != null) {
if (list.size() == 0) {
tv.setText("해당되는 주소 정보는 없습니다");
} else {
// 해당되는 주소로 인텐트 날리기
Address addr = list.get(0);
double lat = addr.getLatitude();
double lon = addr.getLongitude();

String sss = String.format("geo:%f,%f", lat, lon);

Intent intent = new Intent(
Intent.ACTION_VIEW,
Uri.parse(sss));
startActivity(intent);
}
}
}
});

} // end of onCreate
} // end of class

 

 

 

 

 

[실행화면]

 

 

 

 

 

 

 

 

위 시작화면에서 적절한 주소, 혹은 지명 등을 입력하고 [변환2] 버튼을 누르면

아래와 같이 지오코딩 된 전체정보를 볼수 있습니다.  toString() 결과값

 

 

 

 

 

 

한변 [지도2] 버튼을 누르면, 아래와 같이 지도 앱으로 묵시적인텐트를 날려서

해당 지도앱이 넘겨받은 위도,경도 값으로 지도 표시를 합니다.

 

 

 

 

반면 상단의 위도, 경도 값을 직접 입력하고 [변환1] 을 누르면 이또한 지오코딩이 된 결과값이 나옵니다.

 

 


출처: https://bitsoul.tistory.com/135 [Happy Programmer~]

 

 

반응형

댓글()