Polygon area

HTML

<script src="https://api-maps.yandex.ru/2.1/?lang=ru_RU&amp;ns=ym"></script>
<div id="map"></div>

CSS

html, body, #map {
  width: 100%;
  height: 100%;
}

Babel + JSX

// Helper module
// Maybe not good idea to use in separate module
ym.modules.define('geo.utils', provide => {
	provide({
  	RADIUS: 6378137,
    toRad: deg => deg * Math.PI / 180
  });
});

/**
	Calculate area for polygon without self-crossings. Support polygon holes.
  Return area in square meters
  see http://trs-new.jpl.nasa.gov/dspace/bitstream/2014/41271/1/07-0286.pdf
**/
ym.modules.define('geo.polygonArea', ['geo.utils'], (provide, util) => {
	const {RADIUS, toRad} = util;
	function calculatePolygonArea (polygon) {
  	let area = 0;
  	const polyCoords = polygon.geometry.getCoordinates();
    if (polyCoords.length === 0) {
    	return area;
    }
    area = calculateArea(polyCoords[0]);
    for (let i = 1; i < polyCoords.length - 1; i++) {
    	area -= calculateArea(polyCoords[i]);
    }
    
    return area;
  }
  
  function calculateArea (coords) {
  	let area = 0;
  	for (let i = 0; i < coords.length - 1; i++) {
      let p1 = coords[i];
      let p2 = coords[i + 1];
      area += toRad(p2[1] - p1[1]) * (2 + Math.sin(toRad(p1[0])) + Math.sin(toRad(p2[0])));
    }

    return Math.abs(area * RADIUS * RADIUS / 2.0);
  }
  
	provide({calculatePolygonArea});
});

ym.ready({
	require: ['geo.polygonArea'],
	successCallback: () => {
  	const vertices = [];
    let polygon;
    const map = new ym.Map('map', {
      center: [38.89399, -77.03659],
      zoom: 16,
      controls: []
    });

    map.events.add('click', event => {
      vertices.push(event.get('coords'));
      map.geoObjects.add(
      	new ym.Placemark(event.get('coords'), null, {preset: 'islands#lightBlueCircleDotIcon'})
     	);

      polygon && polygon.geometry.setCoordinates([vertices]) && console.log(ym.geo.polygonArea.calculatePolygonArea(polygon) / 1000000);

      if (vertices.length > 2 && !polygon) {
        polygon = new ym.Polygon([vertices]);
        map.geoObjects.add(polygon);
      }
    });
  }
});