Markers

The following examples show the capabilities of markers in Photorealistic 3D Maps in Maps JavaScript.

Simple marker

This example shows creating a new Marker3DElement to add to a map.

Simple Marker

<!DOCTYPE html>
<html>
  <head>
    <title>Photorealistic 3D Maps in Maps JavaScript Simple Marker Demo</title>
    <style>
      html,
      body {
        height:100%;
        margin: 0;
        padding: 0;
      }

      gmp-map-3d {
        height: 400px;
        width: 800px;
      }
    </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: "<YOUR_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 type="text/javascript">
    // Maps JS API is loaded using Dynamic Library import https://developers.google.com/maps/documentation/javascript/load-maps-js-api#dynamic-library-import

    async function init() {
      const { Map3DElement, Marker3DElement } = await google.maps.importLibrary("maps3d");

      const map = new Map3DElement({
        center: { lat: 48.861000, lng: 2.335861, altitude: 0 },
        heading: 110,
        tilt: 67.5,
        range: 1000
      });
      const marker = new Marker3DElement({
        position: { lat: 48.861000, lng: 2.335861 }
      });
      map.append(marker);
      document.body.append(map);
    }

    init();
    </script>
  </body>
</html>

Customize markers

This example shows how to customize markers in the following ways:

  • Add a marker label
  • Scale the marker
  • Change the background color
  • Change the border color
  • Change the glyph color
  • Hide the glyph

Custom Marker

<!DOCTYPE html>
<html>
  <head>
    <title>Photorealistic 3D Maps in Maps JavaScript Custom Marker Demo</title>
    <style>
      html,
      body {
        height:100%;
        margin: 0;
        padding: 0;
      }

      gmp-map-3d {
        height: 400px;
        width: 800px;
      }
    </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: "<YOUR_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 type="text/javascript">
   // Maps JS API is loaded using Dynamic Library import https://developers.google.com/maps/documentation/javascript/load-maps-js-api#dynamic-library-import

    async function init() {
      const { Map3DElement, Marker3DElement } = await google.maps.importLibrary("maps3d");
      const { PinElement } = await google.maps.importLibrary("marker");

      const map = new Map3DElement({
        center: { lat: 37.4176, lng: -122.02, altitude: 0 },
        tilt: 67.5,
        range: 5000
      });

      const markerWithLabel = new Marker3DElement({
        position: { lat: 37.419, lng: -122.03 },
        label: 'Simple label'
      });

      // Adjust the scale.
      const pinScaled = new PinElement({
        scale: 1.5,
      });
      const markerWithScale = new Marker3DElement({
        position: { lat: 37.419, lng: -122.02 },
      });
      markerWithScale.append(pinScaled);

      // Change the background color.
      const pinBackground = new PinElement({
        background: '#FBBC04',
      });
      const markerWithBackground = new Marker3DElement({
        position: { lat: 37.419, lng: -122.01 },
      });
      markerWithBackground.append(pinBackground);

      // Change the border color.
      const pinBorder = new PinElement({
        borderColor: '#137333',
      });
      const markerWithBorder = new Marker3DElement({
        position: { lat: 37.415, lng: -122.035 },
      });
      markerWithBorder.append(pinBorder);

      // Change the glyph color.
      const pinGlyph = new PinElement({
        glyphColor: 'white',
      });
      const markerWithGlyphColor = new Marker3DElement({
        position: { lat: 37.415, lng: -122.025 },
      });
      markerWithGlyphColor.append(pinGlyph);

      const pinTextGlyph = new PinElement({
        glyph: 'T',
        glyphColor: 'white',
      });
      const markerWithGlyphText = new Marker3DElement({
        position: { lat: 37.415, lng: -122.015 },
      });
      markerWithGlyphText.append(pinTextGlyph);

      // Hide the glyph.
      const pinNoGlyph = new PinElement({
        glyph: '',
      });
      const markerWithNoGlyph = new Marker3DElement({
        position: { lat: 37.415, lng: -122.005 },
      });
      markerWithNoGlyph.append(pinNoGlyph);

      map.append(markerWithLabel);
      map.append(markerWithScale);
      map.append(markerWithBackground);
      map.append(markerWithBorder);
      map.append(markerWithGlyphColor);
      map.append(markerWithGlyphText);
      map.append(markerWithNoGlyph);

      document.body.append(map);
    }

    init();

    </script>
  </body>
