index.js 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. "use strict";
  2. var __importDefault = (this && this.__importDefault) || function (mod) {
  3. return (mod && mod.__esModule) ? mod : { "default": mod };
  4. };
  5. Object.defineProperty(exports, "__esModule", { value: true });
  6. var bbox_1 = __importDefault(require("@turf/bbox"));
  7. var boolean_point_on_line_1 = __importDefault(require("@turf/boolean-point-on-line"));
  8. var boolean_point_in_polygon_1 = __importDefault(require("@turf/boolean-point-in-polygon"));
  9. var invariant_1 = require("@turf/invariant");
  10. /**
  11. * Boolean-within returns true if the first geometry is completely within the second geometry.
  12. * The interiors of both geometries must intersect and, the interior and boundary of the primary (geometry a)
  13. * must not intersect the exterior of the secondary (geometry b).
  14. * Boolean-within returns the exact opposite result of the `@turf/boolean-contains`.
  15. *
  16. * @name booleanWithin
  17. * @param {Geometry|Feature<any>} feature1 GeoJSON Feature or Geometry
  18. * @param {Geometry|Feature<any>} feature2 GeoJSON Feature or Geometry
  19. * @returns {boolean} true/false
  20. * @example
  21. * var line = turf.lineString([[1, 1], [1, 2], [1, 3], [1, 4]]);
  22. * var point = turf.point([1, 2]);
  23. *
  24. * turf.booleanWithin(point, line);
  25. * //=true
  26. */
  27. function booleanWithin(feature1, feature2) {
  28. var geom1 = invariant_1.getGeom(feature1);
  29. var geom2 = invariant_1.getGeom(feature2);
  30. var type1 = geom1.type;
  31. var type2 = geom2.type;
  32. switch (type1) {
  33. case "Point":
  34. switch (type2) {
  35. case "MultiPoint":
  36. return isPointInMultiPoint(geom1, geom2);
  37. case "LineString":
  38. return boolean_point_on_line_1.default(geom1, geom2, { ignoreEndVertices: true });
  39. case "Polygon":
  40. case "MultiPolygon":
  41. return boolean_point_in_polygon_1.default(geom1, geom2, { ignoreBoundary: true });
  42. default:
  43. throw new Error("feature2 " + type2 + " geometry not supported");
  44. }
  45. case "MultiPoint":
  46. switch (type2) {
  47. case "MultiPoint":
  48. return isMultiPointInMultiPoint(geom1, geom2);
  49. case "LineString":
  50. return isMultiPointOnLine(geom1, geom2);
  51. case "Polygon":
  52. case "MultiPolygon":
  53. return isMultiPointInPoly(geom1, geom2);
  54. default:
  55. throw new Error("feature2 " + type2 + " geometry not supported");
  56. }
  57. case "LineString":
  58. switch (type2) {
  59. case "LineString":
  60. return isLineOnLine(geom1, geom2);
  61. case "Polygon":
  62. case "MultiPolygon":
  63. return isLineInPoly(geom1, geom2);
  64. default:
  65. throw new Error("feature2 " + type2 + " geometry not supported");
  66. }
  67. case "Polygon":
  68. switch (type2) {
  69. case "Polygon":
  70. case "MultiPolygon":
  71. return isPolyInPoly(geom1, geom2);
  72. default:
  73. throw new Error("feature2 " + type2 + " geometry not supported");
  74. }
  75. default:
  76. throw new Error("feature1 " + type1 + " geometry not supported");
  77. }
  78. }
  79. function isPointInMultiPoint(point, multiPoint) {
  80. var i;
  81. var output = false;
  82. for (i = 0; i < multiPoint.coordinates.length; i++) {
  83. if (compareCoords(multiPoint.coordinates[i], point.coordinates)) {
  84. output = true;
  85. break;
  86. }
  87. }
  88. return output;
  89. }
  90. function isMultiPointInMultiPoint(multiPoint1, multiPoint2) {
  91. for (var i = 0; i < multiPoint1.coordinates.length; i++) {
  92. var anyMatch = false;
  93. for (var i2 = 0; i2 < multiPoint2.coordinates.length; i2++) {
  94. if (compareCoords(multiPoint1.coordinates[i], multiPoint2.coordinates[i2])) {
  95. anyMatch = true;
  96. }
  97. }
  98. if (!anyMatch) {
  99. return false;
  100. }
  101. }
  102. return true;
  103. }
  104. function isMultiPointOnLine(multiPoint, lineString) {
  105. var foundInsidePoint = false;
  106. for (var i = 0; i < multiPoint.coordinates.length; i++) {
  107. if (!boolean_point_on_line_1.default(multiPoint.coordinates[i], lineString)) {
  108. return false;
  109. }
  110. if (!foundInsidePoint) {
  111. foundInsidePoint = boolean_point_on_line_1.default(multiPoint.coordinates[i], lineString, { ignoreEndVertices: true });
  112. }
  113. }
  114. return foundInsidePoint;
  115. }
  116. function isMultiPointInPoly(multiPoint, polygon) {
  117. var output = true;
  118. var oneInside = false;
  119. var isInside = false;
  120. for (var i = 0; i < multiPoint.coordinates.length; i++) {
  121. isInside = boolean_point_in_polygon_1.default(multiPoint.coordinates[1], polygon);
  122. if (!isInside) {
  123. output = false;
  124. break;
  125. }
  126. if (!oneInside) {
  127. isInside = boolean_point_in_polygon_1.default(multiPoint.coordinates[1], polygon, {
  128. ignoreBoundary: true,
  129. });
  130. }
  131. }
  132. return output && isInside;
  133. }
  134. function isLineOnLine(lineString1, lineString2) {
  135. for (var i = 0; i < lineString1.coordinates.length; i++) {
  136. if (!boolean_point_on_line_1.default(lineString1.coordinates[i], lineString2)) {
  137. return false;
  138. }
  139. }
  140. return true;
  141. }
  142. function isLineInPoly(linestring, polygon) {
  143. var polyBbox = bbox_1.default(polygon);
  144. var lineBbox = bbox_1.default(linestring);
  145. if (!doBBoxOverlap(polyBbox, lineBbox)) {
  146. return false;
  147. }
  148. var foundInsidePoint = false;
  149. for (var i = 0; i < linestring.coordinates.length - 1; i++) {
  150. if (!boolean_point_in_polygon_1.default(linestring.coordinates[i], polygon)) {
  151. return false;
  152. }
  153. if (!foundInsidePoint) {
  154. foundInsidePoint = boolean_point_in_polygon_1.default(linestring.coordinates[i], polygon, { ignoreBoundary: true });
  155. }
  156. if (!foundInsidePoint) {
  157. var midpoint = getMidpoint(linestring.coordinates[i], linestring.coordinates[i + 1]);
  158. foundInsidePoint = boolean_point_in_polygon_1.default(midpoint, polygon, {
  159. ignoreBoundary: true,
  160. });
  161. }
  162. }
  163. return foundInsidePoint;
  164. }
  165. /**
  166. * Is Polygon2 in Polygon1
  167. * Only takes into account outer rings
  168. *
  169. * @private
  170. * @param {Polygon} geometry1
  171. * @param {Polygon|MultiPolygon} geometry2
  172. * @returns {boolean} true/false
  173. */
  174. function isPolyInPoly(geometry1, geometry2) {
  175. var poly1Bbox = bbox_1.default(geometry1);
  176. var poly2Bbox = bbox_1.default(geometry2);
  177. if (!doBBoxOverlap(poly2Bbox, poly1Bbox)) {
  178. return false;
  179. }
  180. for (var i = 0; i < geometry1.coordinates[0].length; i++) {
  181. if (!boolean_point_in_polygon_1.default(geometry1.coordinates[0][i], geometry2)) {
  182. return false;
  183. }
  184. }
  185. return true;
  186. }
  187. function doBBoxOverlap(bbox1, bbox2) {
  188. if (bbox1[0] > bbox2[0])
  189. return false;
  190. if (bbox1[2] < bbox2[2])
  191. return false;
  192. if (bbox1[1] > bbox2[1])
  193. return false;
  194. if (bbox1[3] < bbox2[3])
  195. return false;
  196. return true;
  197. }
  198. /**
  199. * compareCoords
  200. *
  201. * @private
  202. * @param {Position} pair1 point [x,y]
  203. * @param {Position} pair2 point [x,y]
  204. * @returns {boolean} true/false if coord pairs match
  205. */
  206. function compareCoords(pair1, pair2) {
  207. return pair1[0] === pair2[0] && pair1[1] === pair2[1];
  208. }
  209. /**
  210. * getMidpoint
  211. *
  212. * @private
  213. * @param {Position} pair1 point [x,y]
  214. * @param {Position} pair2 point [x,y]
  215. * @returns {Position} midpoint of pair1 and pair2
  216. */
  217. function getMidpoint(pair1, pair2) {
  218. return [(pair1[0] + pair2[0]) / 2, (pair1[1] + pair2[1]) / 2];
  219. }
  220. exports.default = booleanWithin;