Circles

  • 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' 
 ) 
  
 as 
  
 google 
 . 
 maps 
 . 
 MapElement 
 ; 
 let 
  
 innerMap 
 ; 
 async 
  
 function 
  
 initMap 
 () 
  
 { 
  
 // Request needed libraries. 
  
 ( 
 await 
  
 google 
 . 
 maps 
 . 
 importLibrary 
 ( 
 'maps' 
 )) 
  
 as 
  
 google 
 . 
 maps 
 . 
 MapsLibrary 
 ; 
  
 ( 
 await 
  
 google 
 . 
 maps 
 . 
 importLibrary 
 ( 
 'marker' 
 )) 
  
 as 
  
 google 
 . 
 maps 
 . 
 MarkerLibrary 
 ; 
  
 // Get the gmp-map element. 
  
 const 
  
 mapElement 
  
 = 
  
 document 
 . 
 querySelector 
 ( 
  
 'gmp-map' 
  
 ) 
  
 as 
  
 google 
 . 
 maps 
 . 
 MapElement 
 ; 
  
 // Set the initial map center point. 
  
 const 
  
 initialCenter 
  
 = 
  
 { 
  
 lat 
 : 
  
 34.98956821576194 
 , 
  
 lng 
 : 
  
 135.74239981260283 
  
 }; 
  
 // Hotel Emion, Kyoto, Japan 
  
 // Get the inner map. 
  
 const 
  
 innerMap 
  
 = 
  
 mapElement 
 . 
 innerMap 
 ; 
  
 // Get the buttons. 
  
 const 
  
 buttons 
  
 = 
  
 document 
 . 
 querySelectorAll 
 ( 
 'input[name="radius"]' 
 ); 
  
 // Create the circle. 
  
 const 
  
 walkingCircle 
  
 = 
  
 new 
  
 google 
 . 
 maps 
 . 
 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 
  
 google 
 . 
 maps 
 . 
 marker 
 . 
 AdvancedMarkerElement 
 ({ 
  
 position 
 : 
  
 initialCenter 
 , 
  
 title 
 : 
  
 'A marker using a custom SVG image.' 
 , 
  
 //@ts-ignore 
  
 anchorLeft 
 : 
  
 '-50%' 
 , 
  
 anchorTop 
 : 
  
 '-50%' 
 , 
  
 }); 
  
 centerMarker 
 . 
 append 
 ( 
 pinSvg 
 ); 
  
 mapElement 
 . 
 append 
 ( 
 centerMarker 
 ); 
  
 // Wait for the map to finish drawing its tiles. 
  
 google 
 . 
 maps 
 . 
 event 
 . 
 addListenerOnce 
 ( 
 innerMap 
 , 
  
 'tilesloaded' 
 , 
  
 function 
  
 () 
  
 { 
  
 // 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' 
 , 
  
 ( 
 event 
 ) 
  
 = 
>  
 { 
  
 const 
  
 target 
  
 = 
  
 event 
 . 
 target 
  
 as 
  
 HTMLInputElement 
 ; 
  
 walkingCircle 
 . 
 setRadius 
 ( 
 Number 
 ( 
 target 
 . 
 value 
 )); 
  
 }); 
  
 }); 
  
 // Handle user click, reset the map center and position the circle. 
  
 innerMap 
 . 
 addListener 
 ( 
 'click' 
 , 
  
 ( 
 mapsMouseEvent 
 ) 
  
 = 
>  
 { 
  
 const 
  
 newCenter 
  
 = 
  
 mapsMouseEvent 
 . 
 latLng 
 ; 
  
 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 
 (); 
  
 }); 
 } 
 initMap 
 (); 
  

