Next.js + TS | Kakao 지도 API 프로젝트에 사용하기 #4.5 장소 검색 결과를 원하는 카테고리로 필터링하기

dayannne·2024년 8월 30일
0
post-thumbnail

장소 검색 결과를 원하는 카테고리로 필터링하기

Next.js + TS | Kakao 지도 API 프로젝트에 사용하기 #4. 키워드로 장소 검색하기에서 장소 결과를 불러온 다음,
나는 프로젝트에 필요한 산책 가능한 장소를 필터링해보기로 했다.

사실 Kakao 지도 API 에서는 '키워드로 장소 검색' 기능과 더불어 '카테고리로 장소 검색'기능을 제공하고 있으나...

KaKao 지도 API - 카테고리별 장소 검색하기

불러올 수 있는 카테고리종류가 다양하지만 내가 원하는 카테고리는 없는 상황이었다...

그래서 다른 방법을 모색하다 적용한 방법이 있다.
'키워드로 장소 검색' 기능을 활용하되 필터링할 수 있는💡


{
    "address_name": "서울 성동구 성수동1가 678-1",
    "category_group_code": "",
    "category_group_name": "",
    "category_name": "여행 > 공원 > 도시근린공원",
    "distance": "28619",
    "id": "11331488",
    "phone": "02-460-2905",
    "place_name": "서울숲",
    "place_url": "http://place.map.kakao.com/11331488",
    "road_address_name": "",
    "x": "127.037617759165",
    "y": "37.5443222301513"
}

서울숲을 검색 후 받아온 결과이다.
category_name을 주목해 보았다.

다른 산책 가능한 장소도 검색해 보았다. 중랑천(하천), 일월수목원(수목원)...

{
    "address_name": "서울 중랑구 면목동 1338-12",
    "category_group_code": "",
    "category_group_name": "",
    "category_name": "여행 > 관광,명소 > 하천",
    "distance": "34196",
    "id": "8089008",
    "phone": "",
    "place_name": "중랑천",
    "place_url": "http://place.map.kakao.com/8089008",
    "road_address_name": "",
    "x": "127.070847357397",
    "y": "37.5897928353235"
}
{
    "address_name": "경기 수원시 장안구 천천동 430",
    "category_group_code": "AT4",
    "category_group_name": "관광명소",
    "category_name": "여행 > 관광,명소 > 수목원,식물원",
    "distance": "189",
    "id": "380088639",
    "phone": "031-369-2380",
    "place_name": "일월수목원",
    "place_url": "http://place.map.kakao.com/380088639",
    "road_address_name": "경기 수원시 장안구 일월로 61",
    "x": "126.97665617545374",
    "y": "37.28835545840041"
}

모두 여행 > 관광,명소 > 하천으로 카테고리가 분류되어 있는 것을 볼 수 있었다.
'카테고리로 장소 검색'기능에 명시되어 있는 카테고리 외로도 장소 데이터마다 카테고리가 잘 분류되어 있는 점을 활용하기로 했다.


1. 카테고리 정의하기

먼저 여러 장소를 검색해보며 산책 가능한 장소마다의 하위 카테고리를 모아 보았고,
상수로 정의한 배열을 만들었다.

export const FILTER_CATEGORIES = [
  '도보여행',
  '둘레길',
  '하천',
  '공원',
  '도시근린공원',
  '국립공원',
  '도립공원',
  '산',
  '오름',
  '호수',
  '저수지',
  '수목원,식물원',
];

2. 필터링 로직 만들기

