[OMT] 지도API사용
2023.12.31(일)
저번달에 개발을 완료했던 지도 API를 복습할겸 다시 포스팅해보려한다.
우선 나는 KAKAO map과 NAVER map 둘다 사용해보았다.
내가 원했던 건 현재 내 위치에서 가까운 영화관을 찾아주고 유저가 선택할 수 있게 만들고 싶었다. 두 API를 사용했을 때 내가 원하는 바를 좀 더 쉽게 이룰 수 있었던 건 KAKAO map이였다.
내가 원한 기능
- 현재 내 위치로 기본 설정 되기 ( Kakao, Naver 둘 다 적용 가능 )
- 전체 영화관 검색 후 띄우기 ( Naver로는 어려움을 겪고 Kakao에서는 비교적 간단하게 해결 )
- 영화관 별 구분해서 띄우기
- 지도가 로드되는 동안 로딩 띄우기
현재 완료되어 배포된 화면
위 화면의 자세한 내용은 빠른예매 개발 포스팅에서 다뤄볼 예정이다. 오늘은 Map Api에 대해서만 설명해보려한다.
참고 페이지
[https://apis.map.kakao.com/web/sample/keywordBasic/] 위 페이지를 참고해서 최대한 활용해보았다.
정말 다양한 방식으로 커스터마이징을 할 수 있는데 우측에 직접해보기를 통해서 내가 원하는 방식으로 코드를 수정해볼 수 있다는 점이 정말 편하고 좋았다.
Code
KakaoMap.tsx
const KakaoMap: React.FC = () => {
const CLIENT_ID = process.env.NEXT_PUBLIC_KAKAO_MAP_KEY;
const KAKAO_SDK_URL = `//dapi.kakao.com/v2/maps/sdk.js?appkey=${CLIENT_ID}&autoload=false&libraries=services`;
const [currentMarker, setCurrentMarker] = useState<any>(null);
const [currentLocation, setCurrentLocation] = useState({ lat: 0, lng: 0 });
const [map, setMap] = useState<any>(null);
const [marker, setMarker] = useState<any>(null);
//영화 티켓 데이터
...
const router = useRouter();
useEffect(() => {
// 현재 위치 가져오기
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
(position) => {
const { latitude, longitude } = position.coords;
setCurrentLocation({ lat: latitude, lng: longitude });
},
(error) => {
console.error('Error getting current location:', error);
}
);
} else {
console.error('Geolocation is not supported by this browser.');
}
}, []);
useEffect(() => {
const script = document.createElement('script');
script.src = KAKAO_SDK_URL;
script.async = true;
document.head.appendChild(script);
script.onload = () => {
kakao.maps.load(() => {
const container = document.getElementById('map');
const options = {
center: new kakao.maps.LatLng(
currentLocation.lat,
currentLocation.lng
),
level: 5
};
AOS.init();
const mapInstance = new kakao.maps.Map(container, options);
setMap(mapInstance);
const ps = new kakao.maps.services.Places();
const redMarkerImage = new kakao.maps.MarkerImage(
'/png/영화관마커.png', // 마커 이미지 제공
new kakao.maps.Size(30, 30), // 마커 이미지 사이즈 커스텀
{ offset: new kakao.maps.Point(15, 30) }
);
// 마커 이미지로 마커를 추가
const addMarkers = (data: any, status: any) => {
if (status === kakao.maps.services.Status.OK) {
data.forEach((place: any) => {
const marker = new kakao.maps.Marker({
position: new kakao.maps.LatLng(place.y, place.x),
map: mapInstance,
title: place.place_name,
image: redMarkerImage
});
// 클릭 이벤트를 통한 현재 마커상태 업데이트
kakao.maps.event.addListener(marker, 'click', function () {
setCurrentMarker(place);
});
});
}
};
ps.keywordSearch('CGV', addMarkers);
ps.keywordSearch('메가박스', addMarkers);
ps.keywordSearch('롯데시네마', addMarkers);
// 현재 위치에 마커 추가하기
const markerInstance = new kakao.maps.Marker({
position: new kakao.maps.LatLng(
currentLocation.lat,
currentLocation.lng
)
});
markerInstance.setMap(mapInstance);
setMarker(markerInstance);
});
};
}, [currentLocation]);
const handleXClick = () => {
setCurrentMarker(null);
};
const handleNextClick = (id: string) => {
localStorage.setItem('장소', id);
setModalOpen(true);
};
const handleCurrentLocation = () => {
if (map && marker) {
map.panTo(
new kakao.maps.LatLng(currentLocation.lat, currentLocation.lng)
);
marker.setPosition(
new kakao.maps.LatLng(currentLocation.lat, currentLocation.lng)
);
}
};
return (
<>
<div className={styled.Map_Container}>
<div
id='map'
style=
className={styled.kakaoMap}
></div>
<div
className={styled.current_location}
onClick={handleCurrentLocation}
>
<img src='/png/현재위치.png' alt='Current Location' />
</div>
{currentMarker && (
<div
className={styled.Theater_Marker}
data-aos='fade-left'
data-aos-duration='1000'
id='Img'
>
<img
src='/png/closed.png'
onClick={handleXClick}
className={styled.close}
/>
<div className={styled.Theater_Content}>
<div className={styled.Theater_Title}>
{currentMarker.place_name}
</div>
.....
위 코드는 공식 페이지에 사용하기 쉽게 코드를 오픈해주어 어렵지 않게 작성할 수 있었다.
내가 애먹었던 부분은
const KAKAO_SDK_URL = `//dapi.kakao.com/v2/maps/sdk.js?appkey=${CLIENT_ID}&autoload=false&libraries=services`;
이 부분인데 libraries=services 이 내용을 추가해주지 않으면 내가 원했던 내 근처 영화관을 검색해서 표시하는 기능 즉
const ps = new kakao.maps.services.Places(); // 계속 오류 발생함
const addMarkers = (data: any, status: any) => {
if (status === kakao.maps.services.Status.OK) {
data.forEach((place: any) => {
const marker = new kakao.maps.Marker({
position: new kakao.maps.LatLng(place.y, place.x),
map: mapInstance,
title: place.place_name,
image: redMarkerImage
});
// 클릭 이벤트를 통한 현재 마커상태 업데이트
kakao.maps.event.addListener(marker, 'click', function () {
setCurrentMarker(place);
});
});
}
};
ps.keywordSearch('CGV', addMarkers);
ps.keywordSearch('메가박스', addMarkers);
ps.keywordSearch('롯데시네마', addMarkers);
이 부분을 사용할 수 없다. ps 부분에서 계속 오류가 발생해서 왜인지 모르고 삽질을 계속 했었는데 libraries=services 를 추가해주지 않아서 생긴 오류였다..
이번에 지도 api를 사용해보면서 다시 한번 놀랐다.. 이게 대기업인가 .. 앞으로도 많은 api를 사용하게 될테지만 개발에 편리한 api가 계속해서 발전해 나가는 게 너무 좋다.. 내가 만들 수 있는 범위가 넓어지니까.. ㅎㅎㅎ