Next.js + TS | Kakao 지도 API 프로젝트에 사용하기 #4. 키워드로 장소 검색하기에서 장소 결과를 불러온 다음,
나는 프로젝트에 필요한 산책 가능한 장소
를 필터링해보기로 했다.
사실 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"
}
모두 여행
> 관광,명소
> 하천
으로 카테고리가 분류되어 있는 것을 볼 수 있었다.
'카테고리로 장소 검색'기능에 명시되어 있는 카테고리 외로도 장소 데이터마다 카테고리가 잘 분류되어 있는 점을 활용하기로 했다.
먼저 여러 장소를 검색해보며 산책 가능한 장소
마다의 하위 카테고리를 모아 보았고,
상수로 정의한 배열을 만들었다.
export const FILTER_CATEGORIES = [
'도보여행',
'둘레길',
'하천',
'공원',
'도시근린공원',
'국립공원',
'도립공원',
'산',
'오름',
'호수',
'저수지',
'수목원,식물원',
];
그 다음 필터링을 위한 함수를 만들었다.
일반 필터링
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));
});
};
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('검색 결과 중 오류가 발생했습니다.');
}
}
};
이전 포스팅과 마찬가지로 서호공원
이라는 장소가 위치한 곳에서, 지도에 보이는 영역만을 기준으로 공원
을 검색했을 때의 결과는 다음과 같다.
KaKao 지도 API 장소 검색 기능을 활용해서 토이 프로젝트를 해보려는 분들에게 조금이라도 활용하는 데 도움이 되었으면 해서 다른 카테고리도 찾아 보았다.
교통,수송 > 휴게소
/ 교통,수송 > 휴게소 > 고속도로 휴게소
교육,학문 > 학교 > 대학교
교통,수송 > 교통시설 > 고속,시외버스터미널