From 78a1ad842bdce8a53dca0a68fa545171755bbeb2 Mon Sep 17 00:00:00 2001 From: boombuler Date: Fri, 22 Feb 2013 20:22:11 +0100 Subject: [PATCH 01/25] new plugin to calculate how to set links for max field count --- plugins/README.md | 1 + plugins/max-links.user.js | 252 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 253 insertions(+) create mode 100644 plugins/max-links.user.js diff --git a/plugins/README.md b/plugins/README.md index 35eb5d86..95a611b7 100644 --- a/plugins/README.md +++ b/plugins/README.md @@ -14,6 +14,7 @@ Available Plugins - [**Highlight Weakened Portals**](https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/show-portal-weakness.user.js) fill portals with red to indicate portal's state of disrepair. The brighter the color the more attention needed (recharge, shields, resonators). A dashed portal means a resonator is missing. - [**Render Limit Increase**](https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/render-limit-increase.user.js) increases render limits. Good for high density areas (e.g. London, UK) and faster PCs. - [**Resonator Display Zoom Level Decrease**](https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/resonator-display-zoom-level-decrease.user.js) Resonator start displaying earlier. +- [**Max-Links**]((https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/rmax-links.user.js) Calculates how to link the portals to create the maximum number of fields. ### available only with the development version diff --git a/plugins/max-links.user.js b/plugins/max-links.user.js new file mode 100644 index 00000000..57074a10 --- /dev/null +++ b/plugins/max-links.user.js @@ -0,0 +1,252 @@ +// ==UserScript== +// @id max-links@boombuler +// @name iitc: Max-Links-Plugin +// @version 0.1 +// @description Calculates how to link the portals to create the maximum number of fields. +// @include http://www.ingress.com/intel* +// @match http://www.ingress.com/intel* +// ==/UserScript== + +// The algorithm is taken from https://github.com/ironwallaby/delaunay + +function wrapper() { + // ensure plugin framework is there, even if iitc is not yet loaded + if(typeof window.plugin !== 'function') + window.plugin = function() {}; + + // PLUGIN START //////////////////////////////////////////////////////// + + // use own namespace for plugin + window.plugin.portalfolding = function() {}; + + var MAX_LINK_COLOR = '#FF0000'; + + var Triangle = function (a, b, c) { + this.a = a + this.b = b + this.c = c + + var A = b.x - a.x, + B = b.y - a.y, + C = c.x - a.x, + D = c.y - a.y, + E = A * (a.x + b.x) + B * (a.y + b.y), + F = C * (a.x + c.x) + D * (a.y + c.y), + G = 2 * (A * (c.y - b.y) - B * (c.x - b.x)), + minx, miny, dx, dy + + /* If the points of the triangle are collinear, then just find the + * extremes and use the midpoint as the center of the circumcircle. */ + if(Math.abs(G) < 0.000001) { + minx = Math.min(a.x, b.x, c.x) + miny = Math.min(a.y, b.y, c.y) + dx = (Math.max(a.x, b.x, c.x) - minx) * 0.5 + dy = (Math.max(a.y, b.y, c.y) - miny) * 0.5 + + this.x = minx + dx + this.y = miny + dy + this.r = dx * dx + dy * dy + } + + else { + this.x = (D*E - B*F) / G + this.y = (A*F - C*E) / G + dx = this.x - a.x + dy = this.y - a.y + this.r = dx * dx + dy * dy + } + } + + Triangle.prototype.draw = function(layer) { + var drawLine = function(src, dest) { + var poly = L.polyline([[src.y, src.x], [dest.y, dest.x]], { + color: MAX_LINK_COLOR, + opacity: 1, + weight:2, + clickable: false, + smoothFactor: 10 + }); + poly.addTo(layer); + }; + + drawLine(this.a, this.b); + drawLine(this.b, this.c); + drawLine(this.c, this.a); + } + + var dedup = function (edges) { + var j = edges.length, + a, b, i, m, n + + outer: while(j) { + b = edges[--j] + a = edges[--j] + i = j + while(i) { + n = edges[--i] + m = edges[--i] + if((a === m && b === n) || (a === n && b === m)) { + edges.splice(j, 2) + edges.splice(i, 2) + j -= 2 + continue outer + } + } + } + } + + var triangulate = function (vertices) { + /* Bail if there aren't enough vertices to form any triangles. */ + if(vertices.length < 3) + return [] + + /* Ensure the vertex array is in order of descending X coordinate + * (which is needed to ensure a subquadratic runtime), and then find + * the bounding box around the points. */ + vertices.sort(function (a, b) { return b.x - a.x }); + + var i = vertices.length - 1, + xmin = vertices[i].x, + xmax = vertices[0].x, + ymin = vertices[i].y, + ymax = ymin + + while(i--) { + if(vertices[i].y < ymin) ymin = vertices[i].y + if(vertices[i].y > ymax) ymax = vertices[i].y + } + + /* Find a supertriangle, which is a triangle that surrounds all the + * vertices. This is used like something of a sentinel value to remove + * cases in the main algorithm, and is removed before we return any + * results. + * + * Once found, put it in the "open" list. (The "open" list is for + * triangles who may still need to be considered; the "closed" list is + * for triangles which do not.) */ + var dx = xmax - xmin, + dy = ymax - ymin, + dmax = (dx > dy) ? dx : dy, + xmid = (xmax + xmin) * 0.5, + ymid = (ymax + ymin) * 0.5, + open = [ + new Triangle( + {x: xmid - 20 * dmax, y: ymid - dmax, __sentinel: true}, + {x: xmid , y: ymid + 20 * dmax, __sentinel: true}, + {x: xmid + 20 * dmax, y: ymid - dmax, __sentinel: true} + ) + ], + closed = [], + edges = [], + j, a, b + + /* Incrementally add each vertex to the mesh. */ + i = vertices.length + while(i--) { + /* For each open triangle, check to see if the current point is + * inside it's circumcircle. If it is, remove the triangle and add + * it's edges to an edge list. */ + edges.length = 0 + j = open.length + while(j--) { + /* If this point is to the right of this triangle's circumcircle, + * then this triangle should never get checked again. Remove it + * from the open list, add it to the closed list, and skip. */ + dx = vertices[i].x - open[j].x + if(dx > 0 && dx * dx > open[j].r) { + closed.push(open[j]) + open.splice(j, 1) + continue + } + + /* If not, skip this triangle. */ + dy = vertices[i].y - open[j].y + if(dx * dx + dy * dy > open[j].r) + continue + + /* Remove the triangle and add it's edges to the edge list. */ + edges.push( + open[j].a, open[j].b, + open[j].b, open[j].c, + open[j].c, open[j].a + ) + open.splice(j, 1) + } + + /* Remove any doubled edges. */ + dedup(edges) + + /* Add a new triangle for each edge. */ + j = edges.length + while(j) { + b = edges[--j] + a = edges[--j] + open.push(new Triangle(a, b, vertices[i])) + } + } + + /* Copy any remaining open triangles to the closed list, and then + * remove any triangles that share a vertex with the supertriangle. */ + Array.prototype.push.apply(closed, open) + + i = closed.length + while(i--) + if(closed[i].a.__sentinel || + closed[i].b.__sentinel || + closed[i].c.__sentinel) + closed.splice(i, 1) + + /* Yay, we're done! */ + return closed + } + + + var layer = null; + + window.plugin.portalfolding.toggle = function() { + if (layer) { + // toggle off + window.map.removeLayer(layer); + layer = null; + return; + } + + var locations = []; + for (var key in window.portals) { + var loc = window.portals[key].options.details.locationE6; + var nloc = { x: loc.lngE6/1E6, y: loc.latE6/1E6 }; + locations.push(nloc); + } + + layer = L.layerGroup([]) + + + var triangles = triangulate(locations); + var i = triangles.length + while(i) { + triangles[--i].draw(layer) + } + + window.map.addLayer(layer); + return layer; + } + + var setup = function() { + $('#toolbox').append('toggle MaxLinks '); + } + + // PLUGIN END ////////////////////////////////////////////////////////// + if(window.iitcLoaded && typeof setup === 'function') { + setup(); + } else { + if(window.bootPlugins) + window.bootPlugins.push(setup); + else + window.bootPlugins = [setup]; + } +} // wrapper end + +// inject code into site context +var script = document.createElement('script'); +script.appendChild(document.createTextNode('('+ wrapper +')();')); +(document.body || document.head || document.documentElement).appendChild(script); \ No newline at end of file From ed7ede3273d6f1e7bf305ba590adb0e326734957 Mon Sep 17 00:00:00 2001 From: boombuler Date: Fri, 22 Feb 2013 20:25:45 +0100 Subject: [PATCH 02/25] added name to readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index c98b771e..f32219af 100644 --- a/README.md +++ b/README.md @@ -83,6 +83,7 @@ Please do! [vita10gy](https://github.com/vita10gy), [Xelio](https://github.com/Xelio), [ZauberNerd](https://github.com/ZauberNerd) +[Boombuler](https://github.com/Boombuler) Attribution & License From c546b7c13dbaff5a15ebb58eca3a2bd6cb4485d9 Mon Sep 17 00:00:00 2001 From: boombuler Date: Fri, 22 Feb 2013 23:04:40 +0100 Subject: [PATCH 03/25] fixed overlapping links --- plugins/max-links.user.js | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/plugins/max-links.user.js b/plugins/max-links.user.js index 57074a10..1f1e4ae7 100644 --- a/plugins/max-links.user.js +++ b/plugins/max-links.user.js @@ -57,9 +57,10 @@ function wrapper() { } } - Triangle.prototype.draw = function(layer) { + Triangle.prototype.draw = function(layer, divX, divY) { var drawLine = function(src, dest) { - var poly = L.polyline([[src.y, src.x], [dest.y, dest.x]], { + var poly = L.polyline([[(src.y + divY)/1E6, (src.x + divX)/1E6], + [(dest.y + divY)/1E6, (dest.x + divX)/1E6]], { color: MAX_LINK_COLOR, opacity: 1, weight:2, @@ -212,19 +213,31 @@ function wrapper() { } var locations = []; + var minX = 0; + var minY = 0; + for (var key in window.portals) { var loc = window.portals[key].options.details.locationE6; - var nloc = { x: loc.lngE6/1E6, y: loc.latE6/1E6 }; + var nloc = { x: loc.lngE6, y: loc.latE6 }; + if (nloc.x < minX) minX = nloc.x; + if (nloc.y < minX) minX = nloc.y; locations.push(nloc); } - - layer = L.layerGroup([]) + var i = locations.length; + while(i) { + var nloc = locations[--i]; + nloc.x += Math.abs(minX); + nloc.y += Math.abs(minY); + } + + layer = L.layerGroup([]) var triangles = triangulate(locations); - var i = triangles.length + i = triangles.length; while(i) { - triangles[--i].draw(layer) + var triangle = triangles[--i]; + triangle.draw(layer, minX, minY) } window.map.addLayer(layer); From 8d419c3c95ee5a12c29d4b9a5cdbeb7023c3bec0 Mon Sep 17 00:00:00 2001 From: boombuler Date: Sat, 23 Feb 2013 15:57:06 +0100 Subject: [PATCH 04/25] added update / download url --- README.md | 2 +- plugins/max-links.user.js | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index eacceeb6..6cd2f6ab 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,7 @@ Please do! [Bananeweizen](https://github.com/Bananeweizen), [blakjakau](https://github.com/blakjakau), +[boombuler](https://github.com/boombuler), [cmrn](https://github.com/cmrn), [epf](https://github.com/epf), [integ3r](https://github.com/integ3r), @@ -85,7 +86,6 @@ Please do! [vita10gy](https://github.com/vita10gy), [Xelio](https://github.com/Xelio), [ZauberNerd](https://github.com/ZauberNerd) -[Boombuler](https://github.com/Boombuler) Attribution & License diff --git a/plugins/max-links.user.js b/plugins/max-links.user.js index 1f1e4ae7..9fa43d56 100644 --- a/plugins/max-links.user.js +++ b/plugins/max-links.user.js @@ -2,6 +2,8 @@ // @id max-links@boombuler // @name iitc: Max-Links-Plugin // @version 0.1 +// @updateURL https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/max-links.user.js +// @downloadURL https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/max-links.user.js // @description Calculates how to link the portals to create the maximum number of fields. // @include http://www.ingress.com/intel* // @match http://www.ingress.com/intel* From c36afe506e612b46e338feabcb90d3ff7bac0c15 Mon Sep 17 00:00:00 2001 From: boombuler Date: Sat, 23 Feb 2013 16:18:02 +0100 Subject: [PATCH 05/25] applyed codingstyle --- plugins/max-links.user.js | 422 +++++++++++++++++++------------------- 1 file changed, 210 insertions(+), 212 deletions(-) diff --git a/plugins/max-links.user.js b/plugins/max-links.user.js index 9fa43d56..07c1261a 100644 --- a/plugins/max-links.user.js +++ b/plugins/max-links.user.js @@ -12,242 +12,240 @@ // The algorithm is taken from https://github.com/ironwallaby/delaunay function wrapper() { - // ensure plugin framework is there, even if iitc is not yet loaded - if(typeof window.plugin !== 'function') - window.plugin = function() {}; + // ensure plugin framework is there, even if iitc is not yet loaded + if(typeof window.plugin !== 'function') + window.plugin = function() {}; - // PLUGIN START //////////////////////////////////////////////////////// + // PLUGIN START //////////////////////////////////////////////////////// - // use own namespace for plugin - window.plugin.portalfolding = function() {}; + // use own namespace for plugin + window.plugin.portalfolding = function() {}; - var MAX_LINK_COLOR = '#FF0000'; + var MAX_LINK_COLOR = '#FF0000'; - var Triangle = function (a, b, c) { - this.a = a - this.b = b - this.c = c + var Triangle = function (a, b, c) { + this.a = a; + this.b = b; + this.c = c; - var A = b.x - a.x, - B = b.y - a.y, - C = c.x - a.x, - D = c.y - a.y, - E = A * (a.x + b.x) + B * (a.y + b.y), - F = C * (a.x + c.x) + D * (a.y + c.y), - G = 2 * (A * (c.y - b.y) - B * (c.x - b.x)), - minx, miny, dx, dy - - /* If the points of the triangle are collinear, then just find the - * extremes and use the midpoint as the center of the circumcircle. */ - if(Math.abs(G) < 0.000001) { - minx = Math.min(a.x, b.x, c.x) - miny = Math.min(a.y, b.y, c.y) - dx = (Math.max(a.x, b.x, c.x) - minx) * 0.5 - dy = (Math.max(a.y, b.y, c.y) - miny) * 0.5 + var A = b.x - a.x, + B = b.y - a.y, + C = c.x - a.x, + D = c.y - a.y, + E = A * (a.x + b.x) + B * (a.y + b.y), + F = C * (a.x + c.x) + D * (a.y + c.y), + G = 2 * (A * (c.y - b.y) - B * (c.x - b.x)), + minx, miny, dx, dy - this.x = minx + dx - this.y = miny + dy - this.r = dx * dx + dy * dy - } + /* If the points of the triangle are collinear, then just find the + * extremes and use the midpoint as the center of the circumcircle. */ + if(Math.abs(G) < 0.000001) { + minx = Math.min(a.x, b.x, c.x) + miny = Math.min(a.y, b.y, c.y) + dx = (Math.max(a.x, b.x, c.x) - minx) * 0.5 + dy = (Math.max(a.y, b.y, c.y) - miny) * 0.5 - else { - this.x = (D*E - B*F) / G - this.y = (A*F - C*E) / G - dx = this.x - a.x - dy = this.y - a.y - this.r = dx * dx + dy * dy - } - } - - Triangle.prototype.draw = function(layer, divX, divY) { - var drawLine = function(src, dest) { - var poly = L.polyline([[(src.y + divY)/1E6, (src.x + divX)/1E6], - [(dest.y + divY)/1E6, (dest.x + divX)/1E6]], { - color: MAX_LINK_COLOR, - opacity: 1, - weight:2, - clickable: false, - smoothFactor: 10 - }); - poly.addTo(layer); - }; - - drawLine(this.a, this.b); - drawLine(this.b, this.c); - drawLine(this.c, this.a); - } - - var dedup = function (edges) { - var j = edges.length, - a, b, i, m, n - - outer: while(j) { - b = edges[--j] - a = edges[--j] - i = j - while(i) { - n = edges[--i] - m = edges[--i] - if((a === m && b === n) || (a === n && b === m)) { - edges.splice(j, 2) - edges.splice(i, 2) - j -= 2 - continue outer - } - } - } + this.x = minx + dx + this.y = miny + dy + this.r = dx * dx + dy * dy + } else { + this.x = (D*E - B*F) / G + this.y = (A*F - C*E) / G + dx = this.x - a.x + dy = this.y - a.y + this.r = dx * dx + dy * dy } + } + + Triangle.prototype.draw = function(layer, divX, divY) { + var drawLine = function(src, dest) { + var poly = L.polyline([[(src.y + divY)/1E6, (src.x + divX)/1E6], + [(dest.y + divY)/1E6, (dest.x + divX)/1E6]], { + color: MAX_LINK_COLOR, + opacity: 1, + weight:2, + clickable: false, + smoothFactor: 10 + }); + poly.addTo(layer); + }; + + drawLine(this.a, this.b); + drawLine(this.b, this.c); + drawLine(this.c, this.a); + } - var triangulate = function (vertices) { - /* Bail if there aren't enough vertices to form any triangles. */ - if(vertices.length < 3) - return [] - - /* Ensure the vertex array is in order of descending X coordinate - * (which is needed to ensure a subquadratic runtime), and then find - * the bounding box around the points. */ - vertices.sort(function (a, b) { return b.x - a.x }); - - var i = vertices.length - 1, - xmin = vertices[i].x, - xmax = vertices[0].x, - ymin = vertices[i].y, - ymax = ymin - - while(i--) { - if(vertices[i].y < ymin) ymin = vertices[i].y - if(vertices[i].y > ymax) ymax = vertices[i].y + var dedup = function (edges) { + var j = edges.length, a, b, i, m, n; + + outer: while(j) { + b = edges[--j]; + a = edges[--j]; + i = j; + while(i) { + n = edges[--i]; + m = edges[--i]; + if((a === m && b === n) || (a === n && b === m)) { + edges.splice(j, 2); + edges.splice(i, 2); + j -= 2; + continue outer; } - - /* Find a supertriangle, which is a triangle that surrounds all the - * vertices. This is used like something of a sentinel value to remove - * cases in the main algorithm, and is removed before we return any - * results. - * - * Once found, put it in the "open" list. (The "open" list is for - * triangles who may still need to be considered; the "closed" list is - * for triangles which do not.) */ - var dx = xmax - xmin, - dy = ymax - ymin, - dmax = (dx > dy) ? dx : dy, - xmid = (xmax + xmin) * 0.5, - ymid = (ymax + ymin) * 0.5, - open = [ - new Triangle( - {x: xmid - 20 * dmax, y: ymid - dmax, __sentinel: true}, - {x: xmid , y: ymid + 20 * dmax, __sentinel: true}, - {x: xmid + 20 * dmax, y: ymid - dmax, __sentinel: true} - ) - ], - closed = [], - edges = [], - j, a, b - - /* Incrementally add each vertex to the mesh. */ - i = vertices.length - while(i--) { - /* For each open triangle, check to see if the current point is - * inside it's circumcircle. If it is, remove the triangle and add - * it's edges to an edge list. */ - edges.length = 0 - j = open.length - while(j--) { - /* If this point is to the right of this triangle's circumcircle, - * then this triangle should never get checked again. Remove it - * from the open list, add it to the closed list, and skip. */ - dx = vertices[i].x - open[j].x - if(dx > 0 && dx * dx > open[j].r) { - closed.push(open[j]) - open.splice(j, 1) - continue - } - - /* If not, skip this triangle. */ - dy = vertices[i].y - open[j].y - if(dx * dx + dy * dy > open[j].r) - continue - - /* Remove the triangle and add it's edges to the edge list. */ - edges.push( - open[j].a, open[j].b, - open[j].b, open[j].c, - open[j].c, open[j].a - ) - open.splice(j, 1) - } - - /* Remove any doubled edges. */ - dedup(edges) - - /* Add a new triangle for each edge. */ - j = edges.length - while(j) { - b = edges[--j] - a = edges[--j] - open.push(new Triangle(a, b, vertices[i])) - } - } - - /* Copy any remaining open triangles to the closed list, and then - * remove any triangles that share a vertex with the supertriangle. */ - Array.prototype.push.apply(closed, open) - - i = closed.length - while(i--) - if(closed[i].a.__sentinel || - closed[i].b.__sentinel || - closed[i].c.__sentinel) - closed.splice(i, 1) - - /* Yay, we're done! */ - return closed } + } + } + var triangulate = function (vertices) { + /* Bail if there aren't enough vertices to form any triangles. */ + if(vertices.length < 3) + return [] + + /* Ensure the vertex array is in order of descending X coordinate + * (which is needed to ensure a subquadratic runtime), and then find + * the bounding box around the points. */ + vertices.sort(function (a, b) { return b.x - a.x }); + + var i = vertices.length - 1, + xmin = vertices[i].x, + xmax = vertices[0].x, + ymin = vertices[i].y, + ymax = ymin; + + while(i--) { + if(vertices[i].y < ymin) + ymin = vertices[i].y; + if(vertices[i].y > ymax) + ymax = vertices[i].y; + } + + /* Find a supertriangle, which is a triangle that surrounds all the + * vertices. This is used like something of a sentinel value to remove + * cases in the main algorithm, and is removed before we return any + * results. + * + * Once found, put it in the "open" list. (The "open" list is for + * triangles who may still need to be considered; the "closed" list is + * for triangles which do not.) */ + var dx = xmax - xmin, + dy = ymax - ymin, + dmax = (dx > dy) ? dx : dy, + xmid = (xmax + xmin) * 0.5, + ymid = (ymax + ymin) * 0.5, + open = [ + new Triangle( + {x: xmid - 20 * dmax, y: ymid - dmax, __sentinel: true}, + {x: xmid , y: ymid + 20 * dmax, __sentinel: true}, + {x: xmid + 20 * dmax, y: ymid - dmax, __sentinel: true} + ) + ], + closed = [], + edges = [], + j, a, b; + + /* Incrementally add each vertex to the mesh. */ + i = vertices.length; + while(i--) { + /* For each open triangle, check to see if the current point is + * inside it's circumcircle. If it is, remove the triangle and add + * it's edges to an edge list. */ + edges.length = 0; + j = open.length; + while(j--) { + /* If this point is to the right of this triangle's circumcircle, + * then this triangle should never get checked again. Remove it + * from the open list, add it to the closed list, and skip. */ + dx = vertices[i].x - open[j].x; + if(dx > 0 && dx * dx > open[j].r) { + closed.push(open[j]); + open.splice(j, 1); + continue; + } + + /* If not, skip this triangle. */ + dy = vertices[i].y - open[j].y; + if(dx * dx + dy * dy > open[j].r) + continue; + + /* Remove the triangle and add it's edges to the edge list. */ + edges.push( + open[j].a, open[j].b, + open[j].b, open[j].c, + open[j].c, open[j].a + ); + open.splice(j, 1); + } + + /* Remove any doubled edges. */ + dedup(edges); + + /* Add a new triangle for each edge. */ + j = edges.length; + while(j) { + b = edges[--j]; + a = edges[--j]; + open.push(new Triangle(a, b, vertices[i])); + } + } + + /* Copy any remaining open triangles to the closed list, and then + * remove any triangles that share a vertex with the supertriangle. */ + Array.prototype.push.apply(closed, open); + + i = closed.length; + while(i--) + if(closed[i].a.__sentinel || closed[i].b.__sentinel || closed[i].c.__sentinel) + closed.splice(i, 1); + + /* Yay, we're done! */ + return closed; + } var layer = null; window.plugin.portalfolding.toggle = function() { - if (layer) { - // toggle off - window.map.removeLayer(layer); - layer = null; - return; - } + if (layer) { + // toggle off + window.map.removeLayer(layer); + layer = null; + return; + } - var locations = []; - var minX = 0; - var minY = 0; + var locations = []; + var minX = 0; + var minY = 0; - for (var key in window.portals) { - var loc = window.portals[key].options.details.locationE6; - var nloc = { x: loc.lngE6, y: loc.latE6 }; - if (nloc.x < minX) minX = nloc.x; - if (nloc.y < minX) minX = nloc.y; - locations.push(nloc); - } + for (var key in window.portals) { + var loc = window.portals[key].options.details.locationE6; + var nloc = { x: loc.lngE6, y: loc.latE6 }; + if (nloc.x < minX) + minX = nloc.x; + if (nloc.y < minX) + minX = nloc.y; + locations.push(nloc); + } - var i = locations.length; - while(i) { - var nloc = locations[--i]; - nloc.x += Math.abs(minX); - nloc.y += Math.abs(minY); - } + var i = locations.length; + while(i) { + var nloc = locations[--i]; + nloc.x += Math.abs(minX); + nloc.y += Math.abs(minY); + } - layer = L.layerGroup([]) + layer = L.layerGroup([]) - var triangles = triangulate(locations); - i = triangles.length; - while(i) { - var triangle = triangles[--i]; - triangle.draw(layer, minX, minY) - } + var triangles = triangulate(locations); + i = triangles.length; + while(i) { + var triangle = triangles[--i]; + triangle.draw(layer, minX, minY) + } - window.map.addLayer(layer); - return layer; - } + window.map.addLayer(layer); + return layer; + } var setup = function() { - $('#toolbox').append('toggle MaxLinks '); + $('#toolbox').append('toggle MaxLinks '); } // PLUGIN END ////////////////////////////////////////////////////////// From 29749ebbe1a64904dd6f0249cf534c5b81e6b6d1 Mon Sep 17 00:00:00 2001 From: boombuler Date: Sat, 23 Feb 2013 17:06:21 +0100 Subject: [PATCH 06/25] add to layerchooser instead of the toolbox + code cleanup --- plugins/max-links.user.js | 113 +++++++++++++++++++------------------- 1 file changed, 55 insertions(+), 58 deletions(-) diff --git a/plugins/max-links.user.js b/plugins/max-links.user.js index 07c1261a..0738f0c9 100644 --- a/plugins/max-links.user.js +++ b/plugins/max-links.user.js @@ -192,71 +192,68 @@ function wrapper() { Array.prototype.push.apply(closed, open); i = closed.length; - while(i--) + while(i--) { if(closed[i].a.__sentinel || closed[i].b.__sentinel || closed[i].c.__sentinel) closed.splice(i, 1); - - /* Yay, we're done! */ - return closed; } + + /* Yay, we're done! */ + return closed; + } - var layer = null; + window.plugin.portalfolding.layer = null; - window.plugin.portalfolding.toggle = function() { - if (layer) { - // toggle off - window.map.removeLayer(layer); - layer = null; - return; - } - - var locations = []; - var minX = 0; - var minY = 0; - - for (var key in window.portals) { - var loc = window.portals[key].options.details.locationE6; - var nloc = { x: loc.lngE6, y: loc.latE6 }; - if (nloc.x < minX) - minX = nloc.x; - if (nloc.y < minX) - minX = nloc.y; - locations.push(nloc); - } - - var i = locations.length; - while(i) { - var nloc = locations[--i]; - nloc.x += Math.abs(minX); - nloc.y += Math.abs(minY); - } - - layer = L.layerGroup([]) - - var triangles = triangulate(locations); - i = triangles.length; - while(i) { - var triangle = triangles[--i]; - triangle.draw(layer, minX, minY) - } - - window.map.addLayer(layer); - return layer; - } + var updating = false; + var fillLayer = function() { + if (updating) + return; + updating = true; + window.plugin.portalfolding.layer.clearLayers(); - var setup = function() { - $('#toolbox').append('toggle MaxLinks '); - } + var locations = []; + var minX = 0; + var minY = 0; + + $.each(window.portals, function(guid, portal) { + var loc = portal.options.details.locationE6; + var nloc = { x: loc.lngE6, y: loc.latE6 }; + if (nloc.x < minX) + minX = nloc.x; + if (nloc.y < minX) + minX = nloc.y; + locations.push(nloc); + }); + + $.each(locations, function(idx, nloc) { + nloc.x += Math.abs(minX); + nloc.y += Math.abs(minY); + }); - // PLUGIN END ////////////////////////////////////////////////////////// - if(window.iitcLoaded && typeof setup === 'function') { - setup(); - } else { - if(window.bootPlugins) - window.bootPlugins.push(setup); - else - window.bootPlugins = [setup]; - } + var triangles = triangulate(locations); + $.each(triangles, function(idx, triangle) { + triangle.draw(window.plugin.portalfolding.layer, minX, minY) + }); + updating = false; + } + + var setup = function() { + window.plugin.portalfolding.layer = L.layerGroup([]); + window.map.on('layeradd', function(e) { + if (e.layer === window.plugin.portalfolding.layer) + fillLayer(); + }); + window.layerChooser.addOverlay(window.plugin.portalfolding.layer, 'Maximum Links'); + } + + // PLUGIN END ////////////////////////////////////////////////////////// + if(window.iitcLoaded && typeof setup === 'function') { + setup(); + } else { + if(window.bootPlugins) + window.bootPlugins.push(setup); + else + window.bootPlugins = [setup]; + } } // wrapper end // inject code into site context From de4ad906458011f82d2a45693b5569cb17543f6c Mon Sep 17 00:00:00 2001 From: boombuler Date: Sun, 24 Feb 2013 11:34:39 +0100 Subject: [PATCH 07/25] changed namespace to maxLinks --- plugins/max-links.user.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/plugins/max-links.user.js b/plugins/max-links.user.js index 0738f0c9..9f35c877 100644 --- a/plugins/max-links.user.js +++ b/plugins/max-links.user.js @@ -19,7 +19,7 @@ function wrapper() { // PLUGIN START //////////////////////////////////////////////////////// // use own namespace for plugin - window.plugin.portalfolding = function() {}; + window.plugin.maxLinks = function() {}; var MAX_LINK_COLOR = '#FF0000'; @@ -201,14 +201,14 @@ function wrapper() { return closed; } - window.plugin.portalfolding.layer = null; + window.plugin.maxLinks.layer = null; var updating = false; var fillLayer = function() { if (updating) return; updating = true; - window.plugin.portalfolding.layer.clearLayers(); + window.plugin.maxLinks.layer.clearLayers(); var locations = []; var minX = 0; @@ -231,18 +231,18 @@ function wrapper() { var triangles = triangulate(locations); $.each(triangles, function(idx, triangle) { - triangle.draw(window.plugin.portalfolding.layer, minX, minY) + triangle.draw(window.plugin.maxLinks.layer, minX, minY) }); updating = false; } var setup = function() { - window.plugin.portalfolding.layer = L.layerGroup([]); + window.plugin.maxLinks.layer = L.layerGroup([]); window.map.on('layeradd', function(e) { - if (e.layer === window.plugin.portalfolding.layer) + if (e.layer === window.plugin.maxLinks.layer) fillLayer(); }); - window.layerChooser.addOverlay(window.plugin.portalfolding.layer, 'Maximum Links'); + window.layerChooser.addOverlay(window.plugin.maxLinks.layer, 'Maximum Links'); } // PLUGIN END ////////////////////////////////////////////////////////// From bbf7f6448898487495389af7d6c0b160881e2b13 Mon Sep 17 00:00:00 2001 From: boombuler Date: Sun, 24 Feb 2013 15:33:10 +0100 Subject: [PATCH 08/25] moved some functions to namespace --- plugins/max-links.user.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/plugins/max-links.user.js b/plugins/max-links.user.js index 9f35c877..6e21d34a 100644 --- a/plugins/max-links.user.js +++ b/plugins/max-links.user.js @@ -95,7 +95,7 @@ function wrapper() { } } - var triangulate = function (vertices) { + window.plugin.maxLinks.triangulate = function (vertices) { /* Bail if there aren't enough vertices to form any triangles. */ if(vertices.length < 3) return [] @@ -204,7 +204,8 @@ function wrapper() { window.plugin.maxLinks.layer = null; var updating = false; - var fillLayer = function() { + + window.plugin.maxLinks.updateLayer = function() { if (updating) return; updating = true; @@ -229,7 +230,7 @@ function wrapper() { nloc.y += Math.abs(minY); }); - var triangles = triangulate(locations); + var triangles = window.plugin.maxLinks.triangulate(locations); $.each(triangles, function(idx, triangle) { triangle.draw(window.plugin.maxLinks.layer, minX, minY) }); @@ -240,8 +241,9 @@ function wrapper() { window.plugin.maxLinks.layer = L.layerGroup([]); window.map.on('layeradd', function(e) { if (e.layer === window.plugin.maxLinks.layer) - fillLayer(); - }); + window.plugin.maxLinks.updateLayer(); + }); + window.map.on('zoomend moveend', fwindow.plugin.maxLinks.updateLayer); window.layerChooser.addOverlay(window.plugin.maxLinks.layer, 'Maximum Links'); } From d8874d10484d17ccb8fb1fa58b3a95da02684ac1 Mon Sep 17 00:00:00 2001 From: boombuler Date: Sun, 24 Feb 2013 15:34:40 +0100 Subject: [PATCH 09/25] readme should be in alphabetical order --- plugins/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/README.md b/plugins/README.md index d23f3a3c..0dc4f5da 100644 --- a/plugins/README.md +++ b/plugins/README.md @@ -13,11 +13,11 @@ Available Plugins - [**Draw Tools**](https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/draw-tools.user.js) allows to draw circles and lines on the map to aid you with planning your next big field. [View screenshot](http://breunigs.github.com/ingress-intel-total-conversion/screenshots/plugin_draw_tools.png) - [**Guess Player Level**](https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/guess-player-levels.user.js) looks for the highest placed resonator per player in the current view to guess the player level. - [**Highlight Weakened Portals**](https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/show-portal-weakness.user.js) fill portals with red to indicate portal's state of disrepair. The brighter the color the more attention needed (recharge, shields, resonators). A dashed portal means a resonator is missing. +- [**Max-Links**]((https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/max-links.user.js) Calculates how to link the portals to create the maximum number of fields. - [**Player Tracker**](https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/player-tracker.user.js) Draws trails for user actions in the last hour. At the last known location there’s a tooltip that shows the data in a table. [View screenshot](http://breunigs.github.com/ingress-intel-total-conversion/screenshots/plugin_player_tracker.png). - [**Render Limit Increase**](https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/render-limit-increase.user.js) increases render limits. Good for high density areas (e.g. London, UK) and faster PCs. - [**Resonator Display Zoom Level Decrease**](https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/resonator-display-zoom-level-decrease.user.js) Resonator start displaying earlier. - [**Show Portal Address**](https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/show-address.user.js) Shows portal address in the side panel. -- [**Max-Links**]((https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/max-links.user.js) Calculates how to link the portals to create the maximum number of fields. ### available only with the development version From f44e9bd3a224e54e9d76c20e76f5430485bb1f8c Mon Sep 17 00:00:00 2001 From: boombuler Date: Sun, 24 Feb 2013 15:56:58 +0100 Subject: [PATCH 10/25] fixed typo + only update links if the layer is visible --- plugins/max-links.user.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/plugins/max-links.user.js b/plugins/max-links.user.js index 6e21d34a..b1cd801f 100644 --- a/plugins/max-links.user.js +++ b/plugins/max-links.user.js @@ -203,10 +203,9 @@ function wrapper() { window.plugin.maxLinks.layer = null; - var updating = false; - + var updating = false; window.plugin.maxLinks.updateLayer = function() { - if (updating) + if (updating || window.plugin.maxLinks.layer === null || !window.map.hasLayer(window.plugin.maxLinks.layer)) return; updating = true; window.plugin.maxLinks.layer.clearLayers(); @@ -243,7 +242,7 @@ function wrapper() { if (e.layer === window.plugin.maxLinks.layer) window.plugin.maxLinks.updateLayer(); }); - window.map.on('zoomend moveend', fwindow.plugin.maxLinks.updateLayer); + window.map.on('zoomend moveend', window.plugin.maxLinks.updateLayer); window.layerChooser.addOverlay(window.plugin.maxLinks.layer, 'Maximum Links'); } From df40a182bea91eebc22903d2ba8d03046727643d Mon Sep 17 00:00:00 2001 From: boombuler Date: Sun, 24 Feb 2013 16:10:47 +0100 Subject: [PATCH 11/25] added screenshot of plugin --- screenshots/plugin_max_links.png | Bin 0 -> 121130 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 screenshots/plugin_max_links.png diff --git a/screenshots/plugin_max_links.png b/screenshots/plugin_max_links.png new file mode 100644 index 0000000000000000000000000000000000000000..d40b40540ddfcdbbac9580633a511cf02d760faa GIT binary patch literal 121130 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%0ACmu}&-slW-Z1`kY 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 Date: Sun, 24 Feb 2013 23:10:22 +0100 Subject: [PATCH 12/25] added a renderlimit for the plugin --- code/hooks.js | 7 +++++-- code/utils_misc.js | 4 +++- plugins/max-links.user.js | 24 ++++++++++++++++++++---- 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/code/hooks.js b/code/hooks.js index 92840b7c..8bef1098 100644 --- a/code/hooks.js +++ b/code/hooks.js @@ -43,13 +43,16 @@ // redrawn. It is called early on in the // code/map_data.js#renderPortal as long as there was an // old portal for the guid. - +// checkRenderLimit: callback is passed the argument of +// {reached : false} to indicate that the renderlimit is reached +// set reached to true. window._hooks = {} window.VALID_HOOKS = ['portalAdded', 'portalDetailsUpdated', - 'publicChatDataAvailable', 'portalDataLoaded', 'beforePortalReRender']; + 'publicChatDataAvailable', 'portalDataLoaded', 'beforePortalReRender', + 'checkRenderLimit']; window.runHooks = function(event, data) { if(VALID_HOOKS.indexOf(event) === -1) throw('Unknown event type: ' + event); diff --git a/code/utils_misc.js b/code/utils_misc.js index 48704d0c..6638955f 100644 --- a/code/utils_misc.js +++ b/code/utils_misc.js @@ -128,7 +128,9 @@ window.renderLimitReached = function() { if(Object.keys(portals).length >= MAX_DRAWN_PORTALS) return true; if(Object.keys(links).length >= MAX_DRAWN_LINKS) return true; if(Object.keys(fields).length >= MAX_DRAWN_FIELDS) return true; - return false; + var param = { 'reached': false }; + window.runHooks('checkRenderLimit', param); + return param.reached; } window.getMinPortalLevel = function() { diff --git a/plugins/max-links.user.js b/plugins/max-links.user.js index b1cd801f..5a7d2476 100644 --- a/plugins/max-links.user.js +++ b/plugins/max-links.user.js @@ -20,9 +20,10 @@ function wrapper() { // use own namespace for plugin window.plugin.maxLinks = function() {}; - + + window.plugin.maxLinks.MAX_DRAWN_LINKS = 400; var MAX_LINK_COLOR = '#FF0000'; - + var Triangle = function (a, b, c) { this.a = a; this.b = b; @@ -203,7 +204,8 @@ function wrapper() { window.plugin.maxLinks.layer = null; - var updating = false; + var updating = false; + var renderLimitReached = false; window.plugin.maxLinks.updateLayer = function() { if (updating || window.plugin.maxLinks.layer === null || !window.map.hasLayer(window.plugin.maxLinks.layer)) return; @@ -230,14 +232,28 @@ function wrapper() { }); var triangles = window.plugin.maxLinks.triangulate(locations); + var drawnLinks = 0; + renderLimitReached = false; $.each(triangles, function(idx, triangle) { - triangle.draw(window.plugin.maxLinks.layer, minX, minY) + if (drawnLinks <= window.plugin.maxLinks.MAX_DRAWN_LINKS) { + triangle.draw(window.plugin.maxLinks.layer, minX, minY); + drawnLinks += 3; + } else { + renderLimitReached = true; + } }); updating = false; + window.renderUpdateStatus(); } var setup = function() { window.plugin.maxLinks.layer = L.layerGroup([]); + + window.addHook('checkRenderLimit', function(e) { + if (window.map.hasLayer(window.plugin.maxLinks.layer) && renderLimitReached) + e.reached = true; + }); + window.map.on('layeradd', function(e) { if (e.layer === window.plugin.maxLinks.layer) window.plugin.maxLinks.updateLayer(); From 1fdad5cfdf6c6bc70beb3a4f202e8984fc08f472 Mon Sep 17 00:00:00 2001 From: Florian Sundermann Date: Mon, 25 Feb 2013 08:50:41 +0100 Subject: [PATCH 13/25] Revert "added a renderlimit for the plugin" This reverts commit a94bf4475ba5366c1c605ffa6e97226839a58552. --- code/hooks.js | 7 ++----- code/utils_misc.js | 4 +--- plugins/max-links.user.js | 24 ++++-------------------- 3 files changed, 7 insertions(+), 28 deletions(-) diff --git a/code/hooks.js b/code/hooks.js index 8bef1098..92840b7c 100644 --- a/code/hooks.js +++ b/code/hooks.js @@ -43,16 +43,13 @@ // redrawn. It is called early on in the // code/map_data.js#renderPortal as long as there was an // old portal for the guid. -// checkRenderLimit: callback is passed the argument of -// {reached : false} to indicate that the renderlimit is reached -// set reached to true. + window._hooks = {} window.VALID_HOOKS = ['portalAdded', 'portalDetailsUpdated', - 'publicChatDataAvailable', 'portalDataLoaded', 'beforePortalReRender', - 'checkRenderLimit']; + 'publicChatDataAvailable', 'portalDataLoaded', 'beforePortalReRender']; window.runHooks = function(event, data) { if(VALID_HOOKS.indexOf(event) === -1) throw('Unknown event type: ' + event); diff --git a/code/utils_misc.js b/code/utils_misc.js index 6638955f..48704d0c 100644 --- a/code/utils_misc.js +++ b/code/utils_misc.js @@ -128,9 +128,7 @@ window.renderLimitReached = function() { if(Object.keys(portals).length >= MAX_DRAWN_PORTALS) return true; if(Object.keys(links).length >= MAX_DRAWN_LINKS) return true; if(Object.keys(fields).length >= MAX_DRAWN_FIELDS) return true; - var param = { 'reached': false }; - window.runHooks('checkRenderLimit', param); - return param.reached; + return false; } window.getMinPortalLevel = function() { diff --git a/plugins/max-links.user.js b/plugins/max-links.user.js index 5a7d2476..b1cd801f 100644 --- a/plugins/max-links.user.js +++ b/plugins/max-links.user.js @@ -20,10 +20,9 @@ function wrapper() { // use own namespace for plugin window.plugin.maxLinks = function() {}; - - window.plugin.maxLinks.MAX_DRAWN_LINKS = 400; + var MAX_LINK_COLOR = '#FF0000'; - + var Triangle = function (a, b, c) { this.a = a; this.b = b; @@ -204,8 +203,7 @@ function wrapper() { window.plugin.maxLinks.layer = null; - var updating = false; - var renderLimitReached = false; + var updating = false; window.plugin.maxLinks.updateLayer = function() { if (updating || window.plugin.maxLinks.layer === null || !window.map.hasLayer(window.plugin.maxLinks.layer)) return; @@ -232,28 +230,14 @@ function wrapper() { }); var triangles = window.plugin.maxLinks.triangulate(locations); - var drawnLinks = 0; - renderLimitReached = false; $.each(triangles, function(idx, triangle) { - if (drawnLinks <= window.plugin.maxLinks.MAX_DRAWN_LINKS) { - triangle.draw(window.plugin.maxLinks.layer, minX, minY); - drawnLinks += 3; - } else { - renderLimitReached = true; - } + triangle.draw(window.plugin.maxLinks.layer, minX, minY) }); updating = false; - window.renderUpdateStatus(); } var setup = function() { window.plugin.maxLinks.layer = L.layerGroup([]); - - window.addHook('checkRenderLimit', function(e) { - if (window.map.hasLayer(window.plugin.maxLinks.layer) && renderLimitReached) - e.reached = true; - }); - window.map.on('layeradd', function(e) { if (e.layer === window.plugin.maxLinks.layer) window.plugin.maxLinks.updateLayer(); From de39c45a3417dbd828c181e44f862edfe8b72386 Mon Sep 17 00:00:00 2001 From: Florian Sundermann Date: Mon, 25 Feb 2013 08:56:39 +0100 Subject: [PATCH 14/25] added a renderlimit --- plugins/max-links.user.js | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/plugins/max-links.user.js b/plugins/max-links.user.js index b1cd801f..9815f350 100644 --- a/plugins/max-links.user.js +++ b/plugins/max-links.user.js @@ -20,7 +20,7 @@ function wrapper() { // use own namespace for plugin window.plugin.maxLinks = function() {}; - + window.plugin.maxLinks.MAX_DRAWN_LINKS = 400; var MAX_LINK_COLOR = '#FF0000'; var Triangle = function (a, b, c) { @@ -203,7 +203,8 @@ function wrapper() { window.plugin.maxLinks.layer = null; - var updating = false; + var updating = false; + var renderLimitReached = false; window.plugin.maxLinks.updateLayer = function() { if (updating || window.plugin.maxLinks.layer === null || !window.map.hasLayer(window.plugin.maxLinks.layer)) return; @@ -230,14 +231,26 @@ function wrapper() { }); var triangles = window.plugin.maxLinks.triangulate(locations); + var drawnLinks = 0; + renderLimitReached = false; $.each(triangles, function(idx, triangle) { - triangle.draw(window.plugin.maxLinks.layer, minX, minY) + if (drawnLinks <= window.plugin.maxLinks.MAX_DRAWN_LINKS) { + triangle.draw(window.plugin.maxLinks.layer, minX, minY) + drawnLinks += 3; + } else { + renderLimitReached = true; + } }); updating = false; + window.renderUpdateStatus(); } var setup = function() { window.plugin.maxLinks.layer = L.layerGroup([]); + window.addHook('checkRenderLimit', function(e) { + if (window.map.hasLayer(window.plugin.maxLinks.layer) && renderLimitReached) + e.reached = true; + }); window.map.on('layeradd', function(e) { if (e.layer === window.plugin.maxLinks.layer) window.plugin.maxLinks.updateLayer(); From 9748664b20efd649246e00d826d04f7d808165c1 Mon Sep 17 00:00:00 2001 From: boombuler Date: Mon, 25 Feb 2013 10:19:24 +0100 Subject: [PATCH 15/25] moved delaunay algorithm to external file --- dist/delaunay.js | 169 ++++++++++++++++++++++++++++ plugins/max-links.user.js | 227 ++++++-------------------------------- 2 files changed, 205 insertions(+), 191 deletions(-) create mode 100644 dist/delaunay.js diff --git a/dist/delaunay.js b/dist/delaunay.js new file mode 100644 index 00000000..c4533930 --- /dev/null +++ b/dist/delaunay.js @@ -0,0 +1,169 @@ + // Source from https://github.com/ironwallaby/delaunay + + window.delaunay = function() {}; + + window.delaunay.Triangle = function (a, b, c) { + this.a = a + this.b = b + this.c = c + + var A = b.x - a.x, + B = b.y - a.y, + C = c.x - a.x, + D = c.y - a.y, + E = A * (a.x + b.x) + B * (a.y + b.y), + F = C * (a.x + c.x) + D * (a.y + c.y), + G = 2 * (A * (c.y - b.y) - B * (c.x - b.x)), + minx, miny, dx, dy + + /* If the points of the triangle are collinear, then just find the + * extremes and use the midpoint as the center of the circumcircle. */ + if(Math.abs(G) < 0.000001) { + minx = Math.min(a.x, b.x, c.x) + miny = Math.min(a.y, b.y, c.y) + dx = (Math.max(a.x, b.x, c.x) - minx) * 0.5 + dy = (Math.max(a.y, b.y, c.y) - miny) * 0.5 + + this.x = minx + dx + this.y = miny + dy + this.r = dx * dx + dy * dy + } + + else { + this.x = (D*E - B*F) / G + this.y = (A*F - C*E) / G + dx = this.x - a.x + dy = this.y - a.y + this.r = dx * dx + dy * dy + } + } + + function byX(a, b) { + return b.x - a.x + } + + function dedup(edges) { + var j = edges.length, + a, b, i, m, n + + outer: while(j) { + b = edges[--j] + a = edges[--j] + i = j + while(i) { + n = edges[--i] + m = edges[--i] + if((a === m && b === n) || (a === n && b === m)) { + edges.splice(j, 2) + edges.splice(i, 2) + j -= 2 + continue outer + } + } + } + } + + window.delaunay.triangulate = function (vertices) { + /* Bail if there aren't enough vertices to form any triangles. */ + if(vertices.length < 3) + return [] + + /* Ensure the vertex array is in order of descending X coordinate + * (which is needed to ensure a subquadratic runtime), and then find + * the bounding box around the points. */ + vertices.sort(byX) + + var i = vertices.length - 1, + xmin = vertices[i].x, + xmax = vertices[0].x, + ymin = vertices[i].y, + ymax = ymin + + while(i--) { + if(vertices[i].y < ymin) ymin = vertices[i].y + if(vertices[i].y > ymax) ymax = vertices[i].y + } + + /* Find a supertriangle, which is a triangle that surrounds all the + * vertices. This is used like something of a sentinel value to remove + * cases in the main algorithm, and is removed before we return any + * results. + * + * Once found, put it in the "open" list. (The "open" list is for + * triangles who may still need to be considered; the "closed" list is + * for triangles which do not.) */ + var dx = xmax - xmin, + dy = ymax - ymin, + dmax = (dx > dy) ? dx : dy, + xmid = (xmax + xmin) * 0.5, + ymid = (ymax + ymin) * 0.5, + open = [ + new window.delaunay.Triangle( + {x: xmid - 20 * dmax, y: ymid - dmax, __sentinel: true}, + {x: xmid , y: ymid + 20 * dmax, __sentinel: true}, + {x: xmid + 20 * dmax, y: ymid - dmax, __sentinel: true} + ) + ], + closed = [], + edges = [], + j, a, b + + /* Incrementally add each vertex to the mesh. */ + i = vertices.length + while(i--) { + /* For each open triangle, check to see if the current point is + * inside it's circumcircle. If it is, remove the triangle and add + * it's edges to an edge list. */ + edges.length = 0 + j = open.length + while(j--) { + /* If this point is to the right of this triangle's circumcircle, + * then this triangle should never get checked again. Remove it + * from the open list, add it to the closed list, and skip. */ + dx = vertices[i].x - open[j].x + if(dx > 0 && dx * dx > open[j].r) { + closed.push(open[j]) + open.splice(j, 1) + continue + } + + /* If not, skip this triangle. */ + dy = vertices[i].y - open[j].y + if(dx * dx + dy * dy > open[j].r) + continue + + /* Remove the triangle and add it's edges to the edge list. */ + edges.push( + open[j].a, open[j].b, + open[j].b, open[j].c, + open[j].c, open[j].a + ) + open.splice(j, 1) + } + + /* Remove any doubled edges. */ + dedup(edges) + + /* Add a new triangle for each edge. */ + j = edges.length + while(j) { + b = edges[--j] + a = edges[--j] + open.push(new window.delaunay.Triangle(a, b, vertices[i])) + } + } + + /* Copy any remaining open triangles to the closed list, and then + * remove any triangles that share a vertex with the supertriangle. */ + Array.prototype.push.apply(closed, open) + + i = closed.length + while(i--) + if(closed[i].a.__sentinel || + closed[i].b.__sentinel || + closed[i].c.__sentinel) + closed.splice(i, 1) + + /* Yay, we're done! */ + return closed + } \ No newline at end of file diff --git a/plugins/max-links.user.js b/plugins/max-links.user.js index 5a7d2476..3f435897 100644 --- a/plugins/max-links.user.js +++ b/plugins/max-links.user.js @@ -9,8 +9,6 @@ // @match http://www.ingress.com/intel* // ==/UserScript== -// The algorithm is taken from https://github.com/ironwallaby/delaunay - function wrapper() { // ensure plugin framework is there, even if iitc is not yet loaded if(typeof window.plugin !== 'function') @@ -21,191 +19,24 @@ function wrapper() { // use own namespace for plugin window.plugin.maxLinks = function() {}; + // const values window.plugin.maxLinks.MAX_DRAWN_LINKS = 400; - var MAX_LINK_COLOR = '#FF0000'; - - var Triangle = function (a, b, c) { - this.a = a; - this.b = b; - this.c = c; - - var A = b.x - a.x, - B = b.y - a.y, - C = c.x - a.x, - D = c.y - a.y, - E = A * (a.x + b.x) + B * (a.y + b.y), - F = C * (a.x + c.x) + D * (a.y + c.y), - G = 2 * (A * (c.y - b.y) - B * (c.x - b.x)), - minx, miny, dx, dy - - /* If the points of the triangle are collinear, then just find the - * extremes and use the midpoint as the center of the circumcircle. */ - if(Math.abs(G) < 0.000001) { - minx = Math.min(a.x, b.x, c.x) - miny = Math.min(a.y, b.y, c.y) - dx = (Math.max(a.x, b.x, c.x) - minx) * 0.5 - dy = (Math.max(a.y, b.y, c.y) - miny) * 0.5 - - this.x = minx + dx - this.y = miny + dy - this.r = dx * dx + dy * dy - } else { - this.x = (D*E - B*F) / G - this.y = (A*F - C*E) / G - dx = this.x - a.x - dy = this.y - a.y - this.r = dx * dx + dy * dy - } - } - - Triangle.prototype.draw = function(layer, divX, divY) { - var drawLine = function(src, dest) { - var poly = L.polyline([[(src.y + divY)/1E6, (src.x + divX)/1E6], - [(dest.y + divY)/1E6, (dest.x + divX)/1E6]], { - color: MAX_LINK_COLOR, - opacity: 1, - weight:2, - clickable: false, - smoothFactor: 10 - }); - poly.addTo(layer); - }; - - drawLine(this.a, this.b); - drawLine(this.b, this.c); - drawLine(this.c, this.a); - } + var STROKE_STYLE = { + color: '#FF0000', + opacity: 1, + weight:2, + clickable: false, + smoothFactor: 10 + }; + var delaunayScriptLocation = "https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/dist/delaunay.js"; - var dedup = function (edges) { - var j = edges.length, a, b, i, m, n; - outer: while(j) { - b = edges[--j]; - a = edges[--j]; - i = j; - while(i) { - n = edges[--i]; - m = edges[--i]; - if((a === m && b === n) || (a === n && b === m)) { - edges.splice(j, 2); - edges.splice(i, 2); - j -= 2; - continue outer; - } - } - } - } - - window.plugin.maxLinks.triangulate = function (vertices) { - /* Bail if there aren't enough vertices to form any triangles. */ - if(vertices.length < 3) - return [] - /* Ensure the vertex array is in order of descending X coordinate - * (which is needed to ensure a subquadratic runtime), and then find - * the bounding box around the points. */ - vertices.sort(function (a, b) { return b.x - a.x }); - - var i = vertices.length - 1, - xmin = vertices[i].x, - xmax = vertices[0].x, - ymin = vertices[i].y, - ymax = ymin; - - while(i--) { - if(vertices[i].y < ymin) - ymin = vertices[i].y; - if(vertices[i].y > ymax) - ymax = vertices[i].y; - } - - /* Find a supertriangle, which is a triangle that surrounds all the - * vertices. This is used like something of a sentinel value to remove - * cases in the main algorithm, and is removed before we return any - * results. - * - * Once found, put it in the "open" list. (The "open" list is for - * triangles who may still need to be considered; the "closed" list is - * for triangles which do not.) */ - var dx = xmax - xmin, - dy = ymax - ymin, - dmax = (dx > dy) ? dx : dy, - xmid = (xmax + xmin) * 0.5, - ymid = (ymax + ymin) * 0.5, - open = [ - new Triangle( - {x: xmid - 20 * dmax, y: ymid - dmax, __sentinel: true}, - {x: xmid , y: ymid + 20 * dmax, __sentinel: true}, - {x: xmid + 20 * dmax, y: ymid - dmax, __sentinel: true} - ) - ], - closed = [], - edges = [], - j, a, b; - - /* Incrementally add each vertex to the mesh. */ - i = vertices.length; - while(i--) { - /* For each open triangle, check to see if the current point is - * inside it's circumcircle. If it is, remove the triangle and add - * it's edges to an edge list. */ - edges.length = 0; - j = open.length; - while(j--) { - /* If this point is to the right of this triangle's circumcircle, - * then this triangle should never get checked again. Remove it - * from the open list, add it to the closed list, and skip. */ - dx = vertices[i].x - open[j].x; - if(dx > 0 && dx * dx > open[j].r) { - closed.push(open[j]); - open.splice(j, 1); - continue; - } - - /* If not, skip this triangle. */ - dy = vertices[i].y - open[j].y; - if(dx * dx + dy * dy > open[j].r) - continue; - - /* Remove the triangle and add it's edges to the edge list. */ - edges.push( - open[j].a, open[j].b, - open[j].b, open[j].c, - open[j].c, open[j].a - ); - open.splice(j, 1); - } - - /* Remove any doubled edges. */ - dedup(edges); - - /* Add a new triangle for each edge. */ - j = edges.length; - while(j) { - b = edges[--j]; - a = edges[--j]; - open.push(new Triangle(a, b, vertices[i])); - } - } - - /* Copy any remaining open triangles to the closed list, and then - * remove any triangles that share a vertex with the supertriangle. */ - Array.prototype.push.apply(closed, open); - - i = closed.length; - while(i--) { - if(closed[i].a.__sentinel || closed[i].b.__sentinel || closed[i].c.__sentinel) - closed.splice(i, 1); - } - - /* Yay, we're done! */ - return closed; - } - window.plugin.maxLinks.layer = null; var updating = false; - var renderLimitReached = false; + var renderLimitReached = false; + window.plugin.maxLinks.updateLayer = function() { if (updating || window.plugin.maxLinks.layer === null || !window.map.hasLayer(window.plugin.maxLinks.layer)) return; @@ -231,7 +62,7 @@ function wrapper() { nloc.y += Math.abs(minY); }); - var triangles = window.plugin.maxLinks.triangulate(locations); + var triangles = window.delaunay.triangulate(locations); var drawnLinks = 0; renderLimitReached = false; $.each(triangles, function(idx, triangle) { @@ -247,19 +78,33 @@ function wrapper() { } var setup = function() { - window.plugin.maxLinks.layer = L.layerGroup([]); + load(delaunayScriptLocation).thenRun(function() { + + window.delaunay.Triangle.prototype.draw = function(layer, divX, divY) { + var drawLine = function(src, dest) { + var poly = L.polyline([[(src.y + divY)/1E6, (src.x + divX)/1E6], [(dest.y + divY)/1E6, (dest.x + divX)/1E6]], STROKE_STYLE); + poly.addTo(layer); + }; + + drawLine(this.a, this.b); + drawLine(this.b, this.c); + drawLine(this.c, this.a); + } + + window.plugin.maxLinks.layer = L.layerGroup([]); - window.addHook('checkRenderLimit', function(e) { - if (window.map.hasLayer(window.plugin.maxLinks.layer) && renderLimitReached) - e.reached = true; - }); + window.addHook('checkRenderLimit', function(e) { + if (window.map.hasLayer(window.plugin.maxLinks.layer) && renderLimitReached) + e.reached = true; + }); - window.map.on('layeradd', function(e) { - if (e.layer === window.plugin.maxLinks.layer) - window.plugin.maxLinks.updateLayer(); + window.map.on('layeradd', function(e) { + if (e.layer === window.plugin.maxLinks.layer) + window.plugin.maxLinks.updateLayer(); + }); + window.map.on('zoomend moveend', window.plugin.maxLinks.updateLayer); + window.layerChooser.addOverlay(window.plugin.maxLinks.layer, 'Maximum Links'); }); - window.map.on('zoomend moveend', window.plugin.maxLinks.updateLayer); - window.layerChooser.addOverlay(window.plugin.maxLinks.layer, 'Maximum Links'); } // PLUGIN END ////////////////////////////////////////////////////////// From c86e8608bf13d278b840adf05e402c1012404a25 Mon Sep 17 00:00:00 2001 From: boombuler Date: Mon, 25 Feb 2013 10:41:02 +0100 Subject: [PATCH 16/25] support increased render limit within the plugin --- plugins/max-links.user.js | 6 ++++-- plugins/render-limit-increase.user.js | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/plugins/max-links.user.js b/plugins/max-links.user.js index 86a86447..416d7852 100644 --- a/plugins/max-links.user.js +++ b/plugins/max-links.user.js @@ -20,7 +20,8 @@ function wrapper() { window.plugin.maxLinks = function() {}; // const values - window.plugin.maxLinks.MAX_DRAWN_LINKS = 400; + var MAX_DRAWN_LINKS = 400; + var MAX_DRAWN_LINKS_INCREASED_LIMIT = 1000; var STROKE_STYLE = { color: '#FF0000', opacity: 1, @@ -63,8 +64,9 @@ function wrapper() { var triangles = window.delaunay.triangulate(locations); var drawnLinks = 0; renderLimitReached = false; + var renderlimit = window.USE_INCREASED_RENDER_LIMIT ? MAX_DRAWN_LINKS_INCREASED_LIMIT : MAX_DRAWN_LINKS; $.each(triangles, function(idx, triangle) { - if (drawnLinks <= window.plugin.maxLinks.MAX_DRAWN_LINKS) { + if (drawnLinks <= renderlimit) { triangle.draw(window.plugin.maxLinks.layer, minX, minY) drawnLinks += 3; } else { diff --git a/plugins/render-limit-increase.user.js b/plugins/render-limit-increase.user.js index 56e66b9a..dddd9c19 100644 --- a/plugins/render-limit-increase.user.js +++ b/plugins/render-limit-increase.user.js @@ -39,7 +39,7 @@ window.plugin.renderLimitIncrease.setHigherLimits = function() { window.MAX_DRAWN_PORTALS = 3000; window.MAX_DRAWN_LINKS = 1000; window.MAX_DRAWN_FIELDS = 500; - + window.USE_INCREASED_RENDER_LIMIT = true; // Used for other plugins }; var setup = window.plugin.renderLimitIncrease.setHigherLimits; From 027e13778b424df980ba304785e36a940349107e Mon Sep 17 00:00:00 2001 From: boombuler Date: Mon, 25 Feb 2013 20:14:12 +0100 Subject: [PATCH 17/25] fixed coding style --- plugins/max-links.user.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/plugins/max-links.user.js b/plugins/max-links.user.js index 416d7852..0b66a5d7 100644 --- a/plugins/max-links.user.js +++ b/plugins/max-links.user.js @@ -23,13 +23,13 @@ function wrapper() { var MAX_DRAWN_LINKS = 400; var MAX_DRAWN_LINKS_INCREASED_LIMIT = 1000; var STROKE_STYLE = { - color: '#FF0000', - opacity: 1, - weight:2, - clickable: false, - smoothFactor: 10 - }; - var delaunayScriptLocation = "https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/dist/delaunay.js"; + color: '#FF0000', + opacity: 1, + weight:2, + clickable: false, + smoothFactor: 10 + }; + var delaunayScriptLocation = 'https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/dist/delaunay.js'; window.plugin.maxLinks.layer = null; From dc058939f40ccf2e20f47e86ec079a3f66f1b1ba Mon Sep 17 00:00:00 2001 From: boombuler Date: Mon, 25 Feb 2013 20:18:04 +0100 Subject: [PATCH 18/25] moved constants to namespace --- plugins/max-links.user.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/plugins/max-links.user.js b/plugins/max-links.user.js index 0b66a5d7..668089e2 100644 --- a/plugins/max-links.user.js +++ b/plugins/max-links.user.js @@ -20,9 +20,9 @@ function wrapper() { window.plugin.maxLinks = function() {}; // const values - var MAX_DRAWN_LINKS = 400; - var MAX_DRAWN_LINKS_INCREASED_LIMIT = 1000; - var STROKE_STYLE = { + window.plugin.maxLinks.MAX_DRAWN_LINKS = 400; + window.plugin.maxLinks.MAX_DRAWN_LINKS_INCREASED_LIMIT = 1000; + window.plugin.maxLinks.STROKE_STYLE = { color: '#FF0000', opacity: 1, weight:2, @@ -64,7 +64,7 @@ function wrapper() { var triangles = window.delaunay.triangulate(locations); var drawnLinks = 0; renderLimitReached = false; - var renderlimit = window.USE_INCREASED_RENDER_LIMIT ? MAX_DRAWN_LINKS_INCREASED_LIMIT : MAX_DRAWN_LINKS; + var renderlimit = window.USE_INCREASED_RENDER_LIMIT ? window.plugin.maxLinks.MAX_DRAWN_LINKS_INCREASED_LIMIT : window.plugin.maxLinks.MAX_DRAWN_LINKS; $.each(triangles, function(idx, triangle) { if (drawnLinks <= renderlimit) { triangle.draw(window.plugin.maxLinks.layer, minX, minY) @@ -82,7 +82,7 @@ function wrapper() { window.delaunay.Triangle.prototype.draw = function(layer, divX, divY) { var drawLine = function(src, dest) { - var poly = L.polyline([[(src.y + divY)/1E6, (src.x + divX)/1E6], [(dest.y + divY)/1E6, (dest.x + divX)/1E6]], STROKE_STYLE); + var poly = L.polyline([[(src.y + divY)/1E6, (src.x + divX)/1E6], [(dest.y + divY)/1E6, (dest.x + divX)/1E6]], window.plugin.maxLinks.STROKE_STYLE); poly.addTo(layer); }; From c75b99a079d758a907174ab59136bead7777ed57 Mon Sep 17 00:00:00 2001 From: boombuler Date: Mon, 25 Feb 2013 20:21:26 +0100 Subject: [PATCH 19/25] added some linebreaks --- plugins/max-links.user.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/plugins/max-links.user.js b/plugins/max-links.user.js index 668089e2..586beb16 100644 --- a/plugins/max-links.user.js +++ b/plugins/max-links.user.js @@ -37,7 +37,8 @@ function wrapper() { var renderLimitReached = false; window.plugin.maxLinks.updateLayer = function() { - if (updating || window.plugin.maxLinks.layer === null || !window.map.hasLayer(window.plugin.maxLinks.layer)) + if (updating || window.plugin.maxLinks.layer === null || + !window.map.hasLayer(window.plugin.maxLinks.layer)) return; updating = true; window.plugin.maxLinks.layer.clearLayers(); @@ -64,7 +65,9 @@ function wrapper() { var triangles = window.delaunay.triangulate(locations); var drawnLinks = 0; renderLimitReached = false; - var renderlimit = window.USE_INCREASED_RENDER_LIMIT ? window.plugin.maxLinks.MAX_DRAWN_LINKS_INCREASED_LIMIT : window.plugin.maxLinks.MAX_DRAWN_LINKS; + var renderlimit = window.USE_INCREASED_RENDER_LIMIT ? + window.plugin.maxLinks.MAX_DRAWN_LINKS_INCREASED_LIMIT : + window.plugin.maxLinks.MAX_DRAWN_LINKS; $.each(triangles, function(idx, triangle) { if (drawnLinks <= renderlimit) { triangle.draw(window.plugin.maxLinks.layer, minX, minY) From 0f728944bd757e1f7ee98b8306583662dc9e8ace Mon Sep 17 00:00:00 2001 From: boombuler Date: Mon, 25 Feb 2013 20:24:01 +0100 Subject: [PATCH 20/25] fixed typo --- plugins/max-links.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/max-links.user.js b/plugins/max-links.user.js index 586beb16..1063cf98 100644 --- a/plugins/max-links.user.js +++ b/plugins/max-links.user.js @@ -53,7 +53,7 @@ function wrapper() { if (nloc.x < minX) minX = nloc.x; if (nloc.y < minX) - minX = nloc.y; + minY = nloc.y; locations.push(nloc); }); From ca6fb9952ba4be62ba4a0e6e58549aa5d26f69ad Mon Sep 17 00:00:00 2001 From: boombuler Date: Mon, 25 Feb 2013 20:27:10 +0100 Subject: [PATCH 21/25] added link to the screenshot to the readme --- plugins/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/README.md b/plugins/README.md index 86280f0e..6d484586 100644 --- a/plugins/README.md +++ b/plugins/README.md @@ -13,7 +13,7 @@ Available Plugins - [**Draw Tools**](https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/draw-tools.user.js) allows to draw circles and lines on the map to aid you with planning your next big field. [View screenshot](http://breunigs.github.com/ingress-intel-total-conversion/screenshots/plugin_draw_tools.png) - [**Guess Player Level**](https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/guess-player-levels.user.js) looks for the highest placed resonator per player in the current view to guess the player level. - [**Highlight Weakened Portals**](https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/show-portal-weakness.user.js) fill portals with red to indicate portal's state of disrepair. The brighter the color the more attention needed (recharge, shields, resonators). A dashed portal means a resonator is missing. Red, needs energy and shields. Orange, only needs energy (either recharge or resonators). Yellow, only needs shields. -- [**Max-Links**]((https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/max-links.user.js) Calculates how to link the portals to create the maximum number of fields. +- [**Max-Links**]((https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/max-links.user.js) Calculates how to link the portals to create the maximum number of fields. [View screenshot](http://breunigs.github.com/ingress-intel-total-conversion/screenshots/plugin_max_links.png) - [**Player Tracker**](https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/player-tracker.user.js) Draws trails for user actions in the last hour. At the last known location there’s a tooltip that shows the data in a table. [View screenshot](http://breunigs.github.com/ingress-intel-total-conversion/screenshots/plugin_player_tracker.png). - [**Render Limit Increase**](https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/render-limit-increase.user.js) increases render limits. Good for high density areas (e.g. London, UK) and faster PCs. - [**Resonator Display Zoom Level Decrease**](https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/resonator-display-zoom-level-decrease.user.js) Resonator start displaying earlier. From a392c0446981477007a88ce91bc850f908a52c85 Mon Sep 17 00:00:00 2001 From: boombuler Date: Mon, 25 Feb 2013 20:34:25 +0100 Subject: [PATCH 22/25] unindented the wrapper function. --- plugins/max-links.user.js | 186 +++++++++++++++++++------------------- 1 file changed, 94 insertions(+), 92 deletions(-) diff --git a/plugins/max-links.user.js b/plugins/max-links.user.js index 1063cf98..053c601e 100644 --- a/plugins/max-links.user.js +++ b/plugins/max-links.user.js @@ -10,115 +10,117 @@ // ==/UserScript== function wrapper() { - // ensure plugin framework is there, even if iitc is not yet loaded - if(typeof window.plugin !== 'function') - window.plugin = function() {}; - // PLUGIN START //////////////////////////////////////////////////////// +// ensure plugin framework is there, even if iitc is not yet loaded +if(typeof window.plugin !== 'function') + window.plugin = function() {}; - // use own namespace for plugin - window.plugin.maxLinks = function() {}; +// PLUGIN START //////////////////////////////////////////////////////// + +// use own namespace for plugin +window.plugin.maxLinks = function() {}; - // const values - window.plugin.maxLinks.MAX_DRAWN_LINKS = 400; - window.plugin.maxLinks.MAX_DRAWN_LINKS_INCREASED_LIMIT = 1000; - window.plugin.maxLinks.STROKE_STYLE = { - color: '#FF0000', - opacity: 1, - weight:2, - clickable: false, - smoothFactor: 10 - }; - var delaunayScriptLocation = 'https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/dist/delaunay.js'; +// const values +window.plugin.maxLinks.MAX_DRAWN_LINKS = 400; +window.plugin.maxLinks.MAX_DRAWN_LINKS_INCREASED_LIMIT = 1000; +window.plugin.maxLinks.STROKE_STYLE = { + color: '#FF0000', + opacity: 1, + weight:2, + clickable: false, + smoothFactor: 10 +}; +var delaunayScriptLocation = 'https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/dist/delaunay.js'; - window.plugin.maxLinks.layer = null; +window.plugin.maxLinks.layer = null; - var updating = false; - var renderLimitReached = false; +var updating = false; +var renderLimitReached = false; - window.plugin.maxLinks.updateLayer = function() { - if (updating || window.plugin.maxLinks.layer === null || - !window.map.hasLayer(window.plugin.maxLinks.layer)) - return; - updating = true; - window.plugin.maxLinks.layer.clearLayers(); +window.plugin.maxLinks.updateLayer = function() { + if (updating || window.plugin.maxLinks.layer === null || + !window.map.hasLayer(window.plugin.maxLinks.layer)) + return; + updating = true; + window.plugin.maxLinks.layer.clearLayers(); - var locations = []; - var minX = 0; - var minY = 0; + var locations = []; + var minX = 0; + var minY = 0; - $.each(window.portals, function(guid, portal) { - var loc = portal.options.details.locationE6; - var nloc = { x: loc.lngE6, y: loc.latE6 }; - if (nloc.x < minX) - minX = nloc.x; - if (nloc.y < minX) - minY = nloc.y; - locations.push(nloc); - }); + $.each(window.portals, function(guid, portal) { + var loc = portal.options.details.locationE6; + var nloc = { x: loc.lngE6, y: loc.latE6 }; + if (nloc.x < minX) + minX = nloc.x; + if (nloc.y < minX) + minY = nloc.y; + locations.push(nloc); + }); - $.each(locations, function(idx, nloc) { - nloc.x += Math.abs(minX); - nloc.y += Math.abs(minY); - }); + $.each(locations, function(idx, nloc) { + nloc.x += Math.abs(minX); + nloc.y += Math.abs(minY); + }); - var triangles = window.delaunay.triangulate(locations); - var drawnLinks = 0; - renderLimitReached = false; - var renderlimit = window.USE_INCREASED_RENDER_LIMIT ? - window.plugin.maxLinks.MAX_DRAWN_LINKS_INCREASED_LIMIT : - window.plugin.maxLinks.MAX_DRAWN_LINKS; - $.each(triangles, function(idx, triangle) { - if (drawnLinks <= renderlimit) { - triangle.draw(window.plugin.maxLinks.layer, minX, minY) - drawnLinks += 3; - } else { - renderLimitReached = true; - } - }); - updating = false; - window.renderUpdateStatus(); - } + var triangles = window.delaunay.triangulate(locations); + var drawnLinks = 0; + renderLimitReached = false; + var renderlimit = window.USE_INCREASED_RENDER_LIMIT ? + window.plugin.maxLinks.MAX_DRAWN_LINKS_INCREASED_LIMIT : + window.plugin.maxLinks.MAX_DRAWN_LINKS; + $.each(triangles, function(idx, triangle) { + if (drawnLinks <= renderlimit) { + triangle.draw(window.plugin.maxLinks.layer, minX, minY) + drawnLinks += 3; + } else { + renderLimitReached = true; + } + }); + updating = false; + window.renderUpdateStatus(); +} - var setup = function() { - load(delaunayScriptLocation).thenRun(function() { +var setup = function() { + load(delaunayScriptLocation).thenRun(function() { - window.delaunay.Triangle.prototype.draw = function(layer, divX, divY) { - var drawLine = function(src, dest) { - var poly = L.polyline([[(src.y + divY)/1E6, (src.x + divX)/1E6], [(dest.y + divY)/1E6, (dest.x + divX)/1E6]], window.plugin.maxLinks.STROKE_STYLE); - poly.addTo(layer); - }; + window.delaunay.Triangle.prototype.draw = function(layer, divX, divY) { + var drawLine = function(src, dest) { + var poly = L.polyline([[(src.y + divY)/1E6, (src.x + divX)/1E6], [(dest.y + divY)/1E6, (dest.x + divX)/1E6]], window.plugin.maxLinks.STROKE_STYLE); + poly.addTo(layer); + }; - drawLine(this.a, this.b); - drawLine(this.b, this.c); - drawLine(this.c, this.a); - } + drawLine(this.a, this.b); + drawLine(this.b, this.c); + drawLine(this.c, this.a); + } - window.plugin.maxLinks.layer = L.layerGroup([]); + window.plugin.maxLinks.layer = L.layerGroup([]); - window.addHook('checkRenderLimit', function(e) { - if (window.map.hasLayer(window.plugin.maxLinks.layer) && renderLimitReached) - e.reached = true; - }); - - window.map.on('layeradd', function(e) { - if (e.layer === window.plugin.maxLinks.layer) - window.plugin.maxLinks.updateLayer(); - }); - window.map.on('zoomend moveend', window.plugin.maxLinks.updateLayer); - window.layerChooser.addOverlay(window.plugin.maxLinks.layer, 'Maximum Links'); + window.addHook('checkRenderLimit', function(e) { + if (window.map.hasLayer(window.plugin.maxLinks.layer) && renderLimitReached) + e.reached = true; }); - } - // PLUGIN END ////////////////////////////////////////////////////////// - if(window.iitcLoaded && typeof setup === 'function') { - setup(); - } else { - if(window.bootPlugins) - window.bootPlugins.push(setup); - else - window.bootPlugins = [setup]; - } + window.map.on('layeradd', function(e) { + if (e.layer === window.plugin.maxLinks.layer) + window.plugin.maxLinks.updateLayer(); + }); + window.map.on('zoomend moveend', window.plugin.maxLinks.updateLayer); + window.layerChooser.addOverlay(window.plugin.maxLinks.layer, 'Maximum Links'); + }); +} + +// PLUGIN END ////////////////////////////////////////////////////////// +if(window.iitcLoaded && typeof setup === 'function') { + setup(); +} else { + if(window.bootPlugins) + window.bootPlugins.push(setup); + else + window.bootPlugins = [setup]; +} + } // wrapper end // inject code into site context From 664c2595cf47707625061afe94e2b923610d3560 Mon Sep 17 00:00:00 2001 From: boombuler Date: Mon, 25 Feb 2013 21:19:46 +0100 Subject: [PATCH 23/25] fixed typo --- plugins/max-links.user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/max-links.user.js b/plugins/max-links.user.js index 053c601e..40d13b49 100644 --- a/plugins/max-links.user.js +++ b/plugins/max-links.user.js @@ -53,7 +53,7 @@ window.plugin.maxLinks.updateLayer = function() { var nloc = { x: loc.lngE6, y: loc.latE6 }; if (nloc.x < minX) minX = nloc.x; - if (nloc.y < minX) + if (nloc.y < minY) minY = nloc.y; locations.push(nloc); }); @@ -81,7 +81,7 @@ window.plugin.maxLinks.updateLayer = function() { window.renderUpdateStatus(); } -var setup = function() { +var setup = function() { load(delaunayScriptLocation).thenRun(function() { window.delaunay.Triangle.prototype.draw = function(layer, divX, divY) { From 6c4ccdff9432414a5ebdd7e3bfa49bf8cffef068 Mon Sep 17 00:00:00 2001 From: boombuler Date: Mon, 25 Feb 2013 21:24:36 +0100 Subject: [PATCH 24/25] moved some vars to namespace --- plugins/max-links.user.js | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/plugins/max-links.user.js b/plugins/max-links.user.js index 40d13b49..ca45d735 100644 --- a/plugins/max-links.user.js +++ b/plugins/max-links.user.js @@ -30,18 +30,19 @@ window.plugin.maxLinks.STROKE_STYLE = { clickable: false, smoothFactor: 10 }; -var delaunayScriptLocation = 'https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/dist/delaunay.js'; +window.plugin.maxLinks._delaunayScriptLocation = 'https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/dist/delaunay.js'; window.plugin.maxLinks.layer = null; -var updating = false; -var renderLimitReached = false; +window.plugin.maxLinks._updating = false; +window.plugin.maxLinks._renderLimitReached = false; window.plugin.maxLinks.updateLayer = function() { - if (updating || window.plugin.maxLinks.layer === null || + if (window.plugin.maxLinks._updating || + window.plugin.maxLinks.layer === null || !window.map.hasLayer(window.plugin.maxLinks.layer)) return; - updating = true; + window.plugin.maxLinks._updating = true; window.plugin.maxLinks.layer.clearLayers(); var locations = []; @@ -65,7 +66,7 @@ window.plugin.maxLinks.updateLayer = function() { var triangles = window.delaunay.triangulate(locations); var drawnLinks = 0; - renderLimitReached = false; + window.plugin.maxLinks._renderLimitReached = false; var renderlimit = window.USE_INCREASED_RENDER_LIMIT ? window.plugin.maxLinks.MAX_DRAWN_LINKS_INCREASED_LIMIT : window.plugin.maxLinks.MAX_DRAWN_LINKS; @@ -74,15 +75,15 @@ window.plugin.maxLinks.updateLayer = function() { triangle.draw(window.plugin.maxLinks.layer, minX, minY) drawnLinks += 3; } else { - renderLimitReached = true; + window.plugin.maxLinks._renderLimitReached = true; } }); - updating = false; + window.plugin.maxLinks._updating = false; window.renderUpdateStatus(); } -var setup = function() { - load(delaunayScriptLocation).thenRun(function() { +window.plugin.maxLinks.setup = function() { + load(window.plugin.maxLinks._delaunayScriptLocation).thenRun(function() { window.delaunay.Triangle.prototype.draw = function(layer, divX, divY) { var drawLine = function(src, dest) { @@ -98,7 +99,8 @@ var setup = function() { window.plugin.maxLinks.layer = L.layerGroup([]); window.addHook('checkRenderLimit', function(e) { - if (window.map.hasLayer(window.plugin.maxLinks.layer) && renderLimitReached) + if (window.map.hasLayer(window.plugin.maxLinks.layer) && + window.plugin.maxLinks._renderLimitReached) e.reached = true; }); @@ -110,6 +112,7 @@ var setup = function() { window.layerChooser.addOverlay(window.plugin.maxLinks.layer, 'Maximum Links'); }); } +var setup = window.plugin.maxLinks.setup; // PLUGIN END ////////////////////////////////////////////////////////// if(window.iitcLoaded && typeof setup === 'function') { From 799a1012edee742c0511a2cab5c423abf57e2c80 Mon Sep 17 00:00:00 2001 From: boombuler Date: Mon, 25 Feb 2013 21:54:52 +0100 Subject: [PATCH 25/25] recalculate the links as soon as the portals are loaded --- plugins/max-links.user.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/plugins/max-links.user.js b/plugins/max-links.user.js index ca45d735..f2af8e20 100644 --- a/plugins/max-links.user.js +++ b/plugins/max-links.user.js @@ -99,9 +99,14 @@ window.plugin.maxLinks.setup = function() { window.plugin.maxLinks.layer = L.layerGroup([]); window.addHook('checkRenderLimit', function(e) { - if (window.map.hasLayer(window.plugin.maxLinks.layer) && - window.plugin.maxLinks._renderLimitReached) - e.reached = true; + if (window.map.hasLayer(window.plugin.maxLinks.layer) && + window.plugin.maxLinks._renderLimitReached) + e.reached = true; + }); + + window.addHook('portalDataLoaded', function(e) { + if (window.map.hasLayer(window.plugin.maxLinks.layer)) + window.plugin.maxLinks.updateLayer(); }); window.map.on('layeradd', function(e) {