그 다음 필터링을 위한 함수를 만들었다.

  • 일반 필터링

    export const filterPlacesByKeyword = (places: any[]) => {
      return places.filter((place) => {
        const categories = place.category_name.split(` > `);
    
        return FILTER_CATEGORIES.some((keyword) => categories.includes(keyword));
      });
    };
  • 강한 필터링
    여행 관광,명소를 포함한 카테고리까지 검색 결과를 정확하게 불러오고 싶다면 강한 필터링을 걸어 놓으면 될 것 같다.
    (나의 경우 필터링하고자 하는 산책 가능한 장소 데이터 중 여행 관광,명소가 포함되지 않는 일부 장소도 있어 제외하였다)

    export const filterPlacesByKeyword = (places: any[]) => {
      return places.filter((place) => {
        const categories = place.category_name.split(` > `);
    
        const isValidPath =
          categories[0] === '여행' && categories[1] === '관광,명소';
        if (!isValidPath) return false;
    
        return FILTER_CATEGORIES.some((keyword) => categories.includes(keyword));
      });
    };

3. 필터링 적용하기

Next.js + TS | Kakao 지도 API 프로젝트에 사용하기 #4. 키워드로 장소 검색하기에서 keywordSearch메서드를 사용할 때 인자로 콜백 함수를 받고 그 곳에서 검색 결과를 처리한다는 부분에 대해 설명한 적이 있다.

검색 결과에서 받아온 데이터를 필터링 함수를 통해 필터링해주면 된다.

  • 필터링 적용 전

    // keywordSearch 콜백 함수
      const searchPlacesCB = async (
        data: any,
        status: kakao.maps.services.Status,
        pagination: any,
      ) => {
        if (status === kakao.maps.services.Status.OK) {
          console.log(data);
        } else {
          if (status === kakao.maps.services.Status.ZERO_RESULT) {
            return alert('검색 결과가 존재하지 않습니다.');
          } else if (status === kakao.maps.services.Status.ERROR) {
            return alert('검색 결과 중 오류가 발생했습니다.');
          }
        }
      };
    
      return { searchPlaces };
    };
  • 필터링 적용 후

      // keywordSearch 콜백 함수
      const searchPlacesCB = async (
        data: any,
        status: kakao.maps.services.Status,
        pagination: any,
      ) => {
        if (status === kakao.maps.services.Status.OK) {
          clearMarkersAndInfo();
    
          const filteredPlaces = filterPlacesByKeyword(data);
          if (filteredPlaces.length === 0) {
            return alert('검색 결과가 존재하지 않습니다.');
          }
          console.log(filteredPlaces)
    
          searchPlace(filteredPlaces);
          displayMarkers(filteredPlaces);
        } else {
          if (status === kakao.maps.services.Status.ZERO_RESULT) {
            return alert('검색 결과가 존재하지 않습니다.');
          } else if (status === kakao.maps.services.Status.ERROR) {
            return alert('검색 결과 중 오류가 발생했습니다.');
          }
        }
      };

4. 검색 결과


이전 포스팅과 마찬가지로 서호공원이라는 장소가 위치한 곳에서, 지도에 보이는 영역만을 기준으로 공원을 검색했을 때의 결과는 다음과 같다.

  • 필터링 적용 전
  • 필터링 적용 후

🤔 필터링할 수 있는 다른 카테고리에는 어떤 것이 있을까?

KaKao 지도 API 장소 검색 기능을 활용해서 토이 프로젝트를 해보려는 분들에게 조금이라도 활용하는 데 도움이 되었으면 해서 다른 카테고리도 찾아 보았다.

  • 휴게소 교통,수송 > 휴게소 / 교통,수송 > 휴게소 > 고속도로 휴게소
  • 초,중,고,대학교 - 교육,학문 > 학교 > 대학교
  • 고속,시외버스터미널
    교통,수송 > 교통시설 > 고속,시외버스터미널

    어쩌면 임시방편의 방법 같기도 하지만, 나의 경우 기획한 프로젝트 아이디어를 꼭 만들어보고 싶어서 모색한 방법이라 유레카였다ㅎ
    이 글을 보고 아이디어를 구현할 방법을 찾은 한 분이라도 있다면 좋을 것 같다😊
profile
☁️

0개의 댓글