Google Maps – Interactive creation of polygons on map

In this post I am going to present to you how to use Google Maps API V3 to create functionality to draw polygons using polyline, just like in example hosted here. User can simply click points on the map that will be interconnected with straight lines (in general creating one polyline), once when all points are set, user can click “Set Polygon” control in left bottom corner and polygon will be created based on the points that are previously set, also coordinates are displayed in the input box below the map so that can be previewed. There is another control “Clear” that removes created polygon and user is able to create new one from scratch.

This example is made based on Google tutorial and examples that can be found on this link.

For start we shall create one html file:

<!DOCTYPE html>
<html>
  <head>
  <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
  <meta charset="utf-8">
  <title>Draw Polygons</title>
  <style>
    html, body, #map-canvas {
      height: 500px;
      width: 800px;
      margin: 0px;
      padding: 0px
    }
  </style>
  <script src="https://maps.googleapis.com/maps/api/js?v=3.exp&signed_in=true"></script>
  </head>
  <body>
    <div id="map-canvas"></div>
    <input type="text" id="valuebox"/>
  </body>
</html>

Basically in this html we are importing Google Maps API and defining in the body two elements, one div element, identified with id map-canvas, that will hold map  (size and position is defined in the style at the beginning of this html file) and input element that will display list of coordinates of a polygon.

Just below imported Google maps script we shall open up script tag where we can put our code, so let me start with code that is supposed to initialize and load map.

var map;
var poly;
var centerPoint= new google.maps.LatLng(41.85, -87.65);
var polyOptions = {
  strokeColor: '#000000',
  strokeOpacity: 1.0,
  strokeWeight: 2
};
var area;

function initialize() {
   var mapDiv = document.getElementById('map-canvas');
   //define map options
   var mapOptions = {
     zoom: 12,
     center: centerPoint
   }
   //create map
   map = new google.maps.Map(mapDiv, mapOptions);
   //create polyline and set it for map.
   poly = new google.maps.Polyline(polyOptions);
   poly.setMap(map);
   //add click listener for map to call function addLatLng()
   google.maps.event.addListener(map, 'click', addLatLng);
   // Create the DIV to hold the control and
   // call the PolygonControl() constructor passing in this DIV.
   var centerControlDiv = document.createElement('div');
   var centerControl = new PolygonControl(centerControlDiv, map);

   map.controls[google.maps.ControlPosition.BOTTOM_LEFT].push(centerControlDiv);
}
google.maps.event.addDomListener(window, 'load', initialize);

As you can see we are first defining couple of variables:

poly – represents polyline that will be drawn based on the points that user will define when clicking on map

centerPoint – center of the map when loaded

polyoptions – array of options for the polyline

area – polygon that will be drawn at the end based on defined polyline

Next defined is a function initialize. This function is called on loading the page (by setting DOM listener to call this method on loading the page – setting this listener is at the end of above code portion). Initialize method does couple of things:  first fetches div tag that will hold map and defines map options (in this case defines initial zoom and center of the map). Based on those two, map gets created by calling google.maps.Map constructor.  After that we define polyline and we associate it with map.

Then we are set click listener on the map to call addLatLng method. This method is supposed to draw polyline based on each click (point) on the map. But lets see details of this method in a few moments.

Final step of initialize method is to create div elements that will hold controls having  two actions, one to create polygon once polyline is fully drawn by user and another one to remove polygon (you can say reset map) in case user wants to create another one.  Creed div is control holder  created by calling createElement method on document object and then  div is passed to constructor of PolygonControl together with map object. This PolygonControl will create two control objects, how this is done will see in later in this article. Finally we add this controller div to map.

Next is to look at the method addLatLng that will be called each time user clicks on a map to draw polyline.


function addLatLng(event) {
  var path = poly.getPath();
  path.push(event.latLng);
}

As you can see this is very simple method, first it takes path of the polyline that is created so far and then pushes to this path latitude and longitude from the current event (click) so that last part of the polyline is automatically drawn.

Let’s now take a look at the PolygonControl constructor that is creating options on the map.


