ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Android Studio - 지오코딩, 역지오코딩(feat.GoogleMapAPI)
    Android Studio 2021. 3. 15. 04:07

    이번 포스팅에서는 지오코딩과 역지오코딩을 안드로이드 스튜디오에서 사용하고 서버로부터 전달받고 서버에 전달하는 방법까지 쭉 포스팅해보려 한다. 

     

    먼저 지오코딩과 역지오코딩이란? 

    지오코딩 : 주소 ▶ 위도,경도로 변환

    역지오코딩 : 위도, 경도 ▶ 주소로 변환

     

    내가 구현한 기능은 사용자가 자신의 현재 위치를 입력하면 그 위치를 기반으로 위도, 경도를 추출해주고(지오코딩) 그 위도, 경도로 국가정보와 도시정보를 추출해서(역지오코딩) 위도, 경도, 국가, 도시 이렇게 4가지 정보를 서버에 전달하는 기능이었다. 

     

    먼저 지오코더 선언과 초기화를 해준다. 

    final Geocoder geocoder = new Geocoder(this.getContext());

     

    우선 지오코딩으로 사용자가 입력한 주소값의 위도 및 경도를 받아오는 것을 먼저 구현해보자.

    address_input이라는 editText에서 값을 받아와서 list에 저장하고, Geocoder의 getFromLocationName으로 받아온다. 

    String str = address_input.getText().toString();
    list = geocoder.getFromLocationName(str,10);
    if (list != null) {
        String city = "";
        String country = "";
        if (list.size() == 0) {
        	address_result.setText("올바른 주소를 입력해주세요. ");
        } 
        else {
        	Address address = list.get(0);
        	double lat = address.getLatitude();
        	double lon = address.getLongitude();
        }
    }

    <코드설명>

    String변수 str에다가 사용자가 입력한 값을 string으로 변환하여 저장한다. getFromLocationName은 매개변수로 장소(string)와 maxResult(int)를 받는다. 따라서 사용자가 입력한 주소 str과 maxResult(그냥 10이라 넣음...)을 매개변수로 넣어준다. getFromLocation의 리턴값은 List<Address>이다. (아래 API document참고)

    public List<Address> getFromLocationName (String locationName, int maxResults)

     

    developer.android.com/reference/android/location/Geocoder

     

    Geocoder  |  Android 개발자  |  Android Developers

     

    developer.android.com

    코드엔 안 나와있지만...미리 선언해둔 list에다가 결과값을 저장한다. 그래서 list가 null이 아니라면(주소가 맞게 입력되었다면) + list의 size가 0이 아니라면 list의 0번째값(가장 처음값) 꺼내어 Address address변수에 저장한다. 이 address 객체는 getLatitude()와 getLongitude()함수가 정의되어있으므로 각각 lat, lon이라는 double값에 저장해주면 된다. 

     

    두번째로 역지오코딩을 구현해보자. 

    위에서 구한 위도와 경도를 가지고 다시 국가와 도시만 꺼내주는 코드를 더해주면 된다.  

    citylist = geocoder.getFromLocation(lat,lon,10);
    if(citylist != null) {
    	if(list.size() == 0){
    		Log.e("reverseGeocoding", "해당 도시 없음");
    	}
    	else {
    		city = citylist.get(0).getAdminArea();
    		country = citylist.get(0).getCountryName();
    	}
    }

    <코드설명>

    citylist도 처음에 선언해둔 Address 객체를 담는 List이다. getFromLocation으로 위도, 경도를 전달해주고 maxResults로 받아올 결과값 개수도 전달해준다. 

    public List<Address> getFromLocation (double latitude, double longitude, int maxResults)

    address에는 getLatitude, getLongitude뿐 아니라 getAdminArea()와 getCountryName()도 정의되어있다. 

    developer.android.com/reference/android/location/Address

     

    Address  |  Android 개발자  |  Android Developers

     

    developer.android.com

    getAdminArea() 의 경우 경기도, 서울특별시 등의 지역을 반환해주고 getCountryName은 '대한민국'이라는 나라 이름을  반환해준다. 각각 city, country라는 String변수에 저장했다.

     

    이제 서버에다가 전송을 해보자. 우선 ServiceAPI에다가 다음과 같이 작성했다. (이건 서버측에서 알려줌)

    @POST("/record")
        Call<EditResponse> userEdit(@Header("token") String token, @Body EditData data);

    저 userEdit을 통해 정보들을 서버에 전송한다. EditData data가 바디로 들어가고, token은 헤더에 들어가는건데 token가지고 처리하는건 후에 포스팅 할 예정... :D

    EditData형태로 서버에 전달을 해줄거라 StartEdit함수에다가 EditData객체를 생성해서 매개변수로 전달해준다. EditData는 미리 자바 파일로 정의해뒀다. (이건 사용하는 사람따라 다르게 작성하면 된다. 서버 해주는 팀원과 이야기해서 데이터 형식만 맞추면 됨) 그냥 액티비티.java 코드에서는 아래처럼 작성해주면 된다. 저장버튼 눌렀을때 서버에 전송하는거니까 나는 저장버튼 클릭 이벤트 처리하는 함수에 아래 코드를 넣어놨다. 

    StartEdit(new EditData(city, country, text_input.getText().toString(), lat, lon, userIdx));

    그 뒤, 밑에다 StartEdit함수를 작성한다. 이 함수에서 serviceApi.userEdit을 통해 서버로부터 전송하고 응답을 받아서 서버통신 성공여부를 판별하면된다. 통신은 Retrofit아 워낙 사용하기 편하게 잘 되어 있어서 ... 쓸말이 별로 없다 허허... 

    private void StartEdit(EditData editData) {
    	serviceApi.userEdit(token, editData).enqueue(new Callback<EditResponse>() {
        	@Override
        	public void onResponse(Call<EditResponse> call, Response<EditResponse> response) {
                EditResponse result = response.body();
                if(result.getStatus() == 200) {
                	Toast.makeText(context,"저장이 완료되었습니다.",Toast.LENGTH_SHORT);
                }
            @Override
            public void onFailure(Call<EditResponse> call, Throwable t) {
                Toast.makeText(context, "작성에러",Toast.LENGTH_SHORT);
            }
        });
    }

    쨌든 이렇게 하면 제대로 서버에 위도, 경도, 도시, 국가라는 정보를 전달할 수 있다~!

    서버에 전달된 내용 ㅋㅋㅋㅋㅋ 

    사진의 왼쪽을 확인하면 지역/국가정보가 있고 오른쪽 보면 위도/경도 정보가 들어가있는걸 확인할 수 있다. :D

Designed by Tistory.