Circles
Stay organized with collections
Save and categorize content based on your preferences.
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
constmapElement=document.querySelector('gmp-map')!; letinnerMap:google.maps.Map; asyncfunctioninit(){ // Request needed libraries. const[{Circle},{AdvancedMarkerElement},{event}]= awaitPromise.all([ google.maps.importLibrary('maps'), google.maps.importLibrary('marker'), google.maps.importLibrary('core'), ]); // Set the initial map center point. constinitialCenter={lat:34.98956821576194,lng:135.74239981260283};// Hotel Emion, Kyoto, Japan // Get the inner map. innerMap=mapElement.innerMap; // Get the buttons. constbuttons=document.querySelectorAll('input[name="radius"]'); // Create the circle. constwalkingCircle=newCircle({ 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 constparser=newDOMParser(); constsvgString=`<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>`; constpinSvg=parser.parseFromString( svgString, 'image/svg+xml' ).documentElement; constcenterMarker=newAdvancedMarkerElement({ 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 constcontrols=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)=>{ consttarget=changeEvent.targetasHTMLInputElement; 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 )=>{ constnewCenter=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(); }); } voidinit();
JavaScript
constmapElement=document.querySelector('gmp-map'); letinnerMap; asyncfunctioninit(){ // Request needed libraries. const[{Circle},{AdvancedMarkerElement},{event}]= awaitPromise.all([ google.maps.importLibrary('maps'), google.maps.importLibrary('marker'), google.maps.importLibrary('core'), ]); // Set the initial map center point. constinitialCenter={lat:34.98956821576194,lng:135.74239981260283};// Hotel Emion, Kyoto, Japan // Get the inner map. innerMap=mapElement.innerMap; // Get the buttons. constbuttons=document.querySelectorAll('input[name="radius"]'); // Create the circle. constwalkingCircle=newCircle({ 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 constparser=newDOMParser(); constsvgString=`<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>`; constpinSvg=parser.parseFromString( svgString, 'image/svg+xml' ).documentElement; constcenterMarker=newAdvancedMarkerElement({ 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 constcontrols=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)=>{ consttarget=changeEvent.target; walkingCircle.setRadius(Number(target.value)); }); }); // Handle user click, reset the map center and position the circle. innerMap.addListener('click',(mapsMouseEvent)=>{ constnewCenter=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(); }); } voidinit();
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:2pxsolid#fff; border-radius:3px; box-shadow:02px6pxrgba(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. The following commands clone, install dependencies and start the sample application.
gitclonehttps://github.com/googlemaps-samples/js-api-samples.gitcdsamples/circle-simplenpminpmstart