123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- import { geomReduce } from "@turf/meta";
- // Note: change RADIUS => earthRadius
- var RADIUS = 6378137;
- /**
- * Takes one or more features and returns their area in square meters.
- *
- * @name area
- * @param {GeoJSON} geojson input GeoJSON feature(s)
- * @returns {number} area in square meters
- * @example
- * var polygon = turf.polygon([[[125, -15], [113, -22], [154, -27], [144, -15], [125, -15]]]);
- *
- * var area = turf.area(polygon);
- *
- * //addToMap
- * var addToMap = [polygon]
- * polygon.properties.area = area
- */
- export default function area(geojson) {
- return geomReduce(geojson, function (value, geom) {
- return value + calculateArea(geom);
- }, 0);
- }
- /**
- * Calculate Area
- *
- * @private
- * @param {Geometry} geom GeoJSON Geometries
- * @returns {number} area
- */
- function calculateArea(geom) {
- var total = 0;
- var i;
- switch (geom.type) {
- case "Polygon":
- return polygonArea(geom.coordinates);
- case "MultiPolygon":
- for (i = 0; i < geom.coordinates.length; i++) {
- total += polygonArea(geom.coordinates[i]);
- }
- return total;
- case "Point":
- case "MultiPoint":
- case "LineString":
- case "MultiLineString":
- return 0;
- }
- return 0;
- }
- function polygonArea(coords) {
- var total = 0;
- if (coords && coords.length > 0) {
- total += Math.abs(ringArea(coords[0]));
- for (var i = 1; i < coords.length; i++) {
- total -= Math.abs(ringArea(coords[i]));
- }
- }
- return total;
- }
- /**
- * @private
- * Calculate the approximate area of the polygon were it projected onto the earth.
- * Note that this area will be positive if ring is oriented clockwise, otherwise it will be negative.
- *
- * Reference:
- * Robert. G. Chamberlain and William H. Duquette, "Some Algorithms for Polygons on a Sphere",
- * JPL Publication 07-03, Jet Propulsion
- * Laboratory, Pasadena, CA, June 2007 https://trs.jpl.nasa.gov/handle/2014/40409
- *
- * @param {Array<Array<number>>} coords Ring Coordinates
- * @returns {number} The approximate signed geodesic area of the polygon in square meters.
- */
- function ringArea(coords) {
- var p1;
- var p2;
- var p3;
- var lowerIndex;
- var middleIndex;
- var upperIndex;
- var i;
- var total = 0;
- var coordsLength = coords.length;
- if (coordsLength > 2) {
- for (i = 0; i < coordsLength; i++) {
- if (i === coordsLength - 2) {
- // i = N-2
- lowerIndex = coordsLength - 2;
- middleIndex = coordsLength - 1;
- upperIndex = 0;
- }
- else if (i === coordsLength - 1) {
- // i = N-1
- lowerIndex = coordsLength - 1;
- middleIndex = 0;
- upperIndex = 1;
- }
- else {
- // i = 0 to N-3
- lowerIndex = i;
- middleIndex = i + 1;
- upperIndex = i + 2;
- }
- p1 = coords[lowerIndex];
- p2 = coords[middleIndex];
- p3 = coords[upperIndex];
- total += (rad(p3[0]) - rad(p1[0])) * Math.sin(rad(p2[1]));
- }
- total = (total * RADIUS * RADIUS) / 2;
- }
- return total;
- }
- function rad(num) {
- return (num * Math.PI) / 180;
- }
|