index.js 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. import earcut from 'earcut';
  2. import { polygon } from '@turf/helpers';
  3. /**
  4. * Tesselates a {@link Feature<Polygon>} into a {@link FeatureCollection<Polygon>} of triangles
  5. * using [earcut](https://github.com/mapbox/earcut).
  6. *
  7. * @name tesselate
  8. * @param {Feature<Polygon>} poly the polygon to tesselate
  9. * @returns {FeatureCollection<Polygon>} a geometrycollection feature
  10. * @example
  11. * var poly = turf.polygon([[[11, 0], [22, 4], [31, 0], [31, 11], [21, 15], [11, 11], [11, 0]]]);
  12. * var triangles = turf.tesselate(poly);
  13. *
  14. * //addToMap
  15. * var addToMap = [poly, triangles]
  16. */
  17. function tesselate(poly) {
  18. if (
  19. !poly.geometry ||
  20. (poly.geometry.type !== "Polygon" && poly.geometry.type !== "MultiPolygon")
  21. ) {
  22. throw new Error("input must be a Polygon or MultiPolygon");
  23. }
  24. var fc = { type: "FeatureCollection", features: [] };
  25. if (poly.geometry.type === "Polygon") {
  26. fc.features = processPolygon(poly.geometry.coordinates);
  27. } else {
  28. poly.geometry.coordinates.forEach(function (coordinates) {
  29. fc.features = fc.features.concat(processPolygon(coordinates));
  30. });
  31. }
  32. return fc;
  33. }
  34. function processPolygon(coordinates) {
  35. var data = flattenCoords(coordinates);
  36. var dim = 2;
  37. var result = earcut(data.vertices, data.holes, dim);
  38. var features = [];
  39. var vertices = [];
  40. result.forEach(function (vert, i) {
  41. var index = result[i];
  42. vertices.push([data.vertices[index * dim], data.vertices[index * dim + 1]]);
  43. });
  44. for (var i = 0; i < vertices.length; i += 3) {
  45. var coords = vertices.slice(i, i + 3);
  46. coords.push(vertices[i]);
  47. features.push(polygon([coords]));
  48. }
  49. return features;
  50. }
  51. function flattenCoords(data) {
  52. var dim = data[0][0].length,
  53. result = { vertices: [], holes: [], dimensions: dim },
  54. holeIndex = 0;
  55. for (var i = 0; i < data.length; i++) {
  56. for (var j = 0; j < data[i].length; j++) {
  57. for (var d = 0; d < dim; d++) result.vertices.push(data[i][j][d]);
  58. }
  59. if (i > 0) {
  60. holeIndex += data[i - 1].length;
  61. result.holes.push(holeIndex);
  62. }
  63. }
  64. return result;
  65. }
  66. export default tesselate;