Friday, May 28, 2010

Google Maps: Dynamically Drawn and Resizable Polygon Overlay

In extension to my previous post on Dynamically Movable and Resizable Circle Overlay, I created yet another nifty tool to dynamically draw a polygon overlay on Google Maps. You won’t find another robust tool like this for Polygon drawing on the internet. Users can draw polygon dynamically by adding, deleting and moving the polygon boundary nodes. User can press shift+click on the map to add a new node to polygon boundary or they can press ctrl+click on any node marker to remove it. The node markers can be dragged around to resize the polygon.

This is how it looks like in action:
Google Maps Dynamic Polygon

The JavaScript code is pretty easy to modify for your custom needs. The initialize() function is used to initialize the Google Map object when the page loads. A click event is also added to the map for adding node markers on the map. The click event takes care of the case when the user click on the previous markers while holding the shift key. When the user clicks on the map, addMarker() function is called to add another boundary node to the polygon. For every newly added marker, drag events are assigned for resizing the polygon and a click event is assigned to delete the node when ctrl key is pressed while clicking the marker pin. The fitPolygon() function is used to set map bounds and center to adjust the polygon inside it.

Put the following JavaScript code in the head section of your page:

<script src=";v=2&amp;key=YOUR_API_KEY&sensor=true" type="text/javascript"></script>
<script type="text/javascript">
/* Developed by: Abhinay Rathore [] */ 
//Global variables
var global = this;
var map;

var PolygonMarkers = []; //Array for Map Markers
var PolygonPoints = []; //Array for Polygon Node Markers
var bounds = new GLatLngBounds; //Polygon Bounds
var Polygon; //Polygon overlay object
var polygon_resizing = false; //To track Polygon Resizing

//Polygon Marker/Node icons
var redpin = new GIcon(); //Red Pushpin Icon
redpin.image = "";
redpin.iconSize = new GSize(32, 32);
redpin.iconAnchor = new GPoint(10, 32);
var bluepin = new GIcon(); //Blue Pushpin Icon
bluepin.image = "";
bluepin.iconSize = new GSize(32, 32);
bluepin.iconAnchor = new GPoint(10, 32);

