[Libreoffice-commits] online.git: loleaflet/src

Mihai Varga mihai.varga at collabora.com
Mon May 25 06:56:06 PDT 2015


 loleaflet/src/layer/tile/TileLayer.js |  174 +++++++++++++++++++++++++++++++---
 1 file changed, 163 insertions(+), 11 deletions(-)

New commits:
commit bcdf048d6d2cd089ef5fdb1b8b3af0eb0e214682
Author: Mihai Varga <mihai.varga at collabora.com>
Date:   Mon May 25 16:54:29 2015 +0300

    Merge adjacent selection rectangles into a single polygon
    
    + the document is scrolled to the average center of the rectangles
    if that is out of the viewing area

diff --git a/loleaflet/src/layer/tile/TileLayer.js b/loleaflet/src/layer/tile/TileLayer.js
index 8875565..1afc87d 100644
--- a/loleaflet/src/layer/tile/TileLayer.js
+++ b/loleaflet/src/layer/tile/TileLayer.js
@@ -152,21 +152,32 @@ L.TileLayer = L.GridLayer.extend({
 			this._clearSelections();
 			if (strTwips != null) {
 				this._map.fire('searchfound');
+				var rectangles = [];
+				var selectionCenter = new L.Point(0,0);
 				for (var i = 0; i < strTwips.length; i += 4) {
 					var topLeftTwips = new L.Point(parseInt(strTwips[i]), parseInt(strTwips[i+1]));
 					var offset = new L.Point(parseInt(strTwips[i+2]), parseInt(strTwips[i+3]));
+					var topRightTwips = topLeftTwips.add(new L.Point(offset.x, 0));
+					var bottomLeftTwips = topLeftTwips.add(new L.Point(0, offset.y));
 					var bottomRightTwips = topLeftTwips.add(offset);
-					var bounds = new L.LatLngBounds(
-							this._twipsToLatLng(topLeftTwips),
-							this._twipsToLatLng(bottomRightTwips));
-					if (!this._map.getBounds().contains(bounds.getCenter())) {
-						var center = this._map.project(bounds.getCenter());
-						center = center.subtract(this._map.getSize().divideBy(2));
-						center.x = center.x < 0 ? 0 : center.x;
-						center.y = center.y < 0 ? 0 : center.y;
-						$('#scroll-container').mCustomScrollbar('scrollTo', [center.y, center.x]);
-					}
-					var selection = new L.Rectangle(bounds, {
+					rectangles.push([bottomLeftTwips, bottomRightTwips, topLeftTwips, topRightTwips]);
+					selectionCenter = selectionCenter.add(topLeftTwips);
+					selectionCenter = selectionCenter.add(offset.divideBy(2));
+				}
+				// average of all rectangles' centers
+				selectionCenter = selectionCenter.divideBy(strTwips.length / 4);
+				selectionCenter = this._twipsToLatLng(selectionCenter);
+				if (!this._map.getBounds().contains(selectionCenter)) {
+					var center = this._map.project(selectionCenter);
+					center = center.subtract(this._map.getSize().divideBy(2));
+					center.x = center.x < 0 ? 0 : center.x;
+					center.y = center.y < 0 ? 0 : center.y;
+					$('#scroll-container').mCustomScrollbar('scrollTo', [center.y, center.x]);
+				}
+
+				var polygons = this._rectanglesToPolygons(rectangles);
+				for (var i = 0; i < polygons.length; i++) {
+					var selection = new L.Polygon(polygons[i], {
 						fillColor: '#43ACE8',
 						fillOpacity: 0.25,
 						weight: 2,
@@ -256,6 +267,147 @@ L.TileLayer = L.GridLayer.extend({
 		}
 	},
 
+	_rectanglesToPolygons: function(rectangles) {
+		// algorithm found here http://stackoverflow.com/questions/13746284/merging-multiple-adjacent-rectangles-into-one-polygon
+		var eps = 20;
+		// Glue rectangles if the space between them is less then eps
+		for (var i = 0; i < rectangles.length - 1; i++) {
+			for (var j = i + 1; j < rectangles.length; j++) {
+				for (var k = 0; k < rectangles[i].length; k++) {
+					for (var l = 0; l < rectangles[j].length; l++) {
+						if (Math.abs(rectangles[i][k].x - rectangles[j][l].x) < eps) {
+							rectangles[j][l].x = rectangles[i][k].x;
+						}
+						if (Math.abs(rectangles[i][k].y - rectangles[j][l].y) < eps) {
+							rectangles[j][l].y = rectangles[i][k].y;
+						}
+					}
+				}
+			}
+		}
+
+		points = {};
+		for (var i = 0; i < rectangles.length; i++) {
+			for (var j = 0; j < rectangles[i].length; j++) {
+				if (points[rectangles[i][j]]) {
+					delete points[rectangles[i][j]];
+				}
+				else {
+					points[rectangles[i][j]] = rectangles[i][j];
+				}
+			}
+		}
+
+		function getKeys(points) {
+			keys = [];
+			for (var key in points) {
+				if (points.hasOwnProperty(key)) {
+					keys.push(key);
+				}
+			}
+			return keys;
+		}
+
+		function x_then_y(a_str, b_str) {
+			a = a_str.match(/\d+/g);
+			a[0] = parseInt(a[0]);
+			a[1] = parseInt(a[1]);
+			b = b_str.match(/\d+/g);
+			b[0] = parseInt(b[0]);
+			b[1] = parseInt(b[1]);
+
+			if (a[0] < b[0] || (a[0] == b[0] && a[1] < b[1])) {
+				return -1;
+			}
+			else if (a[0] == b[0] && a[1] == b[1]) {
+				return 0;
+			}
+			else {
+				return 1;
+			}
+		}
+
+		function y_then_x(a_str, b_str) {
+			a = a_str.match(/\d+/g);
+			a[0] = parseInt(a[0]);
+			a[1] = parseInt(a[1]);
+			b = b_str.match(/\d+/g);
+			b[0] = parseInt(b[0]);
+			b[1] = parseInt(b[1]);
+
+			if (a[1] < b[1] || (a[1] == b[1] && a[0] < b[0])) {
+				return -1;
+			}
+			else if (a[0] == b[0] && a[1] == b[1]) {
+				return 0;
+			}
+			else {
+				return 1;
+			}
+		}
+
+		sort_x = getKeys(points).sort(x_then_y);
+		sort_y = getKeys(points).sort(y_then_x);
+
+		edges_h = {};
+		edges_v = {};
+
+		var len = getKeys(points).length;
+		var i = 0;
+		while (i < len) {
+			var curr_y = points[sort_y[i]].y;
+			while (i < len && points[sort_y[i]].y === curr_y) {
+				edges_h[sort_y[i]] = sort_y[i+1];
+				edges_h[sort_y[i+1]] = sort_y[i];
+				i += 2;
+			}
+		}
+
+		i = 0;
+		while (i < len) {
+			var curr_x = points[sort_x[i]].x;
+			while (i < len && points[sort_x[i]].x === curr_x) {
+				edges_v[sort_x[i]] = sort_x[i+1];
+				edges_v[sort_x[i+1]] = sort_x[i];
+				i += 2;
+			}
+		}
+
+		var polygons = [];
+		var edges_h_keys = getKeys(edges_h);
+		while (edges_h_keys.length > 0) {
+			var p = [[edges_h_keys[0], 0]];
+			while (true) {
+				var curr = p[p.length - 1][0];
+				var e = p[p.length - 1][1];
+				if (e === 0) {
+					var next_vertex = edges_v[curr];
+					delete edges_v[curr];
+					p.push([next_vertex, 1]);
+				}
+				else {
+					var next_vertex = edges_h[curr];
+					delete edges_h[curr];
+					p.push([next_vertex, 0]);
+				}
+				if (p[p.length - 1][0] === p[0][0] && p[p.length - 1][1] === p[0][1]) {
+					p.pop();
+					break;
+				}
+			}
+			var polygon = [];
+			for (var i = 0; i < p.length; i++) {
+				polygon.push(this._twipsToLatLng(points[p[i][0]]));
+				delete edges_h[p[i][0]];
+				delete edges_v[p[i][0]];
+			}
+			polygon.push(this._twipsToLatLng(points[p[0][0]]));
+			edges_h_keys = getKeys(edges_h);
+			polygons.push(polygon);
+		}
+		return polygons;
+	},
+
 	_clearSelections: function () {
 		this._selections.clearLayers();
 	},


More information about the Libreoffice-commits mailing list