Map(WEB)

vworld 지도 만들기(9) - 좌표에 대한 주소 검색하기(2)

별동산 2025. 2. 12. 08:22
반응형

이번에는 alert 창이 아니라 클릭한 지점에 팝업 창을 표시해서 좌표 등 정보를 표시해 보겠습니다.
 

1. vw.ol3.popup.Popup 기능

2D지도 API 2.0중 popup 기능을 이용하면 되는데,
코드 샘플 중 popup을 누릅니다.

 
예제 코드는 아래와 같이 되어 있는데,

    var pop = null ;
 
    vw.ol3.MapOptions = {
       basemapType: vw.ol3.BasemapType.GRAPHIC
     , controlDensity: vw.ol3.DensityType.EMPTY
     , interactionDensity: vw.ol3.DensityType.FULL
     , controlsAutoArrange: true
     , homePosition: vw.ol3.CameraPosition
     , initPosition: vw.ol3.CameraPosition
    }; 
       
    var vmap = new vw.ol3.Map("vmap",  vw.ol3.MapOptions);
     
    vmap.on("click", function(evt) {
      var coordinate = evt.coordinate;
      var hdms = "팝업예제";
      var content = hdms ;
      if(pop == null){
       pop = new vw.ol3.popup.Popup();       
      }
      pop.title = "브이월드 오픈 API";
      pop.content = "오픈 API 2.0 WEB";
      vmap.addOverlay(pop);
      pop.show(content,coordinate);
     }
    );

 
변수 선언하는 부분과

