// ==UserScript== // @id iitc-plugin-cross-links@mcben // @name IITC plugin: cross links // @category Layer // @version 1.0.@@DATETIMEVERSION@@ // @namespace https://github.com/jonatkins/ingress-intel-total-conversion // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ // @description [McBen] requires drawtool! coloring of link collision // @include https://www.ingress.com/intel* // @include http://www.ingress.com/intel* // @match https://www.ingress.com/intel* // @match http://www.ingress.com/intel* // @grant none // ==/UserScript== @@PLUGINSTART@@ // PLUGIN START //////////////////////////////////////////////////////// // use own namespace for plugin window.plugin.crossLinks = function() {}; window.plugin.crossLinks.STYLE_LINECOLLISION = {color: '#f22', weight: 4}; window.plugin.crossLinks.STYLE_INSIDEPOLY = {color: '#ff2', weight: 4}; // Great Circle Arc Intersection // http://geospatialmethods.org/spheres/GCAIntersect.html function intersect(a, b) { var PI = Math.PI, radians = PI / 180, ε = 1e-6; var λ0 = a[0][0], λ1 = a[1][0], λ2 = b[0][0], λ3 = b[1][0], δλ0 = λ1 - λ0, δλ1 = λ3 - λ2, aδλ0 = Math.abs(δλ0), aδλ1 = Math.abs(δλ1), sλ0 = aδλ0 > 180, sλ1 = aδλ1 > 180, φ0 = a[0][1] * radians, φ1 = a[1][1] * radians, φ2 = b[0][1] * radians, φ3 = b[1][1] * radians, t; // Ensure λ0 ≤ λ1 and λ2 ≤ λ3. if (δλ0 < 0) t = λ0, λ0 = λ1, λ1 = t, t = φ0, φ0 = φ1, φ1 = t; if (δλ1 < 0) t = λ2, λ2 = λ3, λ3 = t, t = φ2, φ2 = φ3, φ3 = t; // Check if longitude ranges overlap. // TODO handle antimeridian crossings. if (!sλ0 && !sλ1 && (λ0 > λ3 || λ2 > λ1)) return; // Check for polar endpoints. if (Math.abs(Math.abs(φ0) - PI / 2) < ε) λ0 = λ1, aδλ0 = δλ0 = 0, sλ0 = false; if (Math.abs(Math.abs(φ1) - PI / 2) < ε) λ1 = λ0, aδλ0 = δλ0 = 0, sλ0 = false; if (Math.abs(Math.abs(φ2) - PI / 2) < ε) λ2 = λ3, aδλ1 = δλ1 = 0, sλ1 = false; if (Math.abs(Math.abs(φ3) - PI / 2) < ε) λ3 = λ2, aδλ1 = δλ1 = 0, sλ1 = false; // Check for arcs along meridians. var m0 = aδλ0 < ε || Math.abs(aδλ0 - 180) < ε, m1 = aδλ1 < ε || Math.abs(aδλ1 - 180) < ε; λ0 *= radians, λ1 *= radians, λ2 *= radians, λ3 *= radians; // Intersect two great circles and check the two intersection points against // the longitude ranges. The intersection points are simply the cross // product of the great-circle normals ±n1⨯n2. // First plane. var cosφ, x0 = (cosφ = Math.cos(φ0)) * Math.cos(λ0), y0 = cosφ * Math.sin(λ0), z0 = Math.sin(φ0), x1 = (cosφ = Math.cos(φ1)) * Math.cos(λ1), y1 = cosφ * Math.sin(λ1), z1 = Math.sin(φ1), n0x = y0 * z1 - z0 * y1, n0y = z0 * x1 - x0 * z1, n0z = x0 * y1 - y0 * x1, m = length(n0x, n0y, n0z); n0x /= m, n0y /= m, n0z /= m; // Second plane. var x2 = (cosφ = Math.cos(φ2)) * Math.cos(λ2), y2 = cosφ * Math.sin(λ2), z2 = Math.sin(φ2), x3 = (cosφ = Math.cos(φ3)) * Math.cos(λ3), y3 = cosφ * Math.sin(λ3), z3 = Math.sin(φ3), n1x = y2 * z3 - z2 * y3, n1y = z2 * x3 - x2 * z3, n1z = x2 * y3 - y2 * x3, m = length(n1x, n1y, n1z); n1x /= m, n1y /= m, n1z /= m; var Nx = n0y * n1z - n0z * n1y, Ny = n0z * n1x - n0x * n1z, Nz = n0x * n1y - n0y * n1x; if (length(Nx, Ny, Nz) < ε) return; var λ = Math.atan2(Ny, Nx); if ((sλ0 ^ (λ0 <= λ && λ <= λ1) || m0 && Math.abs(λ - λ0) < ε) && (sλ1 ^ (λ2 <= λ && λ <= λ3) || m1 && Math.abs(λ - λ2) < ε) || (Nz = -Nz, (sλ0 ^ (λ0 <= (λ = (λ + 2 * PI) % (2 * PI) - PI) && λ <= λ1) || m0 && Math.abs(λ - λ0) < ε) && (sλ1 ^ (λ2 <= λ && λ <= λ3) || m1 && Math.abs(λ - λ2) < ε))) { var φ = Math.asin(Nz / length(Nx, Ny, Nz)); if (m0 || m1) { if (m1) φ0 = φ2, φ1 = φ3, λ0 = λ2, λ1 = λ3, aδλ0 = aδλ1; if (aδλ0 > ε) return φ0 + φ1 > 0 ^ φ < (Math.abs(λ - λ0) < ε ? φ0 : φ1) ? [λ / radians, φ / radians] : null; // Ensure φ0 ≤ φ1. if (φ1 < φ0) t = φ0, φ0 = φ1, φ1 = t; return Math.abs(λ - (m0 ? λ0 : λ2)) < ε && φ0 <= φ && φ <= φ1 ? [λ / radians, φ / radians] : null; } return [λ / radians, φ / radians]; } } function length(x, y, z) { return Math.sqrt(x * x + y * y + z * z); } window.plugin.crossLinks.testPolyLine = function (polyline, link) { var a= [[link[0].lat,link[0].lng],[link[1].lat,link[1].lng]]; for (var i=0;i point.lng) != (p2.lng>point.lng)) && (point.lat < (p2.lat - p1.lat)*(point.lng-p1.lng) / (p2.lng-p1.lng) + p1.lat)) c = !c; p2 = p1; } return c; } window.plugin.crossLinks.testPolygons = function (polygons, link) { var linkline= L.geodesicConvertLines(link._latlngs,0); for (var pidx=0;pidx