※ 참고
나는 html을 정식으로 배운게 아니라서 설명이나 표현이 정확하지 않을 수 있다. 실행에 초점을 맞춰서 작성하는 글이므로 감안해서 읽으면 된다.
이전 글에서 naver map 위에 예제 데이터를 올리는 것까지 알아보았다. 이번 글에서는 데이터 레이어의 색을 변경하고, 데이터 레이어에 대한 마우스 이벤트를 설정하는 법에 대해 알아본다.
먼저, 레이어의 색을 변경하는 방법은 map.data.setStyle()을 사용하면 된다. 나는 drawmapStyle()이라는 이름의 함수를 만들어서 그 안에서 색을 변경하는 방법을 사용했다.
레이어를 출력했던 코드 바로 아래 drawmapStyle() 함수를 호출한다. 그리고 그 아래 함수를 다음과 같이 새로 작성하면 된다. styleOption이라는 변수를 만들어 속성값에 따라 면의 색과 투명도, 선의 색, 굵기, 투명도를 조절할 수 있다.
// function.js
naver.maps.Event.once(map, 'init', function () {
...
drawmapStyle();
});
function drawmapStyle() {
let styleOptions = {
fillColor: 0,
fillOpacity: 0,
strokeColor: 0,
strokeWeight: 0,
strokeOpacity: 0
};
map.data.setStyle(function (feature) {
if (feature['property_구분'] === "구") {
styleOptions.fillColor = "LightPink";
styleOptions.fillOpacity = 0;
styleOptions.strokeColor = "DarkSlateGrey";
styleOptions.strokeWeight = 3;
styleOptions.strokeOpacity = 0.8;
}
else if (feature['property_구분'] === "동") {
styleOptions.fillColor = "LightPink";
styleOptions.fillOpacity = 0.1;
styleOptions.strokeColor = "DarkSlateGrey";
styleOptions.strokeWeight = 2;
styleOptions.strokeOpacity = 0.5;
}
return styleOptions;
});
}
속성값은 이전 글에서 만들었던 예제 데이터에서 시군구 레이어와 읍면동 레이어의 구분값을 기준으로 작성했다. map.data.getAllFeature()을 사용해서 조회한 레이어를 살펴보면 레이어가 가지고 있는 속성값들을 확인할 수 있다.
함수를 작성하고 새로고침 하면 다음과 같은 레이어를 확인할 수 있다.
다음으로 마우스 이벤트를 작성하는 방법은 map.data.addListener()를 사용하면 된다. addListener()에서 설정할 수 있는 이벤트들은 click, dblclick, mouseover, mouseout 등이 있다. 모바일을 위한 기능도 있으니 아래 사이트를 참고해서 구현하면 된다.
https://navermaps.github.io/maps.js.ncp/docs/naver.maps.Map.html#toc39__anchor
나는 mouseListener()라는 이름의 함수를 만들어서 마우스 이벤트를 구현했다. 먼저 drawmapStyle() 함수를 호출했던 것과 마찬가지로 mouseListener() 함수도 호출한다. mouseListener() 함수에서 구현한 이벤트는 마우스 클릭에 대한 이벤트로, 레이어가 클릭되면 클릭된 레이어만 색이 변경되도록 했다.
먼저 모든 레이어 정보를 갖는 poly 변수를 사용해서 레이어마다 focus 속성을 확인하고, 클릭된 레이어의 focus 속성값을 true로 설정해준다. 그리고 전에 작성했던 drawmapStyle() 함수에서 focus 속성이 true일 때 레이어의 style을 변경해주면 된다.
// function.js
naver.maps.Event.once(map, 'init', function () {
...
drawmapStyle();
mouseListener();
});
function drawmapStyle() {
let styleOptions = { ... };
map.data.setStyle(function (feature) {
if (feature['property_구분'] === "구") {
...
}
else if (feature['property_구분'] === "동") {
...
}
if (feature.getProperty('focus') === true) {
styleOptions.fillOpacity = 0.5;
styleOptions.fillColor = 'orange';
styleOptions.strokeColor = 'Navy';
styleOptions.strokeWeight = 3;
styleOptions.strokeOpacity = 0.8;
}
return styleOptions;
});
}
function mouseListener() {
map.data.addListener('click', function (e) {
let poly = map.data.getAllFeature();
if (e.feature.getProperty('focus') !== true) {
poly.forEach(function (e) {
if (e['property_focus'] === true) {
e.setProperty('focus', false);
}
});
e.feature.setProperty('focus', true);
}
else {
e.feature.setProperty('focus', false);
}
});
}
함수를 작성하고 새로고침 후 레이어를 클릭해보면 다음과 같은 결과를 확인할 수 있다.
이번에는 마우스 움직임에 대한 이벤트를 추가로 설정해준다. 마우스가 레이어 안에 들어왔을 때는 mouseover, 레이어 밖으로 나갔을 떄는 mouseout 이벤트가 발생하므로 click을 구현했던것과 마찬가지로 mouseListener() 함수에 addListener()를 설정해주면 된다.
먼저 마우스가 레이어 안으로 들어갔을 때 해당 레이어의 이름을 출력할 수 있도록 tooltip 변수를 만들었다. 그리고 레이어의 속성 중 구분을 통해 시군구 레이어와 읍면동 레이어에 각각 이벤트를 주었다. map.dataoverrideStyle()을 통해서도 선택된 레이어 속성을 변경할 수 있다.
마우스가 레이어 안에 들어왔을 때 레이어의 색을 변경하면서 해당 위치에 레이어의 이름을 출력하고, 마우스가 레이어 밖으로 나갔을 때 레이어의 색을 원래대로 변경하면서 해당 위치에 출력된 레이어의 이름을 지운다.
// function.js
naver.maps.Event.once(map, 'init', function () {
...
drawmapStyle();
mouseListener();
});
function drawmapStyle() {
...
}
function mouseListener() {
map.data.addListener('click', function (e) {
...
});
let tooltip = $('<div style="position:absolute;z-index:1000;padding:5px 15px;background-color:#fff;border:solid 2px #000;font-size:15px;pointer-events:none;display:none;"></div>');
tooltip.appendTo(map.getPanes().floatPane);
map.data.addListener('mouseover', function (e) {
if (e.feature['property_구분'] === '구') {
let feature = e.feature,
regionName = feature['property_SGG_NM']
tooltip.css({ display: '', left: e.offset.x, top: e.offset.y }).text(regionName);
map.data.overrideStyle(feature, {
fillColor: 'red',
fillOpacity: 0.3,
strokeColor: 'Navy',
strokeWeight: 2,
strokeOpacity: 0.8
});
}
else if (e.feature['property_구분'] === '동') {
let feature = e.feature,
regionName = feature['property_EMD_NM']
tooltip.css({ display: '', left: e.offset.x, top: e.offset.y }).text(regionName);
map.data.overrideStyle(feature, {
fillColor: 'orange',
fillOpacity: 0.5,
strokeColor: 'Navy',
strokeWeight: 3,
strokeOpacity: 0.8
});
}
});
map.data.addListener('mouseout', function (e) {
tooltip.hide().empty();
map.data.revertStyle();
});
}
tooltip은 jquery를 사용해서 선언되었다. 따라서 jquery 라이브러리를 호출해줘야 하므로, index.html의 head 부분에 jquery 라이브러리를 추가해준다.
<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
...
<script type="text/javascript" src="http://code.jquery.com/jquery-3.5.1.min.js"></script>
<script type="text/javascript"
src="https://openapi.map.naver.com/openapi/v3/maps.js?ncpClientId=라이선스키입력&submodules=geocoder"></script>
</head>
<body>
...
</body>
</html>
실행 결과는 다음과 같다.
그런데 지금까지 과정을 그대로 따라했다면 올라간 레이어가 너무 많아서 렉이 걸리는 것을 알 수 있다. 이 문제를 해결하려면 레이어를 분할해서 이벤트에 따라 각각의 레이어를 불러오도록 하면 된다. 예를 들면 버튼이나 클릭 이벤트를 줘서 유성구에 해당하는 행정동만 불러오는 방법 등을 사용할 수 있겠다. 이건 내가 구청에서 만들었던 시스템인데, 이런식으로 만들 수 있다고 생각하면 될 것 같다.
https://imap.gwangsan.go.kr/imap/home/programs/tongmap/index?menu=226
사실 다음 글을 이 내용으로 작성하려고 했는데 컴퓨터를 포맷해버려서 파일들이 다 날아가버렸다.. (분명 백업해놨는데ㅠㅠ) 다시 환경설정하고 파일을 만들고 글을 작성하기엔 시간이 너무 많이 걸려서 글은 여기까지 쓰는 것으로 마무리한다.
데이터 레이어 분할하는 방법은 작성해둔 글을 참고하면 된다.
https://1545154.tistory.com/46
'공부 > naver map api' 카테고리의 다른 글
[naver map api 예제] 레이어 분할하기 (0) | 2022.03.09 |
---|---|
[naver map api 예제] naver map 위에 레이어 올리기 (0) | 2022.03.07 |
[naver map api 예제] QGIS로 예제 데이터 만들기 (0) | 2022.03.04 |
[naver map api 예제] 소개 (0) | 2022.03.04 |
[naver map api] 정리 (0) | 2022.01.27 |
댓글