import earcut from 'earcut'; import { polygon } from '@turf/helpers'; /** * Tesselates a {@link Feature} into a {@link FeatureCollection} of triangles * using [earcut](https://github.com/mapbox/earcut). * * @name tesselate * @param {Feature} poly the polygon to tesselate * @returns {FeatureCollection} a geometrycollection feature * @example * var poly = turf.polygon([[[11, 0], [22, 4], [31, 0], [31, 11], [21, 15], [11, 11], [11, 0]]]); * var triangles = turf.tesselate(poly); * * //addToMap * var addToMap = [poly, triangles] */ function tesselate(poly) { if ( !poly.geometry || (poly.geometry.type !== "Polygon" && poly.geometry.type !== "MultiPolygon") ) { throw new Error("input must be a Polygon or MultiPolygon"); } var fc = { type: "FeatureCollection", features: [] }; if (poly.geometry.type === "Polygon") { fc.features = processPolygon(poly.geometry.coordinates); } else { poly.geometry.coordinates.forEach(function (coordinates) { fc.features = fc.features.concat(processPolygon(coordinates)); }); } return fc; } function processPolygon(coordinates) { var data = flattenCoords(coordinates); var dim = 2; var result = earcut(data.vertices, data.holes, dim); var features = []; var vertices = []; result.forEach(function (vert, i) { var index = result[i]; vertices.push([data.vertices[index * dim], data.vertices[index * dim + 1]]); }); for (var i = 0; i < vertices.length; i += 3) { var coords = vertices.slice(i, i + 3); coords.push(vertices[i]); features.push(polygon([coords])); } return features; } function flattenCoords(data) { var dim = data[0][0].length, result = { vertices: [], holes: [], dimensions: dim }, holeIndex = 0; for (var i = 0; i < data.length; i++) { for (var j = 0; j < data[i].length; j++) { for (var d = 0; d < dim; d++) result.vertices.push(data[i][j][d]); } if (i > 0) { holeIndex += data[i - 1].length; result.holes.push(holeIndex); } } return result; } export default tesselate;