/** * @class L.Polyline * @aka Polyline */ L.Polyline.include({ // @method intersects(): boolean // Check to see if this polyline has any linesegments that intersect. // NOTE: does not support detecting intersection for degenerate cases. intersects: function () { var points = this._getProjectedPoints(), len = points ? points.length : 0, i, p, p1; if (this._tooFewPointsForIntersection()) { return false; } for (i = len - 1; i >= 3; i--) { p = points[i - 1]; p1 = points[i]; if (this._lineSegmentsIntersectsRange(p, p1, i - 2)) { return true; } } return false; }, // @method newLatLngIntersects(): boolean // Check for intersection if new latlng was added to this polyline. // NOTE: does not support detecting intersection for degenerate cases. newLatLngIntersects: function (latlng, skipFirst) { // Cannot check a polyline for intersecting lats/lngs when not added to the map if (!this._map) { return false; } return this.newPointIntersects(this._map.latLngToLayerPoint(latlng), skipFirst); }, // @method newPointIntersects(): boolean // Check for intersection if new point was added to this polyline. // newPoint must be a layer point. // NOTE: does not support detecting intersection for degenerate cases. newPointIntersects: function (newPoint, skipFirst) { var points = this._getProjectedPoints(), len = points ? points.length : 0, lastPoint = points ? points[len - 1] : null, // The previous previous line segment. Previous line segment doesn't need testing. maxIndex = len - 2; if (this._tooFewPointsForIntersection(1)) { return false; } return this._lineSegmentsIntersectsRange(lastPoint, newPoint, maxIndex, skipFirst ? 1 : 0); }, // Polylines with 2 sides can only intersect in cases where points are collinear (we don't support detecting these). // Cannot have intersection when < 3 line segments (< 4 points) _tooFewPointsForIntersection: function (extraPoints) { var points = this._getProjectedPoints(), len = points ? points.length : 0; // Increment length by extraPoints if present len += extraPoints || 0; return !points || len <= 3; }, // Checks a line segment intersections with any line segments before its predecessor. // Don't need to check the predecessor as will never intersect. _lineSegmentsIntersectsRange: function (p, p1, maxIndex, minIndex) { var points = this._getProjectedPoints(), p2, p3; minIndex = minIndex || 0; // Check all previous line segments (beside the immediately previous) for intersections for (var j = maxIndex; j > minIndex; j--) { p2 = points[j - 1]; p3 = points[j]; if (L.LineUtil.segmentsIntersect(p, p1, p2, p3)) { return true; } } return false; }, _getProjectedPoints: function () { if (!this._defaultShape) { return this._originalPoints; } var points = [], _shape = this._defaultShape(); for (var i = 0; i < _shape.length; i++) { points.push(this._map.latLngToLayerPoint(_shape[i])); } return points; } });