Map(WEB)

vworld 지도 만들기(14) - 개별공시지가 표시하기(2) : JSONP

별동산 2025. 3. 4. 08:29
반응형

이번에는 JSONP를 이용해 코드를 만들어보겠습니다.

 

JSONP를 Wikipedia에서 찾아보니 아래와 같은 설명이 나옵니다. 신기한 것은 JSOP가 CORS를 회피하기 위한 것인데, 아래 결론은 CORS로 대체되고 있다고 합니다. 아이러니네요...

 

1. 샘플 코드

샘플 코드를 HTML 문서에 넣으면 아래와 같이 됩니다.

인증키와 도메인은 자신의 것으로 수정하기 바랍니다.

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no, shrink-to-fit=no">
	<title>개별공시지가 조회(JSONP)</title>
</head>
<body>
	<div id="vmap">
	<script type="text/javascript" src="https://map.vworld.kr/js/vworldMapInit.js.do?version=2.0&apiKey=CEB52025-E065-364C-9DBA-44880E3B02B8&domain=localhost:8080"></script>

	<script type="text/javascript">
	
		/* JSONP 샘플 코드 */     
		xhr=new XMLHttpRequest();
		
		var data = {};
		data.key = "인증키"; /* key */
		data.domain = "도메인"; /* domain */
		data.pnu = "1156011000100010000"; /* 고유번호(8자리 이상) */
		data.stdrYear = "2024"; /* 기준연도(YYYY: 4자리) */
		data.format = "json"; /* 응답결과 형식(json) */
		data.numOfRows = "10"; /* 검색건수 (최대 1000) */
		data.pageNo = "1"; /* 페이지 번호 */
		
		
		$.ajax({
			type : "get",
			dataType : "jsonp",
			url : "https://api.vworld.kr/ned/data/getIndvdLandPriceAttr",
			data : data,
			async : false,
			success : function(data) {
				console.log(data);
			},
			error : function(xhr, stat, err) {}
		});
		
	</script>
</body>
</html>

 

샘플코드는 url이 http://api.vworld.kr/... 라고 되어 있는데, 이렇게 하고 실행하면 https라야 한다는 메시지가 나오므로

 

http를 https로 수정하고 실행하면

 

{indvdLandPrices:{…}}이라고 배열 형태로 결과가 콘솔창에 표시됩니다.

왼쪽의 삼각형 표시를 계속 누르면

 

JSONP는 JSON형태가 아니라 JavaScript 배열이므로 JSON Parsing을 할 필요없이 바로 pblntPclnd에 해당하는 값을

data.indvdLandPrices.field[0].pbIntfPcInd라고 하면 해당 지번에 대한 개별공시지가를 구할 수 있습니다.

 

이번에는 console.log가 아니라 alert를 이용해 표현하겠습니다.

alert(data.indvdLandPrices.field[0].pblntfPclnd);

 

그리고 실행하면 알림창에 18600000이라고 표시됩니다.

 

 

2. 지도를 클릭하면 해당 지번의 개별 공시지가 표시하기

클릭한 지점의 법정동 코드를 구한 후 지번을 지번구분과 본번, 부번을 결합해서 19자리 숫자로 만든 다음

pnu에 대한 개별공시지가를 구하는 코드입니다.

getIndvdLandPrice2_2.html
0.00MB

 

 

3. 코드 수정사항 및 설명

가. 법정동 코드 구하는 코드 수정

function get_legal_code(dong) 로 법정동 코드를 구했는데,

이것을 개별공시지가 구할 때 변수로 넘기려고 했더니 넘어가지 않아 그록 3에 물어보니

 

async function get_legal_code(dong) {로 해야 한다고 해서 수정하고,

아래와 같이 수정하고,

		async function get_legal_code(dong) {
			const HttpUrl = "https://apis.data.go.kr/1741000/StanReginCd/getStanReginCdList";
			
			let parameter = "?" + "ServiceKey" + "=" + "data.go.kr 인증키";			
			parameter += "&" + "type" + "=" + "json";
			parameter += "&" + "locatadd_nm" + "=" + dong;
			
			const searchUrl = HttpUrl + parameter;
			
			try {
				const response = await fetch(searchUrl);
				if (!response.ok) throw new Error("요청 실패: " + response.status);
				const obj = await response.json();
				const regionCd = obj.StanReginCd[1].row[0].region_cd;
				//alert(dong + "의 법정동 코드는 " + regionCd);
				return regionCd;
			} catch (error) {
				console.error(error);
				throw error;
			}
		}

 

데이터를 받는 부분도 아래와 같이 수정했습니다.

(async () => {
    const regionCD = await get_legal_code(dong);
}

 

 

나. PNU 작성하는 것을 코드로 구현

/* PNU(고유번호) 구하기 */
let sanYn = match[2].indexOf('산') > 0 ? '2' : '1';
let numbers = match[2].replace('산', '').split('-');
let bonbun = numbers[0].padStart(4, '0');
let bubun = numbers[1] ? numbers[1].padStart(4, '0') : '0000';
const pnu = regionCD + sanYn + bonbun + bubun;

console.log(pnu);

 

match는 주소를 동/리를 기준으로 분리한 배열로

match[2]가 지번에 해당하며,

match[2]에 '산'이 있으면 필지구분은 2가 되고, 아니면 1입니다.

그리고, 지번에서 숫자 부분을 하이픈으로 구분해서

첫번째 배열이 본번인데 4자리여야 하므로 '0'을 앞에 붙여 4자리 숫자로 만들고

부분은 두번째 배열이 있으면 마찬가지로 그 숫자의 앞에 0을 붙여 4자리 숫자로 만드는데, 없으면 '0000'으로 합니다.

 

그래서 이 4개를 연결해서 pnu를 만드는 것입니다.

 

다. 주소에 해당하는 개별공시지가 구하기

1번에서는 여의도동 1번지로 주소가 고정되었었는데,

getLandPrice 함수를 만들고 위에서 만든 pnu를 인수로 대입합니다.

함수 안의 코드는 1번의 코드와 동일합니다.

 

라. 동이 '가'로 끝나는 경우가 있어 match 구하는 수식 수정

'여의도동'인 경우는 잘 나왔는데, 여의도 왼쪽을 클릭했는데 개별공시지가가 표시되지 않아 주소를 살펴보니

'서울특별시 영등포구 영등포동2가...'로 '가'로 끝나는 경우가 있어서

 

const match = jibun_addr.match(/^(.*[가|로|동|리])\s*(.*)$/);로 수정했습니다.

그리고, '동|리|가'로 했더니 '동'이 우선 적용돼서 '가'를 맨앞에 두었고,

'서울특별시 종로구 세종로'가 있어서 '로'도 추가했습니다.

 

 

4. 코드 실행 화면

'동'으로 끝나지 않고 '세종로 1'로 '로'로 끝나는데도 개별공시지가가 잘 표시됩니다.

 

'신문로1가 2번지의 개별공시지가도 잘 표시됩니다.

반응형