It's the 15th anniversary of Google Maps Platform - Check out the latest news and announcements

Inset Overview Map

Maintaining a geographical frame of reference

An inset map is a smaller map to help the user maintain a geographical frame of reference. The overview map is synchronized with the bounds_changed event on the main map.

TypeScript

const OVERVIEW_DIFFERENCE = 5;
const OVERVIEW_MIN_ZOOM = 3;
const OVERVIEW_MAX_ZOOM = 10;

function initMap(): void {
  const mapOptions = {
    center: { lat: 50, lng: 8 },
    zoom: 7
  };

  // instantiate the primary map
  map = new google.maps.Map(document.getElementById("map") as HTMLElement, {
    ...mapOptions
  });

  // instantiate the overview map without controls
  overview = new google.maps.Map(
    document.getElementById("overview") as HTMLElement,
    {
      ...mapOptions,
      disableDefaultUI: true,
      gestureHandling: "none",
      zoomControl: false
    }
  );

  function clamp(num, min, max) {
    return Math.min(Math.max(num, min), max);
  }

  map.addListener("bounds_changed", () => {
    overview.setCenter(map.getCenter());
    overview.setZoom(
      clamp(
        map.getZoom() - OVERVIEW_DIFFERENCE,
        OVERVIEW_MIN_ZOOM,
        OVERVIEW_MAX_ZOOM
      )
    );
  });
}

JavaScript

let map, overview;
const OVERVIEW_DIFFERENCE = 5;
const OVERVIEW_MIN_ZOOM = 3;
const OVERVIEW_MAX_ZOOM = 10;

function initMap() {
  const mapOptions = {
    center: { lat: 50, lng: 8 },
    zoom: 7
  };
  // instantiate the primary map
  map = new google.maps.Map(document.getElementById("map"), {
    ...mapOptions
  });
  // instantiate the overview map without controls
  overview = new google.maps.Map(document.getElementById("overview"), {
    ...mapOptions,
    disableDefaultUI: true,
    gestureHandling: "none",
    zoomControl: false
  });

  function clamp(num, min, max) {
    return Math.min(Math.max(num, min), max);
  }
  map.addListener("bounds_changed", () => {
    overview.setCenter(map.getCenter());
    overview.setZoom(
      clamp(
        map.getZoom() - OVERVIEW_DIFFERENCE,
        OVERVIEW_MIN_ZOOM,
        OVERVIEW_MAX_ZOOM
      )
    );
  });
}

CSS

/* Always set the map height explicitly to define the size of the div
       * element that contains the map. */
#map {
  height: 100%;
}

/* Optional: Makes the sample page fill the window. */
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

#container,
#map {
  height: 100%;
  width: 100%;
}

#map {
  position: relative;
}

#overview {
  position: absolute;
  left: 40px;
  height: 175px;
  width: 175px;
  bottom: 50px;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
}

HTML

<!DOCTYPE html>
<html>
  <head>
    <title>Inset Overview Map</title>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
    <script
      src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap&libraries=&v=weekly"
      defer
    ></script>
    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script src="./app.js"></script>
  </head>
  <body>
    <div id="container">
      <div id="map"></div>
      <div id="overview"></div>
    </div>
  </body>
</html>

All

<!DOCTYPE html>
<html>
  <head>
    <title>Inset Overview Map</title>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
    <script
      src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap&libraries=&v=weekly"
      defer
    ></script>
    <style type="text/css">
      /* Always set the map height explicitly to define the size of the div
       * element that contains the map. */
      #map {
        height: 100%;
      }

      /* Optional: Makes the sample page fill the window. */
      html,
      body {
        height: 100%;
        margin: 0;
        padding: 0;
      }

      #container,
      #map {
        height: 100%;
        width: 100%;
      }

      #map {
        position: relative;
      }

      #overview {
        position: absolute;
        left: 40px;
        height: 175px;
        width: 175px;
        bottom: 50px;
        box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
      }
    </style>
    <script>
      "use strict";

      let map, overview;
      const OVERVIEW_DIFFERENCE = 5;
      const OVERVIEW_MIN_ZOOM = 3;
      const OVERVIEW_MAX_ZOOM = 10;

      function initMap() {
        const mapOptions = {
          center: {
            lat: 50,
            lng: 8
          },
          zoom: 7
        }; // instantiate the primary map

        map = new google.maps.Map(document.getElementById("map"), {
          ...mapOptions
        }); // instantiate the overview map without controls

        overview = new google.maps.Map(document.getElementById("overview"), {
          ...mapOptions,
          disableDefaultUI: true,
          gestureHandling: "none",
          zoomControl: false
        });

        function clamp(num, min, max) {
          return Math.min(Math.max(num, min), max);
        }

        map.addListener("bounds_changed", () => {
          overview.setCenter(map.getCenter());
          overview.setZoom(
            clamp(
              map.getZoom() - OVERVIEW_DIFFERENCE,
              OVERVIEW_MIN_ZOOM,
              OVERVIEW_MAX_ZOOM
            )
          );
        });
      }
    </script>
  </head>
  <body>
    <div id="container">
      <div id="map"></div>
      <div id="overview"></div>
    </div>
  </body>
</html>
"use strict"; let map, overview; const OVERVIEW_DIFFERENCE = 5; const OVERVIEW_MIN_ZOOM = 3; const OVERVIEW_MAX_ZOOM = 10; function initMap() { const mapOptions = { center: { lat: 50, lng: 8 }, zoom: 7 }; // instantiate the primary map map = new google.maps.Map(document.getElementById("map"), { ...mapOptions }); // instantiate the overview map without controls overview = new google.maps.Map(document.getElementById("overview"), { ...mapOptions, disableDefaultUI: true, gestureHandling: "none", zoomControl: false }); function clamp(num, min, max) { return Math.min(Math.max(num, min), max); } map.addListener("bounds_changed", () => { overview.setCenter(map.getCenter()); overview.setZoom( clamp( map.getZoom() - OVERVIEW_DIFFERENCE, OVERVIEW_MIN_ZOOM, OVERVIEW_MAX_ZOOM ) ); }); }
/* Always set the map height explicitly to define the size of the div * element that contains the map. */ #map { height: 100%; } /* Optional: Makes the sample page fill the window. */ html, body { height: 100%; margin: 0; padding: 0; } #container, #map { height: 100%; width: 100%; } #map { position: relative; } #overview { position: absolute; left: 40px; height: 175px; width: 175px; bottom: 50px; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3); }
<!DOCTYPE html> <html> <head> <title>Inset Overview Map</title> <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script> <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBIwzALxUPNbatRBj3Xi1Uhp0fFzwWNBkE&callback=initMap&libraries=&v=weekly" defer ></script> <!-- jsFiddle will insert css and js --> </head> <body> <div id="container"> <div id="map"></div> <div id="overview"></div> </div> </body> </html>

Create a starter application from sample

A skeleton starter application using TypeScript, Webpack, and Babel can be generated from this sample using one of the methods below.

Run Locally

Node.js is required to run this sample locally. Follow these instructions to install Node.js and NPM.

npm i -g '@googlemaps/js-samples'
googlemaps-js-samples init inset-map DESTINATION_FOLDER

Run in Google Cloud Shell

Google Cloud Shell is an interactive shell environment for Google Cloud Platform that makes it easy for you to learn and experiment with GCP and manage your projects and resources from your web browser.

Run in Cloud Shell