From c5ba5b0456a711d157e317f220e9c739226e7f50 Mon Sep 17 00:00:00 2001 From: Joar Wandborg Date: Tue, 10 Jan 2012 01:54:37 +0100 Subject: Installed leaflet in extlib --- extlib/leaflet/src/geometry/Bounds.js | 48 ++++++++ extlib/leaflet/src/geometry/LineUtil.js | 159 ++++++++++++++++++++++++++ extlib/leaflet/src/geometry/Point.js | 66 +++++++++++ extlib/leaflet/src/geometry/PolyUtil.js | 55 +++++++++ extlib/leaflet/src/geometry/Transformation.js | 31 +++++ 5 files changed, 359 insertions(+) create mode 100644 extlib/leaflet/src/geometry/Bounds.js create mode 100644 extlib/leaflet/src/geometry/LineUtil.js create mode 100644 extlib/leaflet/src/geometry/Point.js create mode 100644 extlib/leaflet/src/geometry/PolyUtil.js create mode 100644 extlib/leaflet/src/geometry/Transformation.js (limited to 'extlib/leaflet/src/geometry') diff --git a/extlib/leaflet/src/geometry/Bounds.js b/extlib/leaflet/src/geometry/Bounds.js new file mode 100644 index 00000000..73448ceb --- /dev/null +++ b/extlib/leaflet/src/geometry/Bounds.js @@ -0,0 +1,48 @@ +/* + * L.Bounds represents a rectangular area on the screen in pixel coordinates. + */ + +L.Bounds = L.Class.extend({ + initialize: function(min, max) { //(Point, Point) or Point[] + if (!min) return; + var points = (min instanceof Array ? min : [min, max]); + for (var i = 0, len = points.length; i < len; i++) { + this.extend(points[i]); + } + }, + + // extend the bounds to contain the given point + extend: function(/*Point*/ point) { + if (!this.min && !this.max) { + this.min = new L.Point(point.x, point.y); + this.max = new L.Point(point.x, point.y); + } else { + this.min.x = Math.min(point.x, this.min.x); + this.max.x = Math.max(point.x, this.max.x); + this.min.y = Math.min(point.y, this.min.y); + this.max.y = Math.max(point.y, this.max.y); + } + }, + + getCenter: function(round)/*->Point*/ { + return new L.Point( + (this.min.x + this.max.x) / 2, + (this.min.y + this.max.y) / 2, round); + }, + + contains: function(/*Bounds or Point*/ obj)/*->Boolean*/ { + var min, max; + + if (obj instanceof L.Bounds) { + min = obj.min; + max = obj.max; + } else { + max = max = obj; + } + + return (min.x >= this.min.x) && + (max.x <= this.max.x) && + (min.y >= this.min.y) && + (max.y <= this.max.y); + } +}); \ No newline at end of file diff --git a/extlib/leaflet/src/geometry/LineUtil.js b/extlib/leaflet/src/geometry/LineUtil.js new file mode 100644 index 00000000..72a80855 --- /dev/null +++ b/extlib/leaflet/src/geometry/LineUtil.js @@ -0,0 +1,159 @@ +/* + * L.LineUtil contains different utility functions for line segments + * and polylines (clipping, simplification, distances, etc.) + */ + +L.LineUtil = { + /* + * Simplify polyline with vertex reduction and Douglas-Peucker simplification. + * Improves rendering performance dramatically by lessening the number of points to draw. + */ + simplify: function(/*Point[]*/ points, /*Number*/ tolerance) { + if (!tolerance) return points.slice(); + + // stage 1: vertex reduction + points = this.reducePoints(points, tolerance); + + // stage 2: Douglas-Peucker simplification + points = this.simplifyDP(points, tolerance); + + return points; + }, + + // distance from a point to a segment between two points + pointToSegmentDistance: function(/*Point*/ p, /*Point*/ p1, /*Point*/ p2) { + return Math.sqrt(this._sqPointToSegmentDist(p, p1, p2)); + }, + + // Douglas-Peucker simplification, see http://en.wikipedia.org/wiki/Douglas-Peucker_algorithm + simplifyDP: function(points, tol) { + var maxDist2 = 0, + index = 0, + t2 = tol * tol; + + for (var i = 1, len = points.length, dist2; i < len - 1; i++) { + dist2 = this._sqPointToSegmentDist(points[i], points[0], points[len - 1]); + if (dist2 > maxDist2) { + index = i; + maxDist2 = dist2; + } + } + + if (maxDist2 >= t2) { + var part1 = points.slice(0, index), + part2 = points.slice(index), + simplifiedPart1 = this.simplifyDP(part1, tol).slice(0, len - 2), + simplifiedPart2 = this.simplifyDP(part2, tol); + + return simplifiedPart1.concat(simplifiedPart2); + } else { + return [points[0], points[len - 1]]; + } + }, + + // reduce points that are too close to each other to a single point + reducePoints: function(points, tol) { + var reducedPoints = [points[0]], + t2 = tol * tol; + + for (var i = 1, prev = 0, len = points.length; i < len; i++) { + if (this._sqDist(points[i], points[prev]) < t2) continue; + reducedPoints.push(points[i]); + prev = i; + } + if (prev < len - 1) { + reducedPoints.push(points[len - 1]); + } + return reducedPoints; + }, + + /* + * Cohen-Sutherland line clipping algorithm. + * Used to avoid rendering parts of a polyline that are not currently visible. + */ + clipSegment: function(a, b, bounds, useLastCode) { + var min = bounds.min, + max = bounds.max; + + var codeA = useLastCode ? this._lastCode : this._getBitCode(a, bounds), + codeB = this._getBitCode(b, bounds); + + // save 2nd code to avoid calculating it on the next segment + this._lastCode = codeB; + + while (true) { + // if a,b is inside the clip window (trivial accept) + if (!(codeA | codeB)) { + return [a, b]; + // if a,b is outside the clip window (trivial reject) + } else if (codeA & codeB) { + return false; + // other cases + } else { + var codeOut = codeA || codeB, + p = this._getEdgeIntersection(a, b, codeOut, bounds), + newCode = this._getBitCode(p, bounds); + + if (codeOut == codeA) { + a = p; + codeA = newCode; + } else { + b = p; + codeB = newCode; + } + } + } + }, + + _getEdgeIntersection: function(a, b, code, bounds) { + var dx = b.x - a.x, + dy = b.y - a.y, + min = bounds.min, + max = bounds.max; + + if (code & 8) { // top + return new L.Point(a.x + dx * (max.y - a.y) / dy, max.y); + } else if (code & 4) { // bottom + return new L.Point(a.x + dx * (min.y - a.y) / dy, min.y); + } else if (code & 2){ // right + return new L.Point(max.x, a.y + dy * (max.x - a.x) / dx); + } else if (code & 1) { // left + return new L.Point(min.x, a.y + dy * (min.x - a.x) / dx); + } + }, + + _getBitCode: function(/*Point*/ p, bounds) { + var code = 0; + + if (p.x < bounds.min.x) code |= 1; // left + else if (p.x > bounds.max.x) code |= 2; // right + if (p.y < bounds.min.y) code |= 4; // bottom + else if (p.y > bounds.max.y) code |= 8; // top + + return code; + }, + + // square distance (to avoid unnecessary Math.sqrt calls) + _sqDist: function(p1, p2) { + var dx = p2.x - p1.x, + dy = p2.y - p1.y; + return dx * dx + dy * dy; + }, + + // square distance from point to a segment + _sqPointToSegmentDist: function(p, p1, p2) { + var x2 = p2.x - p1.x, + y2 = p2.y - p1.y; + + if (!x2 && !y2) return this._sqDist(p, p1); + + var dot = (p.x - p1.x) * x2 + (p.y - p1.y) * y2, + t = dot / this._sqDist(p1, p2); + + if (t < 0) return this._sqDist(p, p1); + if (t > 1) return this._sqDist(p, p2); + + var proj = new L.Point(p1.x + x2 * t, p1.y + y2 * t); + return this._sqDist(p, proj); + } +}; \ No newline at end of file diff --git a/extlib/leaflet/src/geometry/Point.js b/extlib/leaflet/src/geometry/Point.js new file mode 100644 index 00000000..d031ffe1 --- /dev/null +++ b/extlib/leaflet/src/geometry/Point.js @@ -0,0 +1,66 @@ +/* + * L.Point represents a point with x and y coordinates. + */ + +L.Point = function(/*Number*/ x, /*Number*/ y, /*Boolean*/ round) { + this.x = (round ? Math.round(x) : x); + this.y = (round ? Math.round(y) : y); +}; + +L.Point.prototype = { + add: function(point) { + return this.clone()._add(point); + }, + + _add: function(point) { + this.x += point.x; + this.y += point.y; + return this; + }, + + subtract: function(point) { + return this.clone()._subtract(point); + }, + + // destructive subtract (faster) + _subtract: function(point) { + this.x -= point.x; + this.y -= point.y; + return this; + }, + + divideBy: function(num, round) { + return new L.Point(this.x/num, this.y/num, round); + }, + + multiplyBy: function(num) { + return new L.Point(this.x * num, this.y * num); + }, + + distanceTo: function(point) { + var x = point.x - this.x, + y = point.y - this.y; + return Math.sqrt(x*x + y*y); + }, + + round: function() { + return this.clone()._round(); + }, + + // destructive round + _round: function() { + this.x = Math.round(this.x); + this.y = Math.round(this.y); + return this; + }, + + clone: function() { + return new L.Point(this.x, this.y); + }, + + toString: function() { + return 'Point(' + + L.Util.formatNum(this.x) + ', ' + + L.Util.formatNum(this.y) + ')'; + } +}; \ No newline at end of file diff --git a/extlib/leaflet/src/geometry/PolyUtil.js b/extlib/leaflet/src/geometry/PolyUtil.js new file mode 100644 index 00000000..c5460709 --- /dev/null +++ b/extlib/leaflet/src/geometry/PolyUtil.js @@ -0,0 +1,55 @@ +/* + * L.PolyUtil contains utilify functions for polygons (clipping, etc.). + */ + +L.PolyUtil = {}; + +/* + * Sutherland-Hodgeman polygon clipping algorithm. + * Used to avoid rendering parts of a polygon that are not currently visible. + */ +L.PolyUtil.clipPolygon = function(points, bounds) { + var min = bounds.min, + max = bounds.max, + clippedPoints, + edges = [1, 4, 2, 8], + i, j, k, + a, b, + len, edge, p, + lu = L.LineUtil; + + for (i = 0, len = points.length; i < len; i++) { + points[i]._code = lu._getBitCode(points[i], bounds); + } + + // for each edge (left, bottom, right, top) + for (k = 0; k < 4; k++) { + edge = edges[k]; + clippedPoints = []; + + for (i = 0, len = points.length, j = len - 1; i < len; j = i++) { + a = points[i]; + b = points[j]; + + // if a is inside the clip window + if (!(a._code & edge)) { + // if b is outside the clip window (a->b goes out of screen) + if (b._code & edge) { + p = lu._getEdgeIntersection(b, a, edge, bounds); + p._code = lu._getBitCode(p, bounds); + clippedPoints.push(p); + } + clippedPoints.push(a); + + // else if b is inside the clip window (a->b enters the screen) + } else if (!(b._code & edge)) { + p = lu._getEdgeIntersection(b, a, edge, bounds); + p._code = lu._getBitCode(p, bounds); + clippedPoints.push(p); + } + } + points = clippedPoints; + } + + return points; +}; \ No newline at end of file diff --git a/extlib/leaflet/src/geometry/Transformation.js b/extlib/leaflet/src/geometry/Transformation.js new file mode 100644 index 00000000..37f40968 --- /dev/null +++ b/extlib/leaflet/src/geometry/Transformation.js @@ -0,0 +1,31 @@ +/* + * L.Transformation is an utility class to perform simple point transformations through a 2d-matrix. + */ + +L.Transformation = L.Class.extend({ + initialize: function(/*Number*/ a, /*Number*/ b, /*Number*/ c, /*Number*/ d) { + this._a = a; + this._b = b; + this._c = c; + this._d = d; + }, + + transform: function(point, scale) { + return this._transform(point.clone(), scale); + }, + + // destructive transform (faster) + _transform: function(/*Point*/ point, /*Number*/ scale) /*-> Point*/ { + scale = scale || 1; + point.x = scale * (this._a * point.x + this._b); + point.y = scale * (this._c * point.y + this._d); + return point; + }, + + untransform: function(/*Point*/ point, /*Number*/ scale) /*-> Point*/ { + scale = scale || 1; + return new L.Point( + (point.x/scale - this._b) / this._a, + (point.y/scale - this._d) / this._c); + } +}); \ No newline at end of file -- cgit v1.2.3