본문 바로가기

그 땐 IT활동했지/그 땐 영일영 근무했지

[010/API] Kakao Map API | 통신사 카테고리 넣기

728x90

1.  문제상황


2022.04.13 - [그 땐 IT활동했지/그 땐 영일영 근무했지] - [010/API] Kakao Map API | 마커 커스텀하기

통신사별로 마커를 출력하기는 했는데(↑위 링크 참조!) 어떤 마커가 무슨 통신사를 의미하는지 파악하기 힘들다. 그래서 각 마커가 무엇을 지칭하는지 카테고리를 달기로 했다!

(공식문서 참고하기! https://apis.map.kakao.com/web/sample/categoryMarker/)

 

2.  각 마커별로 범례를 달아보자


1단계 HTML&CSS


<div class="map_wrap">
	<!-- 지도 표시 -->
	<div id="map"></div>
	<!-- 지도 카테고리 -->
	<ul id="category">
		<li id="SK" data-order="0"> 
			<span class="category_bg SKT-c"></span>
			SKT
		</li>       
		<li id="KT" data-order="1"> 
			<span class="category_bg KT-c"></span>
			KT
		</li>  
		<li id="LG" data-order="2"> 
			<span class="category_bg LG-c"></span>
			LGU+
		</li>  
	</ul>
</div>

👉🏻먼저 HTML에는 카테고리를 표시하는 코드를 적어보자! ul과 li tag를 이용해서 만든다.

.map_wrap {
    position: relative;
    width: 100%;
    height: 50vh;
}
#category {
    position: absolute;
    bottom: 10px;
    right: 10px;
    border-radius: 5px;
    border: 1px solid #909090;
    box-shadow: 0 1px 1px rgba(0, 0, 0, 0.4);
    background: #fff;
    overflow: hidden;
    z-index: 2;
}
#category li {
    float: left;
    list-style: none;
    width: 50px;
    border-right: 1px solid #acacac;
    padding: 6px 0;
    text-align: center;
    cursor: pointer;
}
#category li.on {
    background: rgb(221, 219, 219);
}
#category li:hover {
    background: #ffe6e6;
    border-left: 1px solid #acacac;
    margin-left: -1px;
}
#category li:last-child{
    margin-right: 0;
    border-right: 0;
}
#category li span {
    display: block;
    margin: 0 auto 3px;
    width: 27px;
    height: 28px;
}

#category li .SKT-c {
    background-image:url("../static/mapmarker/SKTmarker.png");
    background-size: 27px 28px;
}
#category li .KT-c {
    background-image:url("../static/mapmarker/KTmarker.png");
    background-size: 27px 28px;
}
#category li .LG-c {
    background-image:url("../static/mapmarker/LGmarker.png");
    background-size: 27px 28px;
}

 

👉🏻CSS는 다음과 같다. 사실 HTML, CSS 코드는 모두 공식문서에서 긁어와서 고쳐주면 되기 때문에 어렵지 않다!ㅎㅎ

👉🏻여기서 주목할 점은 li.on 부분이다. li tag에 on 클래스가 있으면 background색이 변한다. 그리고 나는 각 범례에 각 통신사에 맞는 마커 이미지를 넣어주었다.

짠! 오른쪽 하단에 생겼지롱

 

 

2단계 범례에 클릭 이벤트 넣기


이제 범례를 클릭하면 클릭한 범례는 다른 CSS를 적용할 것이다.
그리고 선택한 통신사 대리점들만 지도에 표시할 것이다!

1️⃣클릭한 범례 CSS 변경하기

// 각 카테고리에 클릭 이벤트를 등록합니다
addCategoryClickEvent();

// 각 카테고리에 클릭 이벤트를 등록합니다
function addCategoryClickEvent() {
    var category = document.getElementById('category'),
        children = category.children;

    for (var i=0; i<children.length; i++) {
        children[i].onclick = onClickCategory;
    }
}

// 카테고리를 클릭했을 때 호출되는 함수입니다
function onClickCategory() {
    var id = this.id,
        className = this.className;
    if (className === 'on') { 
        currCategory = '';
        changeCategoryClass(); 
    } else { 
        currCategory = id;
        changeCategoryClass(this);
    }
}

// 클릭된 카테고리에만 클릭된 스타일을 적용하는 함수입니다
function changeCategoryClass(el) {
    var category = document.getElementById('category'),
        children = category.children,
        i;

    for ( i = 0; i < children.length; i++ ) {
        children[i].className = '';
    }

    if (el) {
        el.className = 'on';
    }
}

👉🏻먼저 코드는 다음과 같다. 하나씩 살펴보자!

function addCategoryClickEvent() {
    var category = document.getElementById('category'),
        children = category.children;

    for (var i=0; i<children.length; i++) {
        children[i].onclick = onClickCategory;
    }
}
  • category라는 아이디를 사용해서 범례들을 불러온다.
  • 그리고 각 범례에 onClickCategory라는 이벤트를 부여한다.
function onClickCategory() {
    var id = this.id,
        className = this.className;
    if (className === 'on') { 
        currCategory = '';
    } else {
        currCategory = id;
        changeCategoryClass(this);
    }
}
  • 클릭된 카테고리(li tag)의 아이디와 클래스를 각각 id, className에 저장한다.
  • className이 on인지 확인을 한다. (위의 CSS파일을 보면 li tag가 on 클래스를 가지고 있을 때 다른 style을 적용한다.)
    • on이 있다면 이미 선택된 카테고리를 다시 눌렀기 때문에 currCategory를 비워준다.
    • 그렇지 않다면 새로운 카테고리를 선택한 것이기 때문에 currCategory를 id로 바꿔준다. id에는 각 통신사의 tag가 들어있다. 그리고 changeCategoryClass 함수를 실행한다.
