forked from iitc-project/ingress-intel-total-conversion
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathportal-names.user.js
191 lines (156 loc) · 6.67 KB
/
portal-names.user.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
// ==UserScript==
// @id iitc-plugin-portal-names@zaso
// @name IITC plugin: Portal Names
// @category Layer
// @version 0.1.6.@@DATETIMEVERSION@@
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
// @updateURL @@UPDATEURL@@
// @downloadURL @@DOWNLOADURL@@
// @description [@@BUILDNAME@@-@@BUILDDATE@@] Show portal names on the map.
// @include https://*.ingress.com/intel*
// @include http://*.ingress.com/intel*
// @match https://*.ingress.com/intel*
// @match http://*.ingress.com/intel*
// @include https://*.ingress.com/mission/*
// @include http://*.ingress.com/mission/*
// @match https://*.ingress.com/mission/*
// @match http://*.ingress.com/mission/*
// @grant none
// ==/UserScript==
@@PLUGINSTART@@
// PLUGIN START ////////////////////////////////////////////////////////
// use own namespace for plugin
window.plugin.portalNames = function() {};
window.plugin.portalNames.NAME_WIDTH = 80;
window.plugin.portalNames.NAME_HEIGHT = 23;
window.plugin.portalNames.labelLayers = {};
window.plugin.portalNames.labelLayerGroup = null;
window.plugin.portalNames.setupCSS = function() {
$("<style>").prop("type", "text/css").html(''
+'.plugin-portal-names{'
+'color:#FFFFBB;'
+'font-size:11px;line-height:12px;'
+'text-align:center;padding: 2px;' // padding needed so shadow doesn't clip
+'overflow:hidden;'
// could try this if one-line names are used
// +'white-space: nowrap;text-overflow:ellipsis;'
+'text-shadow:1px 1px #000,1px -1px #000,-1px 1px #000,-1px -1px #000, 0 0 5px #000;'
+'pointer-events:none;'
+'}'
).appendTo("head");
}
window.plugin.portalNames.removeLabel = function(guid) {
var previousLayer = window.plugin.portalNames.labelLayers[guid];
if(previousLayer) {
window.plugin.portalNames.labelLayerGroup.removeLayer(previousLayer);
delete plugin.portalNames.labelLayers[guid];
}
}
window.plugin.portalNames.addLabel = function(guid, latLng) {
var previousLayer = window.plugin.portalNames.labelLayers[guid];
if (!previousLayer) {
var d = window.portals[guid].options.data;
var portalName = d.title;
var label = L.marker(latLng, {
icon: L.divIcon({
className: 'plugin-portal-names',
iconAnchor: [window.plugin.portalNames.NAME_WIDTH/2,0],
iconSize: [window.plugin.portalNames.NAME_WIDTH,window.plugin.portalNames.NAME_HEIGHT],
html: portalName
}),
guid: guid,
});
window.plugin.portalNames.labelLayers[guid] = label;
label.addTo(window.plugin.portalNames.labelLayerGroup);
}
}
window.plugin.portalNames.clearAllPortalLabels = function() {
for (var guid in window.plugin.portalNames.labelLayers) {
window.plugin.portalNames.removeLabel(guid);
}
}
window.plugin.portalNames.updatePortalLabels = function() {
// as this is called every time layers are toggled, there's no point in doing it when the leyer is off
if (!map.hasLayer(window.plugin.portalNames.labelLayerGroup)) {
return;
}
var portalPoints = {};
for (var guid in window.portals) {
var p = window.portals[guid];
if (p._map && p.options.data.title) { // only consider portals added to the map and with a title
var point = map.project(p.getLatLng());
portalPoints[guid] = point;
}
}
// for efficient testing of intersection, group portals into buckets based on the label size
var buckets = {};
for (var guid in portalPoints) {
var point = portalPoints[guid];
var bucketId = L.point([Math.floor(point.x/(window.plugin.portalNames.NAME_WIDTH*2)),Math.floor(point.y/window.plugin.portalNames.NAME_HEIGHT)]);
// 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 portal name marker. this is so that there's no left/right
// overlap between two different portals text
var largeBounds = L.bounds (
point.subtract([window.plugin.portalNames.NAME_WIDTH,0]),
point.add([window.plugin.portalNames.NAME_WIDTH,window.plugin.portalNames.NAME_HEIGHT])
);
for (var otherGuid in bucketGuids) {
if (guid != otherGuid) {
var otherPoint = portalPoints[otherGuid];
if (largeBounds.contains(otherPoint)) {
// another portal is within the rectangle for this one's name - so no name for this one
coveredPortals[guid] = true;
break;
}
}
}
}
}
for (var guid in coveredPortals) {
delete portalPoints[guid];
}
// remove any not wanted
for (var guid in window.plugin.portalNames.labelLayers) {
if (!(guid in portalPoints)) {
window.plugin.portalNames.removeLabel(guid);
}
}
// and add those we do
for (var guid in portalPoints) {
window.plugin.portalNames.addLabel(guid, portals[guid].getLatLng());
}
}
// ass 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.portalNames.delayedUpdatePortalLabels = function(wait) {
if (window.plugin.portalNames.timer === undefined) {
window.plugin.portalNames.timer = setTimeout ( function() {
window.plugin.portalNames.timer = undefined;
window.plugin.portalNames.updatePortalLabels();
}, wait*1000);
}
}
var setup = function() {
window.plugin.portalNames.setupCSS();
window.plugin.portalNames.labelLayerGroup = new L.LayerGroup();
window.addLayerGroup('Portal Names', window.plugin.portalNames.labelLayerGroup, true);
window.addHook('requestFinished', function() { setTimeout(function(){window.plugin.portalNames.delayedUpdatePortalLabels(3.0);},1); });
window.addHook('mapDataRefreshEnd', function() { window.plugin.portalNames.delayedUpdatePortalLabels(0.5); });
window.map.on('overlayadd overlayremove', function() { setTimeout(function(){window.plugin.portalNames.delayedUpdatePortalLabels(1.0);},1); });
window.map.on('zoomend', window.plugin.portalNames.clearAllPortalLabels );
}
// PLUGIN END //////////////////////////////////////////////////////////
@@PLUGINEND@@