IT/etc

[API] 카카오 Map API- 입력 지역 근처 편의점

HJ:: 2023. 9. 2. 00:24

 

미리보기

카카오Map API 로 검색 주변 근처 편의점 5개의 리스트를 받아오는 실습을 합니다.

 

설정 환경

- https://developers.kakao.com/ 

 

Kakao Developers

카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.

developers.kakao.com

- 카카오 서비스를 이용하기 위해선 일련의 작업이 필요합니다.

-우선 kakao 개발자 페이지에서 웹용 플랫폼 서비스를 등록해주고, 자바스크립트 키를 받아서,

index.html -> script 부분에 넣어줍니다.

<script
      type="text/javascript"
      src="//dapi.kakao.com/v2/maps/sdk.js?appkey=[api키 입력해주세요]&libraries=services,clusterer"
    ></script>

 

-리액트를 사용하기에

yarn add react-kakao-maps-sdk

로 라이브러리 설치해줍니다.

 

핵심 코드

  const { kakao } = window;
//라이브러리를 사용하기 위해서는 반드시 별도 로드 해야 한다.

 

useEffect(() => {
    if (!map) return;
    const ps = new kakao.maps.services.Places();

    // TODO: 마커 클릭시 그 위치로
    ps.keywordSearch(`${place} 편의점`, (data, status, _pagination) => {
      setStatus(status);
      if (status === kakao.maps.services.Status.OK) {
        // 검색된 장소 위치를 기준으로 지도 범위를 재설정하기위해
        // LatLngBounds 객체에 좌표를 추가합니다
        const bounds = new kakao.maps.LatLngBounds();
        let markers = [];

        for (var i = 0; i < 5; i++) {
          markers.push({
            position: {
              lat: data[i]?.y,
              lng: data[i]?.x
            },
            content: data[i]?.place_name
          });

          bounds.extend(new kakao.maps.LatLng(data[i]?.y, data[i]?.x));
        }
        setMarkers(markers);

        // 검색된 장소 위치를 기준으로 지도 범위를 재설정합니다
        map.setBounds(bounds);
      }
    });
  }, [place]);

- useEffect로 입력을 받을 때, 마다 place 값이 변동되어 검색 기능의 함수를 실행시켜줍니다.

 

for (var i = 0; i < 5; i++) {
          markers.push({
            position: {
              lat: data[i]?.y,
              lng: data[i]?.x
            },
            content: data[i]?.place_name
          });

- 이 부분에서 마커로 지정해줄 장소를 배열로 넣어줍니다.

 

 <MapMarker
              key={`marker-${marker.content}-${marker.position.lat},${marker.position.lng}`}
              position={marker.position}
            >
              <a
                href={`https://map.kakao.com/link/map/${marker.content},${marker.position.lat},${marker.position.lng}`}
                style={{ color: 'blue' }}
                target="_blank"
                rel="noreferrer"
              >
                큰지도보기
              </a>
              <a
                href={`https://map.kakao.com/link/to/${marker.content},${marker.position.lat},${marker.position.lng}`}
                style={{ color: 'blue' }}
                target="_blank"
                rel="noreferrer"
              >
                길찾기
              </a>

- 전에 넣어둔 마커를 하나씩 뽑아서 지정된 형식에 맞춰 랜더링 시켜줍니다.

전체 코드

import React, { useEffect, useState } from 'react';

import { Map, MapMarker, ZoomControl } from 'react-kakao-maps-sdk';
import styled from 'styled-components';

const KakaoSearchMap = () => {
  const [markers, setMarkers] = useState([]);
  const [map, setMap] = useState();
  const [place, setPlace] = useState('이태원');
  const [status, setStatus] = useState('');

  const { kakao } = window;

  const [state, setState] = useState({
    center: {
      lat: 33.450701,
      lng: 126.570667
    },
    errMsg: null,
    isLoading: true
  });



  // TODO: 현재 근처 편의점 5개 가져오기, 맵 드래그해도 동일 -> ps.category

  useEffect(() => {
    if (!map) return;
    const ps = new kakao.maps.services.Places();

    // TODO: 마커 클릭시 그 위치로
    ps.keywordSearch(`${place} 편의점`, (data, status, _pagination) => {
      setStatus(status);
      if (status === kakao.maps.services.Status.OK) {
        // 검색된 장소 위치를 기준으로 지도 범위를 재설정하기위해
        // LatLngBounds 객체에 좌표를 추가합니다
        const bounds = new kakao.maps.LatLngBounds();
        let markers = [];

        for (var i = 0; i < 5; i++) {
          markers.push({
            position: {
              lat: data[i]?.y,
              lng: data[i]?.x
            },
            content: data[i]?.place_name
          });

          bounds.extend(new kakao.maps.LatLng(data[i]?.y, data[i]?.x));
        }
        setMarkers(markers);

        // 검색된 장소 위치를 기준으로 지도 범위를 재설정합니다
        map.setBounds(bounds);
      }
    });
  }, [place]);

  const placeInputHandler = (e) => {
    setPlace(e.target.value);
  };

  return (
    <>
      <Map // 로드뷰를 표시할 Container
        center={state.center}
        style={{
          border: '1px solid black',
          width: '100%',
          height: '350px'
        }}
        level={3}
        onCreate={setMap}
      >
        {markers.map((marker) => (
          <>
            <MapMarker
              key={`marker-${marker.content}-${marker.position.lat},${marker.position.lng}`}
              position={marker.position}
            >
              <a
                href={`https://map.kakao.com/link/map/${marker.content},${marker.position.lat},${marker.position.lng}`}
                style={{ color: 'blue' }}
                target="_blank"
                rel="noreferrer"
              >
                큰지도보기
              </a>
              <a
                href={`https://map.kakao.com/link/to/${marker.content},${marker.position.lat},${marker.position.lng}`}
                style={{ color: 'blue' }}
                target="_blank"
                rel="noreferrer"
              >
                길찾기
              </a>
              <div style={{ color: '#000' }}>{marker.content}</div>
            </MapMarker>
            {!state.isLoading && (
              <MapMarker position={state.center}>
                <div style={{ padding: '5px', color: '#000' }}>{state.errMsg ? state.errMsg : '여기에 계신가요?!'}</div>
              </MapMarker>
            )}
            <ListContainer>
              <ListItem>{marker.content}</ListItem>
            </ListContainer>
          </>
        ))}
        {/* 확대/축소 토글 */}
        <ZoomControl position={kakao.maps.ControlPosition.TOPRIGHT} />
      </Map>
      <input placeholder="장소 입력" onChange={placeInputHandler}></input>
      {/* TODO 현재 사용자 위치로 이동 */}
    </>
  );
};

export default KakaoSearchMap;

const ListContainer = styled.div`
  background-color: #f0f0f0;
  padding: 16px;
  border-radius: 8px;
`;

// 스타일 컴포넌트를 사용하여 목록 아이템 스타일링
const ListItem = styled.div`
  background-color: #fff;
  padding: 8px;
  margin-bottom: 8px;
  border-radius: 4px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
`;

 

다음 계획

다음엔 사용자 위치를 불러와 그 근처 편의점을 구해주는 프로젝트를 만들 계획이다.

드래그 할 때마다 바뀐 새로운 맵 근처 편의점을 구해주도록 짜야한다.

그리고 마카를 누르면 해당 지점으로 이동해준다.