[API] 주소 검색 - 행정안전부 API 사용하기[API] 주소 검색 - 행정안전부 API 사용하기

Posted at 2019. 11. 20. 10:34 | Posted in API/우편번호




참고 : https://www.juso.go.kr/addrlink/devAddrLinkRequestGuide.do?menu=roadApi





■ 주소 검색 API(한국지역정보개발원) 발급받기

 



API를 발급받기 위해서는 https://www.juso.go.kr/addrlink/devAddrLinkRequestWrite.do?returnFn=write&cntcMenu=URL 페이지에 접속한다.






오픈 API 신청 페이지에 접속하면


위와같이 사용할 항목을 선택하고.


신청하기 버튼을 클릭한다.







API를 사용하기 위해서는 본인인증 과정이 필요하다.

(개발용 7일 - 본인 미인증도 가능)







본인 인증 절차가 마무리 되면 위와 같이 API 키가 생성된 것을 확인 할 수 있다.













■ 주소 검색 API(JavaScript, jQuery) - 샘플코드




한국지역정보개발원에서 제공하는 도로명주소 API는 JSON 형태로 데이터를 제공해 준다.


제공하는 예제소스에서는 PHP, JSP, ASP등의 샘플과 팝업창에 띄워서 사용할 수 있는 방법을 제공하지만.


필요한 JSON으로 데이터를 받을 수 있도록,


JavaScript와, jQuery Ajax를 통해 구현 할 수 있게끔 변경을 해 보았다.



# 소스코드

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>:: JUSO GO API ::</title>

<style type="text/css">

