import { polygon, multiPolygon } from '@turf/helpers'; import polygonClipping from 'polygon-clipping'; /** * Takes any type of {@link Polygon|polygon} and an optional mask and returns a {@link Polygon|polygon} exterior ring with holes. * * @name mask * @param {FeatureCollection|Feature} polygon GeoJSON Polygon used as interior rings or holes. * @param {Feature} [mask] GeoJSON Polygon used as the exterior ring (if undefined, the world extent is used) * @returns {Feature} Masked Polygon (exterior ring with holes). * @example * var polygon = turf.polygon([[[112, -21], [116, -36], [146, -39], [153, -24], [133, -10], [112, -21]]]); * var mask = turf.polygon([[[90, -55], [170, -55], [170, 10], [90, 10], [90, -55]]]); * * var masked = turf.mask(polygon, mask); * * //addToMap * var addToMap = [masked] */ function mask(polygon, mask) { // Define mask var maskPolygon = createMask(mask); var polygonOuters = null; if (polygon.type === "FeatureCollection") polygonOuters = unionFc(polygon); else polygonOuters = createGeomFromPolygonClippingOutput( polygonClipping.union(polygon.geometry.coordinates) ); polygonOuters.geometry.coordinates.forEach(function (contour) { maskPolygon.geometry.coordinates.push(contour[0]); }); return maskPolygon; } function unionFc(fc) { var unioned = fc.features.length === 2 ? polygonClipping.union( fc.features[0].geometry.coordinates, fc.features[1].geometry.coordinates ) : polygonClipping.union.apply( polygonClipping, fc.features.map(function (f) { return f.geometry.coordinates; }) ); return createGeomFromPolygonClippingOutput(unioned); } function createGeomFromPolygonClippingOutput(unioned) { return multiPolygon(unioned); } /** * Create Mask Coordinates * * @private * @param {Feature} [mask] default to world if undefined * @returns {Feature} mask coordinate */ function createMask(mask) { var world = [ [ [180, 90], [-180, 90], [-180, -90], [180, -90], [180, 90], ], ]; var coordinates = (mask && mask.geometry.coordinates) || world; return polygon(coordinates); } export default mask;