1. 시작하기 전에
이 튜토리얼에서는 애플리케이션에 3D 마커를 추가하고 스타일을 지정하는 방법을 살펴봅니다. 특정 위치로 이동하고 그 주변을 비행하여 애플리케이션에 애니메이션을 적용하는 방법도 알아봅니다.
이 튜토리얼은 첫 번째 codelab에서 다룬 개념을 기반으로 합니다. 아직 수강하지 않았다면 이 Codelab을 완료하여 이 애플리케이션에 필요한 기본 지식을 습득하세요.
실행할 작업
이 애플리케이션에서는 유럽의 주요 Google 사무실을 간략하게 설명합니다. 사용자는 사무실을 선택하고 사무실을 둘러본 후 축소하여 일반 보기로 돌아갈 수 있습니다. 이러한 기능은 여행 및 탐색 애플리케이션에서 흔히 볼 수 있으며 사용자에게 더 몰입도 높은 환경을 제공합니다.
이 Codelab에서는 다음을 실행하는 3D 웹 앱을 빌드합니다.
- Maps JavaScript API를 동적으로 로드합니다.
- 지도에 3D 마커를 추가합니다.
- SVG를 사용하여 마커의 스타일을 지정합니다.
- 마커로 이동하고 마커 주변을 비행하는 기능을 추가합니다.
- 코드의 위치를 배열로 추상화합니다.
학습할 내용
- 마커의 작동 방식
- 마커의 스타일을 지정하는 방법
- 애니메이션이 내장 함수와 함께 작동하는 방식
- 프레이밍을 개선하기 위해 포즈를 취하는 카메라 위치와 지점 위치
- 카메라 매개변수를 캡처하여 상품을 더 잘 프레이밍하는 데 도움이 되는 유용한 해킹
기본 요건
이 Codelab을 완료하려면 다음 항목을 숙지해야 합니다. Google Maps Platform 사용에 익숙하다면 Codelab으로 건너뛰어도 됩니다.
필수 Google Maps Platform 제품
이 Codelab에서는 다음 Google Maps Platform 제품을 사용합니다.
- Maps JavaScript API
본 Codelab의 기타 요구사항
이 Codelab을 완료하려면 다음과 같은 계정, 서비스, 도구가 필요합니다.
- 결제가 사용 설정된 Google Cloud 계정
- Maps JavaScript API가 사용 설정된 Google Maps Platform API 키
- JavaScript, HTML, CSS에 대한 기본 지식
- 원하는 텍스트 편집기 또는 IDE: 수정한 파일을 저장하여 확인합니다.
- 작업 중에 파일을 볼 수 있는 웹브라우저
2. 설정
Google Maps Platform 설정하기
Google Cloud Platform 계정 및 결제가 사용 설정된 프로젝트가 없는 경우 Google Maps Platform 시작하기 가이드를 참고하여 결제 계정 및 프로젝트를 만듭니다.
- Cloud Console에서 프로젝트 드롭다운 메뉴를 클릭하고 이 Codelab에 사용할 프로젝트를 선택합니다.
3. 간단한 지구본
애플리케이션 빌드를 시작하려면 기본 설정을 설정하는 것이 중요합니다. 그러면 이미지와 같이 지구의 '블루 마블' 뷰가 가장 기본적인 형태로 표시됩니다.
시작 페이지의 코드 추가
사이트에 지구본을 추가하려면 페이지에 다음 코드를 추가해야 합니다. 이렇게 하면 Maps JavaScript API 로더 섹션과 마커 코드를 추가할 페이지 내에 지도 3D 요소를 만드는 init 함수가 추가됩니다.
페이지에 자체 키 (설정 섹션에서 생성됨)를 추가해야 합니다. 그러지 않으면 3D 요소를 초기화할 수 없습니다.
<!DOCTYPE html>
<html>
<head>
<title>Step 1 - Simple Globe</title>
<style>
body {
height: 100vh;
margin: 0;
}
</style>
</head>
<body>
<script>
(g => { var h, a, k, p = "The Google Maps JavaScript API", c = "google", l = "importLibrary", q = "__ib__", m = document, b = window; b = b[c] || (b[c] = {}); var d = b.maps || (b.maps = {}), r = new Set, e = new URLSearchParams, u = () => h || (h = new Promise(async (f, n) => { await (a = m.createElement("script")); e.set("libraries", [...r] + ""); for (k in g) e.set(k.replace(/[A-Z]/g, t => "_" + t[0].toLowerCase()), g[k]); e.set("callback", c + ".maps." + q); a.src = `https://maps.${c}apis.com/maps/api/js?` + e; d[q] = f; a.onerror = () => h = n(Error(p + " could not load.")); a.nonce = m.querySelector("script[nonce]")?.nonce || ""; m.head.append(a) })); d[l] ? console.warn(p + " only loads once. Ignoring:", g) : d[l] = (f, ...n) => r.add(f) && u().then(() => d[l](f, ...n)) })({
key: "<INSERT API KEY>",
v: "alpha",
// Use the 'v' parameter to indicate the version to use (weekly, beta, alpha, etc.).
// Add other bootstrap parameters as needed, using camel case.
});
</script>
<script>
let map3D = null;
async function init() {
const { Map3DElement, MapMode } = await google.maps.importLibrary("maps3d");
map3D = new Map3DElement({
mode: MapMode.HYBRID,
});
document.body.append(map3D);
}
init();
</script>
</body>
</html>
이제 관심 장소의 프레임을 설정할 준비가 되었습니다. 다음 단계에서 진행하겠습니다.
4. 프레임 첫 번째 뷰
이제 지구본 뷰가 포함된 지도를 만들었으므로 다음 구현 단계는 올바른 출발 위치를 프레이밍하는 것입니다. 이렇게 하면 사용자가 작업 중인 위치를 한눈에 파악할 수 있습니다.
이 예에서는 유럽의 Google 사무실을 중점적으로 살펴보지만 이 접근 방식은 국가 전체에서 단일 도시 블록에 이르기까지 전 세계 모든 위치에 적용할 수 있습니다. 제품의 속도와 유연성을 통해 최소한의 코드 변경으로 애플리케이션을 글로벌에서 로컬로 확장할 수 있습니다.
먼저 초기 프레이밍으로 3D 지도를 다음과 같이 표시합니다.
카메라 프레임을 유럽에 맞춤
표시된 것처럼 디스플레이를 가져오려면 마치 공간에 카메라를 배치하여 위치를 내려다보는 것처럼 디스플레이의 프레임을 올바르게 설정해야 합니다.
이렇게 하려면 지도 컨트롤의 여러 매개변수를 사용하여 카메라 세부정보를 설정할 수 있습니다. 다이어그램에서 '실제' 세계에서 매개변수가 상호작용하는 방식을 확인할 수 있습니다. 특히 카메라가 바라보는 중앙 지점과 내가 바라보는 지점과의 거리 (범위)가 있습니다. 카메라 관점의 기울기도 설정해야 합니다. 그러지 않으면 지구를 똑바로 내려다보게 됩니다.
마지막 설정인 방향은 카메라의 방향을 결정합니다. 북쪽에서의 오프셋으로 측정됩니다. 이러한 값은 초기 디스플레이를 설정하는 객체로 3D 지도 요소에 적용됩니다. 업데이트된 3D 요소 생성자가 있는 코드에서 이를 확인할 수 있습니다.
map3D = new Map3DElement({
center: { lat: 46.717, lng: 7.075, altitude: 2175.130 },
range: 5814650,
tilt: 33,
heading: 4.36,
mode: MapMode.HYBRID
});
카메라 매개변수 캡처
3D 지도에서 뷰의 프레임을 지정하려면 정확한 카메라 배치가 필요하며, 이는 코드만으로는 달성하기 어려울 수 있습니다. 이 프로세스를 간소화하려면 다음과 같은 유용한 해킹을 사용하세요. 필요한 뷰를 클릭할 때 카메라 매개변수를 캡처하는 함수를 페이지에 추가합니다. 매개변수가 콘솔에 출력되며 객체의 카메라 설정으로 복사할 수 있습니다.
나중에 사용할 수 있는 코드를 확인할 수 있습니다. 이 코드는 이 페이지의 샘플에 추가되어 있지만 Codelab에는 필요하지 않으므로 후속 페이지의 샘플에는 포함되지 않습니다. 하지만 더 나은 카메라 위치를 통해 몰입도 높은 데모를 만들려면 이 코드를 기억해야 합니다.
map3D.addEventListener('gmp-click', (event) => {
console.log("camera: { center: { lat: " + map3D.center.lat + ", lng : " + map3D.center.lng + ", altitude: " + map3D.center.altitude + " }, range: " + map3D.range + ", tilt: " + map3D.tilt + " ,heading: " + map3D.heading + ", }");
console.log("{ lat: " + event.position.lat + ", lng : " + event.position.lng + ", altitude: " + event.position.altitude + " }");
// Stop the camera animation when the map is clicked.
map3D.stopCameraAnimation();
});
stopCameraAnimation
함수의 사용을 확인하세요. 페이지가 확대 또는 회전 중인 경우 해당 시점의 디스플레이 위치를 캡처할 수 있도록 애니메이션을 중지할 수 있으면 유용합니다. 다음 코드를 사용하면 이 작업을 실행할 수 있습니다. 자세한 내용은 stopCameraAnimation
문서를 참고하세요.
콘솔에 표시되는 클릭의 출력 예시
camera: { center: { lat: 51.39870122020001, lng : -0.08573187165829443, altitude: 51.66845062662254 }, range: 716.4743880553578, tilt: 50.5766672986501 ,heading: -1.048260134782318, }
step2.html:40 { lat: 51.398158351120536, lng : -0.08561139388593597, altitude: 51.860469133677626 }
카메라 텍스트는 3D 지도의 다양한 객체에서 JSON 입력으로 사용할 수 있습니다. 두 번째 출력은 클릭이 발생한 실제 지점 위치이며, 점이나 마커 배치에 유용합니다.
페이지의 프레임이 올바르게 설정되면 이제 마커를 추가할 수 있습니다. 방법을 알아보려면 다음 단계로 진행하세요.
섹션 솔루션
이 단계에서는 구현을 확인하기 위한 솔루션으로 완성된 페이지가 제공됩니다. (복사하는 경우 자체 API 키를 사용해야 합니다.)
<!DOCTYPE html>
<html>
<head>
<title>Step 2 - Europe View</title>
<style>
body {
height: 100vh;
margin: 0;
}
</style>
</head>
<body>
<script>
(g => { var h, a, k, p = "The Google Maps JavaScript API", c = "google", l = "importLibrary", q = "__ib__", m = document, b = window; b = b[c] || (b[c] = {}); var d = b.maps || (b.maps = {}), r = new Set, e = new URLSearchParams, u = () => h || (h = new Promise(async (f, n) => { await (a = m.createElement("script")); e.set("libraries", [...r] + ""); for (k in g) e.set(k.replace(/[A-Z]/g, t => "_" + t[0].toLowerCase()), g[k]); e.set("callback", c + ".maps." + q); a.src = `https://maps.${c}apis.com/maps/api/js?` + e; d[q] = f; a.onerror = () => h = n(Error(p + " could not load.")); a.nonce = m.querySelector("script[nonce]")?.nonce || ""; m.head.append(a) })); d[l] ? console.warn(p + " only loads once. Ignoring:", g) : d[l] = (f, ...n) => r.add(f) && u().then(() => d[l](f, ...n)) })({
key: "<INSERT API KEY>",
v: "alpha",
// Use the 'v' parameter to indicate the version to use (weekly, beta, alpha, etc.).
// Add other bootstrap parameters as needed, using camel case.
});
</script>
<script>
let map3D = null;
async function init() {
const { Map3DElement, MapMode } = await google.maps.importLibrary("maps3d");
map3D = new Map3DElement({
center: { lat: 46.717, lng: 7.075, altitude: 2175.130 },
range: 5814650,
tilt: 33,
heading: 4.36,
mode: MapMode.HYBRID,
});
map3D.addEventListener('gmp-click', (event) => {
console.log("camera: { center: { lat: " + map3D.center.lat + ", lng : " + map3D.center.lng + ", altitude: " + map3D.center.altitude + " }, range: " + map3D.range + ", tilt: " + map3D.tilt + " ,heading: " + map3D.heading + ", }");
console.log("{ lat: " + event.position.lat + ", lng : " + event.position.lng + ", altitude: " + event.position.altitude + " }");
map3D.stopCameraAnimation();
});
document.body.append(map3D);
}
init();
</script>
</body>
</html>
5. 간단한 마커
이 섹션에서는 첫 번째 마커를 추가하는 방법을 알아봅니다. 먼저 마커에 관한 일반적인 세부정보를 알아봅니다.
3D 지도에서는 두 가지 마커 클래스인 Marker3DElement 클래스와 Marker3DInteractiveElement 클래스를 만들 수 있습니다. 이 클래스는 마커 클릭을 사용 설정할지 여부에 따라 선택됩니다. 그 외에는 기본적으로 동일하므로 먼저 Marker3DElement를 만든 다음 이후 단계에서 Marker3DInteractiveElement로 '업그레이드'합니다.
이 단계의 전체 솔루션은 여기에서 확인할 수 있습니다.
마커에 높이 추가
먼저 마커는 3D 지도의 다른 모든 항목과 마찬가지로 3D입니다. 즉, 위치에 높이 (고도)가 있을 수 있으며 이 높이는 해수면, 지상, 메시를 기준으로 한 위치로 나타낼 수 있거나 지상에 고정되고 고도 위치를 무시하도록 설정할 수 있습니다. 자세한 내용은 AltitudeMode 문서의 고도 상수 섹션을 참고하세요.
extruded 값을 사용하여 마커가 돌출되는지 여부를 설정할 수도 있습니다. 이 옵션에 따라 마커에 높이와 관련된 실제 위치를 표시하는 데 도움이 되는 작은 선이 지면에 그려질지 결정됩니다. 이 선은 지상에서 지점을 선택하는 데 유용합니다. Google 영국 위치를 예로 들 수 있습니다. 둘 다 돌출되고 위치가 절대 높이로 설정되어 있습니다. 첫 번째는 75m, 두 번째는 125m에 있습니다.
고도 75미터 | 고도 125m |
가림 및 충돌이 있는 마커 숨기기 또는 표시
위치가 서로 멀리 떨어져 있으므로 이 예시에서는 중요하지 않을 수 있지만, 서로 겹치거나 건물 뒤에 있을 수 있는 마커의 경우 collisionBehavior 또는 drawsWhenOccluded 값으로 마커에 어떤 일이 일어나는지 제어할 수 있습니다.
충돌 동작에는 다음과 같은 옵션이 있습니다.
REQUIRED
(기본값): 충돌과 관계없이 항상 마커를 표시합니다.OPTIONAL_AND_HIDES_LOWER_PRIORITY
: 마커가 다른 마커와 겹치지 않는 경우에만 마커를 표시합니다. 이 유형의 마커 두 개가 겹치면zIndex
가 더 높은 마커가 표시됩니다.zIndex
가 동일하면 세로 화면 위치가 더 낮은 마커가 표시됩니다.REQUIRED_AND_HIDES_OPTIONAL
: 충돌과 관계없이 항상 마커를 표시하고 마커와 겹치는OPTIONAL_AND_HIDES_LOWER_PRIORITY
마커 또는 라벨을 숨깁니다.
정의된 충돌 동작에 따라 마커가 표시되는 방식의 차이는 이미지에 나와 있습니다. REQUIRED
를 설정하면 모든 마커가 표시되지만 REQUIRED_AND_HIDES_OPTIONAL
를 사용하면 이 경우 화면 아래쪽에 있는 마커가 표시됩니다. 원하는 경우 zIndex를 조정하여 다른 마커를 맨 위에 표시할 수 있습니다.
필수 | REQUIRED_AND_HIDES_OPTIONAL |
가림의 경우 마커를 건물 뒤에 그릴지 여부를 선택할 수 있습니다. 다음 이미지를 참고하세요. drawsWhenOccluded
를 true로 설정하면 건물 뒤에 그려질 때 마커가 약간 어두워집니다. false로 설정하면 건물 뒤에 있을 때 마커가 숨겨집니다. 자세한 내용은 다음 표를 참고하세요.
|
|
앞서 언급한 대로 가려진 마커의 그리기가 허용되는 경우 충돌로 인해 숨겨진 마커가 희미하게 표시됩니다. 이미지에서 일부 마커는 건물에 가려져 있고 일부 마커는 다른 마커에 가려져 있습니다.
자세한 내용은 2D 지도의 collision-behavior 예를 참고하세요.
캔버스 지우기
이제 첫 번째 마커를 만들어 보겠습니다. 사용자가 마커에 집중할 수 있도록 3D 지도에서 기본 라벨을 사용 중지할 수 있습니다.
3D 지도 요소의 mode
값을 SATELLITE
로 설정합니다.
자세한 내용은 모드를 참고하세요.
map3D = new Map3DElement({
center: { lat: 46.717, lng: 7.075, altitude: 2175.130 },
range: 5814650,
tilt: 33,
heading: 4.36,
mode: MapMode.SATELLITE
});
이렇게 하면 다음과 같은 3D 지도가 만들어집니다.
첫 번째 마커 추가
이제 캔버스가 깨끗해졌으므로 첫 번째 마커를 추가할 수 있습니다. 주요 매개변수에는 위치 및 라벨이 포함됩니다.
마커를 추가하려면 마커의 위치를 설정하세요. 마커 위에 표시되는 라벨과 Marker3DElement 문서에 설명된 기타 요소를 포함할 수도 있습니다.
마커를 추가하려면 다음과 같이 기본 라벨을 숨기는 줄 뒤에 다음 코드를 추가합니다.
const marker = new Marker3DElement({
position: { lat: 51.5332, lng: -0.1260, altitude: 75 },
label: 'Google UK',
altitudeMode: 'ABSOLUTE',
extruded: true,
});
map3D.append(marker);
마커를 만든 후 append 메서드를 사용하여 3D 지도에 추가합니다. 마커는 3D 지도 내에 하위 요소 배열로 저장됩니다. 마커를 수정하려면 이 배열을 통해 마커에 액세스해야 합니다.
API를 로드할 때 라이브러리 목록에 추가하여 Marker3DElement
가 Maps JavaScript API에서 로드되는지 확인합니다.
const { Map3DElement, MapMode, Marker3DElement } = await google.maps.importLibrary("maps3d");
이제 페이지가 로드되면 런던 지점 위에 마커가 표시된 채로 유럽 전체가 표시됩니다. 애니메이션에서 볼 수 있듯이 수동으로 확대하여 생성된 위치 위에 마커를 표시할 수 있습니다.
이제 첫 번째 마커를 로드했으므로 다음 단계는 마커를 더 보기 좋게 만드는 것입니다.
섹션 솔루션
이 단계에서는 구현을 확인하기 위한 솔루션으로 완성된 페이지가 제공됩니다. (복사하는 경우 자체 API 키를 사용해야 합니다.)
<!DOCTYPE html>
<html>
<head>
<title>Step 3 - Simple Marker</title>
<style>
body {
height: 100vh;
margin: 0;
}
</style>
</head>
<body>
<script>
(g => { var h, a, k, p = "The Google Maps JavaScript API", c = "google", l = "importLibrary", q = "__ib__", m = document, b = window; b = b[c] || (b[c] = {}); var d = b.maps || (b.maps = {}), r = new Set, e = new URLSearchParams, u = () => h || (h = new Promise(async (f, n) => { await (a = m.createElement("script")); e.set("libraries", [...r] + ""); for (k in g) e.set(k.replace(/[A-Z]/g, t => "_" + t[0].toLowerCase()), g[k]); e.set("callback", c + ".maps." + q); a.src = `https://maps.${c}apis.com/maps/api/js?` + e; d[q] = f; a.onerror = () => h = n(Error(p + " could not load.")); a.nonce = m.querySelector("script[nonce]")?.nonce || ""; m.head.append(a) })); d[l] ? console.warn(p + " only loads once. Ignoring:", g) : d[l] = (f, ...n) => r.add(f) && u().then(() => d[l](f, ...n)) })({
key: "<INSERT API KEY>",
v: "alpha",
// Use the 'v' parameter to indicate the version to use (weekly, beta, alpha, etc.).
// Add other bootstrap parameters as needed, using camel case.
});
</script>
<script>
let map3D = null;
async function init() {
const { Map3DElement, MapMode, Marker3DElement } = await google.maps.importLibrary("maps3d");
map3D = new Map3DElement({
center: { lat: 46.717, lng: 7.075, altitude: 2175.130 },
range: 5814650,
tilt: 33,
heading: 4.36,
mode: MapMode.SATELLITE,
});
const marker = new Marker3DElement({
position: { lat: 51.5332, lng: -0.1260, altitude: 75 },
label: 'Google UK',
altitudeMode: 'ABSOLUTE',
extruded: true,
});
map3D.append(marker);
document.body.append(map3D);
}
init();
</script>
</body>
</html>
6. SVG 마커
이 단계에서는 마커를 변경하여 마커에 있는 국가를 나타내는 국기를 추가하여 마커를 더 멋지게 만듭니다. 이를 수행하는 방법을 알아보겠습니다. 이를 위해서는 PinElement를 알아야 합니다.
완료되면 다음과 같이 새로운 디자인이 표시됩니다.
PinElement를 사용한 기본 맞춤설정
2D 또는 3D 지도와 관계없이 JavaScript API의 마커 간에 공유되는 요소 중 하나는 PinElement입니다. Map3DElement에 Marker3DElement를 추가하는 동안 Marker3DElement에 PinElement를 해당 요소의 하위 요소로 추가합니다.
PinElement에는 기본 수준에서 일반 마커를 변경하여 테두리 색상, 내부 점 (또는 글리프) 색상, 배경 색상을 설정하는 기능이 포함되어 있습니다. 2D 마커를 보여주는 이미지에서 확인할 수 있습니다.
배율 값을 설정하여 요소를 통해 마커 크기를 설정할 수도 있습니다(1보다 크면 평소보다 크고 1보다 작으면 비율이 작음).
더 맞춤설정된 모양을 적용하면서도 표준 PinElement 지도 핀 모양을 유지하려면 글리프를 이미지 또는 SVG 파일로 대체할 수도 있습니다.
PinElements 외
이 단계에서는 svg 플래그와 다양한 색상으로 표준 PinElement
를 업데이트합니다. 하지만 마커의 모양을 완전히 변경하여 지도 핀처럼 보이지 않게 할 수도 있습니다. 마커 내에서 HTMLImageElement 및 SVGElement와 같은 템플릿을 사용하여 새 그래픽을 삽입할 수도 있습니다. Marker3DElement-Slots 문서에서 이에 관한 자세한 내용을 확인할 수 있습니다.
가능한 작업을 확인하려면 다양한 기법을 사용하여 마커의 스타일을 지정하는 예를 보여주는 다음 샘플을 살펴보세요.
PinElement를 통한 기본 맞춤설정이 적용된 마커는 샘플을 참고하세요. | SVG 및 이미지를 통해 템플릿을 통한 복잡한 맞춤설정이 적용된 마커는 샘플을 참고하세요. |
PinElement
추가
마커의 모양을 변경하려면 먼저 PinElement 라이브러리가 페이지에 추가되었는지 확인해야 합니다. maps3d
라이브러리를 가져온 후 다음 코드 줄을 추가하면 됩니다.
const { Map3DElement, MapMode, Marker3DElement } = await google.maps.importLibrary("maps3d");
const { PinElement } = await google.maps.importLibrary('marker');
이제 요소가 로드되었으므로 PinElement를 참조하고 만들 수 있습니다. 코드를 살펴보고 마커가 생성되는 위치 사이에 코드를 추가한 후 마커를 3D 지도에 추가합니다.
const marker = new Marker3DElement({
position: { lat: 51.5332, lng: -0.1260, altitude: 75 },
label: 'Google UK',
altitudeMode: 'ABSOLUTE',
extruded: true,
});
const base = document.location.href.substr(0, document.location.href.lastIndexOf("/"));
const markerPin = new PinElement({
"background": 'white',
"glyph": new URL(base + '/images/gb.svg'),
"scale": 1.0,
});
marker.append(markerPin);
map3D.append(marker);
기본 핀을 로드하는 것이 아니므로 PinElement를 설정하는 것 외에도 관련 배경 색상 및 크기와 함께 여러 작업을 실행해야 합니다.
먼저 국기 아이콘의 svg 이미지(이 경우 영국 국기)를 참조해야 합니다. https://flagicons.lipis.dev/와 같은 컬렉션에서 가져올 수 있습니다.
사이트에서 찾을 수 있는 위치에 아이콘을 배치할 수 있습니다. 이 경우 이미지의 위치를 하드코딩하거나 현재 사이트 위치를 디렉터리의 스텁으로 사용할 수 있습니다(여기서는 기본 변수로 표시). 그런 다음 서버의 올바른 위치에 있는 올바른 국기에 연결할 수 있습니다. 여기서는 '/images/gb.svg' 아래에 있습니다.
그러면 다음과 같이 PinElement가 생성됩니다.
따라서 플래그를 올바른 위치에 배치하고 코드를 올바른 위치에 배치하면 다음과 같은 3D 지도가 표시됩니다.
이제 마커가 모두 준비되었습니다. 클릭 가능하도록 변경하여 상호작용을 추가할 수도 있습니다. 다음 단계에서 이 작업을 수행합니다.
섹션 솔루션
이 단계에서는 구현을 확인하기 위한 솔루션으로 완성된 페이지가 제공됩니다. (복사하는 경우 자체 API 키를 사용해야 합니다.)
또한 플래그 svg (또는 원하는 png 파일) 파일을 가져와 페이지에서 찾을 수 있는 디렉터리에 저장해야 합니다 (여기서는 이미지 폴더에 저장됨).
<!DOCTYPE html>
<html>
<head>
<title>Step 4 - SVG Marker</title>
<style>
body {
height: 100vh;
margin: 0;
}
</style>
</head>
<body>
<script>
(g => { var h, a, k, p = "The Google Maps JavaScript API", c = "google", l = "importLibrary", q = "__ib__", m = document, b = window; b = b[c] || (b[c] = {}); var d = b.maps || (b.maps = {}), r = new Set, e = new URLSearchParams, u = () => h || (h = new Promise(async (f, n) => { await (a = m.createElement("script")); e.set("libraries", [...r] + ""); for (k in g) e.set(k.replace(/[A-Z]/g, t => "_" + t[0].toLowerCase()), g[k]); e.set("callback", c + ".maps." + q); a.src = `https://maps.${c}apis.com/maps/api/js?` + e; d[q] = f; a.onerror = () => h = n(Error(p + " could not load.")); a.nonce = m.querySelector("script[nonce]")?.nonce || ""; m.head.append(a) })); d[l] ? console.warn(p + " only loads once. Ignoring:", g) : d[l] = (f, ...n) => r.add(f) && u().then(() => d[l](f, ...n)) })({
key: "<INSERT API KEY>",
v: "alpha",
// Use the 'v' parameter to indicate the version to use (weekly, beta, alpha, etc.).
// Add other bootstrap parameters as needed, using camel case.
});
</script>
<script>
let map3D = null;
async function init() {
const { Map3DElement, MapMode, Marker3DElement } = await google.maps.importLibrary("maps3d");
const { PinElement } = await google.maps.importLibrary('marker');
map3D = new Map3DElement({
center: { lat: 46.717, lng: 7.075, altitude: 2175.130 },
range: 5814650,
tilt: 33,
heading: 4.36,
mode: MapMode.SATELLITE,
});
const marker = new Marker3DElement({
position: { lat: 51.5332, lng: -0.1260, altitude: 75 },
label: 'Google UK',
altitudeMode: 'ABSOLUTE',
extruded: true,
});
const base = document.location.href.substr(0, document.location.href.lastIndexOf("/"));
const markerPin = new PinElement({
"background": 'white',
"glyph": new URL(base + '/images/gb.svg'),
"scale": 1.0,
});
marker.append(markerPin);
map3D.append(marker);
document.body.append(map3D);
}
init();
</script>
</body>
</html>
7. 대화형 마커
이전 단계에서 페이지에 마커가 추가되었지만 보기 좋을 뿐 별다른 기능이 없으며 3D 지도와 동일한 방식으로 상호작용해야 합니다. 다음 단계는 마커를 클릭할 때 마커로 할 수 있는 작업을 추가하여 마커가 사용자 상호작용에 반응하도록 하는 것입니다.
이 기능을 추가하려면 Marker3DElement를 Marker3DInteractiveElement로 변환해야 합니다. 완료하면 비슷한 페이지가 표시되지만 이 페이지에서 마커를 클릭하면 알림이 표시되며 다음과 같이 표시됩니다.
먼저 마커 클래스를 변경합니다.
마커에 상호작용을 추가하려면 올바른 클래스를 사용하고 있는지 확인해야 합니다. 필요한 클래스는 Marker3DInteractiveElement이지만 Marker3DElement의 확장 프로그램이므로 새 클래스를 로드하고 생성자의 클래스 이름을 변경하는 것 외에는 아무것도 할 필요가 없습니다.
const { Map3DElement, MapMode, Marker3DInteractiveElement } = await google.maps.importLibrary("maps3d");
const { PinElement } = await google.maps.importLibrary('marker');
map3D = new Map3DElement({
center: { lat: 46.717, lng: 7.075, altitude: 2175.130 },
range: 5814650,
tilt: 33,
heading: 4.36,
mode: MapMode.SATELLITE,
});
const marker = new Marker3DInteractiveElement({
position: { lat: 51.5332, lng: -0.1260, altitude: 75 },
label: 'Google UK',
altitudeMode: 'ABSOLUTE',
extruded: true,
});
두 번째로 마커에 클릭 이벤트를 추가합니다.
그런 다음 마커에 클릭 이벤트를 추가하여 사용자 상호작용을 처리하고 응답합니다. 스니펫에서 클릭 이벤트가 마커에 추가된 것을 볼 수 있습니다. 이 경우 알림이 실행되고 실행된 이벤트의 타겟에서 가져온 마커의 라벨을 표시하는 텍스트가 팝업되어 라벨 속성에 액세스할 수 있습니다. 마커가 생성된 직후에 애플리케이션에 다음 코드를 추가합니다.
marker.addEventListener('gmp-click', (event) => {
alert('You clicked on : ' + event.target.label);
event.stopPropagation();
});
stopPropagation 이벤트는 스택의 다른 클릭 리스너가 3D 지도 기본 캔버스와 같은 기본 객체에서 실행되도록 하는 데 사용됩니다.
이제 애플리케이션을 실행하면 다음과 같은 결과가 표시됩니다.
마커를 클릭할 때 어떤 작업을 실행할 수 있는 기능이 있으므로 이제 다음 단계에서 페이지에 애니메이션을 추가할 수 있습니다.
섹션 솔루션
이 단계에서는 구현을 확인하기 위한 솔루션으로 완성된 페이지가 제공됩니다. (복사하는 경우 자체 API 키를 사용해야 합니다.)
<!DOCTYPE html>
<html>
<head>
<title>Step 5 - Interactive Marker</title>
<style>
body {
height: 100vh;
margin: 0;
}
</style>
</head>
<body>
<script>
(g => { var h, a, k, p = "The Google Maps JavaScript API", c = "google", l = "importLibrary", q = "__ib__", m = document, b = window; b = b[c] || (b[c] = {}); var d = b.maps || (b.maps = {}), r = new Set, e = new URLSearchParams, u = () => h || (h = new Promise(async (f, n) => { await (a = m.createElement("script")); e.set("libraries", [...r] + ""); for (k in g) e.set(k.replace(/[A-Z]/g, t => "_" + t[0].toLowerCase()), g[k]); e.set("callback", c + ".maps." + q); a.src = `https://maps.${c}apis.com/maps/api/js?` + e; d[q] = f; a.onerror = () => h = n(Error(p + " could not load.")); a.nonce = m.querySelector("script[nonce]")?.nonce || ""; m.head.append(a) })); d[l] ? console.warn(p + " only loads once. Ignoring:", g) : d[l] = (f, ...n) => r.add(f) && u().then(() => d[l](f, ...n)) })({
key: "<INSERT API KEY>",
v: "alpha",
// Use the 'v' parameter to indicate the version to use (weekly, beta, alpha, etc.).
// Add other bootstrap parameters as needed, using camel case.
});
</script>
<script>
let map3D = null;
async function init() {
const { Map3DElement, MapMode, Marker3DInteractiveElement } = await google.maps.importLibrary("maps3d");
const { PinElement } = await google.maps.importLibrary('marker');
map3D = new Map3DElement({
center: { lat: 46.717, lng: 7.075, altitude: 2175.130 },
range: 5814650,
tilt: 33,
heading: 4.36,
mode: MapMode.SATELLITE,
});
const marker = new Marker3DInteractiveElement({
position: { lat: 51.5332, lng: -0.1260, altitude: 75 },
label: 'Google UK',
altitudeMode: 'ABSOLUTE',
extruded: true,
});
marker.addEventListener('gmp-click', (event) => {
alert('You clicked on : ' + event.target.label);
event.stopPropagation();
});
const base = document.location.href.substr(0, document.location.href.lastIndexOf("/"));
const markerPin = new PinElement({
"background": 'white',
"glyph": new URL(base + '/images/gb.svg'),
"scale": 1.0,
});
marker.append(markerPin);
map3D.append(marker);
document.body.append(map3D);
}
init();
</script>
</body>
</html>
8. 빠른 이동
이 단계에서는 마커를 클릭하여 추가된 애니메이션을 사용하여 해당 위치로 이동하는 기능을 사용합니다. 여기에서 이를 실제로 확인할 수 있습니다.
flyCameraTo로 애니메이션 처리
페이지에 이를 추가하려면 3D 지도의 flyCameraTo 메서드를 사용합니다. 이 메서드에서는 현재 있는 카메라 위치와 확인하려는 카메라 위치 간에 카메라가 애니메이션 처리되며, 두 위치 간에 보간하고 3D 지도 내에서 비행을 애니메이션 처리합니다.
flyCameraTo를 사용할 때는 두 가지 속성(애니메이션이 끝날 때 카메라가 가리켜야 하는 위치인 endCamera 및 전환하는 데 걸리는 밀리초 단위의 시간인 durationMillis)이 있는 FlyToAnimationOptions를 지정해야 합니다.
이 예에서는 마커 위치인 건물을 바라보도록 카메라를 설정하고 기울기를 65도, 범위를 500m, 방향을 0도로 설정하여 북쪽을 향하게 합니다. 애니메이션 시간을 12500밀리초 (12.5초)로 설정합니다.
페이지의 현재 알림 이벤트를 flyCameraTo 스니펫으로 바꿉니다.
marker.addEventListener('gmp-click', (event) => {
map3D.flyCameraTo({
endCamera: {
center: marker.position,
tilt: 65,
range: 500,
heading: 0,
},
durationMillis: 12500,
});
event.stopPropagation();
});
이제 페이지를 새로고침하고 마커를 클릭하여 애니메이션과 같이 Google UK로 이동할 수 있습니다.
이 단계에서는 카메라를 마커의 위치로 이동하는 클릭 가능한 마커를 추가했습니다. 다음 단계에서는 위치를 공전하도록 지점 주위를 카메라를 비행하는 기능을 추가합니다.
섹션 솔루션
이 단계에서는 구현을 확인하기 위한 솔루션으로 완성된 페이지가 제공됩니다. (복사하는 경우 자체 API 키를 사용해야 합니다.)
<!DOCTYPE html>
<html>
<head>
<title>Step 6 - Zoom To</title>
<style>
body {
height: 100vh;
margin: 0;
}
</style>
</head>
<body>
<script>
(g => { var h, a, k, p = "The Google Maps JavaScript API", c = "google", l = "importLibrary", q = "__ib__", m = document, b = window; b = b[c] || (b[c] = {}); var d = b.maps || (b.maps = {}), r = new Set, e = new URLSearchParams, u = () => h || (h = new Promise(async (f, n) => { await (a = m.createElement("script")); e.set("libraries", [...r] + ""); for (k in g) e.set(k.replace(/[A-Z]/g, t => "_" + t[0].toLowerCase()), g[k]); e.set("callback", c + ".maps." + q); a.src = `https://maps.${c}apis.com/maps/api/js?` + e; d[q] = f; a.onerror = () => h = n(Error(p + " could not load.")); a.nonce = m.querySelector("script[nonce]")?.nonce || ""; m.head.append(a) })); d[l] ? console.warn(p + " only loads once. Ignoring:", g) : d[l] = (f, ...n) => r.add(f) && u().then(() => d[l](f, ...n)) })({
key: "<INSERT API KEY>",
v: "alpha",
// Use the 'v' parameter to indicate the version to use (weekly, beta, alpha, etc.).
// Add other bootstrap parameters as needed, using camel case.
});
</script>
<script>
let map3D = null;
async function init() {
const { Map3DElement, MapMode, Marker3DInteractiveElement } = await google.maps.importLibrary("maps3d");
const { PinElement } = await google.maps.importLibrary('marker');
map3D = new Map3DElement({
center: { lat: 46.717, lng: 7.075, altitude: 2175.130 },
range: 5814650,
tilt: 33,
heading: 4.36,
mode: MapMode.SATELLITE,
});
const marker = new Marker3DInteractiveElement({
position: { lat: 51.5332, lng: -0.1260, altitude: 75 },
label: 'Google UK',
altitudeMode: 'ABSOLUTE',
extruded: true,
});
marker.addEventListener('gmp-click', (event) => {
map3D.flyCameraTo({
endCamera: {
center: marker.position,
tilt: 65,
range: 500,
heading: 0,
},
durationMillis: 12500,
});
event.stopPropagation();
});
const base = document.location.href.substr(0, document.location.href.lastIndexOf("/"));
const markerPin = new PinElement({
"background": 'white',
"glyph": new URL(base + '/images/gb.svg'),
"scale": 1.0,
});
marker.append(markerPin);
map3D.append(marker);
document.body.append(map3D);
}
init();
</script>
</body>
</html>
9. 둘러보기
애니메이션의 마지막 요소는 flyCameraAround 메서드를 사용하여 건물 주위를 공전하는 애니메이션을 만드는 것입니다. 완료되면 애니메이션과 같이 건물로 날아가고 건물 주위를 날아다니는 애니메이션이 만들어집니다. 실제 예시로는 약간 빠르지만, 너무 길지 않게 작업이 작동하는 방식을 보여주는 데 유용합니다. 적절한 값을 얻을 때까지 타이밍을 조정해 보세요.
둘러보러 가자
flyCameraAround 메서드는 옵션을 입력으로 사용하여 공전할 위치, 카메라 매개변수, 공전하는 데 걸리는 밀리초 시간을 제어한다는 점에서 flyCameraTo 함수와 유사합니다. 마지막으로 지정된 시간에 발생할 수 있는 회전 수를 지정할 수도 있습니다. FlyAroundAnimationOptions에서 모든 옵션을 확인할 수 있습니다.
하지만 잠깐만요!
애니메이션에서 애니메이션이 위치로 이동한 다음 주변을 비행하면서 애니메이션을 연결하는 것을 볼 수 있습니다. 이렇게 하려면 3D 지도 gmp-animationend 이벤트를 사용하여 다음 애니메이션을 실행하기 전에 현재 애니메이션이 완료되었는지 확인합니다. 이 애니메이션은 중지되기 전에 한 번만 실행되어야 합니다.
코드를 살펴본 후 이전 섹션에 추가한 코드 뒤에 삽입합니다.
marker.addEventListener('gmp-click', (event) => {
map3D.flyCameraTo({
endCamera: {
center: marker.position,
tilt: 65,
range: 500,
heading: 0,
},
durationMillis: 5000,
});
map3D.addEventListener('gmp-animationend', () => {
map3D.flyCameraAround({
camera: {
center: marker.position,
tilt: 65,
range: 500,
heading: 0,
},
durationMillis: 5000,
rounds: 1
});
}, { once: true });
event.stopPropagation();
});
gmp-animationend 이벤트를 수신 대기하는 기능을 추가하면 flyCameraAround 이벤트를 호출할 수 있습니다. 시작점을 플라이 투 메서드의 끝 카메라에 사용된 것과 동일하게 설정하면 새로운 위치로 이동할 때 불편한 움직임이 없도록 원활하게 전환됩니다. 다시 durationMillis가 애니메이션을 실행하는 데 걸리는 시간을 제어하도록 설정됩니다. 이 경우 메서드는 다른 옵션인 rounds
도 사용하며, 이 옵션은 1로 설정됩니다.
즉, 카메라가 5초에 한 번 지점을 중심으로 회전합니다. 이러한 값을 실험하여 적합한 값을 찾을 수 있습니다.
이 시점에서 애니메이션이 종료되지만 이 코드로 인해 gmp-animationend 이벤트가 다시 실행되어 궤도가 무한히 반복되는 것을 원하지 않습니다. 이를 방지하려면 리스너에 once를 true로 설정하는 옵션을 제공합니다. 즉, 이벤트가 완료되면 삭제되므로 무한 루프가 방지됩니다.
이렇게 추가하면 솔루션을 실행할 수 있으며 애니메이션이 끝에서 마커 주위를 날아다니는 것을 볼 수 있습니다(애니메이션 참고).
이 단계에서는 클릭할 수 있는 마커를 추가했습니다. 그러면 카메라가 마커 위치로 이동하고 그 주변을 날아다닙니다. 다음 단계에서는 점들을 더 추가하고 점 간에 이동할 수 있도록 허용합니다.
섹션 솔루션
이 단계에서는 구현을 확인하기 위한 솔루션으로 완성된 페이지가 제공됩니다. (복사하는 경우 자체 API 키를 사용해야 합니다.)
<!DOCTYPE html>
<html>
<head>
<title>Step 7 - Zoom Around</title>
<style>
body {
height: 100vh;
margin: 0;
}
</style>
</head>
<body>
<script>
(g => { var h, a, k, p = "The Google Maps JavaScript API", c = "google", l = "importLibrary", q = "__ib__", m = document, b = window; b = b[c] || (b[c] = {}); var d = b.maps || (b.maps = {}), r = new Set, e = new URLSearchParams, u = () => h || (h = new Promise(async (f, n) => { await (a = m.createElement("script")); e.set("libraries", [...r] + ""); for (k in g) e.set(k.replace(/[A-Z]/g, t => "_" + t[0].toLowerCase()), g[k]); e.set("callback", c + ".maps." + q); a.src = `https://maps.${c}apis.com/maps/api/js?` + e; d[q] = f; a.onerror = () => h = n(Error(p + " could not load.")); a.nonce = m.querySelector("script[nonce]")?.nonce || ""; m.head.append(a) })); d[l] ? console.warn(p + " only loads once. Ignoring:", g) : d[l] = (f, ...n) => r.add(f) && u().then(() => d[l](f, ...n)) })({
key: "<INSERT API KEY>",
v: "alpha",
// Use the 'v' parameter to indicate the version to use (weekly, beta, alpha, etc.).
// Add other bootstrap parameters as needed, using camel case.
});
</script>
<script>
let map3D = null;
const europeCamera = {
center: { lat: 46.717, lng: 7.075, altitude: 2175.130 },
range: 5814650,
tilt: 33,
heading: 4.36,
};
async function init() {
const { Map3DElement, MapMode, Marker3DInteractiveElement } = await google.maps.importLibrary("maps3d");
const { PinElement } = await google.maps.importLibrary('marker');
map3D = new Map3DElement({
...europeCamera,
mode: MapMode.SATELLITE,
});
const marker = new Marker3DInteractiveElement({
position: { lat: 51.5332, lng: -0.1260, altitude: 75 },
label: 'Google UK',
altitudeMode: 'ABSOLUTE',
extruded: true,
});
marker.addEventListener('gmp-click', (event) => {
map3D.flyCameraTo({
endCamera: {
center: marker.position,
tilt: 65,
range: 500,
heading: 0,
},
durationMillis: 5000,
});
map3D.addEventListener('gmp-animationend', () => {
map3D.flyCameraAround({
camera: {
center: marker.position,
tilt: 65,
range: 500,
heading: 0,
},
durationMillis: 5000,
rounds: 1
});
}, { once: true });
event.stopPropagation();
});
const base = document.location.href.substr(0, document.location.href.lastIndexOf("/"));
const markerPin = new PinElement({
"background": 'white',
"glyph": new URL(base + '/images/gb.svg'),
"scale": 1.0,
});
marker.append(markerPin);
map3D.append(marker);
document.body.append(map3D);
}
init();
</script>
</body>
</html>
10. 파리!
런던은 멋진 도시이지만 페이지에 런던만 있으면 조금 외로워 보이므로 파리부터 시작해 새로운 위치를 추가해 보겠습니다. 이를 위해 배열을 사용하여 모든 위치 관련 세부정보를 보관한 다음 이를 마커 표시 매개변수와 카메라 위치로 이동 및 주변을 이동하는 기능과 변수의 입력으로 사용할 수 있습니다. 예를 들어 건물의 더 나은 카메라 샷을 찍기 위해 마커 포인트 위치와 다를 수 있습니다.
위치 배열
보기 카메라 , 마커 지점, 표시 옵션과 같이 특정 위치에 관한 모든 세부정보를 하드코딩하지 않아도 되도록 소수의 JSON 객체 배열을 사용하여 이 데이터를 보관할 수 있습니다. 그런 다음 애플리케이션에서 마커가 생성되고 사용될 때 이를 적용할 수 있습니다. 다음 코드 스니펫에서 배열을 보관할 officeLocations
라는 변수를 만드는 예를 확인할 수 있습니다.
init 함수 바로 앞에 다음 코드를 추가합니다. 또한 모든 오피스 위치에 적용할 수 있도록 base 변수가 init 함수 외부로 이동되었습니다.
const base = document.location.href.substr(0, document.location.href.lastIndexOf("/"));
const europeCamera = {
center: { lat: 46.717, lng: 7.075, altitude: 2175.130 },
range: 5814650,
tilt: 33,
heading: 4.36,
};
const officeLocations = [
{
"name": "Google France",
"camera": {
"center": { lat: 48.877276, lng: 2.329978, altitude: 48 },
"range": 178,
"tilt": 57.48,
"heading": -17,
},
"point": { lat: 48.8775183, lng: 2.3299791, altitude: 60 },
"pin": {
"background": 'white',
"glyph": new URL(base + '/images/fr.svg'),
"scale": 1.0,
},
},
{
"name": "Google UK",
"camera": {
"center": { lat: 51.5332, lng: -0.1260, altitude: 38.8 },
"range": 500,
"tilt": 56.21672368296945,
"heading": -31.15763027564165,
},
"point": { lat: 51.5332, lng: -0.1260, altitude: 75 },
"pin": {
"background": 'white',
"glyph": new URL(base + '/images/gb.svg'),
"scale": 1.0,
},
}]
const base = document.location.href.substr(0, document.location.href.lastIndexOf("/"));
각 오피스 위치에는 다음과 같은 속성이 있습니다.
- 이름 : 위치의 이름입니다.
- camera : 이동 및 둘러볼 위치를 확인하는 초기 뷰입니다.
- point : 마커를 배치할 위치입니다.
- pin : 마커 핀 색상 및 글리프 속성의 세부정보
다른 각도
여기서 영국의 경우 카메라 중심과 마커 지점이 고도를 제외하고 동일한 반면 프랑스의 경우 카메라와 지점이 다릅니다. 프랑스의 위치의 경우 마커가 초기 카메라 뷰와 다른 위치에 있어야 하기 때문입니다. 이렇게 하면 마커 지점을 사용할 때보다 건물 전체를 더 잘 볼 수 있습니다.
유럽으로 돌아가기
점의 수가 많을 때의 한 가지 기능은 점 간에 이동할 수 있어야 한다는 요구사항이 추가된다는 것입니다. 드롭다운을 사용하여 선택할 수 있지만 이 예에서는 사용자가 다른 위치를 선택할 수 있도록 카메라가 매번 유럽 뷰로 다시 돌아갑니다.
이렇게 하려면 카메라를 유럽 전체 뷰로 재설정하는 데 사용할 수 있는 변수에 초기 뷰를 저장해야 합니다. 이 예에서는 나중에 사용할 수 있도록 저장할 europeCamera
라는 새 변수를 추가합니다.
init 함수 업데이트
먼저 Map3DElement
를 만들 때 europeCamera
객체를 입력으로 사용해야 합니다.
두 번째로 수정해야 할 사항은 마커 생성 섹션을 루프로 래핑하여 변수에 저장된 매개변수로 업데이트하는 것입니다. 이는 표시된 코드에서 확인할 수 있습니다.
- office.point : 마커 위치입니다.
- office.name : 마커 라벨에 사용되는 지점 이름입니다.
- office.camera : 초기 카메라 위치입니다.
- office.pin : 표시 차이에 관한 PinElement 옵션
프랑스 국기의 SVG 파일이나 이미지도 가져와야 합니다.
async function init() {
const { Map3DElement, MapMode, Marker3DInteractiveElement } = await google.maps.importLibrary("maps3d");
const { PinElement } = await google.maps.importLibrary('marker');
map3D = new Map3DElement({
...europeCamera,
mode: MapMode.SATELLITE,
});
officeLocations.forEach(office => {
const marker = new Marker3DInteractiveElement({
position: office.point,
label: office.name,
altitudeMode: 'ABSOLUTE',
extruded: true,
});
marker.addEventListener('gmp-click', (event) => {
map3D.flyCameraTo({
endCamera: office.camera,
durationMillis: 5000,
});
map3D.addEventListener('gmp-animationend', () => {
map3D.flyCameraAround({
camera: office.camera,
durationMillis: 5000,
rounds: 1
});
map3D.addEventListener('gmp-animationend', () => {
map3D.flyCameraTo({
endCamera: europeCamera,
durationMillis: 5000,
});
}, { once: true });
}, { once: true });
event.stopPropagation();
});
const markerPin = new PinElement(office.pin);
marker.append(markerPin);
map3D.append(marker);
});
document.body.append(map3D);
}
저장된 europeCamera
변수를 사용하여 유럽 뷰로 다시 이동하는 플라이백을 처리하기 위해 flyCameraAround
애니메이션 뒤에 두 번째 gmp-animationend 함수가 추가됩니다. 애니메이션에서 볼 수 있듯이
이 단계에서 애플리케이션은 두 위치와 애니메이션 및 위치 배열을 사용하여 두 위치 간에 이동하는 기능을 갖도록 확장되었습니다. 다음 단계에서는 나머지 오피스 위치가 배열에 추가됩니다.
섹션 솔루션
이 단계에서는 구현을 확인하기 위한 솔루션으로 완성된 페이지가 제공됩니다. (복사하는 경우 자체 API 키를 사용해야 합니다.)
또한 국기 svg (또는 원하는 png 파일) 파일을 가져와 페이지에서 찾을 수 있는 디렉터리에 저장해야 합니다 (여기서는 이미지 폴더에 저장됨).
<!DOCTYPE html>
<html>
<head>
<title>Step 8 - Paris!</title>
<style>
body {
height: 100vh;
margin: 0;
}
</style>
</head>
<body>
<script>
(g => { var h, a, k, p = "The Google Maps JavaScript API", c = "google", l = "importLibrary", q = "__ib__", m = document, b = window; b = b[c] || (b[c] = {}); var d = b.maps || (b.maps = {}), r = new Set, e = new URLSearchParams, u = () => h || (h = new Promise(async (f, n) => { await (a = m.createElement("script")); e.set("libraries", [...r] + ""); for (k in g) e.set(k.replace(/[A-Z]/g, t => "_" + t[0].toLowerCase()), g[k]); e.set("callback", c + ".maps." + q); a.src = `https://maps.${c}apis.com/maps/api/js?` + e; d[q] = f; a.onerror = () => h = n(Error(p + " could not load.")); a.nonce = m.querySelector("script[nonce]")?.nonce || ""; m.head.append(a) })); d[l] ? console.warn(p + " only loads once. Ignoring:", g) : d[l] = (f, ...n) => r.add(f) && u().then(() => d[l](f, ...n)) })({
key: "<INSERT API KEY>",
v: "alpha",
// Use the 'v' parameter to indicate the version to use (weekly, beta, alpha, etc.).
// Add other bootstrap parameters as needed, using camel case.
});
</script>
<script>
let map3D = null;
const base = document.location.href.substr(0, document.location.href.lastIndexOf("/"));
const europeCamera = {
center: { lat: 46.717, lng: 7.075, altitude: 2175.130 },
range: 5814650,
tilt: 33,
heading: 4.36,
};
const officeLocations = [
{
"name": "Google France",
"camera": {
"center": { lat: 48.877276, lng: 2.329978, altitude: 48 },
"range": 178,
"tilt": 57.48,
"heading": -17,
},
"point": { lat: 48.8775183, lng: 2.3299791, altitude: 60 },
"pin": {
"background": 'white',
"glyph": new URL(base + '/images/fr.svg'),
"scale": 1.0,
},
},
{
"name": "Google UK",
"camera": {
"center": { lat: 51.5332, lng: -0.1260, altitude: 38.8 },
"range": 500,
"tilt": 56.21672368296945,
"heading": -31.15763027564165,
},
"point": { lat: 51.5332, lng: -0.1260, altitude: 75 },
"pin": {
"background": 'white',
"glyph": new URL(base + '/images/gb.svg'),
"scale": 1.0,
},
}]
async function init() {
const { Map3DElement, MapMode, Marker3DInteractiveElement } = await google.maps.importLibrary("maps3d");
const { PinElement } = await google.maps.importLibrary('marker');
map3D = new Map3DElement({
...europeCamera,
mode: MapMode.SATELLITE,
});
officeLocations.forEach(office => {
const marker = new Marker3DInteractiveElement({
position: office.point,
label: office.name,
altitudeMode: 'ABSOLUTE',
extruded: true,
});
marker.addEventListener('gmp-click', (event) => {
map3D.flyCameraTo({
endCamera: office.camera,
durationMillis: 5000,
});
map3D.addEventListener('gmp-animationend', () => {
map3D.flyCameraAround({
camera: office.camera,
durationMillis: 5000,
rounds: 1
});
map3D.addEventListener('gmp-animationend', () => {
map3D.flyCameraTo({
endCamera: europeCamera,
durationMillis: 5000,
});
}, { once: true });
}, { once: true });
event.stopPropagation();
});
const markerPin = new PinElement(office.pin);
marker.append(markerPin);
map3D.append(marker);
});
document.body.append(map3D);
}
init();
</script>
</body>
</html>
11. 장소 더보기
이제 애플리케이션에 필요한 모든 기능이 있지만 3D 지도에 아직 약간 빈 공간이 있으므로 위치를 몇 개 더 추가하여 지도에 약간 더 많은 내용을 표시해 보겠습니다. 배열을 사용하면 고유한 마커가 있는 새 위치를 계속 채울 수 있습니다. 마지막 단계는 다음과 같은 보기가 표시될 때까지 마커를 계속 추가하는 것입니다.
마커를 추가합니다.
Google은 유럽의 여러 국가에 사무실을 운영하고 있습니다. 그중 몇 곳을 지도에 추가해 보겠습니다. 배열을 업데이트하기만 하면 됩니다. 웹 서비스에서 가져오거나 어딘가의 정적 파일에서 제공할 수 있습니다. 단순성을 위해 이 경우에는 동일한 페이지에 유지됩니다.
마커는 원하는 만큼 추가할 수 있으며 페이지에서 이를 선택한 후 뷰에 자동으로 추가됩니다. 올바른 플래그를 가져와 이미지 디렉터리 (또는 편리한 위치)에 저장해야 합니다.
const officeLocations = [
{
name: "Google France",
camera: {
center: { lat: 48.877276, lng: 2.329978, altitude: 48 },
range: 178,
tilt: 57.48,
heading: -17,
},
point: { lat: 48.8775183, lng: 2.3299791, altitude: 60 },
pin: {
background: 'white',
glyph: new URL(base + '/images/fr.svg'),
scale: 1.0,
},
},
{
name: "Google UK",
camera: {
center: { lat: 51.5332, lng: -0.1260, altitude: 38.8 },
range: 500,
tilt: 56.21672368296945,
heading: -31.15763027564165,
},
point: { lat: 51.5332, lng: -0.1260, altitude: 75 },
pin: {
background: 'white',
glyph: new URL(base + '/images/gb.svg'),
scale: 1.0,
},
},
{
name: "Google Belgium",
camera: {
center: { lat: 50.83930408436509, lng: 4.38052394507952, altitude: 64.38932203802196},
range: 466.62899893119175,
tilt: 43.61569474716178,
heading: 51.805907046332074,
},
point: { lat: 50.8392653, lng: 4.3808751, altitude: 25 },
pin: {
background: 'white',
glyph: new URL(base + '/images/be.svg'),
scale: 1.0,
},
},
{
name: "Google Czechia",
camera: {
center: {
lat: 50.07004093853976,
lng: 14.402871475443956,
altitude: 223.39574818495532
},
range: 522.0365799222782,
tilt: 62.39511972890614,
heading: -39.150149539328304,
},
point: { lat: 50.0703122, lng: 14.402668199999999, altitude: 50 },
pin: {
background: 'white',
glyph: new URL(base + '/images/cz.svg'),
scale: 1.0,
},
},
{
name: "Google Denmark",
details: "2, Sankt Petri Passage 5, 1165 København",
camera: {
center: {
lat: 55.680359539635866,
lng: 12.570460204526002,
altitude: 30.447654757346044
},
range: 334.8786935049066,
tilt: 55.38819319004654,
heading: 149.63867461295067,
},
point: { lat: 55.6804504, lng: 12.570279099999999, altitude: 25 },
pin: {
background: 'white',
glyph: new URL(base + '/images/dk.svg'),
scale: 1.0,
},
},
,
{
name: "Google Greece",
camera: {
center: {
lat: 38.038634694028055,
lng: 23.802924946201266,
altitude: 196.45884670344995
},
range: 343.57226336076565,
tilt: 54.97375927639567,
heading: -33.26775344055724,
},
point: { lat: 38.038619, lng: 23.8031622, altitude: 25 },
pin: {
background: 'white',
glyph: new URL(base + '/images/gr.svg'),
scale: 1.0,
},
},
{
name: "Google Germany",
camera: {
center: {
lat: 53.55397683312404,
lng: 9.986350507286808,
altitude: 44.83610870143956
},
range: 375.3474077822466,
tilt: 71.35078443829818,
heading: -160.76930098951416,
},
point: { lat: 53.5540227, lng: 9.9863, altitude: 50 },
pin: {
background: 'white',
glyph: new URL(base + '/images/de.svg'),
scale: 1.0,
},
},
{
name: "Google Ireland",
camera: {
center: { lat: 53.339816899999995, lng: -6.2362644, altitude: 38.777415761228006 },
range: 500,
tilt: 56.21672368296945,
heading: -31.15763027564165,
},
point: { lat: 53.339816899999995, lng: -6.2362644, altitude: 50 },
pin: {
background: 'white',
glyph: new URL(base + '/images/ie.svg'),
scale: 1.0,
},
},
{
name: "Google Italy",
camera: {
center: {
lat: 45.486361346538224,
lng: 9.18995496294455,
altitude: 138.55834058400072
},
range: 694.9398023590038,
tilt: 57.822470255679114,
heading: 84.10194883488619,
},
point: { lat: 45.4863064, lng: 9.1894762, altitude: 50 },
pin: {
background: 'white',
glyph: new URL(base + '/images/it.svg'),
scale: 1.0,
},
},
{
name: "Google Lithuania",
camera: {
center: {
lat: 54.698040606567965,
lng: 25.30965338542576,
altitude: 111.80276944294413
},
range: 412.5808304977545,
tilt: 43.50793332082195,
heading: -29.181098269421028,
},
point: { lat: 54.6981204, lng: 25.3098617, altitude: 25 },
pin: {
background: 'white',
glyph: new URL(base + '/images/at.svg'),
scale: 1.0,
},
},
{
name: "Google Netherlands",
camera: {
center: {
lat: 52.33773837150874,
lng: 4.871754560171063,
altitude: 53.68063996154723
},
range: 473.1982259177312,
tilt: 56.216523350388634,
heading: 71.78252318033718,
},
point: { lat: 52.337801, lng: 4.872065999999999, altitude: 100 },
pin: {
background: 'white',
glyph: new URL(base + '/images/nl.svg'),
scale: 1.0,
},
},
{
name: "Google Norway",
camera: {
center: { lat: 59.90991209999999, lng: 10.726020799999999, altitude: 38.777415761228006 },
range: 500,
tilt: 56.21672368296945,
heading: -31.15763027564165,
},
point: { lat: 59.90991209999999, lng: 10.726020799999999, altitude: 25 },
pin: {
background: 'white',
glyph: new URL(base + '/images/no.svg'),
scale: 1.0,
},
},
{
name: "Google Poland",
camera: {
center: { lat: 52.22844380000001, lng: 20.9851819, altitude: 38.777415761228006 },
range: 500,
tilt: 56.21672368296945,
heading: -31.15763027564165,
},
point: { lat: 52.22844380000001, lng: 20.9851819, altitude: 25 },
pin: {
background: 'white',
glyph: new URL(base + '/images/pl.svg'),
scale: 1.0,
},
},
{
name: "Google Portugal",
camera: {
center: {
lat: 38.7240122810727,
lng: -9.150628263172639,
altitude: 55.299662291551044
},
range: 337.7474313328639,
tilt: 56.79772652682846,
heading: 176.0722118222208,
},
point: { lat: 38.723915999999996, lng: -9.150629, altitude: 35 },
pin: {
background: 'white',
glyph: new URL(base + '/images/pt.svg'),
scale: 1.0,
},
},
{
name: "Google Romania",
camera: {
center: {
lat: 44.43076650172983,
lng: 26.109700164718586,
altitude: 125.57895810814505
},
range: 364.25249956711923,
tilt: 38.517539223834326,
heading: -38.81294924429363,
},
point: { lat: 44.4309897, lng: 26.1095719, altitude: 75 },
pin: {
background: 'white',
glyph: new URL(base + '/images/ro.svg'),
scale: 1.0,
},
},
{
name: "Google Spain",
camera: {
center: {
lat: 40.450078762608875,
lng: -3.6930085080020856,
altitude: 753.6446342341894
},
range: 845.7279793010093,
tilt: 46.752510050599746,
heading: 4.718779524265234,
},
point: { lat: 40.450294199999995, lng: -3.6927915, altitude: 175 },
pin: {
background: 'white',
glyph: new URL(base + '/images/es.svg'),
scale: 1.0,
},
},
{
name: "Google Sweden",
camera: {
center: {
lat: 59.33313751316038,
lng: 18.054618219238293,
altitude: 16.728213706832868
},
range: 377.5210725830039,
tilt: 63.59478230626709,
heading: 98.53138488367703,
},
point: { lat: 59.3332093, lng: 18.0536386, altitude: 50 },
pin: {
background: 'white',
glyph: new URL(base + '/images/se.svg'),
scale: 1.0,
},
},
{
name: "Google Switzerland",
camera: {
center: {
lat: 47.365411056285275,
lng: 8.525063594405356,
altitude: 419.2348376754488
},
range: 166.74918737631742,
tilt: 59.31431457129067,
heading: -32.620415961949206,
},
point: { lat: 47.365452, lng: 8.5249253, altitude: 100 },
pin: {
background: 'white',
glyph: new URL(base + '/images/ch.svg'),
scale: 1.0,
},
}
]
완료하면 그림과 같이 사용자가 원하는 위치를 클릭하고 해당 위치로 이동한 후 다시 나올 수 있는 완성된 페이지가 표시됩니다.
Codelab을 완료하셨습니다. 축하합니다. 다음 섹션에서 마무리하고 다른 새로운 작업을 찾아보세요.
섹션 솔루션
이 단계에서는 구현을 확인하기 위한 솔루션으로 완성된 페이지가 제공됩니다. (복사하는 경우 자체 API 키를 사용해야 합니다.)
또한 국기 svg (또는 원하는 png 파일) 파일을 가져와 페이지에서 찾을 수 있는 디렉터리에 저장해야 합니다 (여기서는 이미지 폴더에 저장됨).
<!DOCTYPE html>
<html>
<head>
<title>Step 9 - More Places!</title>
<style>
body {
height: 100vh;
margin: 0;
}
</style>
</head>
<body>
<script>
(g => { var h, a, k, p = "The Google Maps JavaScript API", c = "google", l = "importLibrary", q = "__ib__", m = document, b = window; b = b[c] || (b[c] = {}); var d = b.maps || (b.maps = {}), r = new Set, e = new URLSearchParams, u = () => h || (h = new Promise(async (f, n) => { await (a = m.createElement("script")); e.set("libraries", [...r] + ""); for (k in g) e.set(k.replace(/[A-Z]/g, t => "_" + t[0].toLowerCase()), g[k]); e.set("callback", c + ".maps." + q); a.src = `https://maps.${c}apis.com/maps/api/js?` + e; d[q] = f; a.onerror = () => h = n(Error(p + " could not load.")); a.nonce = m.querySelector("script[nonce]")?.nonce || ""; m.head.append(a) })); d[l] ? console.warn(p + " only loads once. Ignoring:", g) : d[l] = (f, ...n) => r.add(f) && u().then(() => d[l](f, ...n)) })({
key: "<INSERT API KEY>",
v: "alpha",
// Use the 'v' parameter to indicate the version to use (weekly, beta, alpha, etc.).
// Add other bootstrap parameters as needed, using camel case.
});
</script>
<script>
let map3D = null;
const base = document.location.href.substr(0, document.location.href.lastIndexOf("/"));
const europeCamera = {
center: { lat: 46.717, lng: 7.075, altitude: 2175.130 },
range: 5814650,
tilt: 33,
heading: 4.36,
};
const officeLocations = [
{
name: "Google France",
details: "8 Rue de Londres, 75009 Paris, France",
camera: {
center: { lat: 48.877276, lng: 2.329978, altitude: 48 },
range: 178,
tilt: 57.48,
heading: -17,
},
point: { lat: 48.8775183, lng: 2.3299791, altitude: 60 },
pin: {
background: 'white',
glyph: new URL(base + '/images/fr.svg'),
scale: 1.0,
},
},
{
name: "Google UK",
details: "6 Pancras Square, London N1C 4AG, UK",
camera: {
center: { lat: 51.5332, lng: -0.1260, altitude: 38.8 },
range: 500,
tilt: 56.21672368296945,
heading: -31.15763027564165,
},
point: { lat: 51.5332, lng: -0.1260, altitude: 75 },
pin: {
background: 'white',
glyph: new URL(base + '/images/gb.svg'),
scale: 1.0,
},
},
{
name: "Google Belgium",
details: "Chau. d'Etterbeek 180, 1040 Brussel",
camera: {
center: { lat: 50.83930408436509, lng: 4.38052394507952, altitude: 64.38932203802196},
range: 466.62899893119175,
tilt: 43.61569474716178,
heading: 51.805907046332074,
},
point: { lat: 50.8392653, lng: 4.3808751, altitude: 25 },
pin: {
background: 'white',
glyph: new URL(base + '/images/be.svg'),
scale: 1.0,
},
},
{
name: "Google Czechia",
details: "Stroupežnického 3191/17, 150 00 Praha 5-Smíchov",
camera: {
center: {
lat: 50.07004093853976,
lng: 14.402871475443956,
altitude: 223.39574818495532
},
range: 522.0365799222782,
tilt: 62.39511972890614,
heading: -39.150149539328304,
},
point: { lat: 50.0703122, lng: 14.402668199999999, altitude: 50 },
pin: {
background: 'white',
glyph: new URL(base + '/images/cz.svg'),
scale: 1.0,
},
},
{
name: "Google Denmark",
details: "2, Sankt Petri Passage 5, 1165 København",
camera: {
center: {
lat: 55.680359539635866,
lng: 12.570460204526002,
altitude: 30.447654757346044
},
range: 334.8786935049066,
tilt: 55.38819319004654,
heading: 149.63867461295067,
},
point: { lat: 55.6804504, lng: 12.570279099999999, altitude: 25 },
pin: {
background: 'white',
glyph: new URL(base + '/images/dk.svg'),
scale: 1.0,
},
},
,
{
name: "Google Greece",
details: "Fragkokklisias 6, Athina 151 25",
camera: {
center: {
lat: 38.038634694028055,
lng: 23.802924946201266,
altitude: 196.45884670344995
},
range: 343.57226336076565,
tilt: 54.97375927639567,
heading: -33.26775344055724,
},
point: { lat: 38.038619, lng: 23.8031622, altitude: 25 },
pin: {
background: 'white',
glyph: new URL(base + '/images/gr.svg'),
scale: 1.0,
},
},
{
name: "Google Germany",
details: "ABC-Straße 19, 20354 Hamburg",
camera: {
center: {
lat: 53.55397683312404,
lng: 9.986350507286808,
altitude: 44.83610870143956
},
range: 375.3474077822466,
tilt: 71.35078443829818,
heading: -160.76930098951416,
},
point: { lat: 53.5540227, lng: 9.9863, altitude: 50 },
pin: {
background: 'white',
glyph: new URL(base + '/images/de.svg'),
scale: 1.0,
},
},
{
name: "Google Ireland",
details: "Gordon House, 4 Barrow St, Grand Canal Dock, Dublin 4, D04 V4X7",
camera: {
center: { lat: 53.339816899999995, lng: -6.2362644, altitude: 38.777415761228006 },
range: 500,
tilt: 56.21672368296945,
heading: -31.15763027564165,
},
point: { lat: 53.339816899999995, lng: -6.2362644, altitude: 50 },
pin: {
background: 'white',
glyph: new URL(base + '/images/ie.svg'),
scale: 1.0,
},
},
{
name: "Google Italy",
details: "Isola Building C, Via Federico Confalonieri, 4, 20124 Milano",
camera: {
center: {
lat: 45.486361346538224,
lng: 9.18995496294455,
altitude: 138.55834058400072
},
range: 694.9398023590038,
tilt: 57.822470255679114,
heading: 84.10194883488619,
},
point: { lat: 45.4863064, lng: 9.1894762, altitude: 50 },
pin: {
background: 'white',
glyph: new URL(base + '/images/it.svg'),
scale: 1.0,
},
},
{
name: "Google Lithuania",
details: "Vilnius Tech Park, Antakalnis st. 17, 2nd building, LT-10312, Vilnius",
camera: {
center: {
lat: 54.698040606567965,
lng: 25.30965338542576,
altitude: 111.80276944294413
},
range: 412.5808304977545,
tilt: 43.50793332082195,
heading: -29.181098269421028,
},
point: { lat: 54.6981204, lng: 25.3098617, altitude: 25 },
pin: {
background: 'white',
glyph: new URL(base + '/images/at.svg'),
scale: 1.0,
},
},
{
name: "Google Netherlands",
details: "Claude Debussylaan 34, 1082 MD Amsterdam",
camera: {
center: {
lat: 52.33773837150874,
lng: 4.871754560171063,
altitude: 53.68063996154723
},
range: 473.1982259177312,
tilt: 56.216523350388634,
heading: 71.78252318033718,
},
point: { lat: 52.337801, lng: 4.872065999999999, altitude: 100 },
pin: {
background: 'white',
glyph: new URL(base + '/images/nl.svg'),
scale: 1.0,
},
},
{
name: "Google Norway",
details: "Bryggegata 6, 0250 Oslo",
camera: {
center: { lat: 59.90991209999999, lng: 10.726020799999999, altitude: 38.777415761228006 },
range: 500,
tilt: 56.21672368296945,
heading: -31.15763027564165,
},
point: { lat: 59.90991209999999, lng: 10.726020799999999, altitude: 25 },
pin: {
background: 'white',
glyph: new URL(base + '/images/no.svg'),
scale: 1.0,
},
},
{
name: "Google Poland",
details: "Rondo Daszynskiego 2, 00-843 Warsaw",
camera: {
center: { lat: 52.22844380000001, lng: 20.9851819, altitude: 38.777415761228006 },
range: 500,
tilt: 56.21672368296945,
heading: -31.15763027564165,
},
point: { lat: 52.22844380000001, lng: 20.9851819, altitude: 25 },
pin: {
background: 'white',
glyph: new URL(base + '/images/pl.svg'),
scale: 1.0,
},
},
{
name: "Google Portugal",
details: "R. Duque de Palmela 37 Piso 4, 1250-097 Lisboa",
camera: {
center: {
lat: 38.7240122810727,
lng: -9.150628263172639,
altitude: 55.299662291551044
},
range: 337.7474313328639,
tilt: 56.79772652682846,
heading: 176.0722118222208,
},
point: { lat: 38.723915999999996, lng: -9.150629, altitude: 35 },
pin: {
background: 'white',
glyph: new URL(base + '/images/pt.svg'),
scale: 1.0,
},
},
{
name: "Google Romania",
details: "Bulevardul Corneliu Coposu 6-8, București 030167",
camera: {
center: {
lat: 44.43076650172983,
lng: 26.109700164718586,
altitude: 125.57895810814505
},
range: 364.25249956711923,
tilt: 38.517539223834326,
heading: -38.81294924429363,
},
point: { lat: 44.4309897, lng: 26.1095719, altitude: 75 },
pin: {
background: 'white',
glyph: new URL(base + '/images/ro.svg'),
scale: 1.0,
},
},
{
name: "Google Spain",
details: "Torre Picasso, Pl. Pablo Ruiz Picasso, 1, Tetuán, 28020 Madrid",
camera: {
center: {
lat: 40.450078762608875,
lng: -3.6930085080020856,
altitude: 753.6446342341894
},
range: 845.7279793010093,
tilt: 46.752510050599746,
heading: 4.718779524265234,
},
point: { lat: 40.450294199999995, lng: -3.6927915, altitude: 175 },
pin: {
background: 'white',
glyph: new URL(base + '/images/es.svg'),
scale: 1.0,
},
},
{
name: "Google Sweden",
details: "Kungsbron 2, 111 22 Stockholm",
camera: {
center: {
lat: 59.33313751316038,
lng: 18.054618219238293,
altitude: 16.728213706832868
},
range: 377.5210725830039,
tilt: 63.59478230626709,
heading: 98.53138488367703,
},
point: { lat: 59.3332093, lng: 18.0536386, altitude: 50 },
pin: {
background: 'white',
glyph: new URL(base + '/images/se.svg'),
scale: 1.0,
},
},
{
name: "Google Switzerland",
details: "Brandschenkestrasse 110, 8002 Zürich",
camera: {
center: {
lat: 47.365411056285275,
lng: 8.525063594405356,
altitude: 419.2348376754488
},
range: 166.74918737631742,
tilt: 59.31431457129067,
heading: -32.620415961949206,
},
point: { lat: 47.365452, lng: 8.5249253, altitude: 100 },
pin: {
background: 'white',
glyph: new URL(base + '/images/ch.svg'),
scale: 1.0,
},
}
]
async function init() {
const { Map3DElement, MapMode, Marker3DInteractiveElement } = await google.maps.importLibrary("maps3d");
const { PinElement } = await google.maps.importLibrary('marker');
map3D = new Map3DElement({
...europeCamera,
mode: MapMode.SATELLITE,
});
officeLocations.forEach(office => {
const marker = new Marker3DInteractiveElement({
position: office.point,
label: office.name,
altitudeMode: 'RELATIVE_TO_GROUND',
extruded: true,
});
marker.addEventListener('gmp-click', (event) => {
map3D.flyCameraTo({
endCamera: office.camera,
durationMillis: 2000,
});
map3D.addEventListener('gmp-animationend', () => {
map3D.flyCameraAround({
camera: office.camera,
durationMillis: 2000,
rounds: 1
});
map3D.addEventListener('gmp-animationend', () => {
map3D.flyCameraTo({
endCamera: europeCamera,
durationMillis: 2000,
});
}, { once: true });
}, { once: true });
event.stopPropagation();
});
const markerPin = new PinElement(office.pin);
marker.append(markerPin);
map3D.append(marker);
});
document.body.append(map3D);
}
init();
</script>
</body>
</html>
12. 다음 단계
이 Codelab에서는 Maps JavaScript API의 3D로 할 수 있는 작업의 기본사항을 살펴봤습니다. 다음으로, 지도에 다음과 같은 기능을 추가해 보세요.
- 사무실을 선택할 수 있는 드롭다운 목록을 추가합니다.
- 다른 마커 스타일 지정 옵션을 사용하여 더 멋진 지도를 만들어 보세요.
- Maps JavaScript API에서 사용할 수 있는 추가 라이브러리를 확인합니다. 이러한 라이브러리를 사용하면 장소 ID를 사용하여 각 지점의 평점을 표시하는 장소 등의 추가 기능을 사용 설정할 수 있습니다.
계속해서 웹에서 Google Maps Platform 및 3D를 사용하는 방법을 자세히 알아보려면 다음 링크를 참고하세요.