본문 바로가기
JavaScript

[지도API] Open Layers_2

by amoomar 2022. 11. 21.
반응형

 

예시

 

해당 게시글은 예시를 통해 무료 지도 API인 Open Layers의 이벤트 처리, 오버레이어(지도 위의 별개 요소) 생성에 대한 내용을 정리하였다.

 

목차는 다음과 같다.

1. 이벤트 처리
2. 오버레이어
   1) 오버레이어 생성
   2) 오버레이어 삭제(닫기)

* polygon Layer 삭제
* marker 삭제

 

목차의 내용 이외에 레이어의 추가(polygon 생성 등)와 같은 별도 내용에 대한 설명이 필요하다면 이전 게시글을 통해 해당 내용을 확인할 수 있다.

 


 

 

1. 이벤트 처리

레이어의 클릭이나, hover 등 open layer에 대한 이벤트를 설정하기 위한 로직은 아래와 같다.

지도객체.on('이벤트', function(evt) {
	var map=지도객체;
	var feature = map.forEachFeatureAtPixel(evt.pixel,
		function(feature) {
			return feature;
		});
	if (feature) {
		alret('클릭')
	}
});

 

 

클릭한 좌표에 마커 등을 추가하는 동작을 지시하기 위해서는 다음 예시와 같은 코드를 작성할 수 있겠다.

// ol 이벤트 함수
지도객체.on('click', function(evt) {
	var map=지도객체;
	var coordinate = evt.coordinate;

	// 1. 마커 추가
	var feature = map.forEachFeatureAtPixel(evt.pixel,
		function(feature) {
			return feature;
		});
	if (feature) {
		addMarker(map, coordinate); // 마커 등록 함수
	}
});


//마커 등록하기 함수
function addMarker(map, coordinate) {

	//Point 좌표 등록
	var point_feature = new ol.Feature({
		geometry: new ol.geom.Point(coordinate),
		name: 'point_feature'
	});

	var markerSource = new ol.source.Vector();
	markerSource.addFeature(point_feature);

	//style을 활용해서, point의 style을 변경한다.
	var markerStyle = new ol.style.Style({
		image: new ol.style.Icon({
			opacity: 1, //투명도 1=100% 
			scale: 0.04, //크기 1=100%
			src: '../img/marker04.png' //마커 이미지 경로
		}),
		zindex: 10//html의 css, z-index 기능이다.
	});

	// 마커 레이어 생성
	markerLayer = new ol.layer.Vector({
		name: 'markerLayer',
		source: markerSource, //마커 feacture들
		style: markerStyle //마커 스타일
	});

	// 지도에 마커가 그려진 레이어 추가
	map.addLayer(markerLayer);
}

 

 


 

 

2. 오버레이어

 

1) 오버레이어 생성

ol은 map객체로 addOverlay()함수를 사용하여 오버레이어를 추가할 수 있으며, 이때 인자는 사용자가 정의한 new ol.Overlay객체가 된다. 또한 정의한 overlay객체는 setPosition()함수를 통해 인자로 좌표를 전달함으로써 최종적으로 해당 좌표에 오버레이어를 추가할 수 있게 된다.

 

예시의 경우, 레이어를 클릭 했을때 해당 좌표가 어느 해역에 속하는지를 출력하는 동작을 한다. 그러기 위해서는 클릭이벤트 내부에 오버레이어를 생성하는 로직을 작성해야하는 것을 알 수 있다.

지도객체.on('click', function(evt) {
	var map=지도객체;
	var coordinate = evt.coordinate; //클릭이벤트를 통해 전달받은 좌표
	var feature = map.forEachFeatureAtPixel(evt.pixel,
		function(feature) {
			return feature;
		});
	if (feature) {
    	// 1. 기존 마커 제거 및 추가
		map.getLayers().getArray()
			.filter(layer => layer.get('name') === 'markerLayer')
			.forEach(layer => map.removeLayer(layer));
		addMarker(map, coordinate);
        
        // 2. overlay
        // 1) overlay추가를 위한 및작업
        let container = document.createElement('div');
        container.classList.add('ol-popup-custom');
        let content = document.createElement('div');
        content.classList.add('popup-content');
        container.appendChild(content);
        document.body.appendChild(container);
        
        // 2) 내용 정의
        var content='<div class="bold">해역: ' +선택해역 이름+ '</div>';
        content.innerHTML += content;
        
        // 3) overlay객체 정의
        var overlay = new ol.Overlay({
        	element: container,
            //autoPan: true,
            //autoPanAnimation: {
            	//  duration: 250
            //}
        });
        
        // 4) overlay추가
        map.addOverlay(overlay);
        overlay.setPosition(coordinate);
	}
});

 

 


 

 

2) 오버레이어 삭제(닫기)

위에 작성된 코드대로 라면 좌표를 클릭할때마다 계속해서 오버레이가 추가되기만 하고, 기존 오버레이는 닫히지 않는 상황이 발생하게 된다. 생성된 오버레이에 닫기버튼을 생성하고, 해당 버튼 클릭시에 오버레이가 닫히도록(삭제) 하기 위해서는 아래의 코드를 예시로 들 수 있다.