function initialize() { //Initialize Google Map
    if (GBrowserIsCompatible()) {
        map = new GMap2(document.getElementById("map_canvas")); //New GMap object
        map.setCenter(new GLatLng(38.90, -94.68007), 13);

        var ui = new GMapUIOptions(); //Map UI options
        ui.maptypes = { normal:true, satellite:true, hybrid:true, physical:false }
        ui.zoom = {scrollwheel:true, doubleclick:true};
        ui.controls = { largemapcontrol3d:true, maptypecontrol:true, scalecontrol:true };
        map.setUI(ui); //Set Map UI options

        //Add Shift+Click event to add Polygon markers
        GEvent.addListener(map, "click", function(overlay, point, overlaypoint) {
            var p = (overlaypoint) ? overlaypoint : point;
            //Add polygon marker if overlay is not an existing marker and shift key is pressed
            if (global.shiftKey && !checkPolygonMarkers(overlay)) { addMarker(p); }

// Adds a new Polygon boundary marker
function addMarker(point) {
    var markerOptions = { icon: bluepin, draggable: true };
    var marker = new GMarker(point, markerOptions);
    PolygonMarkers.push(marker); //Add marker to PolygonMarkers array
    map.addOverlay(marker); //Add marker on the map
    GEvent.addListener(marker,'dragstart',function(){ //Add drag start event
        polygon_resizing = true;
    GEvent.addListener(marker,'drag',function(){ drawPolygon(); }); //Add drag event
    GEvent.addListener(marker,'dragend',function(){   //Add drag end event
        polygon_resizing = false;
    GEvent.addListener(marker,'click',function(point) { //Add Ctrl+Click event to remove marker
        if (global.ctrlKey) { removeMarker(point); }

    //If more then 2 nodes then automatically fit the polygon
    if(PolygonMarkers.length > 2) fitPolygon();

// Removes a Polygon boundary marker
function removeMarker(point) {
    if(PolygonMarkers.length == 1){ //Only one marker in the array
        PolygonMarkers = [];
      else //More then one marker
        var RemoveIndex = -1;
        var Remove;
        //Search for clicked Marker in PolygonMarkers Array
        for(var m=0; m<PolygonMarkers.length; m++)
                RemoveIndex = m; Remove = PolygonMarkers[m]
        //Shift Array elemeents to left
        for(var n=RemoveIndex; n<PolygonMarkers.length-1; n++)
            PolygonMarkers[n] = PolygonMarkers[n+1];
        PolygonMarkers.length = PolygonMarkers.length-1 //Decrease Array length by 1
        map.removeOverlay(Remove); //Remove Marker
        drawPolygon(); //Redraw Polygon

//Draw Polygon from the PolygonMarkers Array
function drawPolygon()
    for(var m=0; m<PolygonMarkers.length; m++)
        PolygonPoints.push(PolygonMarkers[m].getPoint()); //Add Markers to PolygonPoints node array
    //Add first marker in the end to close the Polygon
    if(Polygon){ map.removeOverlay(Polygon); } //Remove existing Polygon from Map
    var fillColor = (polygon_resizing) ? 'red' : 'blue'; //Set Polygon Fill Color
    Polygon = new GPolygon(PolygonPoints, '#FF0000', 2, 1, fillColor, 0.2); //New GPolygon object
    map.addOverlay(Polygon); //Add Polygon to the Map

    //TO DO: Function Call triggered after Polygon is drawn

//Fits the Map to Polygon bounds
function fitPolygon(){
    bounds = Polygon.getBounds();
    map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));
//check is the marker is a polygon boundary marker
function checkPolygonMarkers(marker) {
    var flag = false;
    for (var m = 0; m < PolygonMarkers.length; m++) {
        if (marker == PolygonMarkers[m])
        { flag = true; break; }
    return flag;

//////////////////[ Key down event handler ]/////////////////////
//Event handler class to attach events
var EventUtil = {
      addHandler: function(element, type, handler){
            if (element.addEventListener){
                    element.addEventListener(type, handler, false);
            } else if (element.attachEvent){
                    element.attachEvent("on" + type, handler);
            } else {
                    element["on" + type] = handler;

// Attach Key down/up events to document
EventUtil.addHandler(document, "keydown", function(event){keyDownHandler(event)});
EventUtil.addHandler(document, "keyup", function(event){keyUpHandler(event)});

//Checks for shift and Ctrl key press
function keyDownHandler(e)
      if (!e) var e = window.event;
      var target = (! ? e.srcElement :;
      if (e.keyCode == 16 && !global.shiftKey) { //Shift Key
            global.shiftKey = true;
      if (e.keyCode == 17 && !global.ctrlKey) { //Ctrl Key
            global.ctrlKey = true;
//Checks for shift and Ctrl key release
function keyUpHandler(e){
      if (!e) var e = window.event;
      if (e.keyCode == 16 && global.shiftKey) { //Shift Key
            global.shiftKey = false;
      if (e.keyCode == 17 && global.ctrlKey) { //Ctrl Key
            global.ctrlKey = false;

To initialize the map you can call the functions on page load event and include a div tag inside your body to hold the Map.

<body onload="initialize()" onunload="GUnload()">
<div id="map_canvas" style="width:100%; height:450px"></div>

Feel free to modify and use this code on your website. I have used API v2 for my code but you can easily modify this code for API v3. Happy Mapping!


  1. Excellent, thanks a lot for sharing this, now, if i wanted to save markers position in a db, what would i have to do?

    1. Hi, Great.. Tutorial is just awesome..It is really helpful for a newbie like me.. I am a regular follower of your blog. Really very informative post you shared here. Kindly keep blogging. If anyone wants to become a Front end developer learn from Javascript Training in Chennai . or Javascript Training in Chennai. Nowadays JavaScript has tons of job opportunities on various vertical industry. ES6 Training in Chennai

  2. You have the marker array (PolygonMarkers)... just use that to populate a list of lat/longs and store it in db.
    You can populate a hidden field with lat/longs on your page and then submit it to next page for processing.

    1. can you elaborate on how you extract each polygon marker value so that I can actually send them to a db, and then how you get a stored points in a db row to overlay/populate on a map. I dont even seem to be able to bring up an alert box to show me what my value is each time I click a point.
      I have tried alert(JSON.stringify(PolygonMarkers)) and alert(PolygonMarkers[1]) and just cant get anything to show.

    2. Hi Abhinay
      How can I store the marker array into the database?

  3. How about an API v3 version?

  4. Hi Abhinav,

    can you please suggest how can i initialize

    var PolygonMarkers = []; and
    var PolygonPoints = [];

    i mean can you please put a dummy data into these 2 variables

    Thanks in advance

    1. ahh there is nothing to do with these 2 variables thanks a lot i got my desired solution

  5. Oooh yess!! After visited lots of page,come to actual mark point...
    Thanks..Its nice..

  6. Hi I don't know if I made a simple mistake but the map seems to load then crash. Here is a fiddle of it
    Any help would be appreciated, thanks!

    1. Hi Nathan,

      Try removing 'YOUR_API_KEY' from script tag.


  7. can any one tell that how this PolygonMarkers can store in the database

  8. Python is a general-purpose interpreted, interactive, object-oriented and high-level programming language. Currently Python is the most popular Language in IT.

  9. mytectra placement Portal is a Web based portal brings Potentials Employers and myTectra Candidates on a common platform for placement assistance.

  10. Thank you for sharing your article. Great efforts put it to find the list of articles which is very useful to know, Definitely will share the same to other forums.
    Data Science Training in chennai at Credo Systemz | data science course fees in chennai | data science course in chennai quora | data science with python training in chennai

  11. Guaranteed #1 Search Engine Ranking Supreme Free Viral Traffic Join Now Get Millions Of Hits Free To Your Site/Blog!

    PornKings Adult Shopping Backlinks-Shopping Mega Store Legendary Stars As Stormy Daniels,Shawna Edwards,Jenna Jamison-New Adult Stars Movies,Adult Toys,Enhancers,Merchandise-More !

    Hits Express Rotator System Do You Need Visitors to Your Website or Affiliate Program? If your looking to gain more visitors to your website Hits Express is your answer. With our program your site is being shown to people all over the world 24/7 365 days a year!

    PAYDIR Free For All Forum Portal Search Engine Crawled Network PR10 Ranking Information Forum XXX!

    FreeLinkExchanges Be Seen In 12 Nations 312 Sites Over 30 Millions Viewers Monthly Buy Featured Link Now With 150 Search Engines Crawling The Network!

    How do I get guaranteed traffic? When someone signs up from your site, they must first click on your classified ad which will open a new window leading to your main website. They will have to wait a few seconds for the code to appear on a separate frame at the top of the screen reach millions free now!

    Blast Your Ad to Over 23,000 Opt-in Prospects at ShowMyLinks Submit Your Solo Email Ad to All Showmylinks Members GET YOUR TEXT LINK ADs LISTED 100% FREE FOR LIFE PLUS EARN MONEY TO YOUR PAYPAL!!

    Adult Store Empires Backlinks Resources Search Engine XXX!

    GET YOUR OWN MONEY-MAKING AD BOARD -- Integrating Text ad, Banner Ad and Email Ad into one Portal Make Money Fast With Your Paypal Reach Million Dollars In A Year Fast !

    Full Length Homemade Videos Watch real people's private home sex videos. Forget about those shitty 1-2 minute clips, these are all high quality full length videos! 40+ Bonus Sites You will also get full access to the entire reelpass network of sites which features over 40+ awesome movie sites, 1000's of movies and pictures to download! Download, Burn & Share Not only do you get to watch all our movies, you can also download every single one and save it forever, burn them to dvd or share with friends!!


Thanks a lot for your valuable comments :)