function PolygonControl(controlDiv, map) {

  var createPolygonControl = document.createElement('div');
  createPolygonControl.style.backgroundColor = '#fff';
  createPolygonControl.style.border = '2px solid #fff';
  createPolygonControl.style.borderRadius = '3px';
  createPolygonControl.style.boxShadow = '0 2px 6px rgba(0,0,0,.3)';
  createPolygonControl.style.cursor = 'pointer';
  createPolygonControl.style.marginBottom = '22px';
  createPolygonControl.style.textAlign = 'center';
  createPolygonControl.title = 'Click to set area';
  controlDiv.appendChild(createPolygonControl);

  var createPolygonText = document.createElement('div');
  createPolygonText.style.color = 'rgb(25,25,25)';
  createPolygonText.style.fontFamily = 'Roboto,Arial,sans-serif';
  createPolygonText.style.fontSize = '16px';
  createPolygonText.style.lineHeight = '38px';
  createPolygonText.style.paddingLeft = '5px';
  createPolygonText.style.paddingRight = '5px';
  createPolygonText.innerHTML = 'Set Polygon';
  createPolygonControl.appendChild(createPolygonText);

  var resetPolygonControll = document.createElement('div');
  resetPolygonControll.style.backgroundColor = '#fff';
  resetPolygonControll.style.border = '2px solid #fff';
  resetPolygonControll.style.borderRadius = '3px';
  resetPolygonControll.style.boxShadow = '0 2px 6px rgba(0,0,0,.3)';
  resetPolygonControll.style.cursor = 'pointer';
  resetPolygonControll.style.marginBottom = '22px';
  resetPolygonControll.style.textAlign = 'center';
  resetPolygonControll.title = 'Clear Area';
  controlDiv.appendChild(resetPolygonControll);

  var resetPolygonText = document.createElement('div');
  resetPolygonText.style.color = 'rgb(25,25,25)';
  resetPolygonText.style.fontFamily = 'Roboto,Arial,sans-serif';
  resetPolygonText.style.fontSize = '16px';
  resetPolygonText.style.lineHeight = '38px';
  resetPolygonText.style.paddingLeft = '5px';
  resetPolygonText.style.paddingRight = '5px';
  resetPolygonText.innerHTML = 'Clear';
  resetPolygonControll.appendChild(resetPolygonText);

  // Setup the click event listeners
  google.maps.event.addDomListener(createPolygonControl, 'click', drawPolygon);

  google.maps.event.addDomListener(resetPolygonControll, 'click', removePolygon);

}

This long method is actually simple one, first four blocks are just used to define two controls (one to draw polygon and one to remove it), for each control we have two blocks of code, one to define the control and one to define inner text of the control (nested divs in general) and finally to add them to the main control div passed as argument of this constructor (function).

Final part is to add listeners for each option that will on click call methods:

drawPolygon  – for “Set Polygon” control

removePolygon – for “Clear” control

We shall see now how those two methods are defined.

 

function drawPolygon(){
  google.maps.event.clearListeners(map, 'click');
  if(area!=null){
    area.setMap(null);
  }
  var valuebox = document.getElementById('valuebox');
  var points = poly.getPath().getArray();
  valuebox.value = points.toString();
  poly.setMap(null);

  area = new google.maps.Polygon({
    paths: points,
    strokeColor: '#FF0000',
    strokeOpacity: 0.8,
    strokeWeight: 3,
    fillColor: '#FF0000',
    fillOpacity: 0.35
  });
  area.setMap(map);
}

if we take a look at the drawPolygon method we shall see that first we remove click listener on the map, so that we do not register another clicks at the moment we draw polygon. Next we remove existing polygon from the map (in case user draw previously polygons they shall be drawn again, so we want then to be removed and draw only new polygon based on polyline user created), after this we fetch input box to set it’s value with list of points from the polyline (these points can be saved and used later to draw polygon again). Finally we define Polygon and set it on the map.

function removePolygon(){
 poly = new google.maps.Polyline(polyOptions);
 poly.setMap(map);
 area.setMap(null);
 google.maps.event.addListener(map, 'click', addLatLng);
 var valuebox = document.getElementById('valuebox');
 valuebox.value = "";
}

removePolygon method is supposed to reset things so that user can draw new polygon. To do that first creates new polyline and associates map to it, removes polygon from the map and adds new listener that will call addLatLng method on each click of the map (just like in initialize method). Finally it clears the input box.

I hope you guys found this article useful for some of your integration with Google Maps. As I mentioned at the beginning of this article you can find example here and also find full source of this example by viewing source.

Have a nice day!

 

 

 

Posted in General Programming Tagged with: , ,

Leave a Reply

Your email address will not be published. Required fields are marked *

*

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Subscribe for Newsletter

Categories