This commit is contained in:
Jon Atkins 2014-03-21 16:26:19 +00:00
commit 01990b8e73

View File

@ -2,7 +2,7 @@
// @id iitc-plugin-portal-level-numbers@rongou // @id iitc-plugin-portal-level-numbers@rongou
// @name IITC plugin: Portal Level Numbers // @name IITC plugin: Portal Level Numbers
// @category Layer // @category Layer
// @version 0.1.2.@@DATETIMEVERSION@@ // @version 0.1.3.@@DATETIMEVERSION@@
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion // @namespace https://github.com/jonatkins/ingress-intel-total-conversion
// @updateURL @@UPDATEURL@@ // @updateURL @@UPDATEURL@@
// @downloadURL @@DOWNLOADURL@@ // @downloadURL @@DOWNLOADURL@@
@ -19,50 +19,16 @@
// PLUGIN START //////////////////////////////////////////////////////// // PLUGIN START ////////////////////////////////////////////////////////
// use own namespace for plugin // use own namespace for plugin
window.plugin.portalLevelNumbers = function() {}; window.plugin.portalLevelNumbers = function() {
};
window.plugin.portalLevelNumbers.ICON_SIZE = 12;
window.plugin.portalLevelNumbers.MOBILE_SCALE = 1.5;
window.plugin.portalLevelNumbers.levelLayers = {}; window.plugin.portalLevelNumbers.levelLayers = {};
window.plugin.portalLevelNumbers.levelLayerGroup = null; window.plugin.portalLevelNumbers.levelLayerGroup = null;
// Use portal add and remove event to control render of portal level numbers window.plugin.portalLevelNumbers.setupCSS = function() {
window.plugin.portalLevelNumbers.portalAdded = function(data) {
data.portal.on('add', function() {
plugin.portalLevelNumbers.renderLevel(this.options.guid, this.getLatLng());
});
data.portal.on('remove', function() {
plugin.portalLevelNumbers.removeLevel(this.options.guid);
});
}
window.plugin.portalLevelNumbers.renderLevel = function(guid,latLng) {
plugin.portalLevelNumbers.removeLevel(guid);
var p = window.portals[guid];
var levelNumber = p.options.level;
var level = L.marker(latLng, {
icon: L.divIcon({
className: 'plugin-portal-level-numbers',
iconAnchor: [6,7],
iconSize: [12,10],
html: levelNumber
}),
guid: guid
});
plugin.portalLevelNumbers.levelLayers[guid] = level;
level.addTo(plugin.portalLevelNumbers.levelLayerGroup);
}
window.plugin.portalLevelNumbers.removeLevel = function(guid) {
var previousLayer = plugin.portalLevelNumbers.levelLayers[guid];
if(previousLayer) {
plugin.portalLevelNumbers.levelLayerGroup.removeLayer(previousLayer);
delete plugin.portalLevelNumbers.levelLayers[guid];
}
}
var setup = function() {
$("<style>") $("<style>")
.prop("type", "text/css") .prop("type", "text/css")
.html(".plugin-portal-level-numbers {\ .html(".plugin-portal-level-numbers {\
@ -75,12 +41,140 @@ var setup = function() {
-webkit-text-size-adjust:none;\ -webkit-text-size-adjust:none;\
}") }")
.appendTo("head"); .appendTo("head");
}
window.plugin.portalLevelNumbers.removeLabel = function(guid) {
var previousLayer = window.plugin.portalLevelNumbers.levelLayers[guid];
if(previousLayer) {
window.plugin.portalLevelNumbers.levelLayerGroup.removeLayer(previousLayer);
delete plugin.portalLevelNumbers.levelLayers[guid];
}
}
window.plugin.portalLevelNumbers.addLabel = function(guid,latLng) {
var previousLayer = window.plugin.portalLevelNumbers.levelLayers[guid];
if (!previousLayer) {
var p = window.portals[guid];
var levelNumber = p.options.level;
var level = L.marker(latLng, {
icon: L.divIcon({
className: 'plugin-portal-level-numbers',
iconSize: [window.plugin.portalLevelNumbers.ICON_SIZE, window.plugin.portalLevelNumbers.ICON_SIZE],
html: levelNumber
}),
guid: guid
});
plugin.portalLevelNumbers.levelLayers[guid] = level;
level.addTo(plugin.portalLevelNumbers.levelLayerGroup);
}
}
window.plugin.portalLevelNumbers.updatePortalLabels = function() {
var SQUARE_SIZE = L.Browser.mobile ? (window.plugin.portalLevelNumbers.ICON_SIZE + 3) * window.plugin.portalLevelNumbers.MOBILE_SCALE
: (window.plugin.portalLevelNumbers.ICON_SIZE + 3);
// as this is called every time layers are toggled, there's no point in doing it when the layer is off
if (!map.hasLayer(window.plugin.portalLevelNumbers.levelLayerGroup)) {
return;
}
var portalPoints = {};
for (var guid in window.portals) {
var p = window.portals[guid];
if (p._map) { // only consider portals added to the map
var point = map.project(p.getLatLng());
portalPoints[guid] = point;
}
}
// for efficient testing of intersection, group portals into buckets based on the defined rectangle size
var buckets = {};
for (var guid in portalPoints) {
var point = portalPoints[guid];
var bucketId = L.point([Math.floor(point.x/(SQUARE_SIZE*2)),Math.floor(point.y/SQUARE_SIZE*2)]);
// the guid is added to four buckets. this way, when testing for overlap we don't need to test
// all 8 buckets surrounding the one around the particular portal, only the bucket it is in itself
var bucketIds = [bucketId, bucketId.add([1,0]), bucketId.add([0,1]), bucketId.add([1,1])];
for (var i in bucketIds) {
var b = bucketIds[i].toString();
if (!buckets[b]) buckets[b] = {};
buckets[b][guid] = true;
}
}
var coveredPortals = {};
for (var bucket in buckets) {
var bucketGuids = buckets[bucket];
for (var guid in bucketGuids) {
var point = portalPoints[guid];
// the bounds used for testing are twice as wide as the rectangle. this is so that there's no left/right
// overlap between two different portals text
var southWest = point.subtract([SQUARE_SIZE, SQUARE_SIZE]);
var northEast = point.add([SQUARE_SIZE, SQUARE_SIZE]);
var largeBounds = L.bounds(southWest, northEast);
for (var otherGuid in bucketGuids) {
// do not check portals already marked as covered
if (guid != otherGuid && !coveredPortals[otherGuid]) {
var otherPoint = portalPoints[otherGuid];
if (largeBounds.contains(otherPoint)) {
// another portal is within the rectangle - remove if it has not a higher level
if (portals[guid].options.level > portals[otherGuid].options.level) continue;
else coveredPortals[guid] = true;
break;
}
}
}
}
}
for (var guid in coveredPortals) {
delete portalPoints[guid];
}
// remove any not wanted
for (var guid in window.plugin.portalLevelNumbers.levelLayers) {
if (!(guid in portalPoints)) {
window.plugin.portalLevelNumbers.removeLabel(guid);
}
}
// and add those we do
for (var guid in portalPoints) {
window.plugin.portalLevelNumbers.addLabel(guid, portals[guid].getLatLng());
}
}
// as calculating portal marker visibility can take some time when there's lots of portals shown, we'll do it on
// a short timer. this way it doesn't get repeated so much
window.plugin.portalLevelNumbers.delayedUpdatePortalLabels = function(wait) {
if (window.plugin.portalLevelNumbers.timer === undefined) {
window.plugin.portalLevelNumbers.timer = setTimeout ( function() {
window.plugin.portalLevelNumbers.timer = undefined;
window.plugin.portalLevelNumbers.updatePortalLabels();
}, wait*1000);
}
}
var setup = function() {
window.plugin.portalLevelNumbers.setupCSS();
window.plugin.portalLevelNumbers.levelLayerGroup = new L.LayerGroup(); window.plugin.portalLevelNumbers.levelLayerGroup = new L.LayerGroup();
window.addLayerGroup('Portal Levels', window.plugin.portalLevelNumbers.levelLayerGroup, true); window.addLayerGroup('Portal Levels', window.plugin.portalLevelNumbers.levelLayerGroup, true);
window.addHook('portalAdded', window.plugin.portalLevelNumbers.portalAdded); window.addHook('requestFinished', function() { setTimeout(function(){window.plugin.portalLevelNumbers.delayedUpdatePortalLabels(3.0);},1); });
window.addHook('mapDataRefreshEnd', function() { window.plugin.portalLevelNumbers.delayedUpdatePortalLabels(0.5); });
window.map.on('overlayadd overlayremove', function() { setTimeout(function(){window.plugin.portalLevelNumbers.delayedUpdatePortalLabels(1.0);},1); });
} }
// PLUGIN END ////////////////////////////////////////////////////////// // PLUGIN END //////////////////////////////////////////////////////////