function changeCategoryClass(el) {
    var category = document.getElementById('category'),
        children = category.children,
        i;

    for ( i = 0; i < children.length; i++ ) {
        children[i].className = '';
    }

    if (el) {
        el.className = 'on';
    }
}
  • category라는 아이디를 사용해서 범례들을 불러온다.
  • 범례들을 for문을 돌리면서 클래스를 비워준다.
  • 그리고 받은 인자(클릭된 카테고리)에만 on이라는 클래스를 넣어준다.

👉🏻클릭된 범례에만 클래스 on을 넣어주면서 background 색이 변하게 된다!

클릭한 범례의 색만 변했다!

 

2️⃣클릭한 통신사에 해당하는 대리점들만 지도에 찍기

...중략...

// 카테고리를 클릭했을 때 호출되는 함수입니다
function onClickCategory() {
    var id = this.id,
        className = this.className;
    if (className === 'on') { 
        currCategory = '';
        changeCategoryClass(); 
        getStoreInMap();
    } else { 
        currCategory = id;
        changeCategoryClass(this);
        searchPlaces();
    }
}

...중략...

// 카테고리 검색을 요청하는 함수입니다.
function searchPlaces() {
    if (!currCategory) {
        return false;
    }
    let categoryStore = []
    for (var i=0; i<storeInMap.length; i++ ){
        if(currCategory === storeInMap[i].tag) {
            categoryStore.push(storeInMap[i])
        } 
    }
    addCategoryMarker(categoryStore, currCategory);
}

function addCategoryMarker(List, category) {
    removeMarker();

    if (category === "SK") {
        var img = imageSrcSKT; 
    }
    else if (category === "KT") {
        var img = imageSrcKT; 
    }
    else if (category === "LG") {
        var img = imageSrcLG; 
    }
    
    if (Object.keys(List).length > 0) {
        for (var i = 0; i < Object.keys(List).length; i ++) {
            var imageSize = new kakao.maps.Size(48, 53); 
            let marker = new kakao.maps.Marker({
                map: map, 
                position: new kakao.maps.LatLng(List[i].lat, List[i].lon), 
                title : List[i].name, 
                image : new kakao.maps.MarkerImage(img, imageSize), 
            });

            markers.push(marker);
        }
    }
}

👉🏻이제 선택한 통신사에 해당하는 대리점들만 지도에 불러오는 함수를 만들어보자!

function onClickCategory() {
    var id = this.id,
        className = this.className;
    if (className === 'on') { 
        currCategory = '';
        changeCategoryClass(); 
        getStoreInMap();
    } else { 
        currCategory = id;
        changeCategoryClass(this);
        searchPlaces();
    }
}

👉🏻먼저 onClickCategory함수에 두 줄이 추가되었다. getStoreInMap함수를 호출하는 코드와 searchPlaces함수를 호출하는 코드가 추가되었다.

  • className이 on일 때 즉, 이미 선택된 카테고리일 때는 다시 모든 대리점들을 불러오기 위해 getStoreInMap함수를 호출한다.
  • 새로운 카테고리를 선택하면 searchPlaces함수를 호출하는데 이는 아래에서 살펴보자!
function searchPlaces() {
    if (!currCategory) {
        return false;
    }
    let categoryStore = []
    for (var i=0; i<storeInMap.length; i++ ){
        if(currCategory === storeInMap[i].tag) {
            categoryStore.push(storeInMap[i])
        } 
    }
    addCategoryMarker(categoryStore, currCategory);
}
  • 먼저 storeInMap을 for문에 돌리면서 위에서 저장한 currCategory랑 대리점들의 tag와 비교한다. 
  • 같다면 선택한 통신사에 해당하는 대리점이므로 categoryStore 리스트에 넣는다.
  • 그리고 이 리스트를 currCategory와 함께 addCategoryMarker함수의 인자로 넣는다.

👉🏻storeInMap리스트는 현재 지도에 찍힌 대리점들을 모은 객체이다. 해당 내용은 아래 글에서 살펴보자!

2022.04.11 - [그 땐 IT활동했지/그 땐 영일영 근무했지] - [010/API] Kakao Map API | 가게 위치 ajax로 불러오기

function addCategoryMarker(List, category) {
    removeMarker();

    if (category === "SK") {
        var img = imageSrcSKT; 
    }
    else if (category === "KT") {
        var img = imageSrcKT; 
    }
    else if (category === "LG") {
        var img = imageSrcLG; 
    }
    
    if (Object.keys(List).length > 0) {
        for (var i = 0; i < Object.keys(List).length; i ++) {
            var imageSize = new kakao.maps.Size(48, 53); 
            let marker = new kakao.maps.Marker({
                map: map, 
                position: new kakao.maps.LatLng(List[i].lat, List[i].lon), 
                title : List[i].name, 
                image : new kakao.maps.MarkerImage(img, imageSize), 
            });

            markers.push(marker);
        }
    }
}

👉🏻addCategoryMarker에서는 각 카테고리에 해당하는 마커만 찍어준다. 마커 이미지만 받아온 category라는 인자로 잘 설정해주면 된다! 마커 찍는 코드는 아래 글을 참고하자!

2022.04.10 - [그 땐 IT활동했지/그 땐 영일영 근무했지] - [010/API] Kakao Map API | 위치 표시하기

선택한 카테고리에 맞는 대리점들만 잘 나타나고 있다!ㅎㅎ

728x90