Page Summary
-
This example demonstrates how to create circles on a Google Map to represent populations in North America.
-
Circles are scaled based on city population data using a mathematical formula.
-
The map is centered on North America and uses a "terrain" map type.
-
The example uses JavaScript or TypeScript to define city data and create the map and circles with the Google Maps API.
This sample demonstrates using the Circle class to show approximate walking times between locations in Kyoto, Japan.
- Select the needed distance from the menu.
- Click the map to re-center the circle.
- Drag the circle to reposition it.
The radii for the walking distances were calculated using the following formula: Distance = Speed x Time. For example, at a speed of 1.4 meters per second (approx. 3 mph), it takes a person approximately five minutes to walk 400 meters. The larger circles (15 and 30 minutes) were calculated using a slightly lower average speed to account for 'urban friction' — the delays caused by crosswalks, traffic lights, and crowds that accumulate over longer walks.
Read the documentation.
TypeScript
const mapElement = document.querySelector('gmp-map')!; let innerMap: google.maps.Map; async function init() { // Request needed libraries. const [{ Circle }, { AdvancedMarkerElement }, { event }] = await Promise.all([ google.maps.importLibrary('maps'), google.maps.importLibrary('marker'), google.maps.importLibrary('core'), ]); // Set the initial map center point. const initialCenter = { lat: 34.98956821576194, lng: 135.74239981260283 }; // Hotel Emion, Kyoto, Japan // Get the inner map. innerMap = mapElement.innerMap; // Get the buttons. const buttons = document.querySelectorAll('input[name="radius"]'); // Create the circle. const walkingCircle = new Circle({ strokeColor: '#ffdd00ff', strokeOpacity: 0.8, strokeWeight: 2, fillColor: '#ffdd00ff', fillOpacity: 0.35, map: innerMap, center: initialCenter, radius: 400, draggable: true, editable: false, }); // Define a "Crosshair" vector icon const parser = new DOMParser(); const svgString = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="-6 -6 12 12"><path d="M -6,0 L 6,0 M 0,-6 L 0,6" stroke="black" stroke-width="1"/></svg>`; const pinSvg = parser.parseFromString( svgString, 'image/svg+xml' ).documentElement; const centerMarker = new AdvancedMarkerElement({ position: initialCenter, title: 'A marker using a custom SVG image.', anchorLeft: '-50%', anchorTop: '-50%', }); centerMarker.append(pinSvg); mapElement.append(centerMarker); // Wait for the map to finish drawing its tiles. event.addListenerOnce(innerMap, 'tilesloaded', () => { // Get the controls div const controls = document.getElementById('control-panel'); // Display controls once map is loaded. if (controls) { controls.style.display = 'block'; } }); // Add event listener to update the radius based on user selection. buttons.forEach((button) => { button.addEventListener('change', (changeEvent) => { const target = changeEvent.target as HTMLInputElement; walkingCircle.setRadius(Number(target.value)); }); }); // Handle user click, reset the map center and position the circle. innerMap.addListener( 'click', ( mapsMouseEvent: google.maps.MapMouseEvent | google.maps.IconMouseEvent ) => { const newCenter = mapsMouseEvent.latLng; if (!newCenter) return; walkingCircle.setCenter(newCenter); centerMarker.position = newCenter; innerMap.panTo(newCenter); } ); // Handle user dragging the circle, update the center marker position. walkingCircle.addListener('center_changed', () => { centerMarker.position = walkingCircle.getCenter(); }); } void init();
JavaScript
const mapElement = document.querySelector('gmp-map'); let innerMap; async function init() { // Request needed libraries. const [{ Circle }, { AdvancedMarkerElement }, { event }] = await Promise.all([ google.maps.importLibrary('maps'), google.maps.importLibrary('marker'), google.maps.importLibrary('core'), ]); // Set the initial map center point. const initialCenter = { lat: 34.98956821576194, lng: 135.74239981260283 }; // Hotel Emion, Kyoto, Japan // Get the inner map. innerMap = mapElement.innerMap; // Get the buttons. const buttons = document.querySelectorAll('input[name="radius"]'); // Create the circle. const walkingCircle = new Circle({ strokeColor: '#ffdd00ff', strokeOpacity: 0.8, strokeWeight: 2, fillColor: '#ffdd00ff', fillOpacity: 0.35, map: innerMap, center: initialCenter, radius: 400, draggable: true, editable: false, }); // Define a "Crosshair" vector icon const parser = new DOMParser(); const svgString = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="-6 -6 12 12"><path d="M -6,0 L 6,0 M 0,-6 L 0,6" stroke="black" stroke-width="1"/></svg>`; const pinSvg = parser.parseFromString( svgString, 'image/svg+xml' ).documentElement; const centerMarker = new AdvancedMarkerElement({ position: initialCenter, title: 'A marker using a custom SVG image.', anchorLeft: '-50%', anchorTop: '-50%', }); centerMarker.append(pinSvg); mapElement.append(centerMarker); // Wait for the map to finish drawing its tiles. event.addListenerOnce(innerMap, 'tilesloaded', () => { // Get the controls div const controls = document.getElementById('control-panel'); // Display controls once map is loaded. if (controls) { controls.style.display = 'block'; } }); // Add event listener to update the radius based on user selection. buttons.forEach((button) => { button.addEventListener('change', (changeEvent) => { const target = changeEvent.target; walkingCircle.setRadius(Number(target.value)); }); }); // Handle user click, reset the map center and position the circle. innerMap.addListener('click', (mapsMouseEvent) => { const newCenter = mapsMouseEvent.latLng; if (!newCenter) return; walkingCircle.setCenter(newCenter); centerMarker.position = newCenter; innerMap.panTo(newCenter); }); // Handle user dragging the circle, update the center marker position. walkingCircle.addListener('center_changed', () => { centerMarker.position = walkingCircle.getCenter(); }); } void init();
CSS
/* * Optional: Makes the sample page fill the window. */ html, body { height: 100%; margin: 0; padding: 0; } #control-panel { display: none; /* Set to 'display: block' after the map loads. */ background-color: #fff; border: 2px solid #fff; border-radius: 3px; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3); font-family: 'Roboto', sans-serif; font-size: medium; margin: 10px; padding: 10px; }
HTML
<html>
<head>
<title>Circles</title>
<link rel="stylesheet" type="text/css" href="./style.css" />
<script type="module" src="./index.js"></script>
<script>
// prettier-ignore
(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: "GOOGLE_MAPS_API_KEY"
});
</script>
</head>
<body>
<gmp-map
center="34.98956821576194, 135.74239981260283"
zoom="15"
map-id="DEMO_MAP_ID">
<div id="control-panel" slot="control-inline-start-block-start">
<input
id="short-walk"
type="radio"
name="radius"
value="400"
checked />
<label for="short-walk">Short Walk (~5 minutes)</label><br />
<input
id="medium-walk"
type="radio"
name="radius"
value="800" />
<label for="medium-walk">Medium Walk (~15 minutes)</label><br />
<input id="long-walk" type="radio" name="radius" value="1600" />
<label for="long-walk">Long Walk (~30 minutes) </label>
</div>
</gmp-map>
</body>
</html>Clone Sample
Git and Node.js are required to run this sample locally. Follow these instructions to install Node.js and NPM. You will also need a Google Maps API key.
The following commands clone the repository, install dependencies, and copy the environment file.
git clone https://github.com/googlemaps-samples/js-api-samples.gitcd js-api-samplesnpm icp .env.template .env
Once you copy the environment file, make sure to open the .env file and replace <Insert your own development API key here> with your actual API key before starting the sample.
cd samples/circle-simplenpm start