</html>

Create markers with graphics

This example shows how to create markers and replace the default marker icon with custom graphic images in various formats.

Markers with graphics

<!DOCTYPE html>
<html>
  <head>
    <title>Photorealistic 3D Maps in Maps JavaScript Marker with Graphics Demo</title>
    <style>
      html,
      body {
        height:100%;
        margin: 0;
        padding: 0;
      }

      gmp-map-3d {
        height: 400px;
        width: 800px;
      }
    </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: "<YOUR_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 type="text/javascript">
    // Maps JS API is loaded using Dynamic Library import https://developers.google.com/maps/documentation/javascript/load-maps-js-api#dynamic-library-import

    async function init() {
      const { Map3DElement, Marker3DElement } = await google.maps.importLibrary('maps3d');
      const { PinElement } = await google.maps.importLibrary('marker');
      const { Place } = await google.maps.importLibrary('places');

      const map = new Map3DElement({
          center: { lat: 37.4239, lng: -122.0827, altitude: 0 },
          tilt: 55,
          range: 5000,
          defaultLabelsDisabled: true
      });

      const parser = new DOMParser();

      // A marker with a custom inline SVG.
      const pinSvgString = '<svg xmlns="http://www.w3.org/2000/svg" width="56" height="56" viewBox="0 0 56 56" fill="none"><rect width="56" height="56" rx="28" fill="#7837FF"></rect><path d="M46.0675 22.1319L44.0601 22.7843" stroke="white" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"></path><path d="M11.9402 33.2201L9.93262 33.8723" stroke="white" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"></path><path d="M27.9999 47.0046V44.8933" stroke="white" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"></path><path d="M27.9999 9V11.1113" stroke="white" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"></path><path d="M39.1583 43.3597L37.9186 41.6532" stroke="white" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"></path><path d="M16.8419 12.6442L18.0816 14.3506" stroke="white" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"></path><path d="M9.93262 22.1319L11.9402 22.7843" stroke="white" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"></path><path d="M46.0676 33.8724L44.0601 33.2201" stroke="white" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"></path><path d="M39.1583 12.6442L37.9186 14.3506" stroke="white" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"></path><path d="M16.8419 43.3597L18.0816 41.6532" stroke="white" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"></path><path d="M28 39L26.8725 37.9904C24.9292 36.226 23.325 34.7026 22.06 33.4202C20.795 32.1378 19.7867 30.9918 19.035 29.9823C18.2833 28.9727 17.7562 28.0587 17.4537 27.2401C17.1512 26.4216 17 25.5939 17 24.7572C17 23.1201 17.5546 21.7513 18.6638 20.6508C19.7729 19.5502 21.1433 19 22.775 19C23.82 19 24.7871 19.2456 25.6762 19.7367C26.5654 20.2278 27.34 20.9372 28 21.8649C28.77 20.8827 29.5858 20.1596 30.4475 19.6958C31.3092 19.2319 32.235 19 33.225 19C34.8567 19 36.2271 19.5502 37.3362 20.6508C38.4454 21.7513 39 23.1201 39 24.7572C39 25.5939 38.8488 26.4216 38.5463 27.2401C38.2438 28.0587 37.7167 28.9727 36.965 29.9823C36.2133 30.9918 35.205 32.1378 33.94 33.4202C32.675 34.7026 31.0708 36.226 29.1275 37.9904L28 39Z" fill="#FF7878"></path></svg>';

      const pinSvg =
          parser.parseFromString(pinSvgString, 'image/svg+xml').documentElement;

      const markerWithCustomSvg = new Marker3DElement({
          position: { lat: 37.425, lng: -122.094 },
      });
      const templateForSvg = document.createElement('template');
      templateForSvg.content.append(pinSvg);
      markerWithCustomSvg.append(templateForSvg);

      // A marker with a with a URL pointing to a PNG.
      const beachFlagImg = document.createElement('img');
      beachFlagImg.src = 'https://developers.google.com/maps/documentation/javascript/examples/full/images/beachflag.png';

      const beachFlagMarker = new Marker3DElement({
          position: { lat: 37.434, lng: -122.082 },
      });
      const templateForImg = document.createElement('template');
      templateForImg.content.append(beachFlagImg);
      beachFlagMarker.append(templateForImg);

      // A marker with a custom SVG glyph.
      const glyphImgUrl = 'https://www.gstatic.com/images/branding/productlogos/maps/v7/192px.svg';
      const glyphSvgPinElement = new PinElement({
          background: 'white',
          glyph: new URL(glyphImgUrl),
      });
      const glyphSvgMarker = new Marker3DElement({
          position: { lat: 37.425, lng: -122.07 },
      });
      glyphSvgMarker.append(glyphSvgPinElement);

      // A marker customized using a place icon and color, name, and geometry.
      const place = new Place({
          id: 'ChIJN5Nz71W3j4ARhx5bwpTQEGg',
      });

      // Call fetchFields, passing the desired data fields.
      await place.fetchFields({ fields: ['location', 'displayName', 'svgIconMaskURI', 'iconBackgroundColor'] });

      const pinElement = new PinElement({
          background: place.iconBackgroundColor,
          glyph: new URL(String(place.svgIconMaskURI)),
      });
      const placeIconMarker = new Marker3DElement({
          position: place.location,
      });
      placeIconMarker.append(pinElement);

      map.append(markerWithCustomSvg);
      map.append(beachFlagMarker);
      map.append(glyphSvgMarker);
      map.append(placeIconMarker);

      document.body.append(map);
    }

    init();
    </script>
  </body>