지도객체.on('click', function(evt) {
	var map=지도객체;
	var coordinate = evt.coordinate; //클릭이벤트를 통해 전달받은 좌표
	var feature = map.forEachFeatureAtPixel(evt.pixel,
		function(feature) {
			return feature;
		});
	if (feature) {
    	// 1. 기존 마커 제거 및 추가
		map.getLayers().getArray()
			.filter(layer => layer.get('name') === 'markerLayer')
			.forEach(layer => map.removeLayer(layer));
		addMarker(map, coordinate);
        
        // 2. overlay
        // 1) overlay추가를 위한 및작업
        let container = document.createElement('div');
        container.classList.add('ol-popup-custom');
        let content = document.createElement('div');
        content.classList.add('popup-content');
        container.appendChild(content);
        document.body.appendChild(container);
        
        // 2) 내용 정의
        var content = '<div id="closebtn"><img onClick="clickOfCloseImg()" src="../img/ic_close.svg" alt="닫기"></div>'
        content += '<div class="bold">해역: ' + 해역이름 + '</div>';
        content.innerHTML += content;
        
        // 3) overlay객체 정의
        var overlay = new ol.Overlay({
        	element: container,
            //autoPan: true,
            //autoPanAnimation: {
            	//  duration: 250
            //}
        });
        
        // 4) overlay추가
        $(".ol-overlay-container").remove() //새 오버레이가 열리기 전에 기존 오버레이를 삭제
        map.addOverlay(overlay);
        overlay.setPosition(coordinate);
	}
});

// 닫힘버튼 클릭시 동작 함수
function clickOfCloseImg(){
	var map=지도 객체;
	$(".ol-overlay-container").remove()// 오버레이 지우고
	map.getLayers().getArray() // 마커도 지우기
		.filter(layer => layer.get('name') === 'markerLayer')
		.forEach(layer => map.removeLayer(layer));	
}

 

 

 


 

 

*polygon Layer 삭제

바로 직전 목차의 clickOfCoseImg()를 자세히 확인해보면, 마커 삭제를 위한 코드를 확인할 수 있는데 이는 특정 레이어의 삭제에도 동일하게 사용될 수 있다. 해당되는 부분은 아래와 같다.

지도객체.getLayers().getArray()
	.filter(layer => layer.get('name') === '삭제할 레이어의 이름')
	.forEach(layer => map.removeLayer(layer));

 

이때 사용되는 레이어 이름은 layer생성시 선택적으로 정의할 수 있는 new ol.layer.vector의 name속성값을 의미한다. polygon layer의 추가를 위해 사용했던 함수의 내용을 예시로 살펴보자면 아래와 같으며, 주석을 통해 어떤 부분을 특정하는 것인지 확인해 볼 수 있다.

function drawMap(map, color, path) {
	var polygonLayer = new ol.layer.Vector({
		name: path, //해당 vector의 이름
		opacity: 0.5,
		source: new ol.source.Vector({ format: new ol.format.GeoJSON(), url: filePath + path + '.geojson' }),
		style: [
			new ol.style.Style({
				stroke: new ol.style.Stroke({
					color: color,
					width: 2
				}),
				fill: new ol.style.Fill({
					color: color.replace(')', ', 0.6)')//투명도설정
				}),
			})
		]
	});

	map.addLayer(polygonLayer);
}

 

처음 제시했던 삭제 로직의 '삭제할 레이어의 이름'을 아래 제시한 예시의 path부분과 동일하게 한다면, path라는 name을 가진 vector레이어가 정상적으로 삭제되는 모습을 확인할 수 있다.

 

 

 


 

 

*marker 삭제

내용은 위와 동일하지만, 예시를 통해 다시 한 번 설명하자면 아래와 같다.

지도객체.getLayers().getArray()
	.filter(layer => layer.get('name') === '삭제할 레이어의 이름')
	.forEach(layer => map.removeLayer(layer));
//마커 등록하기 함수
function addMarker(map, point) {

	var point_feature = new ol.Feature({
		geometry: new ol.geom.Point(point),
		name: 'point_feature'
	});

	var markerSource = new ol.source.Vector();
	markerSource.addFeature(point_feature);

	var markerStyle = new ol.style.Style({
		image: new ol.style.Icon({ //마커 이미지
			opacity: 1, //투명도 1=100% 
			scale: 0.04, //크기 1=100%
			src: '../img/marker04.png'
		}),
		zindex: 10
	});

	markerLayer = new ol.layer.Vector({
		name: 'markerLayer',
		source: markerSource,
		style: markerStyle
	});

	map.addLayer(markerLayer);
}

addMarker()의 내용을 자세히 확인하면 name속성을 가지는 객체는 Feature와 Vector, 총 두가지인 것을 알 수 있다.

 

이번 예시에서도 기존 설명과 마찬가지로, '삭제할 레이어의 이름'은 new ol.layer.Vector의 name속성값, 즉 'markerLayer'와 동일하게 작성하면 정상적으로 마커레이어가 삭제되는 것을 확인할 수 있다.

 

 

 


 

반응형

'JavaScript' 카테고리의 다른 글

Object의 value로 index접근하는 방법  (0) 2022.11.24
[openLayers_proj] 좌표계 변환  (0) 2022.11.21
Object_value로 key 참조하기  (0) 2022.09.23
[그래프 API] HighCharts  (0) 2022.07.07
[지도 API] OpenLayers_1  (0) 2022.07.06