본문 바로가기

NextJS

[NextJS] 카카오맵 API로 지도 구현하기 (2)

728x90
반응형
관련 포스팅

 

2024.07.06 - [NextJS] - [NextJS] 카카오맵 API로 지도 구현하기 (1)

 

[NextJS] 카카오맵 API로 지도 구현하기 (1)

혼자 프로젝트를 진행하면서 지도 API를 사용해하는 상황이 생겼다. 전부터 지도 API를 사용해보고 싶었기에 이번 기회에 카카오맵을 사용하여 지도 기능을 구현해보고자 한다. 우선 카카오맵 AP

rlawo32.tistory.com

 

 

이전 포스팅에 이어서 이번엔 카카오맵 API에서 여러 지도 기능들을 추가하여 구현해 보겠다.

 

 

 

 

 

1. 마커 구현하기

우선 SDK 설치를 했을 때 구현 방법을 보겠다.

MapMarker를 아래와 같이 추가해 주고 동일한 좌표를 넣어주면 된다.

// nextJsKakaoMap.tsx

'use client';

import { useEffect, useState } from "react";
import { Map, MapMarker } from "react-kakao-maps-sdk";


const ReactKakaoMap = () => {
    const apiKey:string|undefined = process.env.NEXT_PUBLIC_KAKAO_KEY;
    const [scriptLoad, setScriptLoad] = useState<boolean>(false);

    useEffect(() => {
        const script:HTMLScriptElement = document.createElement("script");
        script.async = true;
        script.src = `//dapi.kakao.com/v2/maps/sdk.js?appkey=${apiKey}&autoload=false`;
        document.head.appendChild(script);

        script.addEventListener("load", () => {
            setScriptLoad(true);
        })
    }, [])

    return (
        <div>
            {scriptLoad ? 
                <Map 
                center={{ lat: 33.450701, lng: 126.570667 }}   
                style={{ width: '800px', height: '600px' }} 
                level={3}>
                    // MapMarker 추가!
                    <MapMarker position={{ lat: 33.450701, lng: 126.570667 }}></MapMarker>
                </Map>
                :
                <div></div>
            }
        </div>
    )
}

export default ReactKakaoMap;

 

 

 

 

 

아래와 같이 마커 표시가 된다.

 

 

 

마커 위에 추가 설명을 위한 표시를 하고 싶다면 CustomOverlayMap을 추가해 주면 된다.

// nextJsKakaoMap.tsx

'use client';

import { useEffect, useState } from "react";
import { CustomOverlayMap, Map, MapMarker } from "react-kakao-maps-sdk";


const ReactKakaoMap = () => {
    const apiKey:string|undefined = process.env.NEXT_PUBLIC_KAKAO_KEY;
    const [scriptLoad, setScriptLoad] = useState<boolean>(false);

    useEffect(() => {
        const script:HTMLScriptElement = document.createElement("script");
        script.async = true;
        script.src = `//dapi.kakao.com/v2/maps/sdk.js?appkey=${apiKey}&autoload=false`;
        document.head.appendChild(script);

        script.addEventListener("load", () => {
            setScriptLoad(true);
        })
    }, [])

    return (
        <div>
            {scriptLoad ? 
                <Map 
                center={{ lat: 33.450701, lng: 126.570667 }}   
                style={{ width: '800px', height: '600px' }} 
                level={3}>
                    // CustomOverlayMap 추가!
                    <CustomOverlayMap position={{ lat: 33.450701, lng: 126.570667 }}>
                        <div style={{position:'absolute', top:-60, left:-7, width:'100px', padding:'4px 0', textAlign:'center', color:'black', background:'white', borderRadius:'10px'}}>
                        카카오 본사
                        </div>
                    </CustomOverlayMap>
                    <MapMarker position={{ lat: 33.450701, lng: 126.570667 }}></MapMarker>
                </Map>
                :
                <div></div>
            }
        </div>
    )
}

export default ReactKakaoMap;

 

 

 

 

위 코드를 구현하면 아래와 같이 추가 텍스트 박스가 표시되는 것을 확인할 수 있을 것이다.

CSS는 자신이 원하는 대로 구성하여 표현해 주면 된다.

 

 

 

 

 

다음으로 SDK 설치 없이 구현하는 방법이다.

이전에 카카오맵 API를 구현했던 코드에서 window.kakao.maps.Marker를 추가해 주면 된다.
그리고 위 방법과 다른 방식으로 InfoWindow를 사용하여 텍스트 박스를 생성해 주었다.

// nextJsKakaoMap.tsx

'use client';

import { useEffect, useState } from "react";

declare global {
    interface Window {
        kakao: any;
    }
}