</html>

Create interactive markers

This example shows how to create interactive markers.

Interactive markers

<!DOCTYPE html>
<html>
  <head>
    <title>Photorealistic 3D Maps in Maps JavaScript Interactive Markers Demo</title>
    <style>
      html,
      body {
        height:100%;
        margin: 0;
        padding: 0;
      }

      gmp-map-3d {
        height: 400px;
        width: 800px;
      }
    </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: "<YOUR_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 type="text/javascript">
    // Maps JS API is loaded using Dynamic Library import https://developers.google.com/maps/documentation/javascript/load-maps-js-api#dynamic-library-import

    async function init() {
      // Request needed libraries.
      const { Map3DElement, Marker3DInteractiveElement } = await google.maps.importLibrary("maps3d");

      const map = new Map3DElement({
        center: { lat: 37.4690, lng: -122.1074, altitude: 0 },
        tilt: 67.5,
        range: 45000
      });

      for (const position of positions) {
        const interactiveMarker = new Marker3DInteractiveElement({
          position,
        });

        interactiveMarker.addEventListener('gmp-click', (event) => {
          // TODO: Do some work here. `event.position` can be used to get coordinates of the
          // click. `event.target.position` can be used to get marker's position.
        });

        map.append(interactiveMarker);
      }

      document.body.append(map);
    }

    const positions = [{
      lat: 37.50024109655184,
      lng: -122.28528451834352,
    }, {
      lat: 37.44440882321596,
      lng: -122.2160620727,
    }, {
      lat: 37.39561833718522,
      lng: -122.21855116258479,
    }, {
      lat: 37.423928529779644,
      lng: -122.1087629822001,
    }, {
      lat: 37.40578635332598,
      lng: -122.15043378466069,
    }, {
      lat: 37.36399747905774,
      lng: -122.10465384268522,
    }, {
      lat: 37.38343706184458,
      lng: -122.02340436985183,
    }, {
      lat: 37.34576403052,
      lng: -122.04455090047453,
    }, {
      lat: 37.362863347890716,
      lng: -121.97802139023555,
    }, {
      lat: 37.41391636421949,
      lng: -121.94592071575907,
    }];

    init();
    </script>
  </body>
