// ==UserScript== // @author Wintervorst // @id s2celldrawer@wintervorst // @name S2 Cell Drawer // @category Layer // @version 0.0.4.20181209.010307 // @namespace https://github.com/jonatkins/ingress-intel-total-conversion // @updateURL https://raw.githubusercontent.com/IITC-CE/Community-plugins/master/dist/wintervorst/s2celldrawer.meta.js // @downloadURL https://raw.githubusercontent.com/IITC-CE/Community-plugins/master/dist/wintervorst/s2celldrawer.user.js // @description [iitc-20181209.010307] Allows drawing of s2cells and creates a layerselected hook // @include https://*.ingress.com/intel* // @include http://*.ingress.com/intel* // @include https://*.ingress.com/mission/* // @include http://*.ingress.com/mission/* // @match https://*.ingress.com/intel* // @match http://*.ingress.com/intel* // @match https://*.ingress.com/mission/* // @match http://*.ingress.com/mission/* // @grant none // ==/UserScript== var L; // to prevent script errors on load var $; // to prevent script errors on load var map; // to prevent script errors on load function wrapper(plugin_info) { // ensure plugin framework is there, even if iitc is not yet loaded if(typeof window.plugin !== 'function') window.plugin = function() {}; //PLUGIN AUTHORS: writing a plugin outside of the IITC build environment? if so, delete these lines!! //(leaving them in place might break the 'About IITC' page or break update checks) plugin_info.buildName = 'iitc'; plugin_info.dateTimeVersion = '20181209.010307'; plugin_info.pluginId = 'S2 Cell Drawer'; // PLUGIN START /////////////////////////////////////////////////////// // use own namespace for plugin window.plugin.s2celldrawer = function() {}; window.plugin.s2celldrawer.seenCells = {}; window.plugin.s2celldrawer.bounds = null; window.plugin.s2celldrawer.drawCellList = function(layer, cellSize, cellOptions, showCallback, markerCss) { window.plugin.s2celldrawer.bounds = map.getBounds(); window.plugin.s2celldrawer.seenCells = {}; // centre cell var zoom = map.getZoom(); var maxzoom = 15; if (cellSize <= 14) maxzoom = 10; if (cellSize <= 8) maxzoom = 5; if (zoom >= maxzoom) { // 5 // ;;;; // var cellSize = zoom>=7 ? 6 : 4; // ;;;;vib var cell = S2.S2Cell.FromLatLng ( map.getCenter(), cellSize ); window.plugin.s2celldrawer.drawCellAndNeighbors(layer, cell, cellSize, cellOptions, showCallback, markerCss); } } window.plugin.s2celldrawer.drawCellAndNeighbors = function(layer, cell, cellSize, cellOptions, showCallback, markerCss) { var cellStr = cell.toString(); if (!window.plugin.s2celldrawer.seenCells[cellStr]) { // cell not visited - flag it as visited now window.plugin.s2celldrawer.seenCells[cellStr] = true; // is it on the screen? var corners = cell.getCornerLatLngs(); var cellBounds = L.latLngBounds([corners[0],corners[1]]).extend(corners[2]).extend(corners[3]); // Only draw filled cells when they are completely on screen because we must likely calculate something in it if ((cellOptions.fill && window.plugin.s2celldrawer.bounds.contains(cellBounds)) || (!cellOptions.fill && cellBounds.intersects(window.plugin.s2celldrawer.bounds))) { // on screen - draw it window.plugin.s2celldrawer.drawCell(layer, cell, cellSize, cellOptions, showCallback, markerCss); // and recurse to our neighbors var neighbors = cell.getNeighbors(); for (var i=0; i= 9) { var namebounds = map.getBounds().pad(-0.1); // pad 10% inside the screen bounds if (!namebounds.contains(center)) { // name is off-screen. pull it in so it's inside the bounds var newlat = Math.max(Math.min(center.lat, namebounds.getNorth()), namebounds.getSouth()); var newlng = Math.max(Math.min(center.lng, namebounds.getEast()), namebounds.getWest()); var newpos = L.latLng(newlat,newlng); // ensure the new position is still within the same cell var newposcell = S2.S2Cell.FromLatLng ( newpos, 6 ); if ( newposcell.toString() == cell.toString() ) { center=newpos; } // else we leave the name where it was - offscreen } } layer.addLayer(region); if (name != '') { var marker = L.marker(center, { icon: L.divIcon({ className: markerCss, iconAnchor: [100,5], iconSize: [200,10], html: name, }) }); layer.addLayer(marker); } } var setup = function() { // Custom hook for triggering layer updates window.pluginCreateHook('displayedLayerUpdated'); // window.addHook('displayedLayerUpdated', window.plugin.s2celldrawer.layerUpdated); window.updateDisplayedLayerGroup = window.updateDisplayedLayerGroupModified; } // Overload for IITC default in order to catch the manual select/deselect event and handle it properly // Update layerGroups display status to window.overlayStatus and localStorage 'ingress.intelmap.layergroupdisplayed' window.updateDisplayedLayerGroupModified = function(name, display) { overlayStatus[name] = display; localStorage['ingress.intelmap.layergroupdisplayed'] = JSON.stringify(overlayStatus); runHooks('displayedLayerUpdated', {name: name, display: display}); } if (!google.maps.Polygon.prototype.getBounds) { google.maps.Polygon.prototype.getBounds = function(latLng) { var bounds = new google.maps.LatLngBounds(), paths = this.getPaths(), path, p, i; for (p = 0; p < paths.getLength(); p++) { path = paths.getAt(p); for (i = 0; i < path.getLength(); i++) { bounds.extend(path.getAt(i)); } } return bounds; }; } // Polygon containsLatLng - method to determine if a latLng is within a polygon google.maps.Polygon.prototype.containsLatLng = function(latLng) { // Exclude points outside of bounds as there is no way they are in the poly var inPoly = false, bounds, lat, lng, numPaths, p, path, numPoints, i, j, vertex1, vertex2; // Arguments are a pair of lat, lng variables if (arguments.length == 2) { if ( typeof arguments[0] == "number" && typeof arguments[1] == "number" ) { lat = arguments[0]; lng = arguments[1]; } } else if (arguments.length == 1) { bounds = this.getBounds(); if (!bounds && !bounds.contains(latLng)) { return false; } lat = latLng.lat; lng = latLng.lng; } else { console.log("Wrong number of inputs in google.maps.Polygon.prototype.contains.LatLng"); } // Raycast point in polygon method numPaths = this.getPaths().getLength(); for (p = 0; p < numPaths; p++) { path = this.getPaths().getAt(p); numPoints = path.getLength(); j = numPoints - 1; for (i = 0; i < numPoints; i++) { vertex1 = path.getAt(i); vertex2 = path.getAt(j); if ( vertex1.lng() < lng && vertex2.lng() >= lng || vertex2.lng() < lng && vertex1.lng() >= lng ) { if ( vertex1.lat() + (lng - vertex1.lng()) / (vertex2.lng() - vertex1.lng()) * (vertex2.lat() - vertex1.lat()) < lat ) { inPoly = !inPoly; } } j = i; } } return inPoly; }; window.S2 = {}; var LatLngToXYZ = function(latLng) { var d2r = Math.PI/180.0; var phi = latLng.lat*d2r; var theta = latLng.lng*d2r; var cosphi = Math.cos(phi); return [Math.cos(theta)*cosphi, Math.sin(theta)*cosphi, Math.sin(phi)]; }; var XYZToLatLng = function(xyz) { var r2d = 180.0/Math.PI; var lat = Math.atan2(xyz[2], Math.sqrt(xyz[0]*xyz[0]+xyz[1]*xyz[1])); var lng = Math.atan2(xyz[1], xyz[0]); return L.latLng(lat*r2d, lng*r2d); }; var largestAbsComponent = function(xyz) { var temp = [Math.abs(xyz[0]), Math.abs(xyz[1]), Math.abs(xyz[2])]; if (temp[0] > temp[1]) { if (temp[0] > temp[2]) { return 0; } else { return 2; } } else { if (temp[1] > temp[2]) { return 1; } else { return 2; } } }; var faceXYZToUV = function(face,xyz) { var u,v; switch (face) { case 0: u = xyz[1]/xyz[0]; v = xyz[2]/xyz[0]; break; case 1: u = -xyz[0]/xyz[1]; v = xyz[2]/xyz[1]; break; case 2: u = -xyz[0]/xyz[2]; v = -xyz[1]/xyz[2]; break; case 3: u = xyz[2]/xyz[0]; v = xyz[1]/xyz[0]; break; case 4: u = xyz[2]/xyz[1]; v = -xyz[0]/xyz[1]; break; case 5: u = -xyz[1]/xyz[2]; v = -xyz[0]/xyz[2]; break; default: throw {error: 'Invalid face'}; break; } return [u,v]; } var XYZToFaceUV = function(xyz) { var face = largestAbsComponent(xyz); if (xyz[face] < 0) { face += 3; } uv = faceXYZToUV (face,xyz); return [face, uv]; }; var FaceUVToXYZ = function(face,uv) { var u = uv[0]; var v = uv[1]; switch (face) { case 0: return [ 1, u, v]; case 1: return [-u, 1, v]; case 2: return [-u,-v, 1]; case 3: return [-1,-v,-u]; case 4: return [ v,-1,-u]; case 5: return [ v, u,-1]; default: throw {error: 'Invalid face'}; } }; var STToUV = function(st) { var singleSTtoUV = function(st) { if (st >= 0.5) { return (1/3.0) * (4*st*st - 1); } else { return (1/3.0) * (1 - (4*(1-st)*(1-st))); } }; return [singleSTtoUV(st[0]), singleSTtoUV(st[1])]; }; var UVToST = function(uv) { var singleUVtoST = function(uv) { if (uv >= 0) { return 0.5 * Math.sqrt (1 + 3*uv); } else { return 1 - 0.5 * Math.sqrt (1 - 3*uv); } }; return [singleUVtoST(uv[0]), singleUVtoST(uv[1])]; }; var STToIJ = function(st,order) { var maxSize = (1<=0; i--) { var mask = 1<=0 && ij[1]>=0 && ij[0]