const ReactKakaoMap = () => {
    const apiKey:string|undefined = process.env.NEXT_PUBLIC_KAKAO_KEY;

    useEffect(() => {
        const script:HTMLScriptElement = document.createElement("script");
        script.async = true;
        script.src = `//dapi.kakao.com/v2/maps/sdk.js?appkey=${apiKey}&autoload=false`;
        document.head.appendChild(script);

        script.addEventListener("load", () => {window.kakao.maps.load(() => {
                // 결과값 위치 좌표
                let coords = new window.kakao.maps.LatLng(33.450701, 126.570667);

                // 지도를 담을 영역의 DOM 레퍼런스
                let container = document.getElementById('map');
                
                // 지도의 중심을 결과값으로 받은 위치로 이동시킵니다
                let options = { 	// 지도를 생성할 때 필요한 기본 옵션
                    center: coords, 	// 지도의 중심좌표
                    level: 3 		// 지도의 레벨(확대, 축소 정도)
                };
                // 지도 생성 및 객체 리턴
                let map = new window.kakao.maps.Map(container, options); 
                
                // 결과값으로 받은 위치를 마커로 표시합니다
                let marker = new window.kakao.maps.Marker({
                    map: map,
                    position: coords
                });

                // 인포윈도우로 장소에 대한 설명을 표시합니다
                let infowindow = new window.kakao.maps.InfoWindow({
                    content: '<div style="width:150px;text-align:center;padding:6px 0;color:black;">'+ "카카오 본사" +'</div>'
                });
                infowindow.open(map, marker);
            })
        })
    }, [])

    return (
        <div id="map" style={{height: "500px", width: "100%"}} />
    )
}

export default ReactKakaoMap;

 

 

 

 

아래와 같이 잘 구현된 것을 확인할 수 있을 것이다.

 

728x90

 

 

 

 

 

 

 

 

 

2. 주소 좌표로 이동하기

실제로 있는 주소를 검색하여 해당 주소 좌표를 반환하여 지도에 표시하는 것과 해당 좌표의 주소 정보를 출력 방법에 대해 구현하고 작성해 보겠다.

주소와 관련된 기능을 구현할 땐 SDK를 설치했더라도 Kakao 객체를 Window 객체의 interface로 추가해 주고 진행해야 한다. 그리고 script 부분에도 추가로 입력해주어야 하는 것도 있다.

 

우선 script에 아래와 같이 libraries를 추가로 넣어주자

// script 주입

script.async = true;
// libraries=services 추가!
script.src = `//dapi.kakao.com/v2/maps/sdk.js?appkey=${apiKey}&libraries=services&autoload=false`;
document.head.appendChild(script);

 

 

 

그리고 기존 코드에서 주소-좌표 변환 객체인 Geocoder를 작성해 주고 addressSearch를 사용하여 찾을 주소의 좌표를 검색해 준다. 좌표 검색이 완료되면 해당 좌표를 결과 값 위치 좌표에 넣어주고 지도 객체를 생성해 주면 된다.

// nextJsKakaoMap.tsx

'use client';

import { useEffect, useState } from "react";

declare global {
    interface Window {
        kakao: any;
    }
}

const ReactKakaoMap = () => {
    const apiKey:string|undefined = process.env.NEXT_PUBLIC_KAKAO_KEY;

    useEffect(() => {
        const script:HTMLScriptElement = document.createElement("script");
        script.async = true;
        script.src = `//dapi.kakao.com/v2/maps/sdk.js?appkey=${apiKey}&libraries=services&autoload=false`;
        document.head.appendChild(script);

        script.addEventListener("load", () => {window.kakao.maps.load(() => {
                const geocoder = new window.kakao.maps.services.Geocoder();

                // 주소로 좌표를 검색합니다
                geocoder.addressSearch('제주특별자치도 제주시 첨단로 242', function(result:any, status:any) {
                    
                    // 정상적으로 검색이 완료됐으면
                    if (status === window.kakao.maps.services.Status.OK) {
                        // 결과값 위치 좌표
                        let coords = new window.kakao.maps.LatLng(result[0].y, result[0].x);

                        // 지도를 담을 영역의 DOM 레퍼런스
                        let container = document.getElementById('map');
                        // 지도의 중심을 결과값으로 받은 위치로 이동시킵니다
                        let options = { 	// 지도를 생성할 때 필요한 기본 옵션
                            center: coords, 	// 지도의 중심좌표
                            level: 3 		// 지도의 레벨(확대, 축소 정도)
                        };
                        // 지도 생성 및 객체 리턴
                        let map = new window.kakao.maps.Map(container, options); 

                        // 결과값으로 받은 위치를 마커로 표시합니다
                        let marker = new window.kakao.maps.Marker({
                            map: map,
                            position: coords
                        });

                        // 인포윈도우로 장소에 대한 설명을 표시합니다
                        let infowindow = new window.kakao.maps.InfoWindow({
                            content: '<div style="width:150px;text-align:center;padding:6px 0;color:black;">'+ '카카오 본사' +'</div>'
                        });
                        infowindow.open(map, marker);
                    }
                });
            })
        })
    }, [])

    return (
        <div id="map" style={{height: "500px", width: "100%"}} />
    )
}

export default ReactKakaoMap;

 

 

 

검색할 주소를 넣어주고 좌표를 검색하여 아래처럼 해당 좌표로 잘 이동이 된 것을 확인할 수 있다.

 

 

 

SDK를 설치했을 경우엔 먼저 해당 주소의 좌표 검색을 해주고 좌표를 전달해 주는 식으로 구현해 주면 된다.

