Polygon area
HTML
<script src="https://api-maps.yandex.ru/2.1/?lang=ru_RU&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);
}
});
}
});