Google Maps API
Google Maps API는 Google이 제공하는 Map 인터페이스다. 지리정보와 지도 데이터를 사용할 수 있는 도구를 제공해준다. 위 API를 이용해서 내가 작업하고 있는 프로젝트에 사용해보려고 한다.
Google Maps API는 여러 방법으로 프로젝트에 적용할 수 있다.
- 지도 위에서 위치를 검색하거나 상호작용 가능
- API를 사용하여 위도, 경도를 표시
- API의 경로를 검색하고 지도에 표시
- 현재 사용자의 위치를 추적
나는 내 프로젝트에 해당 국가의 위치만 표시하려고 한다. 이제 내 프로젝트에 적용을 해보자! 현재 내 프로젝트에서는 국가 정보 페이지에 접속하게 되면 Map의 링크로 이동하도록 구현하였다.
프로젝트에 사용하는 api 구조는 다음과 같다.
{
"code":"GBR",
"commonName":"United Kingdom",
"officialName":"United Kingdom of Great Britain and Northern Ireland",
"flagEmoji":"🇬🇧",
"flagImg":"https://flagcdn.com/w320/gb.png",
"capital":["London"],
"region":"Europe",
"population":67215293,
"googleMapURL":"https://goo.gl/maps/FoDtc3UKMkFsXAjHA"
}
데이터 가장 아래 googleMapURL의 https://goo.gl/maps/FoDtc3UKMkFsXAjHA로 접속하면 해당 google Maps의 해당 국가 검색 결과가 나온다.
처음에 해당 데이터로 링크만 걸었지만 페이지에다 직접 Map을 구현하려 하니 필요한 데이터가 위도와 경도였다.
그러나 위도 경도는 이동한 페이지의 URL에서 받을 수 있는데, 이를 내가 받은 링크url로 사용해보려 했지만 렌더링 과정에서 상호작용이 불가능하다고 판단되었다.
https://goo.gl/maps/FoDtc3UKMkFsXAjHA
// 내 데이터
https://www.google.com/maps/place/%EC%98%81%EA%B5%AD/@54.5512799,-4.4737716,5z/data=!3m1!4b1!4m6!3m5!1s0x25a3b1142c791a9:0xc4f8a0433288257a!8m2!3d55.378051!4d-3.435973!16zL20vMDdzc2M?entry=ttu
// 내가 필요한 place/ 뒤의 @54.5512799(위도) -4.4737716(경도)
그럼 위도 경도를 어떻게 가져와?
결국 각 국가별로 위치데이터 Map을 사용하기 위해 필요한 위도 경도를 얻기 위해, Google Maps JavaScript API의 Geocoder 클래스를 사용하여 주어진 주소에 대한 좌표를 얻어내려 노력했다.
function getLatLngBycommonName(commonName: string) {
return new Promise<{ lat: number; lng: number }>((resolve, reject) => {
const geocoder = new google.maps.Geocoder();
geocoder.geocode({ address: commonName }, (results, status) => {
if (status === google.maps.GeocoderStatus.OK) {
const location = results?.[0]?.geometry?.location;
if (location) {
const lat = location.lat();
const lng = location.lng();
resolve({ lat, lng });
} else {
reject("위도와 경도를 찾을 수 없습니다.");
}
} else {
reject("지오코딩에 실패했습니다.");
}
});
});
}
getLatLngBycommonName 함수는 내가 사용할 수 있는 데이터 중 conmmonName(일반적인 국가 이름, ex. south korea, japan)을 통해 해당 국가 위치정보를 검색하고 위도 경도를 반환하는 함수이다.
함수의 작동 순서는 다음과 같다.
- commonName이라는 매개변수를 받음
- Promise로 비동기 작업을 수행하여 매개변수로 위치정보를 검색
- geocoder는 Google Maps JavaScript API의 Geocoder객체를 생성
- Geocoder객체는 주소를 지리적 좌표로 변환하거나 반대로 변환하는 데 사용
- geocoder요청이 완료되었는 지 확인하고, 성공하면 result?.[0]에서 지리적 좌표 정보를 가져옴
- 가져온 좌표 정보 location에서 lat과 lng을 추출하고 resolve를 호출하여 성공상태로 해결
위의 코드로 commonName의 좌표정보를 가져올 수 있었다. 이제 해당 각 국가 상세 정보화면으로 이동시 위 함수가 실행되어 좌표정보를 위도, 경도로 나뉘에 state에 저장하면 된다.
const [mapCenter, setMapCenter] = useState({
lat: 0,
lng: 0,
});
useEffect(() => {
if (country) {
getLatLngBycommonName(country.commonName)
.then(({ lat, lng }) => {
setMapCenter({ lat, lng });
})
.catch(error => {
console.error("위치 정보를 가져오는 중 오류 발생:", error);
});
}
}, [country]);
데이터를 관리할 state의 초기값을 0으로 설정해준다. country는 해당 SSG 컴포넌트가 받는 props이다. country가 존재하면 getLatLngBycommonName함수를 호출하여 setMapCenter에 resolve되는 좌표 위도, 경도를 담는다. 잘 담기는지 확인해보자!!
지오코딩으로 좌표정보를 가져와 사용할 수 있게 되었다.
만약 내가 사용하는 api의 url이 있었다면 굳이 위와 같은 geocoder를 사용할 필요는 없다. 그러나 내 상황과 같이 좌표정보를 url에서 사용할 수 없는 shortLink와 같은 형태면 geocoder를 사용해야 하기 때문에 좋은 학습이 되었다.
Google Maps API Key 발급하기
Google Maps API를 사용하려면 API Key를 먼저 발급받아야 한다. 먼저 Google 계정에 로그인을 하여 https://mapsplatform.google.com/에서 Get Start하면 된다.
위의 약관에 두 개를 체크하고 동의 및 계속하기를 누른다.
키 및 사용자 인증 정보를 클릭하면 다음과 같이 약관에 체크하라고 나오는데, 두 개 다 체크하고 계속을 누르면 된다.
개인이용자와 주소 정보 및 결제 카드정보를 입력하면 된다. 학습을 위해서는 무료 체험으로 충분하다.
90일 동안 무료 기간이 종료되어도 직접 업그레이드 하지 않으면 과금이 되지 않는다.
그 외에 개인정보를 입력하고 나면 API키를 발급해준다.
위의 API키를 이용하여 이제 Google Maps API 서비스를 이용할 수 있다.
이제 진짜 Google Maps API 사용해보기
먼저, API키는 보안을 위해 .env파일에 보관하고 repo에 올라가지 않도록 gitignore에 추가해준다.
React에서는 REACT_APP_MY_KEY 라고 썼었지만, Next에서는 다음과 같이 사용한다.
.env 작성 요령 : NEXT_PUBLIC_~~~
API_KEY 사용 요령 : process.env.NEXT_PUBLIC_~~~
React에서 Google Maps API를 사용하기 위해 ReactHook을 사용할 수 있다.
먼저 아래의 명령어로 패키지를 다운로드 해야한다.
npm i @react-google-maps/api
useLoadScript를 사용하여 스크립트가 성공적으로 로딩될 때 까지 isLoaded를 반환하고, 이를 이용하여 Loading 컴포넌트를 띄울 수 있다. useLoadScript를 import 하여 사용해보자.
import { useLoadScript } from '@react-google-maps/api'
로딩이 완료되면, GoogleMap 컴포넌트를 사용하여 실제 지도를 로드할 수 있다.
GoogleMap을 어떻게 사용할 수 있는지 먼저 살펴보자.
import { GoogleMap } from '@react-google-maps/api'
- option : API에서 제공하는 데이터를 옵션을 통해 커스텀이 가능 (boolean)
- disableDefaultUI : 지도의 기본 인터페이스를 활성/비활성
- clickableIcons : 지도 위의 표시된 마커와 같은 아이콘을 클릭하여 상호작용 가능/불가능
- scrollwheel : 스크롤로 확대, 축소 가능/불가능
- zoom : 지도의 확대범위를 지정
- center : 위도와 경도를 중심으로 지도를 표현
- mapTypeId : 지도를 구현해주는 유형을 설정
- ROADMAP : 일반적인 도로지도
- SATELLITE : 위성만 나오는 지도
- HYBRID: ROADMAP과 SATELLITE를 합친 지도
- TERRAIN : 지형지도. 고도 및 지형 특징을 강조
- HISTOGRAM : 히스토그램
- mapContainerStyle : 지도의 사이즈를 조절가능
위와 같이 코드를 구성할 수 있다.
center의 좌표를 넣어야 하는데, 이전에 Geocoder로 구한 좌표값을 미리 state에 저장해두었다. 이를 갖다 사용하면 된다.
잘 구현된 것을 볼 수 있다.
근데 뭔가 허전하다.
영국의 위치를 마커로 표시해보자!
다음과 같이 마커를 import 할 수 있다.
import { MarkerF } from "@react-google-maps/api";
마커를 GoogleMap의 child로 삽입하면 되고, 역시 마커의 위치를 지정하기 위해서 좌표가 필요하다.
국가를 표시하는 좌표와 같은 좌표를 입력하면 되기에 이전에 state에 담아준 좌표를 사용하면 된다.
구현 결과
출처
https://www.99darshan.com/posts/interactive-maps-using-nextjs-and-google-maps
Build Interactive Maps in Next.js using Google Maps API
Build Interactive Maps in Next.js using Google Maps API This tutorial will demonstrate how to use google Maps API and Google Places API to build interactive maps in Next.js. Demo Here is a demo of what we will be building by the end of this tutorial. Proje
www.99darshan.com
'개발기록' 카테고리의 다른 글
[React-Query | Next.js | Prisma | Planetscale] Wishlist Mutation 적용 (0) | 2023.09.11 |
---|---|
[React-Query] React-Query와 Debounce를 활용한 효율적인 데이터 페칭 (0) | 2023.09.09 |
[Next.js] Next.js + TypeScript + Tailwind CSS 초기세팅 (0) | 2023.08.31 |
[Next.js] context를 이용해보자! + TypeScript (0) | 2023.08.25 |
RunBase ( 2 ) - 극한의 컴포넌트 재활용 (0) | 2023.08.13 |