// nextJsKakaoMap.tsx

'use client';

import { useEffect, useState } from "react";
import { CustomOverlayMap, Map, MapMarker } from "react-kakao-maps-sdk";

declare global {
    interface Window {
        kakao: any;
    }
}

const ReactKakaoMap = () => {
    const apiKey:string|undefined = process.env.NEXT_PUBLIC_KAKAO_KEY;
    const [scriptLoad, setScriptLoad] = useState<boolean>(false);
    const [lat, setLat] = useState<number>(0);
    const [lng, setLng] = useState<number>(0);

    useEffect(() => {
        const script:HTMLScriptElement = document.createElement("script");
        script.async = true;
        script.src = `//dapi.kakao.com/v2/maps/sdk.js?appkey=${apiKey}&libraries=services&autoload=false`;
        document.head.appendChild(script);

        script.addEventListener("load", () => {
            window.kakao.maps.load(() => {
                const geocoder = new window.kakao.maps.services.Geocoder();

                geocoder.addressSearch('제주특별자치도 제주시 첨단로 242', function(result:any, status:any) {
                    if (status === window.kakao.maps.services.Status.OK) {
                        setLat(result[0].y);
                        setLng(result[0].x);
                        setScriptLoad(true);
                    }
                })
            })
        })
    }, [])

    return (
        <div>
            {scriptLoad ? 
                <Map 
                center={{ lat: lat, lng: lng }}   
                style={{ width: '800px', height: '600px' }} 
                level={3}>
                    <CustomOverlayMap position={{ lat: lat, lng: lng }}>
                        <div style={{position:'absolute', top:-60, left:-7, width:'100px', padding:'4px 0', textAlign:'center', color:'black', background:'white', borderRadius:'10px'}}>
                        카카오 본사
                        </div>
                    </CustomOverlayMap>
                    <MapMarker position={{ lat: lat, lng: lng }}></MapMarker>
                </Map>
                :
                <div></div>
            }
        </div>
    )
}

export default ReactKakaoMap;

 

반응형

 

 

 

 

 

 

 

 

 

3. 좌표 주소 출력하기

이전 주소 좌표로 이동하기와 반대로 좌표를 먼저 입력하고 해당 좌표의 주소 값 출력을 구현해 보겠다.

 

우선 위치 좌표 값을 넣어서 좌표 값 객체를 만들어주고 coored2Address를 사용하여 좌표를 넣어 주소를 검색한다.

검색이 완료되면 도로명 주소 값을 useState로 전달해 주고 출력을 해준다.

'use client';

import { useEffect, useState } from "react";
import { CustomOverlayMap, Map, MapMarker } from "react-kakao-maps-sdk";

declare global {
    interface Window {
        kakao: any;
    }
}

const ReactKakaoMap = () => {
    const apiKey:string|undefined = process.env.NEXT_PUBLIC_KAKAO_KEY;
    const [scriptLoad, setScriptLoad] = useState<boolean>(false);
    const [address, setAddress] = useState<string>("");

    useEffect(() => {
        const script:HTMLScriptElement = document.createElement("script");
        script.async = true;
        script.src = `//dapi.kakao.com/v2/maps/sdk.js?appkey=${apiKey}&libraries=services&autoload=false`;
        document.head.appendChild(script);

        script.addEventListener("load", () => {
            window.kakao.maps.load(() => {
                const geocoder = new window.kakao.maps.services.Geocoder();
                let coords = new window.kakao.maps.LatLng(33.450701, 126.570667);

		geocoder.coord2Address(coords.getLng(), coords.getLat(), function(result:any, status:any) {
                    if (status === kakao.maps.services.Status.OK) {
                        setAddress(result[0].road_address.address_name);
                        setScriptLoad(true);
                    }
                });
            })
        })
    }, [])

    return (
        <div>
            {scriptLoad ? 
                <Map 
                center={{ lat: 33.450701, lng: 126.570667 }}   
                style={{ width: '800px', height: '600px' }} 
                level={3}>
                    <CustomOverlayMap position={{ lat: 33.450701, lng: 126.570667 }}>
                        <div style={{position:'absolute', top:-75, left:-140, width:'300px', padding:'4px 0', textAlign:'center', color:'black', background:'white', borderRadius:'10px'}}>
                        {address}
                        </div>
                    </CustomOverlayMap>
                    <MapMarker position={{ lat: 33.450701, lng: 126.570667 }}></MapMarker>
                </Map>
                :
                <div></div>
            }
        </div>
    )
}

export default ReactKakaoMap;

 

 

 

아래처럼 해당 좌표의 도로명 주소 값을 확인할 수 있다.

 

 

 

위 방법들을 통해 주소 또는 좌표를 사용하여 해당 위치로 이동하고 해당 위치의 정보를 알아낼 수 있다.

 

 

 

 

 

 

 

 

728x90
반응형

'NextJS' 카테고리의 다른 글

[NextJS] Console.log 2번 출력 해결  (1) 2024.11.05
[NextJS] 카카오맵 API로 지도 구현하기 (1)  (0) 2024.07.06