index.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. import turfBBox from "@turf/bbox";
  2. import { getCoords, getGeom } from "@turf/invariant";
  3. import { polygon, multiPolygon, lineString, } from "@turf/helpers";
  4. import clone from "@turf/clone";
  5. /**
  6. * Converts (Multi)LineString(s) to Polygon(s).
  7. *
  8. * @name lineToPolygon
  9. * @param {FeatureCollection|Feature<LineString|MultiLineString>} lines Features to convert
  10. * @param {Object} [options={}] Optional parameters
  11. * @param {Object} [options.properties={}] translates GeoJSON properties to Feature
  12. * @param {boolean} [options.autoComplete=true] auto complete linestrings (matches first & last coordinates)
  13. * @param {boolean} [options.orderCoords=true] sorts linestrings to place outer ring at the first position of the coordinates
  14. * @param {boolean} [options.mutate=false] mutate the original linestring using autoComplete (matches first & last coordinates)
  15. * @returns {Feature<Polygon|MultiPolygon>} converted to Polygons
  16. * @example
  17. * var line = turf.lineString([[125, -30], [145, -30], [145, -20], [125, -20], [125, -30]]);
  18. *
  19. * var polygon = turf.lineToPolygon(line);
  20. *
  21. * //addToMap
  22. * var addToMap = [polygon];
  23. */
  24. function lineToPolygon(lines, options) {
  25. if (options === void 0) { options = {}; }
  26. var _a, _b, _c;
  27. // Optional parameters
  28. var properties = options.properties;
  29. var autoComplete = (_a = options.autoComplete) !== null && _a !== void 0 ? _a : true;
  30. var orderCoords = (_b = options.orderCoords) !== null && _b !== void 0 ? _b : true;
  31. var mutate = (_c = options.mutate) !== null && _c !== void 0 ? _c : false;
  32. if (!mutate) {
  33. lines = clone(lines);
  34. }
  35. switch (lines.type) {
  36. case "FeatureCollection":
  37. var coords = [];
  38. lines.features.forEach(function (line) {
  39. coords.push(getCoords(lineStringToPolygon(line, {}, autoComplete, orderCoords)));
  40. });
  41. return multiPolygon(coords, properties);
  42. default:
  43. return lineStringToPolygon(lines, properties, autoComplete, orderCoords);
  44. }
  45. }
  46. /**
  47. * LineString to Polygon
  48. *
  49. * @private
  50. * @param {Feature<LineString|MultiLineString>} line line
  51. * @param {Object} [properties] translates GeoJSON properties to Feature
  52. * @param {boolean} [autoComplete=true] auto complete linestrings
  53. * @param {boolean} [orderCoords=true] sorts linestrings to place outer ring at the first position of the coordinates
  54. * @returns {Feature<Polygon>} line converted to Polygon
  55. */
  56. function lineStringToPolygon(line, properties, autoComplete, orderCoords) {
  57. properties = properties
  58. ? properties
  59. : line.type === "Feature"
  60. ? line.properties
  61. : {};
  62. var geom = getGeom(line);
  63. var coords = geom.coordinates;
  64. var type = geom.type;
  65. if (!coords.length)
  66. throw new Error("line must contain coordinates");
  67. switch (type) {
  68. case "LineString":
  69. if (autoComplete)
  70. coords = autoCompleteCoords(coords);
  71. return polygon([coords], properties);
  72. case "MultiLineString":
  73. var multiCoords = [];
  74. var largestArea = 0;
  75. coords.forEach(function (coord) {
  76. if (autoComplete)
  77. coord = autoCompleteCoords(coord);
  78. // Largest LineString to be placed in the first position of the coordinates array
  79. if (orderCoords) {
  80. var area = calculateArea(turfBBox(lineString(coord)));
  81. if (area > largestArea) {
  82. multiCoords.unshift(coord);
  83. largestArea = area;
  84. }
  85. else
  86. multiCoords.push(coord);
  87. }
  88. else {
  89. multiCoords.push(coord);
  90. }
  91. });
  92. return polygon(multiCoords, properties);
  93. default:
  94. throw new Error("geometry type " + type + " is not supported");
  95. }
  96. }
  97. /**
  98. * Auto Complete Coords - matches first & last coordinates
  99. *
  100. * @private
  101. * @param {Array<Array<number>>} coords Coordinates
  102. * @returns {Array<Array<number>>} auto completed coordinates
  103. */
  104. function autoCompleteCoords(coords) {
  105. var first = coords[0];
  106. var x1 = first[0];
  107. var y1 = first[1];
  108. var last = coords[coords.length - 1];
  109. var x2 = last[0];
  110. var y2 = last[1];
  111. if (x1 !== x2 || y1 !== y2) {
  112. coords.push(first);
  113. }
  114. return coords;
  115. }
  116. /**
  117. * area - quick approximate area calculation (used to sort)
  118. *
  119. * @private
  120. * @param {Array<number>} bbox BBox [west, south, east, north]
  121. * @returns {number} very quick area calculation
  122. */
  123. function calculateArea(bbox) {
  124. var west = bbox[0];
  125. var south = bbox[1];
  126. var east = bbox[2];
  127. var north = bbox[3];
  128. return Math.abs(west - east) * Math.abs(south - north);
  129. }
  130. export default lineToPolygon;