티스토리 뷰
[출처] OpenLayers3 와 VWORLD 를 사용해보자|작성자 곰구리
지도 서비스 하면 국내에서 유명한 것에는 네이버지도, 다음(카카오)지도, 구글지도 등이 있다.
워낙 다양하게 쓰이고 기능도 좋고.. 뭐든 다 좋다.. 검색도 엄청난 데이터를 기반으로 짜잔 하고 뿌려주니.. 정말 대단하다 라고 밖에 말할 수 없는 듯 싶다.
하지만, 이것을 내가 만든 프로그램에 넣을순 있어도 기능을 넣어보는 것은 쉽지가 않다. 특히 내가 모아놓은 좌표정보를 거기에다가 뿌리려면.... 어휴;;
이런 부분들을 공부해보려 하면.. GIS 엔진으로 어쩌구 저쩌구 하면서.. 디게 복잡한 이야기가 나오던데... 이건.. 혼자 해보기에는 너무 어렵다..
그래서 블로그나 카페들에서 가끔 다루는 오픈소스기반 GIS 를 써서.. 맵을 얹어서 해야한다는데.. 하하하..... 이것도 이해를 잘 못하겠다 ㄱ-;;;
그래도 어쩔수 없지.. 일단 정보를 수집해보자.
OpenLayers3 사이트 : https://openlayers.org/
Leaflet 사이트 : http://leafletjs.com/
VWORLD 사이트 : http://map.vworld.kr
OpenLayer(이하 OL3) 와 Leaflet 은 오픈소스기반 GIS 엔진이라고 말하시는 분도 있고.. 웹에서 지도서비스를 쉽게 구축하기 위한 도구라고도 말하는데 뭐 같은 의미인듯 싶다.
Leaflet 과 OL3 로 지도서비스 환경을 구축하고, GoogleMap 이나 OpenStreetMap 등을 올리면 되는데..
VWORLD 라고 공간사업진흥청?(왠지 국가기관 같다..) 거기서 제공하는 국산지도도 있길래 이 포스팅에서는 이 VWORLD를 사용해볼까 한다.
일단 국산이니까.. 국내지리정보에 대한 것은 더 잘 나와있지 않을까..... (구글지도가 더 좋으려나;;)
Leaflet 과 OL3 둘 중에 무엇을 사용해볼까 하고 참 고심을 많이 해보았는데..
구글링 해보니, Leaflet 보다 OpenLayers 자동완성이 더 많길래.. 자료 많은 것으로 방향을 잡아 볼까 한다 ㄱ-;;
일단 OpenLayers 에 대한 정보가 있는 페이지들을 다 모아보자.
- 위에서도 적었지만, OpenLayers 사이트를 방문하면 Examples 가 있는데 꼭 대충 훑어보자. 기본 제공되는 예제가 참 많다.
- 그다음은 정말 정리가 잘 되어 있는 국내 블로그가 있어서 링크를 걸어둔다. (http://blog.naver.com/junddang2/30133261952)
여기서는 개념정리 뿐만 아니라, 예제 코드도 많이 있는데, 약간 염려스러운건 2012년 블로그라는 것이다.. 버전이 바뀌면 메소드도 바뀌는지라.. 음;;
- http://openlayersbook.github.io 여기는 github 에서 제공하는지 아닌지는 모르겠지만 초보자가이드 같은 느낌? OL3 홈페이지의 Example 과 비슷하긴 하지만,
약간 더 쉽게 정리도 되어있고, 그러해서 참고가 많이 되는듯 싶다.
OL3 라이브러리는.. https://github.com/openlayers/openlayers 여기에 가서 다운로드 받아서 찾아보면 있긴한데.. 찾는데 한참 걸려서..
일단 압축해서 올려놀까 싶다. (압축한 파일에는, 여기에 정리한 부분의 예제파일(html)도 같이 첨부하도록 하겠다)
1. js 라이브러리 및 페이지 디자인 하기
- 가장 먼저 할 일은, 라이브러리를 추가하는 일이다.
- 라이브러리 파일들을 알아서 잘~ 좋은 위치에 두고, html 파일에 추가하고, 간단하게 페이지 디자인도 해주자.
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) --> <script src="resources/jquery/jquery-1.11.3.min.js"></script>
<!-- openlayers --> <link href="resources/openlayers/ol.css"rel="stylesheet"> <script src="resources/openlayers/ol.js"></script>
<script src="resources/js/proj4.js"></script>
<!-- 지도 스타일 --> <style type="text/css"> #map { width: 600px; height: 400px; border: 2px solid #ccc; }
table.list_t1 { margin:10px 0; text-align:center;border-collapse:collapse; width:600px; border-top:2px solid #005aa1; border-bottom:1px solid #e3e8e9; } table.list_t1 th, table.list_t1 td { border-right:1px solid #e3e8e9;border-bottom:1px solid #e3e8e9;font-size:13px; } table.list_t1 td { padding:2px; height:25px; } table.list_t1 th { background:#f6f6f6;padding:9px 10px;text-align:center; } table.list_t1 th:last-child,table.list_t1 td:last-child { border-right:none; } </style>
</head> <body>
<div id="content_wp"> <div id="content">
<div class="custom-popup" id="map">
</div> <input id="base-layer" type="button" value="지도" onclick="baseChange('satellite')"> <input type="button" value="포인트" onclick="mapSubmit()">
<table class="list_t1" id="gisTable"> <tr> <th>위치</th> <th>경도</th> <th>위도</th> </tr> </table> </div> </div>
</body> |
2. 지도 뿌리기
- 먼저 VWORLD 지도를 id=map 인 div 에 뿌려보도록 하겠다.
// 지도 var layers = {}; layers['vworld'] = new ol.layer.Tile({ title : 'VWorld Gray Map', visible : true, type : 'base', source : new ol.source.XYZ({ url : 'http://xdworld.vworld.kr:8080/2d/Base/201612/{z}/{x}/{y}.png' }) });
// vectorSource 선언 var vectorSource = new ol.source.Vector({ projection: 'EPSG:4326' });
// vectorLayer 선언 var vectorLayer = new ol.layer.Vector({ source: vectorSource });
// 지도뿌리기 var map = new ol.Map({
layers : [ layers['vworld'], vectorLayer ], target : 'map', view : new ol.View({ // center: ol.proj.transform([getLongi, getLati ], 'EPSG:4326', 'EPSG:3857'), center: ol.proj.fromLonLat([127.5, 36]), // center 좌표 zoom: 7, // 초기화면 zoom level minZoom: 6, // 최소 zoom level maxZoom: 19 // 최대 zoom level }) }); |
- 위와 같이 하면, layers['vworld'] 라는 레이어가 map 이라는 target 에 들어가며, center 좌표값, 현재줌 등을 설정을 할 수 있다.
- 실제로 지도만 뿌리는건 위가 끝이다.
- 여기서 중요한건, 첫번째 메소드 내에 url을 보면 지도 이미지 정보를 받는 주소가 있는데, 테스트용으로 알고 있다.
실제로 사용하려면, api-key를 받아서 사용을 해야 한다는데, 그냥 VWORLD 사이트 가입 후 신청하면 보내준다고 하는거 같다.
3. 지도 바꾸기
- 네이버지도나 구글지도를 보면, 위성사진 보기 기능이 있다. 우리도 그 기능을 넣어보도록 하자.
- 뷰페이지쪽에 보면 벌써 버튼을 만들어 놓았다. (id=base-layer)
- 이 버튼을 누르면 지도가 위성으로 바뀌고, 다시 누르면 원래 지도로 돌아가는 것을 추가해보자.
- 먼저 위성지도 부분을 작성하자. (
// 지도 var layers = {}; layers['vworld'] = new ol.layer.Tile({ title : 'VWorld Gray Map', visible : true, type : 'base', source : new ol.source.XYZ({ url : 'http://xdworld.vworld.kr:8080/2d/Base/201612/{z}/{x}/{y}.png' }) }); layers['satellite'] = new ol.layer.Tile({ title : 'VWorld Gray Map', visible : true, type : 'base', source : new ol.source.XYZ({ url : 'http://xdworld.vworld.kr:8080/2d/Satellite/201612/{z}/{x}/{y}.jpeg' }) });
// vectorSource 선언 var vectorSource = new ol.source.Vector({ projection: 'EPSG:4326' }); |
- 위와 같이 layers['satellite'] 를 추가해주고 (여기에서는 위성사진 이미지를 받아온다)
- 아래와 같이 버튼을 눌렀을때 지도를 바꿔주는 메서드를 추가해주자.
// 버튼 클릭시, 해당 타일(지도와 위성)로 변경 function baseChange(data){ if(data=="satellite"){ // 위성으로 변경 $("#base-layer").val("위성"); $("#base-layer").attr("onclick", "baseChange('vworld')");
} else { // 지도로 변경 $("#base-layer").val("지도"); $("#base-layer").attr("onclick", "baseChange('satellite')"); }
var layer = layers[data]; if (layer) { layer.setOpacity(1); updateRenderEdgesOnLayer(layer); map.getLayers().setAt(0, layer); } }
// 타일 변경 var updateRenderEdgesOnLayer = function(layer) { if (layer instanceof ol.layer.Tile) { var source = layer.getSource(); } }; |
- 생각보다 쉬워보인다. 뭔말인지는 잘 모르는 부분은 많지만.. 일단 여기까지 해보면 버튼을 누를때 배경지도가 바뀌는 것을 확인할 수 있다.
4. 지도에 포인트 찍기.
- 작동방식을 보자면, 포인트버튼(mapSubmit())을 누르면 좌표정보를 전역변수 선언을 한 svyData 라는 변수에 담은 후, addFeature() 라는 메서드를 이용해서, 이 변수 안에 들어있는 좌표정보 및 기타 정보들을 iconFeature 라는 변수에 담고. 그 iconFeature 를 iconFeatures 라는 배열에 담은 후, 지도 생성할때 선언한 vectorSource에 add를 하여 포인트를 찍는다.
- 그 생성된 포인트에는 iconFeature를 생성하면서 넣은 정보가 들어있으면, map.on() 메소드를 이용하여 클릭 시 그 정보를 alert으로 띄우게 하며, DragBox 이벤트를 이용하여 선택한 포인트들(features)에 대한 정보를 table 에 뿌린다.
(드래그는, Ctrl+마우스드래그 로 작동한다)
- 는 것이 기본 작동방식이다.
- 이부분에 대해서는 파일로 첨부한 것을 참고하면 쉽게 이해할 수 있을 것이라 보긴하는데.. mapSubmit() 메서드 부분만 짧게 추가적으로 적어보자면
function mapSubmit(){ // get // 이 부분은 나중에 ajax 등을 통해서 좌표 값을 json object 형태로 가져와서 data 에 넣어주면 됨. var data = new Array();
var coord = new Object(); coord.svy_name = "약진너머해수욕장"; coord.svy_longi = 126.233439; coord.svy_lati = 37.180287; data.push(coord); var coord = new Object(); coord.svy_name = "떼뿌루해수욕장"; coord.svy_longi = 126.175860; coord.svy_lati = 37.211874; data.push(coord); // get
svyData = data; var jsonData = JSON.stringify(data) ;
addFeatures(); } |
- 지금 위의 코드를 보면, json object 형태로 데이터를 생성하고 있다.
실제로 위와같이 쓰일일은 없을 듯 싶고, mysql 등의 DB에서 값을 가져다가 json 형태로 리턴해줬을때로 가정을 하고 작성을 했다.
// get 사이 부분을 ajax json 으로 만들어서 쓰면 간단하게 응용해서 쓸 수 있을것이라 생각된다.
5. 실제실행 모습
6. 추가
지도에 보면 우측 아래에 아이콘 같은 것이 있다. Attribution 이라 부르는 것 같던데. 이거 없앨 수가 있다고 한다.
var map 정의하는 곳에 이거 한줄 추가해주면 된다.
var map = new ol.Map({
layers : [ layers['vworld'], layers['bng'], vectorLayer ], logo : false, target : 'map', view : ........ }); |
7. 전체 소스
<!DOCTYPE html>
<html>
<head>
<!-- jQuery -->
<script src="https://code.jquery.com/jquery-1.8.3.min.js"></script>
<!-- openlayers -->
<!-- Openlayers 6 -->
<link rel="stylesheet" href="/js-lib/openlayers/ol6/ol.css"/>
<script type="text/javascript" src="/js-lib/openlayers/ol6/ol.js"></script>
<script type="text/javascript" src="/js-lib/openlayers/ol6/ol-ext.js"></script>
<script type="text/javascript" src="/js-lib/openlayers/ol6/proj4-src.js"></script>
<!-- proj4.js -->
<script type="text/javascript" src="/js-lib/openlayers/ol2/proj4.js"></script>
<!-- <script src="resources/js/proj4.js"></script> -->
<!-- 지도 스타일 -->
<style type="text/css">
#map {
width: 600px;
height: 400px;
border: 2px solid #ccc;
}
table.list_t1 {
margin:10px 0; text-align:center;border-collapse:collapse; width:600px;
border-top:2px solid #005aa1; border-bottom:1px solid #e3e8e9;
}
table.list_t1 th, table.list_t1 td {
border-right:1px solid #e3e8e9;border-bottom:1px solid #e3e8e9;font-size:13px;
}
table.list_t1 td {
padding:2px; height:25px;
}
table.list_t1 th {
background:#f6f6f6;padding:9px 10px;text-align:center;
}
table.list_t1 th:last-child,table.list_t1 td:last-child {
border-right:none;
}
</style>
</head>
<body>
<div id="content_wp">
<div id="content">
<div class="custom-popup" id="map">
</div>
<input id="base-layer" type="button" value="지도" onclick="baseChange('satellite')">
<input type="button" value="포인트" onclick="mapSubmit()">
<table class="list_t1" id="gisTable">
<tr>
<th>위치</th>
<th>경도</th>
<th>위도</th>
</tr>
</table>
</div>
</div>
<script type="text/javascript">
//지도
var layers = {};
layers['vworld'] = new ol.layer.Tile({
title : 'VWorld Gray Map',
visible : true,
type : 'base',
source : new ol.source.XYZ({
url : 'http://xdworld.vworld.kr:8080/2d/Base/201612/{z}/{x}/{y}.png'
})
});
layers['satellite'] = new ol.layer.Tile({
title : 'VWorld Gray Map',
visible : true,
type : 'base',
source : new ol.source.XYZ({
url : 'http://xdworld.vworld.kr:8080/2d/Satellite/201612/{z}/{x}/{y}.jpeg'
})
});
// vectorSource 선언
var vectorSource = new ol.source.Vector({
projection: 'EPSG:4326'
});
// vectorLayer 선언
var vectorLayer = new ol.layer.Vector({
source: vectorSource
});
// 지도뿌리기
var map = new ol.Map({
layers : [ layers['vworld'], vectorLayer ],
target : 'map',
view : new ol.View({
//center: ol.proj.transform([127.5, 36 ], 'EPSG:4326', 'EPSG:3857'),
center: ol.proj.fromLonLat([127.5, 36]), // center 좌표
zoom: 7, // 초기화면 zoom level
minZoom: 6, // 최소 zoom level
maxZoom: 19 // 최대 zoom level
})
});
// 버튼 클릭시, 해당 타일(지도와 위성)로 변경
function baseChange(data){
if(data=="satellite"){ // 위성으로 변경
$("#base-layer").val("위성");
$("#base-layer").attr("onclick", "baseChange('vworld')");
} else { // 지도로 변경
$("#base-layer").val("지도");
$("#base-layer").attr("onclick", "baseChange('satellite')");
}
var layer = layers[data];
if (layer) {
layer.setOpacity(1);
updateRenderEdgesOnLayer(layer);
map.getLayers().setAt(0, layer);
}
}
// 타일 변경
var updateRenderEdgesOnLayer = function(layer) {
if (layer instanceof ol.layer.Tile) {
var source = layer.getSource();
}
};
</script>
</body>
</html>
'Skill > OpenLayers' 카테고리의 다른 글
[OpenLayers] ol.control (0) | 2020.09.22 |
---|---|
[OpenLayers] 마우스로 도형 그리기 (0) | 2020.09.20 |
[OpenLayers] 마우스 오버시 특정 구역 하이라이팅하기(with ol.interaction.select) (0) | 2020.09.20 |
[OpenLayers] 사용법 기초1 (1) | 2020.09.20 |
[OpenLayers] 개론 (0) | 2020.09.20 |
- Total
- Today
- Yesterday
- $.each
- Keycode
- sumifs
- 여러 컬럼 update
- devtools
- CSS
- Javascript
- 진열사랑
- getter
- object key
- @ExceptionHandler
- spring
- QueryDSL
- draw.io
- DatePicker
- excel
- springboot
- caniuse
- oracle
- lombok
- ul li로 테이블
- JQuery
- 전후방탐색
- $.extend
- setter
- 프로젝트명변경
- border-collapse
- PostgreSQL
- element위치
- 정규식
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |