index.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. // index.ts
  2. import {
  3. featureCollection,
  4. isNumber,
  5. isObject,
  6. lineString,
  7. point,
  8. polygon,
  9. validateBBox
  10. } from "@turf/helpers";
  11. function randomPosition(bbox) {
  12. checkBBox(bbox);
  13. return randomPositionUnchecked(bbox);
  14. }
  15. function randomPositionUnchecked(bbox) {
  16. if (Array.isArray(bbox)) {
  17. return coordInBBox(bbox);
  18. }
  19. if (bbox && bbox.bbox) {
  20. return coordInBBox(bbox.bbox);
  21. }
  22. return [lon(), lat()];
  23. }
  24. function checkBBox(bbox) {
  25. if (bbox == null) {
  26. return;
  27. } else if (Array.isArray(bbox)) {
  28. validateBBox(bbox);
  29. } else if (bbox.bbox != null) {
  30. validateBBox(bbox.bbox);
  31. }
  32. }
  33. function randomPoint(count, options = {}) {
  34. checkBBox(options.bbox);
  35. if (count === void 0 || count === null) {
  36. count = 1;
  37. }
  38. const features = [];
  39. for (let i = 0; i < count; i++) {
  40. features.push(point(randomPositionUnchecked(options.bbox)));
  41. }
  42. return featureCollection(features);
  43. }
  44. function randomPolygon(count, options = {}) {
  45. checkBBox(options.bbox);
  46. if (count === void 0 || count === null) {
  47. count = 1;
  48. }
  49. if (options.bbox === void 0 || options.bbox === null) {
  50. options.bbox = [-180, -90, 180, 90];
  51. }
  52. if (!isNumber(options.num_vertices) || options.num_vertices === void 0) {
  53. options.num_vertices = 10;
  54. }
  55. if (!isNumber(options.max_radial_length) || options.max_radial_length === void 0) {
  56. options.max_radial_length = 10;
  57. }
  58. const bboxWidth = Math.abs(options.bbox[0] - options.bbox[2]);
  59. const bboxHeight = Math.abs(options.bbox[1] - options.bbox[3]);
  60. const maxRadius = Math.min(bboxWidth / 2, bboxHeight / 2);
  61. if (options.max_radial_length > maxRadius) {
  62. throw new Error("max_radial_length is greater than the radius of the bbox");
  63. }
  64. const paddedBbox = [
  65. options.bbox[0] + options.max_radial_length,
  66. options.bbox[1] + options.max_radial_length,
  67. options.bbox[2] - options.max_radial_length,
  68. options.bbox[3] - options.max_radial_length
  69. ];
  70. const features = [];
  71. for (let i = 0; i < count; i++) {
  72. let vertices = [];
  73. const circleOffsets = [...Array(options.num_vertices + 1)].map(Math.random);
  74. circleOffsets.forEach((cur, index, arr) => {
  75. arr[index] = index > 0 ? cur + arr[index - 1] : cur;
  76. });
  77. circleOffsets.forEach((cur) => {
  78. cur = cur * 2 * Math.PI / circleOffsets[circleOffsets.length - 1];
  79. const radialScaler = Math.random();
  80. vertices.push([
  81. radialScaler * (options.max_radial_length || 10) * Math.sin(cur),
  82. radialScaler * (options.max_radial_length || 10) * Math.cos(cur)
  83. ]);
  84. });
  85. vertices[vertices.length - 1] = vertices[0];
  86. vertices = vertices.reverse().map(vertexToCoordinate(randomPositionUnchecked(paddedBbox)));
  87. features.push(polygon([vertices]));
  88. }
  89. return featureCollection(features);
  90. }
  91. function randomLineString(count, options = {}) {
  92. options = options || {};
  93. if (!isObject(options)) {
  94. throw new Error("options is invalid");
  95. }
  96. const bbox = options.bbox;
  97. checkBBox(bbox);
  98. let num_vertices = options.num_vertices;
  99. let max_length = options.max_length;
  100. let max_rotation = options.max_rotation;
  101. if (count === void 0 || count === null) {
  102. count = 1;
  103. }
  104. if (!isNumber(num_vertices) || num_vertices === void 0 || num_vertices < 2) {
  105. num_vertices = 10;
  106. }
  107. if (!isNumber(max_length) || max_length === void 0) {
  108. max_length = 1e-4;
  109. }
  110. if (!isNumber(max_rotation) || max_rotation === void 0) {
  111. max_rotation = Math.PI / 8;
  112. }
  113. const features = [];
  114. for (let i = 0; i < count; i++) {
  115. const startingPoint = randomPositionUnchecked(bbox);
  116. const vertices = [startingPoint];
  117. for (let j = 0; j < num_vertices - 1; j++) {
  118. const priorAngle = j === 0 ? Math.random() * 2 * Math.PI : Math.tan(
  119. (vertices[j][1] - vertices[j - 1][1]) / (vertices[j][0] - vertices[j - 1][0])
  120. );
  121. const angle = priorAngle + (Math.random() - 0.5) * max_rotation * 2;
  122. const distance = Math.random() * max_length;
  123. vertices.push([
  124. vertices[j][0] + distance * Math.cos(angle),
  125. vertices[j][1] + distance * Math.sin(angle)
  126. ]);
  127. }
  128. features.push(lineString(vertices));
  129. }
  130. return featureCollection(features);
  131. }
  132. function vertexToCoordinate(hub) {
  133. return (cur) => {
  134. return [cur[0] + hub[0], cur[1] + hub[1]];
  135. };
  136. }
  137. function rnd() {
  138. return Math.random() - 0.5;
  139. }
  140. function lon() {
  141. return rnd() * 360;
  142. }
  143. function lat() {
  144. return rnd() * 180;
  145. }
  146. function coordInBBox(bbox) {
  147. return [
  148. Math.random() * (bbox[2] - bbox[0]) + bbox[0],
  149. Math.random() * (bbox[3] - bbox[1]) + bbox[1]
  150. ];
  151. }
  152. export {
  153. randomLineString,
  154. randomPoint,
  155. randomPolygon,
  156. randomPosition
  157. };
  158. //# sourceMappingURL=index.js.map