본문 바로가기

이상/Andrioid

[Android/Kotlin] 주소에서 위/경도 가져오기

반응형

Android에서도 주소에서 위/경도로 어떻게 변환하는지 찾아봤다.

 

주소를 입력하면 위/경도 값을 알아내 현재 위치로부터 얼마나 멀리있는지 보여주도록 해보자.

 

 

 

1. 화면

 

상단에 EditText와 버튼을 배치하여

 

주소를 입력한 후 Enter 또는 검색버튼을 클릭할 수 있도록 화면을 만든다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:context=".gmap.GmapViewFragment"
    android:clickable="true">
 
    <com.google.android.gms.maps.MapView
        android:id="@+id/mapView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
 
    <ProgressBar
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:id="@+id/progressBar"
        android:indeterminateOnly="true"
        android:keepScreenOn="true"
        android:gravity="center"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
 
    <EditText
        android:id="@+id/addressString"
        android:layout_width="0dp"
        android:layout_height="60dp"
        android:hint="주소입력"
        android:text="서울특별시 동작구 노량진로 238"
        android:background="@drawable/card_border"
        android:inputType="text"
        android:lines="1"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toStartOf="@id/searchButton"
        android:layout_marginTop="8dp"
        android:layout_marginStart="16dp"
        android:layout_marginEnd="8dp"/>
 
    <Button
        android:id="@+id/searchButton"
        android:layout_width="80dp"
        android:layout_height="60dp"
        android:text="검색"
        android:textColor="@color/white"
        android:background="@color/indigo"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="16dp">
    </Button>
 
</androidx.constraintlayout.widget.ConstraintLayout>
cs

 

.xml

 

 

 

2. 구현

 

그 다음, EditText와 버튼에 Listener를 연결한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Fragment 기준
override fun onActivityCreated(savedInstanceState: Bundle?) {
    // GoogleMap 설정부분은 생략
 
    // 주소 EditText Listener
    addressString.setOnKeyListener(View.OnKeyListener { v, keyCode, event ->
        if (keyCode == KeyEvent.KEYCODE_ENTER && event.action == KeyEvent.ACTION_UP) {
            // 키보드의 Enter 버튼 클릭 시 키보드 hide
            val imm = ContextCompat.getSystemService(v.context, InputMethodManager::class.java)
            imm!!.hideSoftInputFromWindow(v.windowToken, 0)
            return@OnKeyListener true
        }
        false
    })
 
    // 검색 Button Listener
    searchButton.setOnClickListener {
    }
}
cs

 

Location의 Geocoder 클래스getFromLocationName()를 이용하여

 

주소를 이용하여 위/경도를 가져오는 메소드를 구현한다.

 

그리고 Location의 Location 클래스distanceTo()를 이용하여

 

두 위치간의 거리를 구한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 주소 -> 위/경도
fun getGeocodeFromAddress(address: String): Address {
    val coder = Geocoder(mContext)
    val geocodedAddress = coder.getFromLocationName(address, 1)
    Log.d("GmapViewFragment""Geocode from Address. Lat: ${geocodedAddress.get(0).latitude}, lon: ${geocodedAddress.get(0).longitude}")
    return geocodedAddress[0]
}
 
// 현재 위치 ~ 목적지 간의 거리(m)
fun getDistanceFromCurrentLocation(current: LatLng, dest: LatLng): Float {
    val currentLocation = Location("현재위치")
    currentLocation.latitude = current.latitude
    currentLocation.longitude = current.longitude
    val destLocation = Location("목적지")
    destLocation.latitude = dest.latitude
    destLocation.longitude = dest.longitude
    val distance: Float = currentLocation.distanceTo(destLocation)
    Log.d("GmapViewFragment","Current Lat: ${currentLocation.latitude}, Lng: ${currentLocation.longitude}")
    Log.d("GmapViewFragment","Dest Lat: ${destLocation.latitude}, Lng: ${destLocation.longitude}")
    return distance
}
cs

 

앞서 만들었던 버튼의 ClickListener에 위 메소드를 적용하고

 

EditText의 리스너에서 버튼클릭 이벤트를 호출하도록 한다.

 

이제 거리를 구한 뒤 마커를 찍어 지도에 표시한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
override fun onActivityCreated(savedInstanceState: Bundle?) {
    super.onActivityCreated(savedInstanceState)
 
    addressString.setOnKeyListener(View.OnKeyListener { v, keyCode, event ->
        if (keyCode == KeyEvent.KEYCODE_ENTER && event.action == KeyEvent.ACTION_UP) {
            searchButton.performClick()
            // hide 키보드
            val imm = ContextCompat.getSystemService(v.context, InputMethodManager::class.java)
            imm!!.hideSoftInputFromWindow(v.windowToken, 0)
            return@OnKeyListener true
        }
        false
    })
 
    searchButton.setOnClickListener {
        val address = addressString.text.toString()
        val geocode = getGeocodeFromAddress(address)
        val latlng = LatLng(geocode.latitude, geocode.longitude)
        val distance = getDistanceFromCurrentLocation(currentLatLng!!, latlng)
        Log.e("GmapViewFragment""Current <-> Destination: ${distance}m")
        gMap!!.addMarker(
            MarkerOptions()
                .position(latlng).title("노들역")
                .icon(BitmapDescriptorFactory.fromResource(markerIcons[1]))
        )
    }
 
}
 
// 주소 -> 위/경도
fun getGeocodeFromAddress(address: String): Address {
    val coder = Geocoder(mContext)
    val geocodedAddress = coder.getFromLocationName(address, 1)
    Log.d("GmapViewFragment""Geocode from Address. Lat: ${geocodedAddress.get(0).latitude}, lon: ${geocodedAddress.get(0).longitude}")
    return geocodedAddress[0]
}
 
// 현재 위치 ~ 목적지 간의 거리(m)
fun getDistanceFromCurrentLocation(current: LatLng, dest: LatLng): Float {
    val currentLocation = Location("현재위치")
    currentLocation.latitude = current.latitude
    currentLocation.longitude = current.longitude
    val destLocation = Location("목적지")
    destLocation.latitude = dest.latitude
    destLocation.longitude = dest.longitude
    val distance: Float = currentLocation.distanceTo(destLocation)
    Log.d("GmapViewFragment","Current Lat: ${currentLocation.latitude}, Lng: ${currentLocation.longitude}")
    Log.d("GmapViewFragment","Dest Lat: ${destLocation.latitude}, Lng: ${destLocation.longitude}")
    return distance
}
cs

 

앱을 실행해보자.

 

searchButton 클릭

 

searchButton Listener의 log

 

 

 

끝.

반응형