Polyline.Intersect.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. /**
  2. * @class L.Polyline
  3. * @aka Polyline
  4. */
  5. L.Polyline.include({
  6. // @method intersects(): boolean
  7. // Check to see if this polyline has any linesegments that intersect.
  8. // NOTE: does not support detecting intersection for degenerate cases.
  9. intersects: function () {
  10. var points = this._getProjectedPoints(),
  11. len = points ? points.length : 0,
  12. i, p, p1;
  13. if (this._tooFewPointsForIntersection()) {
  14. return false;
  15. }
  16. for (i = len - 1; i >= 3; i--) {
  17. p = points[i - 1];
  18. p1 = points[i];
  19. if (this._lineSegmentsIntersectsRange(p, p1, i - 2)) {
  20. return true;
  21. }
  22. }
  23. return false;
  24. },
  25. // @method newLatLngIntersects(): boolean
  26. // Check for intersection if new latlng was added to this polyline.
  27. // NOTE: does not support detecting intersection for degenerate cases.
  28. newLatLngIntersects: function (latlng, skipFirst) {
  29. // Cannot check a polyline for intersecting lats/lngs when not added to the map
  30. if (!this._map) {
  31. return false;
  32. }
  33. return this.newPointIntersects(this._map.latLngToLayerPoint(latlng), skipFirst);
  34. },
  35. // @method newPointIntersects(): boolean
  36. // Check for intersection if new point was added to this polyline.
  37. // newPoint must be a layer point.
  38. // NOTE: does not support detecting intersection for degenerate cases.
  39. newPointIntersects: function (newPoint, skipFirst) {
  40. var points = this._getProjectedPoints(),
  41. len = points ? points.length : 0,
  42. lastPoint = points ? points[len - 1] : null,
  43. // The previous previous line segment. Previous line segment doesn't need testing.
  44. maxIndex = len - 2;
  45. if (this._tooFewPointsForIntersection(1)) {
  46. return false;
  47. }
  48. return this._lineSegmentsIntersectsRange(lastPoint, newPoint, maxIndex, skipFirst ? 1 : 0);
  49. },
  50. // Polylines with 2 sides can only intersect in cases where points are collinear (we don't support detecting these).
  51. // Cannot have intersection when < 3 line segments (< 4 points)
  52. _tooFewPointsForIntersection: function (extraPoints) {
  53. var points = this._getProjectedPoints(),
  54. len = points ? points.length : 0;
  55. // Increment length by extraPoints if present
  56. len += extraPoints || 0;
  57. return !points || len <= 3;
  58. },
  59. // Checks a line segment intersections with any line segments before its predecessor.
  60. // Don't need to check the predecessor as will never intersect.
  61. _lineSegmentsIntersectsRange: function (p, p1, maxIndex, minIndex) {
  62. var points = this._getProjectedPoints(),
  63. p2, p3;
  64. minIndex = minIndex || 0;
  65. // Check all previous line segments (beside the immediately previous) for intersections
  66. for (var j = maxIndex; j > minIndex; j--) {
  67. p2 = points[j - 1];
  68. p3 = points[j];
  69. if (L.LineUtil.segmentsIntersect(p, p1, p2, p3)) {
  70. return true;
  71. }
  72. }
  73. return false;
  74. },
  75. _getProjectedPoints: function () {
  76. if (!this._defaultShape) {
  77. return this._originalPoints;
  78. }
  79. var points = [],
  80. _shape = this._defaultShape();
  81. for (var i = 0; i < _shape.length; i++) {
  82. points.push(this._map.latLngToLayerPoint(_shape[i]));
  83. }
  84. return points;
  85. }
  86. });