index.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. // index.js
  2. import { flattenEach } from "@turf/meta";
  3. import { getCoords, getType } from "@turf/invariant";
  4. import {
  5. isObject,
  6. lineString,
  7. multiLineString,
  8. lengthToDegrees
  9. } from "@turf/helpers";
  10. // lib/intersection.js
  11. function ab(segment) {
  12. var start = segment[0];
  13. var end = segment[1];
  14. return [end[0] - start[0], end[1] - start[1]];
  15. }
  16. function crossProduct(v1, v2) {
  17. return v1[0] * v2[1] - v2[0] * v1[1];
  18. }
  19. function add(v1, v2) {
  20. return [v1[0] + v2[0], v1[1] + v2[1]];
  21. }
  22. function sub(v1, v2) {
  23. return [v1[0] - v2[0], v1[1] - v2[1]];
  24. }
  25. function scalarMult(s, v) {
  26. return [s * v[0], s * v[1]];
  27. }
  28. function intersectSegments(a, b) {
  29. var p = a[0];
  30. var r = ab(a);
  31. var q = b[0];
  32. var s = ab(b);
  33. var cross = crossProduct(r, s);
  34. var qmp = sub(q, p);
  35. var numerator = crossProduct(qmp, s);
  36. var t = numerator / cross;
  37. var intersection2 = add(p, scalarMult(t, r));
  38. return intersection2;
  39. }
  40. function isParallel(a, b) {
  41. var r = ab(a);
  42. var s = ab(b);
  43. return crossProduct(r, s) === 0;
  44. }
  45. function intersection(a, b) {
  46. if (isParallel(a, b)) return false;
  47. return intersectSegments(a, b);
  48. }
  49. // index.js
  50. function lineOffset(geojson, distance, options) {
  51. options = options || {};
  52. if (!isObject(options)) throw new Error("options is invalid");
  53. var units = options.units;
  54. if (!geojson) throw new Error("geojson is required");
  55. if (distance === void 0 || distance === null || isNaN(distance))
  56. throw new Error("distance is required");
  57. var type = getType(geojson);
  58. var properties = geojson.properties;
  59. switch (type) {
  60. case "LineString":
  61. return lineOffsetFeature(geojson, distance, units);
  62. case "MultiLineString":
  63. var coords = [];
  64. flattenEach(geojson, function(feature) {
  65. coords.push(
  66. lineOffsetFeature(feature, distance, units).geometry.coordinates
  67. );
  68. });
  69. return multiLineString(coords, properties);
  70. default:
  71. throw new Error("geometry " + type + " is not supported");
  72. }
  73. }
  74. function lineOffsetFeature(line, distance, units) {
  75. var segments = [];
  76. var offsetDegrees = lengthToDegrees(distance, units);
  77. var coords = getCoords(line);
  78. var finalCoords = [];
  79. coords.forEach(function(currentCoords, index) {
  80. if (index !== coords.length - 1) {
  81. var segment = processSegment(
  82. currentCoords,
  83. coords[index + 1],
  84. offsetDegrees
  85. );
  86. segments.push(segment);
  87. if (index > 0) {
  88. var seg2Coords = segments[index - 1];
  89. var intersects = intersection(segment, seg2Coords);
  90. if (intersects !== false) {
  91. seg2Coords[1] = intersects;
  92. segment[0] = intersects;
  93. }
  94. finalCoords.push(seg2Coords[0]);
  95. if (index === coords.length - 2) {
  96. finalCoords.push(segment[0]);
  97. finalCoords.push(segment[1]);
  98. }
  99. }
  100. if (coords.length === 2) {
  101. finalCoords.push(segment[0]);
  102. finalCoords.push(segment[1]);
  103. }
  104. }
  105. });
  106. return lineString(finalCoords, line.properties);
  107. }
  108. function processSegment(point1, point2, offset) {
  109. var L = Math.sqrt(
  110. (point1[0] - point2[0]) * (point1[0] - point2[0]) + (point1[1] - point2[1]) * (point1[1] - point2[1])
  111. );
  112. var out1x = point1[0] + offset * (point2[1] - point1[1]) / L;
  113. var out2x = point2[0] + offset * (point2[1] - point1[1]) / L;
  114. var out1y = point1[1] + offset * (point1[0] - point2[0]) / L;
  115. var out2y = point2[1] + offset * (point1[0] - point2[0]) / L;
  116. return [
  117. [out1x, out1y],
  118. [out2x, out2y]
  119. ];
  120. }
  121. var turf_line_offset_default = lineOffset;
  122. export {
  123. turf_line_offset_default as default,
  124. lineOffset
  125. };
  126. //# sourceMappingURL=index.js.map