문서 / 설정 / React / Google Maps

Google Maps 설정

Web에서 Google Maps를 MapConductor에서 쓰는 절차입니다. Google Maps JavaScript API는 동적으로 읽히므로, script 태그를 쓸 필요는 없습니다. 2D와 3D에서 다른 뷰를 씁니다.

PACKAGE
react-for-googlemaps
API KEY
필요
CSS
불필요
REACT NATIVE
있음
같은 프로바이더, 다른 플랫폼AndroidiOS

시작하기 전에

Node.js 18 이상
Maps SDK / JavaScript API가 활성화된 Google Cloud 프로젝트
HTTP 리퍼러로 제한한 API 키
STEP 01

API 키를 취득한다

  1. Google Cloud Console에서 Maps JavaScript API를 활성화합니다.
  2. 「인증 정보」에서 API 키를 만듭니다.
  3. 키를 배포 도메인의 HTTP 리퍼러로 제한합니다.
주의
키는 빌드 시의 환경 변수(Vite라면 import.meta.env.VITE_*)에서 넘기고, 소스 관리에는 넣지 마세요. 프런트엔드로 전달되는 이상, 공개되어도 피해가 나지 않도록 리퍼러 제한이나 도메인 제한을 반드시 겁니다.
STEP 02

설치한다

Google Maps JavaScript API는 @googlemaps/js-api-loader로 동적으로 읽힙니다. 이 loader는 패키지에 동봉되어 있으므로, 별도로 설치할 필요도, CSS를 읽어 들일 필요도 없습니다.

terminalnpm
npm install @mapconductor/js-sdk-core @mapconductor/js-sdk-react \
            @mapconductor/react-for-googlemaps
STEP 03

키를 상태 훅에 넘긴다

키는 뷰 component의 props가 아니라, 상태 훅에 넘깁니다. props에 두면 테스트의 로그나 스냅숏에 섞이기 때문입니다.

HelloMap.tsxTypeScript · React
const mapState = useGoogleMapViewState({
  id: 'web-google-map',
  apiKey: import.meta.env.VITE_GOOGLE_MAPS_API_KEY,
  mapDesignType: GoogleMapDesign.Normal,
  cameraPosition: createMapCameraPosition({ position: TOKYO, zoom: 12 }),
});
키가 없을 때의 전용 오류는 나오지 않습니다. 읽기 실패로서 나타나므로, 우선 키를 의심해 주세요.
STEP 04

2D와 3D를 나눠 쓴다

Google Maps는 2개의 스택을 가지고, MapConductor는 각각에 다른 뷰를 마련하고 있습니다. 양자는 같은 상태 객체를 공유합니다. mapId를 설정하면 2D 쪽의 마커가 AdvancedMarkerElement로 렌더링되고, 설정하지 않으면 종래의 마커가 됩니다.

HelloMap.tsxTypeScript · React
// Classic 2D map (google.maps.Map)
<GoogleMapView2D state={mapState} mapId="YOUR_MAP_ID" />

// True 3D camera (google.maps.maps3d.Map3DElement)
<GoogleMapView state={mapState} mapId="YOUR_MAP_ID" version="alpha" />
주의
3D 뷰(GoogleMapView)에서 쓸 수 있는 디자인은 Normal・Hybrid・Satellite뿐입니다. Terrain과 None을 넘기면 실행 시에 예외가 됩니다. 3D는 maps3d 라이브러리를 쓰기 때문에 version="alpha"가 필요합니다.

동작 확인

여기까지 보이면 완료

도쿄를 중심으로 지도가 나오고, 마커가 하나 서면 완료입니다.

HelloMap.tsxTypeScript · React
import { useState } from 'react';
import { createGeoPoint, createMapCameraPosition, createMarkerState } from '@mapconductor/js-sdk-core';
import { Marker } from '@mapconductor/js-sdk-react';
import { GoogleMapDesign, GoogleMapView2D, useGoogleMapViewState } from '@mapconductor/react-for-googlemaps';

const TOKYO = createGeoPoint({ latitude: 35.6812, longitude: 139.7671 });

export function HelloMap() {
  const mapState = useGoogleMapViewState({
    id: 'web-google-map',
    apiKey: import.meta.env.VITE_GOOGLE_MAPS_API_KEY,
    mapDesignType: GoogleMapDesign.Normal,
    cameraPosition: createMapCameraPosition({ position: TOKYO, zoom: 12 }),
  });
  const [markerState] = useState(() => createMarkerState({ id: 'tokyo', position: TOKYO }));

  return (
    <GoogleMapView2D state={mapState} style={{ height: 480 }}>
      <Marker state={markerState} />
    </GoogleMapView2D>
  );
}

상태 객체

useGoogleMapViewState가 받는 파라미터입니다.

signatureTypeScript
useGoogleMapViewState({
  id?: string;
  apiKey?: string;                     // required in practice
  mapId?: string;                      // Advanced Markers / cloud styling
  mapDesignType?: GoogleMapDesignType; // default GoogleMapDesign.Normal
  cameraPosition?: MapCameraPosition;  // default MapCameraPosition.Default
})

지도 디자인

GoogleMapDesign은 Google의 맵 타입에 대응합니다.

GoogleMapDesign
Notes
Normal
roadmap. 3D에서도 쓸 수 있다
Satellite
위성 화상. 3D에서도 쓸 수 있다
Hybrid
위성 화상+라벨. 3D에서도 쓸 수 있다
Terrain
지형도. 2D만
None
베이스맵 없음. 2D만

잘 안 될 때

지도가 나오지 않는다

  • 키가 상태 훅에 전달되고 있는지, 환경 변수를 읽을 수 있는지 확인합니다.
  • Console에서 키의 리퍼러 제한이 실제의 배포 도메인과 일치하는지 확인합니다.

3D 뷰가 예외를 던진다

  • mapDesignType에 Terrain이나 None을 넘기고 있지 않은지 확인합니다. 3D는 Normal・Hybrid・Satellite뿐입니다.
  • version="alpha"를 넘기고 있는지 확인합니다.

개발 시에만 지도가 이중으로 초기화된다

  • React StrictMode는 effect를 2번 실행합니다. 각 프로바이더는 이것을 감지해 한쪽을 파기하도록 되어 있으므로, StrictMode를 뺄 필요는 없습니다.

다음

3D 뷰에서는 윈도의 크기 변경에 맞춰 카메라의 range를 보정하고 있기 때문에, 화면 크기가 바뀌어도 줌의 보이는 모습이 맞춰집니다.