index.js 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579
  1. // index.ts
  2. import { flattenEach, featureEach } from "@turf/meta";
  3. import { polygon as polygon2, featureCollection as featureCollection2 } from "@turf/helpers";
  4. // lib/geojson-polygon-self-intersections.js
  5. import rbush from "rbush";
  6. function geojsonPolygonSelfIntersections(feature, filterFn, useSpatialIndex) {
  7. if (feature.geometry.type !== "Polygon")
  8. throw new Error("The input feature must be a Polygon");
  9. if (useSpatialIndex === void 0) useSpatialIndex = 1;
  10. var coord = feature.geometry.coordinates;
  11. var output = [];
  12. var seen = {};
  13. if (useSpatialIndex) {
  14. var allEdgesAsRbushTreeItems = [];
  15. for (var ring0 = 0; ring0 < coord.length; ring0++) {
  16. for (var edge0 = 0; edge0 < coord[ring0].length - 1; edge0++) {
  17. allEdgesAsRbushTreeItems.push(rbushTreeItem(ring0, edge0));
  18. }
  19. }
  20. var tree = new rbush();
  21. tree.load(allEdgesAsRbushTreeItems);
  22. }
  23. for (var ringA = 0; ringA < coord.length; ringA++) {
  24. for (var edgeA = 0; edgeA < coord[ringA].length - 1; edgeA++) {
  25. if (useSpatialIndex) {
  26. var bboxOverlaps = tree.search(rbushTreeItem(ringA, edgeA));
  27. bboxOverlaps.forEach(function(bboxIsect) {
  28. var ring12 = bboxIsect.ring;
  29. var edge12 = bboxIsect.edge;
  30. ifIsectAddToOutput(ringA, edgeA, ring12, edge12);
  31. });
  32. } else {
  33. for (var ring1 = 0; ring1 < coord.length; ring1++) {
  34. for (var edge1 = 0; edge1 < coord[ring1].length - 1; edge1++) {
  35. ifIsectAddToOutput(ringA, edgeA, ring1, edge1);
  36. }
  37. }
  38. }
  39. }
  40. }
  41. if (!filterFn)
  42. output = {
  43. type: "Feature",
  44. geometry: { type: "MultiPoint", coordinates: output }
  45. };
  46. return output;
  47. function ifIsectAddToOutput(ring02, edge02, ring12, edge12) {
  48. var start0 = coord[ring02][edge02];
  49. var end0 = coord[ring02][edge02 + 1];
  50. var start1 = coord[ring12][edge12];
  51. var end1 = coord[ring12][edge12 + 1];
  52. var isect = intersect(start0, end0, start1, end1);
  53. if (isect === null) return;
  54. var frac0;
  55. var frac1;
  56. if (end0[0] !== start0[0]) {
  57. frac0 = (isect[0] - start0[0]) / (end0[0] - start0[0]);
  58. } else {
  59. frac0 = (isect[1] - start0[1]) / (end0[1] - start0[1]);
  60. }
  61. if (end1[0] !== start1[0]) {
  62. frac1 = (isect[0] - start1[0]) / (end1[0] - start1[0]);
  63. } else {
  64. frac1 = (isect[1] - start1[1]) / (end1[1] - start1[1]);
  65. }
  66. if (frac0 >= 1 || frac0 <= 0 || frac1 >= 1 || frac1 <= 0) return;
  67. var key = isect;
  68. var unique = !seen[key];
  69. if (unique) {
  70. seen[key] = true;
  71. }
  72. if (filterFn) {
  73. output.push(
  74. filterFn(
  75. isect,
  76. ring02,
  77. edge02,
  78. start0,
  79. end0,
  80. frac0,
  81. ring12,
  82. edge12,
  83. start1,
  84. end1,
  85. frac1,
  86. unique
  87. )
  88. );
  89. } else {
  90. output.push(isect);
  91. }
  92. }
  93. function rbushTreeItem(ring, edge) {
  94. var start = coord[ring][edge];
  95. var end = coord[ring][edge + 1];
  96. var minX;
  97. var maxX;
  98. var minY;
  99. var maxY;
  100. if (start[0] < end[0]) {
  101. minX = start[0];
  102. maxX = end[0];
  103. } else {
  104. minX = end[0];
  105. maxX = start[0];
  106. }
  107. if (start[1] < end[1]) {
  108. minY = start[1];
  109. maxY = end[1];
  110. } else {
  111. minY = end[1];
  112. maxY = start[1];
  113. }
  114. return {
  115. minX,
  116. minY,
  117. maxX,
  118. maxY,
  119. ring,
  120. edge
  121. };
  122. }
  123. }
  124. function intersect(start0, end0, start1, end1) {
  125. if (equalArrays(start0, start1) || equalArrays(start0, end1) || equalArrays(end0, start1) || equalArrays(end1, start1))
  126. return null;
  127. var x0 = start0[0], y0 = start0[1], x1 = end0[0], y1 = end0[1], x2 = start1[0], y2 = start1[1], x3 = end1[0], y3 = end1[1];
  128. var denom = (x0 - x1) * (y2 - y3) - (y0 - y1) * (x2 - x3);
  129. if (denom === 0) return null;
  130. var x4 = ((x0 * y1 - y0 * x1) * (x2 - x3) - (x0 - x1) * (x2 * y3 - y2 * x3)) / denom;
  131. var y4 = ((x0 * y1 - y0 * x1) * (y2 - y3) - (y0 - y1) * (x2 * y3 - y2 * x3)) / denom;
  132. return [x4, y4];
  133. }
  134. function equalArrays(array1, array2) {
  135. if (!array1 || !array2) return false;
  136. if (array1.length !== array2.length) return false;
  137. for (var i = 0, l = array1.length; i < l; i++) {
  138. if (array1[i] instanceof Array && array2[i] instanceof Array) {
  139. if (!equalArrays(array1[i], array2[i])) return false;
  140. } else if (array1[i] !== array2[i]) {
  141. return false;
  142. }
  143. }
  144. return true;
  145. }
  146. // lib/simplepolygon.js
  147. import { area } from "@turf/area";
  148. import { featureCollection, polygon } from "@turf/helpers";
  149. import { booleanPointInPolygon } from "@turf/boolean-point-in-polygon";
  150. import rbush2 from "rbush";
  151. function simplepolygon(feature) {
  152. if (feature.type != "Feature")
  153. throw new Error("The input must a geojson object of type Feature");
  154. if (feature.geometry === void 0 || feature.geometry == null)
  155. throw new Error(
  156. "The input must a geojson object with a non-empty geometry"
  157. );
  158. if (feature.geometry.type != "Polygon")
  159. throw new Error("The input must be a geojson Polygon");
  160. var numRings = feature.geometry.coordinates.length;
  161. var vertices = [];
  162. for (var i = 0; i < numRings; i++) {
  163. var ring = feature.geometry.coordinates[i];
  164. if (!equalArrays2(ring[0], ring[ring.length - 1])) {
  165. ring.push(ring[0]);
  166. }
  167. for (var j = 0; j < ring.length - 1; j++) {
  168. vertices.push(ring[j]);
  169. }
  170. }
  171. if (!isUnique(vertices))
  172. throw new Error(
  173. "The input polygon may not have duplicate vertices (except for the first and last vertex of each ring)"
  174. );
  175. var numvertices = vertices.length;
  176. var selfIsectsData = geojsonPolygonSelfIntersections(
  177. feature,
  178. function filterFn(isect, ring0, edge0, start0, end0, frac0, ring1, edge1, start1, end1, frac1, unique) {
  179. return [
  180. isect,
  181. ring0,
  182. edge0,
  183. start0,
  184. end0,
  185. frac0,
  186. ring1,
  187. edge1,
  188. start1,
  189. end1,
  190. frac1,
  191. unique
  192. ];
  193. }
  194. );
  195. var numSelfIsect = selfIsectsData.length;
  196. if (numSelfIsect == 0) {
  197. var outputFeatureArray = [];
  198. for (var i = 0; i < numRings; i++) {
  199. outputFeatureArray.push(
  200. polygon([feature.geometry.coordinates[i]], {
  201. parent: -1,
  202. winding: windingOfRing(feature.geometry.coordinates[i])
  203. })
  204. );
  205. }
  206. var output = featureCollection(outputFeatureArray);
  207. determineParents();
  208. setNetWinding();
  209. return output;
  210. }
  211. var pseudoVtxListByRingAndEdge = [];
  212. var isectList = [];
  213. for (var i = 0; i < numRings; i++) {
  214. pseudoVtxListByRingAndEdge.push([]);
  215. for (var j = 0; j < feature.geometry.coordinates[i].length - 1; j++) {
  216. pseudoVtxListByRingAndEdge[i].push([
  217. new PseudoVtx(
  218. feature.geometry.coordinates[i][modulo(j + 1, feature.geometry.coordinates[i].length - 1)],
  219. 1,
  220. [i, j],
  221. [i, modulo(j + 1, feature.geometry.coordinates[i].length - 1)],
  222. void 0
  223. )
  224. ]);
  225. isectList.push(
  226. new Isect(
  227. feature.geometry.coordinates[i][j],
  228. [i, modulo(j - 1, feature.geometry.coordinates[i].length - 1)],
  229. [i, j],
  230. void 0,
  231. void 0,
  232. false,
  233. true
  234. )
  235. );
  236. }
  237. }
  238. for (var i = 0; i < numSelfIsect; i++) {
  239. pseudoVtxListByRingAndEdge[selfIsectsData[i][1]][selfIsectsData[i][2]].push(
  240. new PseudoVtx(
  241. selfIsectsData[i][0],
  242. selfIsectsData[i][5],
  243. [selfIsectsData[i][1], selfIsectsData[i][2]],
  244. [selfIsectsData[i][6], selfIsectsData[i][7]],
  245. void 0
  246. )
  247. );
  248. if (selfIsectsData[i][11])
  249. isectList.push(
  250. new Isect(
  251. selfIsectsData[i][0],
  252. [selfIsectsData[i][1], selfIsectsData[i][2]],
  253. [selfIsectsData[i][6], selfIsectsData[i][7]],
  254. void 0,
  255. void 0,
  256. true,
  257. true
  258. )
  259. );
  260. }
  261. var numIsect = isectList.length;
  262. for (var i = 0; i < pseudoVtxListByRingAndEdge.length; i++) {
  263. for (var j = 0; j < pseudoVtxListByRingAndEdge[i].length; j++) {
  264. pseudoVtxListByRingAndEdge[i][j].sort(function(a, b) {
  265. return a.param < b.param ? -1 : 1;
  266. });
  267. }
  268. }
  269. var allIsectsAsIsectRbushTreeItem = [];
  270. for (var i = 0; i < numIsect; i++) {
  271. allIsectsAsIsectRbushTreeItem.push({
  272. minX: isectList[i].coord[0],
  273. minY: isectList[i].coord[1],
  274. maxX: isectList[i].coord[0],
  275. maxY: isectList[i].coord[1],
  276. index: i
  277. });
  278. }
  279. var isectRbushTree = new rbush2();
  280. isectRbushTree.load(allIsectsAsIsectRbushTreeItem);
  281. for (var i = 0; i < pseudoVtxListByRingAndEdge.length; i++) {
  282. for (var j = 0; j < pseudoVtxListByRingAndEdge[i].length; j++) {
  283. for (var k = 0; k < pseudoVtxListByRingAndEdge[i][j].length; k++) {
  284. var coordToFind;
  285. if (k == pseudoVtxListByRingAndEdge[i][j].length - 1) {
  286. coordToFind = pseudoVtxListByRingAndEdge[i][modulo(j + 1, feature.geometry.coordinates[i].length - 1)][0].coord;
  287. } else {
  288. coordToFind = pseudoVtxListByRingAndEdge[i][j][k + 1].coord;
  289. }
  290. var IsectRbushTreeItemFound = isectRbushTree.search({
  291. minX: coordToFind[0],
  292. minY: coordToFind[1],
  293. maxX: coordToFind[0],
  294. maxY: coordToFind[1]
  295. })[0];
  296. pseudoVtxListByRingAndEdge[i][j][k].nxtIsectAlongEdgeIn = IsectRbushTreeItemFound.index;
  297. }
  298. }
  299. }
  300. for (var i = 0; i < pseudoVtxListByRingAndEdge.length; i++) {
  301. for (var j = 0; j < pseudoVtxListByRingAndEdge[i].length; j++) {
  302. for (var k = 0; k < pseudoVtxListByRingAndEdge[i][j].length; k++) {
  303. var coordToFind = pseudoVtxListByRingAndEdge[i][j][k].coord;
  304. var IsectRbushTreeItemFound = isectRbushTree.search({
  305. minX: coordToFind[0],
  306. minY: coordToFind[1],
  307. maxX: coordToFind[0],
  308. maxY: coordToFind[1]
  309. })[0];
  310. var l = IsectRbushTreeItemFound.index;
  311. if (l < numvertices) {
  312. isectList[l].nxtIsectAlongRingAndEdge2 = pseudoVtxListByRingAndEdge[i][j][k].nxtIsectAlongEdgeIn;
  313. } else {
  314. if (equalArrays2(
  315. isectList[l].ringAndEdge1,
  316. pseudoVtxListByRingAndEdge[i][j][k].ringAndEdgeIn
  317. )) {
  318. isectList[l].nxtIsectAlongRingAndEdge1 = pseudoVtxListByRingAndEdge[i][j][k].nxtIsectAlongEdgeIn;
  319. } else {
  320. isectList[l].nxtIsectAlongRingAndEdge2 = pseudoVtxListByRingAndEdge[i][j][k].nxtIsectAlongEdgeIn;
  321. }
  322. }
  323. }
  324. }
  325. }
  326. var queue = [];
  327. var i = 0;
  328. for (var j = 0; j < numRings; j++) {
  329. var leftIsect = i;
  330. for (var k = 0; k < feature.geometry.coordinates[j].length - 1; k++) {
  331. if (isectList[i].coord[0] < isectList[leftIsect].coord[0]) {
  332. leftIsect = i;
  333. }
  334. i++;
  335. }
  336. var isectAfterLeftIsect = isectList[leftIsect].nxtIsectAlongRingAndEdge2;
  337. for (var k = 0; k < isectList.length; k++) {
  338. if (isectList[k].nxtIsectAlongRingAndEdge1 == leftIsect || isectList[k].nxtIsectAlongRingAndEdge2 == leftIsect) {
  339. var isectBeforeLeftIsect = k;
  340. break;
  341. }
  342. }
  343. var windingAtIsect = isConvex(
  344. [
  345. isectList[isectBeforeLeftIsect].coord,
  346. isectList[leftIsect].coord,
  347. isectList[isectAfterLeftIsect].coord
  348. ],
  349. true
  350. ) ? 1 : -1;
  351. queue.push({ isect: leftIsect, parent: -1, winding: windingAtIsect });
  352. }
  353. queue.sort(function(a, b) {
  354. return isectList[a.isect].coord > isectList[b.isect].coord ? -1 : 1;
  355. });
  356. var outputFeatureArray = [];
  357. while (queue.length > 0) {
  358. var popped = queue.pop();
  359. var startIsect = popped.isect;
  360. var currentOutputRingParent = popped.parent;
  361. var currentOutputRingWinding = popped.winding;
  362. var currentOutputRing = outputFeatureArray.length;
  363. var currentOutputRingCoords = [isectList[startIsect].coord];
  364. var currentIsect = startIsect;
  365. if (isectList[startIsect].ringAndEdge1Walkable) {
  366. var walkingRingAndEdge = isectList[startIsect].ringAndEdge1;
  367. var nxtIsect = isectList[startIsect].nxtIsectAlongRingAndEdge1;
  368. } else {
  369. var walkingRingAndEdge = isectList[startIsect].ringAndEdge2;
  370. var nxtIsect = isectList[startIsect].nxtIsectAlongRingAndEdge2;
  371. }
  372. while (!equalArrays2(isectList[startIsect].coord, isectList[nxtIsect].coord)) {
  373. currentOutputRingCoords.push(isectList[nxtIsect].coord);
  374. var nxtIsectInQueue = void 0;
  375. for (var i = 0; i < queue.length; i++) {
  376. if (queue[i].isect == nxtIsect) {
  377. nxtIsectInQueue = i;
  378. break;
  379. }
  380. }
  381. if (nxtIsectInQueue != void 0) {
  382. queue.splice(nxtIsectInQueue, 1);
  383. }
  384. if (equalArrays2(walkingRingAndEdge, isectList[nxtIsect].ringAndEdge1)) {
  385. walkingRingAndEdge = isectList[nxtIsect].ringAndEdge2;
  386. isectList[nxtIsect].ringAndEdge2Walkable = false;
  387. if (isectList[nxtIsect].ringAndEdge1Walkable) {
  388. var pushing = { isect: nxtIsect };
  389. if (isConvex(
  390. [
  391. isectList[currentIsect].coord,
  392. isectList[nxtIsect].coord,
  393. isectList[isectList[nxtIsect].nxtIsectAlongRingAndEdge2].coord
  394. ],
  395. currentOutputRingWinding == 1
  396. )) {
  397. pushing.parent = currentOutputRingParent;
  398. pushing.winding = -currentOutputRingWinding;
  399. } else {
  400. pushing.parent = currentOutputRing;
  401. pushing.winding = currentOutputRingWinding;
  402. }
  403. queue.push(pushing);
  404. }
  405. currentIsect = nxtIsect;
  406. nxtIsect = isectList[nxtIsect].nxtIsectAlongRingAndEdge2;
  407. } else {
  408. walkingRingAndEdge = isectList[nxtIsect].ringAndEdge1;
  409. isectList[nxtIsect].ringAndEdge1Walkable = false;
  410. if (isectList[nxtIsect].ringAndEdge2Walkable) {
  411. var pushing = { isect: nxtIsect };
  412. if (isConvex(
  413. [
  414. isectList[currentIsect].coord,
  415. isectList[nxtIsect].coord,
  416. isectList[isectList[nxtIsect].nxtIsectAlongRingAndEdge1].coord
  417. ],
  418. currentOutputRingWinding == 1
  419. )) {
  420. pushing.parent = currentOutputRingParent;
  421. pushing.winding = -currentOutputRingWinding;
  422. } else {
  423. pushing.parent = currentOutputRing;
  424. pushing.winding = currentOutputRingWinding;
  425. }
  426. queue.push(pushing);
  427. }
  428. currentIsect = nxtIsect;
  429. nxtIsect = isectList[nxtIsect].nxtIsectAlongRingAndEdge1;
  430. }
  431. }
  432. currentOutputRingCoords.push(isectList[nxtIsect].coord);
  433. outputFeatureArray.push(
  434. polygon([currentOutputRingCoords], {
  435. index: currentOutputRing,
  436. parent: currentOutputRingParent,
  437. winding: currentOutputRingWinding,
  438. netWinding: void 0
  439. })
  440. );
  441. }
  442. var output = featureCollection(outputFeatureArray);
  443. determineParents();
  444. setNetWinding();
  445. function determineParents() {
  446. var featuresWithoutParent = [];
  447. for (var i2 = 0; i2 < output.features.length; i2++) {
  448. if (output.features[i2].properties.parent == -1)
  449. featuresWithoutParent.push(i2);
  450. }
  451. if (featuresWithoutParent.length > 1) {
  452. for (var i2 = 0; i2 < featuresWithoutParent.length; i2++) {
  453. var parent = -1;
  454. var parentArea = Infinity;
  455. for (var j2 = 0; j2 < output.features.length; j2++) {
  456. if (featuresWithoutParent[i2] == j2) continue;
  457. if (booleanPointInPolygon(
  458. output.features[featuresWithoutParent[i2]].geometry.coordinates[0][0],
  459. output.features[j2],
  460. { ignoreBoundary: true }
  461. )) {
  462. if (area(output.features[j2]) < parentArea) {
  463. parent = j2;
  464. }
  465. }
  466. }
  467. output.features[featuresWithoutParent[i2]].properties.parent = parent;
  468. }
  469. }
  470. }
  471. function setNetWinding() {
  472. for (var i2 = 0; i2 < output.features.length; i2++) {
  473. if (output.features[i2].properties.parent == -1) {
  474. var netWinding = output.features[i2].properties.winding;
  475. output.features[i2].properties.netWinding = netWinding;
  476. setNetWindingOfChildren(i2, netWinding);
  477. }
  478. }
  479. }
  480. function setNetWindingOfChildren(parent, ParentNetWinding) {
  481. for (var i2 = 0; i2 < output.features.length; i2++) {
  482. if (output.features[i2].properties.parent == parent) {
  483. var netWinding = ParentNetWinding + output.features[i2].properties.winding;
  484. output.features[i2].properties.netWinding = netWinding;
  485. setNetWindingOfChildren(i2, netWinding);
  486. }
  487. }
  488. }
  489. return output;
  490. }
  491. var PseudoVtx = function(coord, param, ringAndEdgeIn, ringAndEdgeOut, nxtIsectAlongEdgeIn) {
  492. this.coord = coord;
  493. this.param = param;
  494. this.ringAndEdgeIn = ringAndEdgeIn;
  495. this.ringAndEdgeOut = ringAndEdgeOut;
  496. this.nxtIsectAlongEdgeIn = nxtIsectAlongEdgeIn;
  497. };
  498. var Isect = function(coord, ringAndEdge1, ringAndEdge2, nxtIsectAlongRingAndEdge1, nxtIsectAlongRingAndEdge2, ringAndEdge1Walkable, ringAndEdge2Walkable) {
  499. this.coord = coord;
  500. this.ringAndEdge1 = ringAndEdge1;
  501. this.ringAndEdge2 = ringAndEdge2;
  502. this.nxtIsectAlongRingAndEdge1 = nxtIsectAlongRingAndEdge1;
  503. this.nxtIsectAlongRingAndEdge2 = nxtIsectAlongRingAndEdge2;
  504. this.ringAndEdge1Walkable = ringAndEdge1Walkable;
  505. this.ringAndEdge2Walkable = ringAndEdge2Walkable;
  506. };
  507. function isConvex(pts, righthanded) {
  508. if (typeof righthanded === "undefined") righthanded = true;
  509. if (pts.length != 3)
  510. throw new Error("This function requires an array of three points [x,y]");
  511. var d = (pts[1][0] - pts[0][0]) * (pts[2][1] - pts[0][1]) - (pts[1][1] - pts[0][1]) * (pts[2][0] - pts[0][0]);
  512. return d >= 0 == righthanded;
  513. }
  514. function windingOfRing(ring) {
  515. var leftVtx = 0;
  516. for (var i = 0; i < ring.length - 1; i++) {
  517. if (ring[i][0] < ring[leftVtx][0]) leftVtx = i;
  518. }
  519. if (isConvex(
  520. [
  521. ring[modulo(leftVtx - 1, ring.length - 1)],
  522. ring[leftVtx],
  523. ring[modulo(leftVtx + 1, ring.length - 1)]
  524. ],
  525. true
  526. )) {
  527. var winding = 1;
  528. } else {
  529. var winding = -1;
  530. }
  531. return winding;
  532. }
  533. function equalArrays2(array1, array2) {
  534. if (!array1 || !array2) return false;
  535. if (array1.length != array2.length) return false;
  536. for (var i = 0, l = array1.length; i < l; i++) {
  537. if (array1[i] instanceof Array && array2[i] instanceof Array) {
  538. if (!equalArrays2(array1[i], array2[i])) return false;
  539. } else if (array1[i] != array2[i]) {
  540. return false;
  541. }
  542. }
  543. return true;
  544. }
  545. function modulo(n, m) {
  546. return (n % m + m) % m;
  547. }
  548. function isUnique(array) {
  549. var u = {};
  550. var isUnique2 = 1;
  551. for (var i = 0, l = array.length; i < l; ++i) {
  552. if (Object.prototype.hasOwnProperty.call(u, array[i])) {
  553. isUnique2 = 0;
  554. break;
  555. }
  556. u[array[i]] = 1;
  557. }
  558. return isUnique2;
  559. }
  560. // index.ts
  561. function unkinkPolygon(geojson) {
  562. var features = [];
  563. flattenEach(geojson, function(feature) {
  564. if (feature.geometry.type !== "Polygon") return;
  565. featureEach(simplepolygon(feature), function(poly) {
  566. features.push(polygon2(poly.geometry.coordinates, feature.properties));
  567. });
  568. });
  569. return featureCollection2(features);
  570. }
  571. var turf_unkink_polygon_default = unkinkPolygon;
  572. export {
  573. turf_unkink_polygon_default as default,
  574. unkinkPolygon
  575. };
  576. //# sourceMappingURL=index.js.map