Skip to content

Commit e37a0ac

Browse files
Andreas HelmsAndreas Helms
authored andcommitted
docs(example): maps 3d markers example
1 parent 42c4c7e commit e37a0ac

File tree

18 files changed

+647
-0
lines changed

18 files changed

+647
-0
lines changed

examples/map-3d-markers/README.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# 3D Maps with Markers Example
2+
3+
This example implements a new `Map3D` component that renders
4+
a 3D Globe based on the new experimental [`Map3DElement`][gmp-map3d-overview]
5+
web-component.
6+
7+
The map contains basic [`Marker3DElements`][gmp-map3d-marker-add] as well as markers with a custom pin and a 3D model.
8+
9+
[gmp-map3d-overview]: https://developers.google.com/maps/documentation/javascript/3d-maps-overview
10+
[gmp-map3d-marker-add]: https://developers.google.com/maps/documentation/javascript/3d/marker-add
11+
12+
## Google Maps API key
13+
14+
This example does not come with an API key. Running the examples locally requires a valid API key for the Google Maps Platform.
15+
See [the official documentation][get-api-key] on how to create and configure your own key.
16+
17+
The API key has to be provided via an environment variable `GOOGLE_MAPS_API_KEY`. This can be done by creating a
18+
file named `.env` in the example directory with the following content:
19+
20+
```shell title=".env"
21+
GOOGLE_MAPS_API_KEY="<YOUR API KEY HERE>"
22+
```
23+
24+
If you are on the CodeSandbox playground you can also choose to [provide the API key like this](https://codesandbox.io/docs/learn/environment/secrets)
25+
26+
## Development
27+
28+
Go into the example-directory and run
29+
30+
```shell
31+
npm install
32+
```
33+
34+
To start the example with the local library run
35+
36+
```shell
37+
npm run start-local
38+
```
39+
40+
The regular `npm start` task is only used for the standalone versions of the example (CodeSandbox for example)
41+
42+
[get-api-key]: https://developers.google.com/maps/documentation/javascript/get-api-key
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
{
2+
"basic": {
3+
"markerOptions": {
4+
"position": {"lat": 40.707275, "lng": -73.998332, "altitude": 80},
5+
"altitudeMode": "RELATIVE_TO_GROUND"
6+
}
7+
},
8+
"basicExtruded": {
9+
"markerOptions": {
10+
"position": {"lat": 40.707275, "lng": -73.998332, "altitude": 200},
11+
"extruded": true,
12+
"altitudeMode": "RELATIVE_TO_GROUND"
13+
}
14+
},
15+
"basicColored": {
16+
"markerOptions": {
17+
"position": {
18+
"lat": 40.706461,
19+
"lng": -73.997409,
20+
"altitude": 50
21+
},
22+
"altitudeMode": "RELATIVE_TO_GROUND"
23+
},
24+
"pinOptions": {
25+
"borderColor": "blue",
26+
"background": "blue",
27+
"glyphColor": "white"
28+
}
29+
},
30+
"customLogo": {
31+
"markerOptions": {
32+
"position": {
33+
"lat": 40.705666,
34+
"lng": -73.996382,
35+
"altitude": 50
36+
},
37+
"altitudeMode": "RELATIVE_TO_GROUND"
38+
},
39+
"pinOptions": {
40+
"borderColor": "white",
41+
"background": "white",
42+
"glyph": "https://www.gstatic.com/images/branding/productlogos/maps/v7/192px.svg"
43+
}
44+
},
45+
"svg": {
46+
"markerOptions": {
47+
"position": {
48+
"lat": 40.704876,
49+
"lng": -73.995379,
50+
"altitude": 50
51+
},
52+
"altitudeMode": "RELATIVE_TO_GROUND"
53+
}
54+
},
55+
"model3d": {
56+
"markerOptions": {
57+
"position": {
58+
"lat": 40.704118,
59+
"lng": -73.994371,
60+
"altitude": 100
61+
},
62+
"altitudeMode": "RELATIVE_TO_GROUND"
63+
}
64+
}
65+
}
343 KB
Binary file not shown.

examples/map-3d-markers/index.html

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8" />
5+
<meta
6+
name="viewport"
7+
content="width=device-width, initial-scale=1.0, user-scalable=no" />
8+
<title>Example: Photorealistic 3D Map with Markers</title>
9+
10+
<style>
11+
body {
12+
margin: 0;
13+
font-family: sans-serif;
14+
}
15+
#app {
16+
width: 100vw;
17+
height: 100vh;
18+
}
19+
</style>
20+
</head>
21+
<body>
22+
<div id="app"></div>
23+
<script type="module">
24+
import '@vis.gl/react-google-maps/examples.css';
25+
import '@vis.gl/react-google-maps/examples.js';
26+
import {renderToDom} from './src/app';
27+
28+
renderToDom(document.querySelector('#app'));
29+
</script>
30+
</body>
31+
</html>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"type": "module",
3+
"dependencies": {
4+
"@vis.gl/react-google-maps": "latest",
5+
"react": "^19.0.0",
6+
"react-dom": "^19.0.0",
7+
"typescript": "^5.4.5",
8+
"vite": "^6.0.11"
9+
},
10+
"scripts": {
11+
"start": "vite",
12+
"start-local": "vite --config ../vite.config.local.js",
13+
"build": "vite build"
14+
}
15+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import React from 'react';
2+
import {createRoot} from 'react-dom/client';
3+
4+
import {APIProvider} from '@vis.gl/react-google-maps';
5+
6+
import {Map3D} from './map-3d';
7+
import ControlPanel from './control-panel';
8+
9+
const API_KEY =
10+
globalThis.GOOGLE_MAPS_API_KEY ?? (process.env.GOOGLE_MAPS_API_KEY as string);
11+
12+
const INITIAL_VIEW_PROPS = {
13+
center: {lat: 40.7006119, lng: -74.0032485, altitude: 600},
14+
range: 600,
15+
heading: 45,
16+
tilt: 60,
17+
roll: 0
18+
};
19+
20+
const App = () => {
21+
return (
22+
<APIProvider
23+
apiKey={API_KEY}
24+
version={'alpha'}
25+
libraries={['maps3d', 'marker']}>
26+
<Map3D {...INITIAL_VIEW_PROPS} defaultLabelsDisabled />
27+
<ControlPanel />
28+
</APIProvider>
29+
);
30+
};
31+
export default App;
32+
33+
export function renderToDom(container: HTMLElement) {
34+
const root = createRoot(container);
35+
36+
root.render(
37+
<React.StrictMode>
38+
<App />
39+
</React.StrictMode>
40+
);
41+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import * as React from 'react';
2+
3+
const GMP_3D_MAPS_OVERVIEW_URL =
4+
'https://developers.google.com/maps/documentation/javascript/3d-maps-overview';
5+
6+
const GMP_3D_MAPS_MARKER_ADD_URL =
7+
'https://developers.google.com/maps/documentation/javascript/3d/marker-add';
8+
9+
function ControlPanel() {
10+
return (
11+
<div className="control-panel">
12+
<h3>3D Maps with Markers</h3>
13+
<p>
14+
This example implements a new <code>Map3D</code> component that renders
15+
a 3D Globe based on the new experimental{' '}
16+
<a href={GMP_3D_MAPS_OVERVIEW_URL} target={'_blank'}>
17+
<code>Map3DElement</code>
18+
</a>{' '}
19+
web-component.
20+
</p>
21+
22+
<p>
23+
The map contains basic{' '}
24+
<a href={GMP_3D_MAPS_MARKER_ADD_URL} target={'_blank'}>
25+
<code>Marker3DElements</code>
26+
</a>{' '}
27+
as well as markers with a custom pin and a 3D model.
28+
</p>
29+
30+
<div className="links">
31+
<a
32+
href="https://codesandbox.io/s/github/visgl/react-google-maps/tree/main/examples/map-3d-markers"
33+
target="_new">
34+
Try on CodeSandbox ↗
35+
</a>
36+
37+
<a
38+
href="https://github.com/visgl/react-google-maps/tree/main/examples/map-3d-markers"
39+
target="_new">
40+
View Code ↗
41+
</a>
42+
</div>
43+
</div>
44+
);
45+
}
46+
47+
export default React.memo(ControlPanel);
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './map-3d';
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/* eslint-disable @typescript-eslint/no-namespace, @typescript-eslint/no-explicit-any */
2+
3+
import {DOMAttributes, RefAttributes} from 'react';
4+
5+
// add an overload signature for the useMapsLibrary hook, so typescript
6+
// knows what the 'maps3d' library is.
7+
declare module '@vis.gl/react-google-maps' {
8+
export function useMapsLibrary(
9+
name: 'maps3d'
10+
): typeof google.maps.maps3d | null;
11+
}
12+
13+
// temporary fix until @types/google.maps is updated with the latest changes
14+
declare global {
15+
namespace google.maps.maps3d {
16+
interface Map3DElement extends HTMLElement {
17+
mode?: 'HYBRID' | 'SATELLITE';
18+
}
19+
}
20+
}
21+
22+
// add the <gmp-map-3d> custom-element to the JSX.IntrinsicElements
23+
// interface, so it can be used in jsx
24+
declare module 'react' {
25+
namespace JSX {
26+
interface IntrinsicElements {
27+
['gmp-map-3d']: CustomElement<
28+
google.maps.maps3d.Map3DElement,
29+
google.maps.maps3d.Map3DElement
30+
>;
31+
}
32+
33+
interface IntrinsicElements {
34+
['gmp-marker-3d']: CustomElement<
35+
google.maps.maps3d.Marker3DElement,
36+
google.maps.maps3d.Marker3DElement
37+
>;
38+
}
39+
}
40+
}
41+
42+
// a helper type for CustomElement definitions
43+
type CustomElement<TElem, TAttr> = Partial<
44+
TAttr &
45+
DOMAttributes<TElem> &
46+
RefAttributes<TElem> & {
47+
// for whatever reason, anything else doesn't work as children
48+
// of a custom element, so we allow `any` here
49+
children: any;
50+
}
51+
>;

0 commit comments

Comments
 (0)