table { width:100%;border:1px solid #444444;border-collapse:collapse; }

th, td { border: 1px solid #444444; }

tr > td:first-child { text-align:center; }

div#wrap { display:none;border:1px solid #DDDDDD;width:500px;margin-top:5px;padding:5px; }

div#wrap > div { margin-top:10px;margin-left::5px;margin-right:5px;margin-bottom::5px; }

div#wrap a:link { color:#000000;text-decoration:none; }

div#wrap a:hover { color:#0000FF;text-decoration:underline; }

div#totoalOutcome { display:none; }

#closeBtn { float:right;margin-top:-5px;margin-right:-5px; }

#searchAddr { width:380px; }

#zipCode { text-align:center; }

#address, #detail { width:500px; }

</style>

<script type="text/JavaScript" src="https://code.jquery.com/jquery-1.12.4.js"></script>

<script language="javascript">


/// @brief 주소검색창 - 키보드 Enter키 입력

function enterSearch() {

var evt_code = (window.netscape) ? event.which : event.keyCode;

if (evt_code == 13) {

event.keyCode = 0;

getAddr();

}

}


/// @brief 주소검색창 - 데이터 조회

function getAddr() {


// 적용예 (api 호출 전에 검색어 체크)

let keyword = document.getElementById("searchAddr");

if(!checkSearchedWord(keyword)) {

return;

}


jQuery.ajax({

  url : "http://www.juso.go.kr/addrlink/addrLinkApiJsonp.do"

, type : "POST"

, data : {

  confmKey : "발급받은 도로명 주소 API KEY"

, currentPage : document.getElementById("currentPage").value

, countPerPage : document.getElementById("countPerPage").value

, keyword : keyword.value

, resultType : "json"

}

, dataType : "jsonp"

, crossDomain : true

, success : function(jsonStr) {


jQuery("#list").html("");

let errCodejsonStr.results.common.errorCode;

let errDescjsonStr.results.common.errorMessage;


if(errCode == "0") {

if(jsonStr != null) {

makeListJson(jsonStr);

}

} else {

alert(errDesc);

}

}

, error : function(xhr, status, error) {

alert("에러발생");

}

});

}


/// @brief 주소검색창 - 주소지 선택

function makeListJson(jsonStr) {


let htmlStr = "<thead><tr><th style='width:70px;'>우편번호</th><th>주소</th></tr></thead><tbody>";


if(jsonStr.results.common.totalCount > 0) {


jQuery("#totoalOutcome").css("display", "block");

jQuery("#totalCnt").html(jsonStr.results.common.totalCount);


jQuery(jsonStr.results.juso).each(function() {


let zipNo = this.zipNo;                  // 우편번호

let roadAddr = this.roadAddr;        // 도로명 주소

let jibunAddr = this.jibunAddr;       // 지번 주소


htmlStr += "<tr>";

htmlStr += "<td>";

htmlStr += "<a href='javascript:;' onClick='inputTextAddress(\""+zipNo+"\", \""+roadAddr+"\");'>";

htmlStr += zipNo;

htmlStr += "</a>";

htmlStr += "</td>";

htmlStr += "<td>";

htmlStr += "<a href='javascript:;' onClick='inputTextAddress(\""+zipNo+"\", \""+roadAddr+"\");'>";

htmlStr += "도로명 : " + roadAddr;

htmlStr += "</a>";

htmlStr += "<br/>";

htmlStr += "<a href='javascript:;' onClick='inputTextAddress(\""+zipNo+"\", \""+jibunAddr+"\");'>";

htmlStr += "지번 : " + jibunAddr;

htmlStr += "</a>";

htmlStr += "</td>";

htmlStr += "</tr>";

});


pageMake(jsonStr);


} else {

htmlStr += "<tr><td colspan='2'>조회된 데이터가 않습니다.<br/>다시 검색하여 주시기 바랍니다.</td></tr>";

}


htmlStr += "</tbody>";

jQuery("#list").html(htmlStr);

}


/// @brief 주소검색창 - 주소지 삽입

function inputTextAddress(zipcode, address) {

document.getElementById("zipCode").value = zipCode;

document.getElementById("address").value = address;

}


/// @brief 주소검색창 - 열기

function addressWindowOpen() {

jQuery("#wrap").slideDown();

jQuery("#searchAddr").focus();

}


/// @brief 주소검색창 - 닫기

function addressWindowClose() {

jQuery("#wrap").slideUp();

jQuery("#searchAddr").val("");

jQuery("#totoalOutcome").css("display", "none");

jQuery("#list").empty();

jQuery("#pagingList").empty();

jQuery("#currentPage").val("1");

}


/// @brief 주소검색창 - 특수문자 제거

function checkSearchedWord(obj) {


if(obj.value.length > 0) {


// 특수문자 제거

var expText = /[%=><]/;


if(expText.test(obj.value) == true) {

alert("특수문자를 입력 할수 없습니다.") ;

obj.value = obj.value.split(expText).join("");

return false;

}


// 특정문자열(sql예약어의 앞뒤공백포함) 제거

var sqlArray = new Array(

  "OR", "SELECT", "INSERT", "DELETE", "UPDATE", "CREATE"

  , "DROP", "EXEC", "UNION",  "FETCH", "DECLARE", "TRUNCATE"

);

// sql 예약어


var regex = "";

for(var num = 0num < sqlArray.lengthnum++) {


regex = new RegExp(sqlArray[num], "gi") ;


if(regex.test(obj.value)) {

alert("\"" + sqlArray[num]+"\"와(과) 같은 특정문자로 검색할 수 없습니다.");

obj.value = obj.value.replace(regex, "");

return false;

}

}

}

return true ;

}


/// @brief 주소검색창 - 페이징 생성

function pageMake(jsonStr) {


var totaljsonStr.results.common.totalCount; // 총건수

var pageNum = document.getElementById("currentPage").value; // 현재페이지

                var pageBlock = Number(document.getElementById("countPerPage").value); // 페이지당 출력 개수

var paggingStr = "";


// 검색 갯수가 페이지당 출력갯수보다 작으면 페이징을 나타내지 않는다.

if(total > pageBlock) {


var totalPages = Math.floor((total - 1) / pageNum) + 1;

var firstPage = Math.floor((pageNum1) / pageBlock) * pageBlock + 1;


if(firstPage <= 0) { firstPage1; };


var lastPage = (firstPage1) + pageBlock;


if(lastPagetotalPages) { lastPage = totalPages; };

var nextPagelastPage + 1;

var prePage = firstPage - pageBlock;


if(firstPage > pageBlock) {

paggingStr += "<a href='javascript:;' onClick='goPage(" + prePage + ");'>◀</a>";

paggingStr += "&nbsp;";

}


for(let num = firstPage; lastPage >= numnum++) {

if(pageNum == num) {

paggingStr += "<a style='font-weight:bold;color:#0000FF;' href='javascript:;'>" + num + "</a>";

paggingStr += "&nbsp;";

} else {

paggingStr += "<a href='javascript:;' onClick='goPage(" + num + ");'>" + num + "</a>";

paggingStr += "&nbsp;";

}

}


if(lastPage < totalPages) {

paggingStr += "<a href='javascript:;' onClick='goPage(" + nextPage + ");'>▶</a>";

}

}


                jQuery("#pagingList").html(paggingStr);

}


/// @brief 페이징 이동

function goPage(pageNum) {

document.getElementById("currentPage").value = pageNum;

getAddr();

}

</script>

</head>

<body>

<h1>■ 행정안정부 - 주소 검색 API</h1>

<hr/>

현재 페이지 : <input type="number" id="currentPage" value="1" style="text-align:center;"/>

<div style="height:5px;"></div>

페이지당 출력 개수 : <input type="number" id="countPerPage" value="5" style="text-align:center;"/>

<hr/><br/>

<input type="text" id="zipCode" value="" onClick="addressWindowOpen();" placeholder="00000" readonly/>

<input type="button" onClick="addressWindowOpen();" value="우편번호 찾기"/>

<div id="wrap">

<img id="closeBtn" src="./close_box_red.png" onClick="addressWindowClose();"/>

<div>

<input type="text" id="searchAddr" value="" onkeydown="enterSearch();" placeholder="도로명주소, 건물명 또는 지번 입력"/>

<input type="button" onClick="getAddr();" value="주소검색"/>

</div>

<div>

<div id="totoalOutcome">

검색결과 : <span id="totalCnt">0</span>

</div>

<table id="list"></table>

</div>

<div id="pagingList" style='text-align:center;'></div>

</div>

<div style="height:5px;"></div>

<input type="text" id="address" value="" placeholder="도로명 주소, 지번 주소" readonly/>

<div style="height:5px;"></div>

<input type="text" id="detail" value="" placeholder="상세 주소지 입력"/>

</body>

</html>




# 출력결과





Name __

Password __

Link (Your Website)

Comment

SECRET | 비밀글로 남기기

[API] 다음 - 우편번호 API 모바일에서 사용하기[API] 다음 - 우편번호 API 모바일에서 사용하기

Posted at 2018. 4. 4. 20:11 | Posted in API/우편번호




■ 다음 우편번호 - 팝업창 띄우지 않고 사용하기



-. 이전 포스팅에서 팝업창을 띄워서 사용하는 방법에 대한 포스팅을 작성하였는데. 이 방법만으로는 사용에 한계가 있었다.

 ① 모바일 환경에서의 사용을 고려한 반응형 웹에서 사용가능하도록 UI 변경

 ② 팝업창 사용을 막아둔 브라우저 환경 대응


-. postcode.v2.js 가 나오면서 좀더 다양하고 많은 기능을 사용할 수 있게 되었다.

-. 다음 우편번호 서비스의 "iframe을 이용하여 페이지에 끼워 넣기"를 바탕으로 작성하였다.



# 소스코드

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>:: 다음 주소록 API ::</title>
<script type="text/JavaScript" src="http://code.jquery.com/jquery-1.7.min.js"></script>
<script type="text/JavaScript" src="http://dmaps.daum.net/map_js_init/postcode.v2.js"></script>
<script type="text/javascript">
    function openDaumZipAddress() {

        // 우편번호 찾기 화면을 넣을 element를 지정
        var element_wrap = document.getElementById("wrap");

        // wrap 레이어가 off된 상태라면 다음 우편번호 레이어를 open 한다.
        if(jQuery("#wrap").css("display") == "none") {
            new daum.Postcode({
                oncomplete:function(data) {
                    jQuery("#zonecode").val(data.zonecode);
                    jQuery("#address").val(data.address);
                    jQuery("#address_detail").focus();
                    console.log(data);
                }

                // 사용자가 값을 주소를 선택해서 레이어를 닫을 경우
                // 다음 주소록 레이어를 완전히 종료 시킨다.
                , onclose:function(state) {
                    if(state === "COMPLETE_CLOSE") {

                        // 콜백함수를 실행하여 슬라이드 업 기능이 실행 완료후 작업을 진행한다.
                        offDaumZipAddress(function() {
                            element_wrap.style.display = "none";
                        });
                    }
                }
            }).embed(element_wrap);

            // 슬라이드 다운 기능을 이용해 레이어 창을 오픈한다.
            jQuery("#wrap").slideDown();
        }
        
        // warp 레이어가 open된 상태라면 다음 우편번호 레이어를 off 상태로 변경한다.
        else {

            // 콜백함수를 실행하여 슬라이드 업 기능이 실행 완료후 작업을 진행한다.
            offDaumZipAddress(function() {
                element_wrap.style.display = "none";
                return false;
            });
        }
    }

    function offDaumZipAddress() {


        // 슬라이드 업 기능을 이용해 레이어 창을 닫는다.
        jQuery("#wrap").slideUp();

    }

</script>
</head>
<body>
    <input id="zonecode" type="text" value="" style="width:50px;" readOnly/>
    &nbsp;
    <input type="button" onClick="openDaumZipAddress();" value = "주소 찾기"/>

    <!-- 다음 우편번호 찾기 리스트를 띄울 영역을 지정 -->

    <div id="wrap" style="display:none;border:1px solid #DDDDDD;width:500px;margin-top:5px"></div>
    <div style="height:10px;"></div>
    <input type="text" id="address" value="" style="width:240px;" readOnly/>
    <input type="text" id="address_detail" value="" style="width:200px;"/>
</body>
</html>



※ 계속 값을 체크해 강제로 display:none 처리한 이유


기본적으로 위에서 설명한 다음 우편번호 서비스의

"iframe을 이용하여 페이지에 끼워 넣기"를 필자의 입맛에 맞게 수정한 내용이다.

이렇게 한 이유는 좀 자연스러운 애니메이션(슬라이드) 효과를 사용하고 싶어서 였다.


그래서 위 코드에서는 if(jQuery("#wrap").css("display") == "none") 으로 한번

onclose:function(state) 기능으로 또 한번

다음 주소록 레이어를 강제로 종료시키고 있는데.

이렇게 한 이유는 아래와 같다.


처음 제작 했을때는 slideUpslideDown 기능이 아니라 slideToggle만을 사용하여 편하게

display 설정 만을 변경해가며 사용했었다.

그런데 다음 주소록 레이어가 제대로 종료가 되지 않아서 발생을 하는지.

실제 사용중 종종 <div id="wrap"></div>를 지정한 영역에



# slideToggle 기능만을 사용한 결과물



위와 같이 실선이 생기는경우가 발견되었다.

그래서 위와같이 callback과 slideDown기능을 사용하여 레이어를 한번 닫고.

작업이 완료된 이후 한번더 다음 주소록 레이어를 완전히 숨기는 방식으로 변경하였다.



 


# 출력결과 - Computer Web




# 출력결과 - Mobile Web



위와같이 모바일에서의 사용에 문제가 없게끔 변경해 보았다.





Name __

Password __

Link (Your Website)

Comment

SECRET | 비밀글로 남기기

[API] 다음 - 우편번호 API 사용하기[API] 다음 - 우편번호 API 사용하기

Posted at 2018. 3. 13. 13:46 | Posted in API/우편번호




■ DAUM - 우편번호 API



 · 다음 우편번호 서비스 API(http://postcode.map.daum.net/guide)는 스크립트 한번에 손쉽게 우편번호를 받아올 수 있어서 사용이 매우 간편하다.

 · http://dmaps.daum.net/map_js_init/postcode.v2.js 스크립트를 추가만 해주면 된다.




# 다음 에디터 데이터 정리

항목

값(예시)

 postcode

 463-400

 구 우편번호 6자리

 postcode1

 463

 구 우편번호 앞 3자리

 postcode2

 400

 구 우편번호 뒤 3자리

 zonecode

 13494

 국가기초구역번호

 2015년 8월 1일부터 시행될 새 우편번호

 address

 경기 성남시 분당구 판교역로 235

 기본주소(검색결과에서 첫줄에 나오는 주소)

 addressEnglish

 235 Pangyoyeok-ro,

 Bundang-gu,

 Seongnam-si, Gyeonggi-do, korea

 기본 영문 주소

 addressType

 R/J

 검색된 기본 주소 타입 : R(도로명), J(지번)

 userSelectedType

 R/J

 검색 결과에서 사용자가 선택한 주소의 타입

 roadAddress

 경기 성남시 분당구 판교역로 235

 도로명 주소
 (모든 주소에 도로명 주소가 부여되어 있지는 않다.)

 roadAddressEnglish

 235, Pangyoyeok-ro, Bundang-gu,

 Seongnam-si, Gyeonggi-do, Korea

 영문 도로명 주소

 jibunAddress

 경기 성남시 분당구 삼평동 681

 지번 주소

 jibunAddressEnglish

 681, Sampyeong-dong,

 Bundang-gu,

 Seongnam-si, Gyeonggi-do, Korea

 영문 지번 주소

 autoRoadAddress

 경기 성남시 분당구 판교역로 235

 매핑된 도로명 주소가 여러개인 경우, 사용자가 '선택안함'을

 클릭했을 때 임의로 첫번째 매핑 주소를 넣어서 반환합니다.

 (autoMapping을 false로 설정한 경우에는 값이 채워지지 않습니다.)

 autoRoadAddressEnglish

 235, Pangyoyeok-ro, Bundang-gu, Seongnam-si, Gyeonggi-do, Korea

 autoRoadAddress의 영문 도로명 주소

 autoJibunAddress

 경기 성남시 분당구 삼평동 681

 매핑된 지번 주소가 여러개인 경우, 사용자가 '선택안함'을

 클릭했을 때 임의로 첫번째 매핑 주소를 넣어서 반환합니다.

 (autoMapping을 false로 설정한 경우에는 값이 채워지지 않습니다.)

 autoJibunAddressEnglish

 681, Sampyeong-dong,

 Bundang-gu,

 Seongnam-si, Gyeonggi-do, Korea

 autoJibunAddress의 영문 지번 주소

 buildingCode

 4113510900106810000000001

 건물코드

 buildingName

 에이치스퀘어 엔동

 건물명

 postcodeSeq

 001

 우편번호 일련번호

 sido

 경기

 도 / 시 이름

 sigungu

 성남시 분당동

 시 / 군 / 수 이름

 bcode

 4113510900

 법정동 코드

 bname

 삼평동

 법정동 이름









■ 팝업창 띄워서 사용하기




# 소스코드

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

<title>:: 다음 주소록 API ::</title>

<script type="text/JavaScript" src="http://code.jquery.com/jquery-1.7.min.js"></script>

<script type="text/JavaScript" src="http://dmaps.daum.net/map_js_init/postcode.v2.js"></script>

<script type="text/javascript">

function openDaumZipAddress() {

new daum.Postcode({

oncomplete:function(data) {

jQuery("#postcode1").val(data.postcode1);

jQuery("#postcode2").val(data.postcode2);

jQuery("#zonecode").val(data.zonecode);

jQuery("#address").val(data.address);

jQuery("#address_etc").focus();

console.log(data);

}

}).open();

}

</script>

</head>

<body>

<input id="postcode1" type="text" value="" style="width:50px;" readonly/>

&nbsp;-&nbsp;

<input id="postcode2" type="text" value="" style="width:50px;" readonly/>

&nbsp;&nbsp;

<input id="zonecode" type="text" value="" style="width:50px;" readonly/>

&nbsp;

<input type="button" onClick="openDaumZipAddress();" value = "주소 찾기" />

<br/>

<input type="text" id="address" value="" style="width:240px;" readonly/>

<input type="text" id="address_etc" value="" style="width:200px;"/>

</body>

</html>




# 출력결과





다음 우편번호 API - 모바일에서 사용하기 로 이어집니다.




Name __

Password __

Link (Your Website)

Comment

SECRET | 비밀글로 남기기