vmap.on("click", function(evt) {
...
}
의 아래에 있는 다음 내용을 참고해서 만들면 됩니다.

      var coordinate = evt.coordinate;
      var hdms = "팝업예제";
      var content = hdms ;
      if(pop == null){
       pop = new vw.ol3.popup.Popup();       
      }
      pop.title = "브이월드 오픈 API";
      pop.content = "오픈 API 2.0 WEB";
      vmap.addOverlay(pop);
      pop.show(content,coordinate);

 

2. 코드

작성된 코드는 아래와 같습니다.

<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>좌표로 주소 알아내기</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">
		let pop = null ;
		
		vw.ol3.MapOptions = {
			basemapType: vw.ol3.BasemapType.GRAPHIC
			, controlDensity: vw.ol3.DensityType.EMPTY
			, interactionDensity: vw.ol3.DensityType.BASIC
			, controlsAutoArrange: true
			, homePosition: vw.ol3.CameraPosition
			, initPosition: vw.ol3.CameraPosition
		};

		let vmap = new vw.ol3.Map("vmap",  vw.ol3.MapOptions); 		 

		vmap.getView().setCenter([14129132.729661161, 4512073.703926638]);
		vmap.getView().setZoom(18);

		vmap.on("click", function(evt) {
			if(pop == null){
				pop = new vw.ol3.popup.Popup();       
			}
			
			let coordinate = evt.coordinate //좌표정보(EPSG:900913)
			//let latlng_4326 = ol.proj.transform(coordinate, 'EPSG:900913', 'EPSG:4326');
			//let latlng_4326_str=latlng_4326[0] + "," + latlng_4326[1];
			let latlng_900913_str=coordinate[0] + "," + coordinate[1];

			$.ajax({	
				url: "https://api.vworld.kr/req/address?",	
				type: "GET",	
				dataType: "jsonp",	
				data: {	
					service: "address",	
					request: "getaddress",	
					version: "2.0",	
					crs: "EPSG:3857",	
					type: "BOTH",	
					point: latlng_900913_str,
					format: "json",	
					errorformat: "json",	
					key: "CEB52025-E065-364C-9DBA-44880E3B02B8"	
				},	
				success: function (result) {				
					console.log(result);
					// 좌표 변환
					content = ol.coordinate.toStringHDMS(ol.proj.transform(vmap.getView().getCenter(),"EPSG:3857","EPSG:4326"));
					pop.title = "좌표 및 주소";
					if (result.response.result.length > 1) {
						content += "<br>" + result.response.result[0].text + '<br>' + result.response.result[1].text;
					} 
					else {
						content += "<br>" + result.response.result[0].text;
					}
					vmap.addOverlay(pop);
					pop.show(content, coordinate);	
				},
				error: function (xhr, status, error) {
					console.error("Error:", status, error);
				}
			});
		});

	</script>
</body>
</html>

 

3. 코드 설명

let pop = null ;  : pop이란 변수를 선언합니다.
 

if(pop == null){
    pop = new vw.ol3.popup.Popup();       
}

pop 변수가 null, 다시 말해 popup 생성이 안 되어 있으면 vw.ol3.popup.Popup(); 을 새로 만듭니다.
 

content = ol.coordinate.toStringHDMS(ol.proj.transform(vmap.getView().getCenter(),"EPSG:3857","EPSG:4326"));

 
content를 위, 경도로 표시할 수 있도록 ol.proj.transform함수를 이용해 EPSG:3857을 EPSG:4326으로 변환하고,

toStringHDMS, 다시 말해 실수(예, 127.5... , 37.2...)로 되어 있는 좌표를 도, 분, 초 형식의 각도(degree)로 변환합니다.
 

pop.title = "좌표 및 주소";

popup의 제목을 '좌표 및 주소'로 지정합니다.
 

if (result.response.result.length > 1) {
    content += "<br>" + result.response.result[0].text + '<br>' + result.response.result[1].text;

else {
    content += "<br>" + result.response.result[0].text;
}

content를 위에서 구한 도, 분, 초 형식의 위, 경도에 경우에 따라 지번주소 또는 지번 주소와 도로명 주소를 결합합니다.
 

vmap.addOverlay(pop);
pop.show(content, coordinate);

vmap 지도에 pop을 추가한 후
content를 coordinate 위치(클릭 위치)에 표시합니다.
 

4. 실행 결과

아래와 같이 '좌표 및 주소'란 제목에 위도와 경도가 도, 분, 초 형식으로 표시되는데, N으로 북위, E로 동경을 표시합니다.

그리고, 아래에 지번 주소와 도로명 주소가 표시되는데, 너비가 좁아 두 줄로 표시됩니다.

 

5. 너비 조절이 가능한가?

너비를 늘릴 수 있나 하고 vw.ol3.popup.Popup의 레퍼런스를 찾아보니
메서드에 close, show만 있고, setWidth 메서드가 없는 것을 보니 힘들 듯합니다.

 
혹시나 하고 div 내에 style을 적용해 봐도 안됩니다.

content += "<div style='width:350px;'><br>" + result.response.result[0].text + '<br>' + result.response.result[1].text + "</div>";

 
오히려 줄이 바뀌지 않아 글자가 잘렸습니다.

 

6. 글자 굵게 등 설정은 가능

좌표 및 주소의 글자를 굵게 하니 구분되어 보기 좋네요. 그리고 <br> 태그를 사용해 줄 바꾸기도 했습니다.

content = "<b>좌표: </b>" + ol.coordinate.toStringHDMS(ol.proj.transform(vmap.getView().getCenter(),"EPSG:3857","EPSG:4326")) + "<br>";
pop.title = "<b>좌표 및 주소</b>";
if (result.response.result.length > 1) {
    content += "<br><b>지번 주소: </b>" + result.response.result[0].text + '<br><br><b>도로명 주소: </b>' + result.response.result[1].text;

else {
    content += "<br><b>지번 주소: </b>" + result.response.result[0].text;
}

 

 

7. 전체 코드

<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>좌표로 주소 알아내기</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">
		let pop = null ;
		
		vw.ol3.MapOptions = {
			basemapType: vw.ol3.BasemapType.GRAPHIC
			, controlDensity: vw.ol3.DensityType.EMPTY
			, interactionDensity: vw.ol3.DensityType.BASIC
			, controlsAutoArrange: true
			, homePosition: vw.ol3.CameraPosition
			, initPosition: vw.ol3.CameraPosition
		};

		let vmap = new vw.ol3.Map("vmap",  vw.ol3.MapOptions); 		 

		vmap.getView().setCenter([14129132.729661161, 4512073.703926638]);
		vmap.getView().setZoom(18);

		vmap.on("click", function(evt) {
			if(pop == null){
				pop = new vw.ol3.popup.Popup();       
			}
			
			let coordinate = evt.coordinate //좌표정보(EPSG:900913)
			//let latlng_4326 = ol.proj.transform(coordinate, 'EPSG:900913', 'EPSG:4326');
			//let latlng_4326_str=latlng_4326[0] + "," + latlng_4326[1];
			let latlng_900913_str=coordinate[0] + "," + coordinate[1];

			$.ajax({	
				url: "https://api.vworld.kr/req/address?",	
				type: "GET",	
				dataType: "jsonp",	
				data: {	
					service: "address",	
					request: "getaddress",	
					version: "2.0",	
					crs: "EPSG:3857",	
					type: "BOTH",	
					point: latlng_900913_str,
					format: "json",	
					errorformat: "json",	
					key: "CEB52025-E065-364C-9DBA-44880E3B02B8"	
				},	
				success: function (result) {				
					console.log(result);
					
					// 좌표 변환
					content = "<b>좌표: </b>" + ol.coordinate.toStringHDMS(ol.proj.transform(vmap.getView().getCenter(),"EPSG:3857","EPSG:4326")) + "<br>";
					
					pop.title = "<b>좌표 및 주소</b>";
					
					if (result.response.result.length > 1) {
						content += "<br><b>지번 주소: </b>" + result.response.result[0].text + '<br><br><b>도로명 주소: </b>' + result.response.result[1].text;
					} 
					else {
						content += "<br><b>지번 주소: </b>" + result.response.result[0].text;
					}
					
					vmap.addOverlay(pop);
					pop.show(content, coordinate);	
				},
				error: function (xhr, status, error) {
					console.error("Error:", status, error);
				}
			});
		});

	</script>
</body>
</html>
반응형