index.js 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. import { segmentEach } from "@turf/meta";
  2. import { getGeom } from "@turf/invariant";
  3. import lineOverlap from "@turf/line-overlap";
  4. import lineIntersect from "@turf/line-intersect";
  5. import GeojsonEquality from "geojson-equality";
  6. /**
  7. * Compares two geometries of the same dimension and returns true if their intersection set results in a geometry
  8. * different from both but of the same dimension. It applies to Polygon/Polygon, LineString/LineString,
  9. * Multipoint/Multipoint, MultiLineString/MultiLineString and MultiPolygon/MultiPolygon.
  10. *
  11. * In other words, it returns true if the two geometries overlap, provided that neither completely contains the other.
  12. *
  13. * @name booleanOverlap
  14. * @param {Geometry|Feature<LineString|MultiLineString|Polygon|MultiPolygon>} feature1 input
  15. * @param {Geometry|Feature<LineString|MultiLineString|Polygon|MultiPolygon>} feature2 input
  16. * @returns {boolean} true/false
  17. * @example
  18. * var poly1 = turf.polygon([[[0,0],[0,5],[5,5],[5,0],[0,0]]]);
  19. * var poly2 = turf.polygon([[[1,1],[1,6],[6,6],[6,1],[1,1]]]);
  20. * var poly3 = turf.polygon([[[10,10],[10,15],[15,15],[15,10],[10,10]]]);
  21. *
  22. * turf.booleanOverlap(poly1, poly2)
  23. * //=true
  24. * turf.booleanOverlap(poly2, poly3)
  25. * //=false
  26. */
  27. export default function booleanOverlap(feature1, feature2) {
  28. var geom1 = getGeom(feature1);
  29. var geom2 = getGeom(feature2);
  30. var type1 = geom1.type;
  31. var type2 = geom2.type;
  32. if ((type1 === "MultiPoint" && type2 !== "MultiPoint") ||
  33. ((type1 === "LineString" || type1 === "MultiLineString") &&
  34. type2 !== "LineString" &&
  35. type2 !== "MultiLineString") ||
  36. ((type1 === "Polygon" || type1 === "MultiPolygon") &&
  37. type2 !== "Polygon" &&
  38. type2 !== "MultiPolygon")) {
  39. throw new Error("features must be of the same type");
  40. }
  41. if (type1 === "Point")
  42. throw new Error("Point geometry not supported");
  43. // features must be not equal
  44. var equality = new GeojsonEquality({ precision: 6 });
  45. if (equality.compare(feature1, feature2))
  46. return false;
  47. var overlap = 0;
  48. switch (type1) {
  49. case "MultiPoint":
  50. for (var i = 0; i < geom1.coordinates.length; i++) {
  51. for (var j = 0; j < geom2.coordinates.length; j++) {
  52. var coord1 = geom1.coordinates[i];
  53. var coord2 = geom2.coordinates[j];
  54. if (coord1[0] === coord2[0] && coord1[1] === coord2[1]) {
  55. return true;
  56. }
  57. }
  58. }
  59. return false;
  60. case "LineString":
  61. case "MultiLineString":
  62. segmentEach(feature1, function (segment1) {
  63. segmentEach(feature2, function (segment2) {
  64. if (lineOverlap(segment1, segment2).features.length)
  65. overlap++;
  66. });
  67. });
  68. break;
  69. case "Polygon":
  70. case "MultiPolygon":
  71. segmentEach(feature1, function (segment1) {
  72. segmentEach(feature2, function (segment2) {
  73. if (lineIntersect(segment1, segment2).features.length)
  74. overlap++;
  75. });
  76. });
  77. break;
  78. }
  79. return overlap > 0;
  80. }