</html>

Create extruded markers

This example shows how to create extruded markers.

Extruded markers

<!DOCTYPE html>
<html>
  <head>
    <title>Photorealistic 3D Maps in Maps JavaScript Extruded Marker Demo</title>
    <style>
      html,
      body {
        height:100%;
        margin: 0;
        padding: 0;
      }

      gmp-map-3d {
        height: 400px;
        width: 800px;
      }
    </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: "<YOUR_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 type="text/javascript">
     // Maps JS API is loaded using Dynamic Library import https://developers.google.com/maps/documentation/javascript/load-maps-js-api#dynamic-library-import

    async function init() {
      const { Map3DElement, Marker3DElement } = await google.maps.importLibrary("maps3d");

      const map = new Map3DElement({
        center: { lat: 37.4239163, lng: -122.0947209, altitude: 0 },
        tilt: 67.5,
        range: 1000
      });
      const marker = new Marker3DElement({
        position: { lat: 37.4239163, lng: -122.0947209, altitude: 100 },
        altitudeMode: 'RELATIVE_TO_GROUND',
        extruded: true,
      });

      map.append(marker);
      document.body.append(map);
    }

    init();
    </script>
  </body>
</html>

Control marker collision behavior

This example shows setting collision behavior for a marker.

Markers with collision set to OPTIONAL_AND_HIDES_LOWER_PRIORITY

<!DOCTYPE html>
<html>
  <head>
    <title>Photorealistic 3D Maps in Maps JavaScript Custom Marker Demo</title>
    <style>
      html,
      body {
        height:100%;
        margin: 0;
        padding: 0;
      }

      gmp-map-3d {
        height: 400px;
        width: 800px;
      }
    </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: "<YOUR_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 type="text/javascript">
      // Maps JS API is loaded using Dynamic Library import https://developers.google.com/maps/documentation/javascript/load-maps-js-api#dynamic-library-import

      async function init() {
        // Request needed libraries.
        const { Map3DElement, Marker3DElement } = await google.maps.importLibrary("maps3d");

        const map = new Map3DElement({
          center: { lat: 47.6094, lng: -122.3390, altitude: 0 },
          range: 1000
        });

        for (const [lng, lat] of positions) {
          const marker = new Marker3DElement({
            position: {lat, lng},
            // Try setting a different collision behavior here.
            collisionBehavior: google.maps.CollisionBehavior.OPTIONAL_AND_HIDES_LOWER_PRIORITY
          });

          map.append(marker);
        }

        document.body.append(map);
      }

      const positions = [
        [-122.3402, 47.6093],
        [-122.3402, 47.6094],
        [-122.3403, 47.6094],
        [-122.3384, 47.6098],
        [-122.3389, 47.6095],
        [-122.3396, 47.6095],
        [-122.3379, 47.6097],
        [-122.3378, 47.6097],
        [-122.3396, 47.6091],
        [-122.3383, 47.6089],
        [-122.3379, 47.6093],
        [-122.3381, 47.6095],
        [-122.3378, 47.6095],
      ];

      init();
    </script>
  </body>
</html>

Remove markers

This example shows how to remove markers.

<!DOCTYPE html>
<html>
  <head>
    <title>Photorealistic 3D Maps in Maps JavaScript Remove Markers Demo</title>
    <style>
      html,
      body {
        height:100%;
        margin: 0;
        padding: 0;
      }

      gmp-map-3d {
        height: 400px;
        width: 800px;
      }
    </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: "<YOUR_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 type="text/javascript">     
    const marker = document.querySelector('gmp-marker-3d');
    marker.remove();

    const interactiveMarker = document.querySelector('gmp-marker-3d-interactive');
    interactiveMarker.remove();
    </script>
  </body>
</html>