ABOUT ME

-

  • [ Next ] KaKao 지도 API 사용하기
    Front/Next 2025. 9. 28. 16:22
    반응형

    검색한 장소를 카카오 지도에 표시하기 위해서 카카오지도 api를 활용했다.

     

    카카오 개발자 센터에서 api를 발급받고 난후 카카오 지도는 Javascript Key를 사용한다.


    Initialized

    kakao sdk를 사용하기위해 해당 라이브러리를 설치해준다.

    react-kakao-maps-sdk는 kakao map을 react에서 편하게 쓸 수 있게 되어있는 라이브러리이어서

    좀 더 편하게 사용할 수 있다.

     

    예전에는 ref로 직접 참조해서 사용했었는데 해당 라이브러리를 사용하면 단순히 컴포넌트만 불러와서 사용할 수 있어서 편하다.

    npm install react-kakao-maps-sdk

     

    이후 .env.local파일에 환경변수를 등록해준다.

    앞에 NEXT_PUBLIC을 안붙히면 route에서만 해당 환경변수를 불러올 수 있기때문에

    javascriptKey는 클라이언트쪽에서 써야하므로 NEXT_PUBLIC을 앞에 붙혀서 환경변수를 만들어준다.

    NEXT_PUBLIC_KAKAO_JAVASCRIPT_KEY=

     

    이후 카카오 개발자 센터에서 web에서 사용할 곳의 도메인을 추가해준다.

    도메인을 추가하지 않으면 sdk로드가 안되니 꼭 추가해야한다.

     

    현재는 vercel을 활용하여 해당 프로젝트를 배포해둔 상태여서 vercel의 도메인주소도 추가해두었다.

     


    Useage

    카카오 맵 컴포넌트를 새로 만들어 활용했다.

    우선 kakao 지도를 사용하기 위해서 카카오 sdk를 불러와준다.

    이때 환경변수에 등록된 키를 불러와서 script를 로드 해준다.

     

    Map 컴포넌트를 사용하면 카카오 맵을 불러올 수 있다.

    map-size 클래스를 만들어서 반응형으로 크기에 따라서 카카오 맵의 크기가 변경되도록 했다.

    import Script from 'next/script';
    import { Map } from 'react-kakao-maps-sdk';
    
    const [center, setCenter] = useState<{ lat: number, lng: number }>({ lat: 37.555946, lng: 126.972317 });
    const KAKAO_SDK_URL = `//dapi.kakao.com/v2/maps/sdk.js?appkey=${process.env.NEXT_PUBLIC_KAKAO_JAVASCRIPT_KEY}&autoload=false`;
    
        return (
            <>
                <Script src={KAKAO_SDK_URL} strategy='beforeInteractive'/>
                <Map
                        center={center} // 지도의 중심
                        className="map-size"
                        level={5} // 확대 레벨
                    ></Map>
            </>
    )

    이러면 지도는 나오게 되고, 이제 장소에 마커를 찍어야한다.

     

    장소는 kakao 장소 검색 api를 사용해서 해당 장소들을 불러와서 props로 전달했다.

    이후 center좌표는 해당 장소의 첫번째를 기준으로 했다. 

     

    처음에는 모든 좌표들의 평균값을해서 할려했는데 거리가 너무 엄청 멀어지면 center좌표가 엉뚱하게 나와서 그냥 첫번째 장소의 좌표를 기준으로 처리

    export default function KaKaoMap(props: KaKaoMapProps) {
        const [placeInfo, setPlaceInfo] = useState<PlaceInfo[]>(props.initialPlaces);
        const [center, setCenter] = useState<{ lat: number, lng: number }>({ lat: 37.555946, lng: 126.972317 });
    
        useEffect(() => {
            if(props.initialPlaces?.length > 0 ) {
                setCenter(calculateCenterByAverage(props.initialPlaces))
                setPlaceInfo(props.initialPlaces);
            } else {
                setPlaceInfo([]);
            }
        }, [props.initialPlaces]);
        
            const calculateCenterByAverage = (places: PlaceInfo[]) => {
            if(places.length === 0) return { lat: 37.555946, lng: 126.972317 }
    
            return {
                lat: parseFloat(places[0].y),
                lng: parseFloat(places[0].x),
            }
        }

     

    그럼 props로 전달받은 장소들을 map으로 해서 MapMarker를 찍는다.

    이떄 MapMarker만 사용하면 장소 마커만 표시해주고 정보 설명은 없어서 설정을 달기 위해서 CustomOverlayMap으로 장소명과 카카오맵 링크를 달았다.

     

    CustomOverlayMap의 위치는 marker와 똑같이 잡고, anchor로 마커위에 표시

    그리고 안에는 직접 원하는대로 꾸미면 된다.

    placeInfo.length > 0 && <Map
                        center={center} // 지도의 중심
                        className="map-size"
                        level={5} // 확대 레벨
                    >
                        {
                            placeInfo.map((item, index) => (
                                <React.Fragment key={`marker-${index}`}>
                                    <MapMarker
                                        position={{lat: parseFloat(item.y), lng: parseFloat(item.x)}}
                                    />
    
                                    <CustomOverlayMap
                                        position={{ lat: parseFloat(item.y), lng: parseFloat(item.x) }}
                                        xAnchor={0.5}
                                        yAnchor={2.4}
                                    >
                                        <div className="flex gap-[5px] items-center justify-center px-2 py-1 bg-white border rounded-lg shadow text-sm text-gray-950">
                                            <div>{item.place_name}</div>
                                            <Button
                                                className="!text-gray-950"
                                                size="small"
                                                icon={<LinkOutlined />}
                                                onClick={() => handleClickKaKaoMap(item)}
                                            />
                                        </div>
                                    </CustomOverlayMap>
                                </React.Fragment>
                            ))
                        }
                    </Map>

     

    그러면 이제 검색을 해보면 해당 장소의 마커가 정상적으로 표시된다.

    728x90
    반응형