JavaScript

 const 
  
 mapElement 
  
 = 
  
 document 
 . 
 querySelector 
 ( 
 'gmp-map' 
 ); 
 let 
  
 innerMap 
 ; 
 async 
  
 function 
  
 initMap 
 () 
  
 { 
  
 // Request needed libraries. 
  
 ( 
 await 
  
 google 
 . 
 maps 
 . 
 importLibrary 
 ( 
 'maps' 
 )); 
  
 ( 
 await 
  
 google 
 . 
 maps 
 . 
 importLibrary 
 ( 
 'marker' 
 )); 
  
 // Get the gmp-map element. 
  
 const 
  
 mapElement 
  
 = 
  
 document 
 . 
 querySelector 
 ( 
 'gmp-map' 
 ); 
  
 // Set the initial map center point. 
  
 const 
  
 initialCenter 
  
 = 
  
 { 
  
 lat 
 : 
  
 34.98956821576194 
 , 
  
 lng 
 : 
  
 135.74239981260283 
  
 }; 
  
 // Hotel Emion, Kyoto, Japan 
  
 // Get the inner map. 
  
 const 
  
 innerMap 
  
 = 
  
 mapElement 
 . 
 innerMap 
 ; 
  
 // Get the buttons. 
  
 const 
  
 buttons 
  
 = 
  
 document 
 . 
 querySelectorAll 
 ( 
 'input[name="radius"]' 
 ); 
  
 // Create the circle. 
  
 const 
  
 walkingCircle 
  
 = 
  
 new 
  
 google 
 . 
 maps 
 . 
 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 
  
 google 
 . 
 maps 
 . 
 marker 
 . 
 AdvancedMarkerElement 
 ({ 
  
 position 
 : 
  
 initialCenter 
 , 
  
 title 
 : 
  
 'A marker using a custom SVG image.' 
 , 
  
 //@ts-ignore 
  
 anchorLeft 
 : 
  
 '-50%' 
 , 
  
 anchorTop 
 : 
  
 '-50%' 
 , 
  
 }); 
  
 centerMarker 
 . 
 append 
 ( 
 pinSvg 
 ); 
  
 mapElement 
 . 
 append 
 ( 
 centerMarker 
 ); 
  
 // Wait for the map to finish drawing its tiles. 
  
 google 
 . 
 maps 
 . 
 event 
 . 
 addListenerOnce 
 ( 
 innerMap 
 , 
  
 'tilesloaded' 
 , 
  
 function 
  
 () 
  
 { 
  
 // 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' 
 , 
  
 ( 
 event 
 ) 
  
 = 
>  
 { 
  
 const 
  
 target 
  
 = 
  
 event 
 . 
 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 
 ; 
  
 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 
 (); 
  
 }); 
 } 
 initMap 
 (); 
  

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 
 : 
  
 2 
 px 
  
 solid 
  
 #fff 
 ; 
  
 border-radius 
 : 
  
 3 
 px 
 ; 
  
 box-shadow 
 : 
  
 0 
  
 2 
 px 
  
 6 
 px 
  
 rgba 
 ( 
 0 
 , 
  
 0 
 , 
  
 0 
 , 
  
 0.3 
 ); 
  
 font-family 
 : 
  
 "Roboto" 
 , 
  
 "sans-serif" 
 ; 
  
 font-size 
 : 
  
 medium 
 ; 
  
 margin 
 : 
  
 10 
 px 
 ; 
  
 padding 
 : 
  
 10 
 px 
 ; 
 } 
  

HTML

<html>
    <head>
        <title>Circles</title>

        <link rel="stylesheet" type="text/css" href="./style.css" />
        <script type="module" src="./index.js"></script>
        <!-- prettier-ignore -->
        <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: "AIzaSyA6myHzS10YXdcazAFalmXvDkrYCp5cLc8", v: "weekly", internalUsageAttributionIds: "gmp_git_jsapisamples_v1_core-maps" });</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>  

Try Sample

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.

  
  git 
  
 clone 
  
 https 
 : 
 //github.com/googlemaps-samples/js-api-samples.git 
 
  
  cd 
  
 samples 
 / 
 circle 
 - 
 simple 
 
  
  npm 
  
 i 
 
  
  npm 
  
 start 
 
Design a Mobile Site
View Site in Mobile | Classic
Share by: