2017-04-30 12:59:39 +00:00
|
|
|
|
define(['leaflet', 'rbush', 'helper', 'moment'],
|
|
|
|
|
function (L, rbush, helper, moment) {
|
2017-01-29 23:51:08 +00:00
|
|
|
|
'use strict';
|
|
|
|
|
|
2017-04-30 12:59:39 +00:00
|
|
|
|
var groupOnline;
|
|
|
|
|
var groupOffline;
|
|
|
|
|
var groupNew;
|
|
|
|
|
var groupLost;
|
|
|
|
|
var groupLines;
|
|
|
|
|
|
2017-01-29 23:51:08 +00:00
|
|
|
|
var labelLocations = [['left', 'middle', 0 / 8],
|
|
|
|
|
['center', 'top', 6 / 8],
|
|
|
|
|
['right', 'middle', 4 / 8],
|
|
|
|
|
['left', 'top', 7 / 8],
|
|
|
|
|
['left', 'ideographic', 1 / 8],
|
|
|
|
|
['right', 'top', 5 / 8],
|
|
|
|
|
['center', 'ideographic', 2 / 8],
|
|
|
|
|
['right', 'ideographic', 3 / 8]];
|
2016-07-23 12:52:19 +00:00
|
|
|
|
var labelShadow;
|
2017-02-08 22:32:17 +00:00
|
|
|
|
var bodyStyle = { fontFamily: 'sans-serif' };
|
2016-05-22 11:23:43 +00:00
|
|
|
|
var nodeRadius = 4;
|
2015-04-20 00:51:27 +00:00
|
|
|
|
|
2017-01-29 23:51:08 +00:00
|
|
|
|
var cFont = document.createElement('canvas').getContext('2d');
|
2015-04-20 00:51:27 +00:00
|
|
|
|
|
|
|
|
|
function measureText(font, text) {
|
2017-01-29 23:51:08 +00:00
|
|
|
|
cFont.font = font;
|
|
|
|
|
return cFont.measureText(text);
|
2015-04-20 00:51:27 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function mapRTree(d) {
|
2017-02-12 23:31:31 +00:00
|
|
|
|
return { minX: d.position.lat, minY: d.position.lng, maxX: d.position.lat, maxY: d.position.lng, label: d };
|
2015-04-20 00:51:27 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-02-08 19:51:10 +00:00
|
|
|
|
function prepareLabel(fillStyle, fontSize, offset, stroke) {
|
2015-04-20 00:51:27 +00:00
|
|
|
|
return function (d) {
|
2017-01-29 23:51:08 +00:00
|
|
|
|
var font = fontSize + 'px ' + bodyStyle.fontFamily;
|
2016-05-22 12:51:30 +00:00
|
|
|
|
return {
|
2017-10-29 14:11:24 +00:00
|
|
|
|
position: L.latLng(d.location.latitude, d.location.longitude),
|
|
|
|
|
label: d.hostname,
|
2016-05-22 12:51:30 +00:00
|
|
|
|
offset: offset,
|
|
|
|
|
fillStyle: fillStyle,
|
|
|
|
|
height: fontSize * 1.2,
|
|
|
|
|
font: font,
|
|
|
|
|
stroke: stroke,
|
2017-10-29 14:11:24 +00:00
|
|
|
|
width: measureText(font, d.hostname).width
|
2016-05-22 12:51:30 +00:00
|
|
|
|
};
|
2016-05-22 11:23:43 +00:00
|
|
|
|
};
|
2015-04-20 00:51:27 +00:00
|
|
|
|
}
|
|
|
|
|
|
2015-04-21 14:28:06 +00:00
|
|
|
|
function calcOffset(offset, loc) {
|
2016-05-22 12:51:30 +00:00
|
|
|
|
return [offset * Math.cos(loc[2] * 2 * Math.PI),
|
2017-04-30 12:59:39 +00:00
|
|
|
|
offset * Math.sin(loc[2] * 2 * Math.PI)];
|
2015-04-20 00:51:27 +00:00
|
|
|
|
}
|
|
|
|
|
|
2015-07-11 13:52:33 +00:00
|
|
|
|
function labelRect(p, offset, anchor, label, minZoom, maxZoom, z) {
|
2016-05-22 11:23:43 +00:00
|
|
|
|
var margin = 1 + 1.41 * (1 - (z - minZoom) / (maxZoom - minZoom));
|
2015-07-11 13:52:33 +00:00
|
|
|
|
|
2016-05-22 11:23:43 +00:00
|
|
|
|
var width = label.width * margin;
|
|
|
|
|
var height = label.height * margin;
|
2015-07-11 13:52:33 +00:00
|
|
|
|
|
2016-05-22 12:51:30 +00:00
|
|
|
|
var dx = {
|
|
|
|
|
left: 0,
|
|
|
|
|
right: -width,
|
|
|
|
|
center: -width / 2
|
|
|
|
|
};
|
2015-04-20 00:51:27 +00:00
|
|
|
|
|
2016-05-22 12:51:30 +00:00
|
|
|
|
var dy = {
|
|
|
|
|
top: 0,
|
|
|
|
|
ideographic: -height,
|
|
|
|
|
middle: -height / 2
|
|
|
|
|
};
|
2015-04-20 00:51:27 +00:00
|
|
|
|
|
2016-05-22 11:23:43 +00:00
|
|
|
|
var x = p.x + offset[0] + dx[anchor[0]];
|
|
|
|
|
var y = p.y + offset[1] + dy[anchor[1]];
|
2015-04-20 00:51:27 +00:00
|
|
|
|
|
2017-02-06 00:50:08 +00:00
|
|
|
|
return { minX: x, minY: y, maxX: x + width, maxY: y + height };
|
2015-04-20 00:51:27 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-11-03 21:07:22 +00:00
|
|
|
|
function mkMarker(dict, iconFunc) {
|
2017-04-30 12:59:39 +00:00
|
|
|
|
return function (d) {
|
2017-10-29 14:11:24 +00:00
|
|
|
|
var m = L.circleMarker([d.location.latitude, d.location.longitude], iconFunc(d));
|
2017-04-30 12:59:39 +00:00
|
|
|
|
|
|
|
|
|
m.resetStyle = function resetStyle() {
|
|
|
|
|
m.setStyle(iconFunc(d));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
m.on('click', function () {
|
2017-10-29 14:11:24 +00:00
|
|
|
|
router.fullUrl({ node: d.node_id });
|
2017-04-30 12:59:39 +00:00
|
|
|
|
});
|
2017-10-29 14:11:24 +00:00
|
|
|
|
m.bindTooltip(d.hostname);
|
2017-04-30 12:59:39 +00:00
|
|
|
|
|
2017-10-29 14:11:24 +00:00
|
|
|
|
dict[d.node_id] = m;
|
2017-04-30 12:59:39 +00:00
|
|
|
|
|
|
|
|
|
return m;
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-03 21:07:22 +00:00
|
|
|
|
function addLinksToMap(dict, linkScale, graph) {
|
2017-04-30 12:59:39 +00:00
|
|
|
|
graph = graph.filter(function (d) {
|
2017-10-31 13:22:00 +00:00
|
|
|
|
return 'distance' in d && d.type.indexOf('vpn') !== 0;
|
2017-04-30 12:59:39 +00:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return graph.map(function (d) {
|
|
|
|
|
var opts = {
|
2017-10-29 14:11:24 +00:00
|
|
|
|
color: linkScale((d.source_tq + d.target_tq) / 2),
|
2017-04-30 12:59:39 +00:00
|
|
|
|
weight: 4,
|
|
|
|
|
opacity: 0.5,
|
|
|
|
|
dashArray: 'none'
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var line = L.polyline(d.latlngs, opts);
|
|
|
|
|
|
|
|
|
|
line.resetStyle = function resetStyle() {
|
|
|
|
|
line.setStyle(opts);
|
|
|
|
|
};
|
|
|
|
|
|
2017-10-29 14:11:24 +00:00
|
|
|
|
line.bindTooltip(d.source.hostname + ' – ' + d.target.hostname + '<br><strong>' + helper.showDistance(d) + ' / ' + helper.showTq(d.source_tq) + ' - ' + helper.showTq(d.target_tq) + '</strong>');
|
2017-04-30 12:59:39 +00:00
|
|
|
|
line.on('click', function () {
|
|
|
|
|
router.fullUrl({ link: d.id });
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
dict[d.id] = line;
|
|
|
|
|
|
|
|
|
|
return line;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-03 21:07:22 +00:00
|
|
|
|
function getIcon(color) {
|
2017-04-30 12:59:39 +00:00
|
|
|
|
return Object.assign({}, config.icon.base, config.icon[color]);
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-14 18:25:11 +00:00
|
|
|
|
return L.GridLayer.extend({
|
2015-04-20 00:51:27 +00:00
|
|
|
|
onAdd: function (map) {
|
2017-03-14 18:25:11 +00:00
|
|
|
|
L.GridLayer.prototype.onAdd.call(this, map);
|
2016-05-22 12:51:30 +00:00
|
|
|
|
if (this.data) {
|
2016-05-22 11:23:43 +00:00
|
|
|
|
this.prepareLabels();
|
2016-05-22 12:51:30 +00:00
|
|
|
|
}
|
2015-04-20 00:51:27 +00:00
|
|
|
|
},
|
2017-11-03 21:07:22 +00:00
|
|
|
|
setData: function (data, map, nodeDict, linkDict, linkScale) {
|
|
|
|
|
var iconOnline = getIcon('online');
|
|
|
|
|
var iconOffline = getIcon('offline');
|
|
|
|
|
var iconLost = getIcon('lost');
|
|
|
|
|
var iconAlert = getIcon('alert');
|
|
|
|
|
var iconNew = getIcon('new');
|
2017-04-30 12:59:39 +00:00
|
|
|
|
// Check if init or data is already set
|
|
|
|
|
if (groupLines) {
|
|
|
|
|
groupOffline.clearLayers();
|
|
|
|
|
groupOnline.clearLayers();
|
|
|
|
|
groupNew.clearLayers();
|
|
|
|
|
groupLost.clearLayers();
|
|
|
|
|
groupLines.clearLayers();
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-03 21:07:22 +00:00
|
|
|
|
var lines = addLinksToMap(linkDict, linkScale, data.links);
|
2017-04-30 12:59:39 +00:00
|
|
|
|
groupLines = L.featureGroup(lines).addTo(map);
|
|
|
|
|
|
2017-11-01 18:51:30 +00:00
|
|
|
|
var nodesOnline = helper.subtract(data.nodes.online, data.nodes.new).filter(helper.hasLocation);
|
|
|
|
|
var nodesOffline = helper.subtract(data.nodes.offline, data.nodes.lost).filter(helper.hasLocation);
|
|
|
|
|
var nodesNew = data.nodes.new.filter(helper.hasLocation);
|
|
|
|
|
var nodesLost = data.nodes.lost.filter(helper.hasLocation);
|
|
|
|
|
|
|
|
|
|
var markersOnline = nodesOnline.map(mkMarker(nodeDict, function () {
|
|
|
|
|
return iconOnline;
|
2017-11-03 21:07:22 +00:00
|
|
|
|
}));
|
2017-11-01 18:51:30 +00:00
|
|
|
|
|
|
|
|
|
var markersOffline = nodesOffline.map(mkMarker(nodeDict, function () {
|
|
|
|
|
return iconOffline;
|
2017-11-03 21:07:22 +00:00
|
|
|
|
}));
|
2017-11-01 18:51:30 +00:00
|
|
|
|
|
|
|
|
|
var markersNew = nodesNew.map(mkMarker(nodeDict, function () {
|
|
|
|
|
return iconNew;
|
2017-11-03 21:07:22 +00:00
|
|
|
|
}));
|
2017-11-01 18:51:30 +00:00
|
|
|
|
|
|
|
|
|
var markersLost = nodesLost.map(mkMarker(nodeDict, function (d) {
|
|
|
|
|
var age = moment(data.now).diff(d.lastseen, 'days', true);
|
|
|
|
|
if (age <= config.maxAgeAlert) {
|
|
|
|
|
return iconAlert;
|
|
|
|
|
}
|
|
|
|
|
if (age <= config.maxAge) {
|
|
|
|
|
return iconLost;
|
|
|
|
|
}
|
|
|
|
|
return null;
|
2017-11-03 21:07:22 +00:00
|
|
|
|
}));
|
2017-04-30 12:59:39 +00:00
|
|
|
|
|
|
|
|
|
groupOffline = L.featureGroup(markersOffline).addTo(map);
|
|
|
|
|
groupLost = L.featureGroup(markersLost).addTo(map);
|
|
|
|
|
groupOnline = L.featureGroup(markersOnline).addTo(map);
|
|
|
|
|
groupNew = L.featureGroup(markersNew).addTo(map);
|
|
|
|
|
|
|
|
|
|
this.data = {
|
2017-11-01 18:51:30 +00:00
|
|
|
|
online: nodesOnline,
|
|
|
|
|
offline: nodesOffline,
|
|
|
|
|
new: nodesNew,
|
|
|
|
|
lost: nodesLost
|
2017-04-30 12:59:39 +00:00
|
|
|
|
};
|
2017-01-20 14:06:06 +00:00
|
|
|
|
this.updateLayer();
|
2015-04-20 00:51:27 +00:00
|
|
|
|
},
|
2017-01-20 14:06:06 +00:00
|
|
|
|
updateLayer: function () {
|
|
|
|
|
if (this._map) {
|
2016-07-23 12:52:19 +00:00
|
|
|
|
this.prepareLabels();
|
|
|
|
|
}
|
|
|
|
|
},
|
2015-04-20 00:51:27 +00:00
|
|
|
|
prepareLabels: function () {
|
2016-05-22 11:23:43 +00:00
|
|
|
|
var d = this.data;
|
2015-04-20 00:51:27 +00:00
|
|
|
|
|
|
|
|
|
// label:
|
|
|
|
|
// - position (WGS84 coords)
|
|
|
|
|
// - offset (2D vector in pixels)
|
|
|
|
|
// - anchor (tuple, textAlignment, textBaseline)
|
|
|
|
|
// - minZoom (inclusive)
|
|
|
|
|
// - label (string)
|
|
|
|
|
// - color (string)
|
|
|
|
|
|
2017-02-08 22:32:17 +00:00
|
|
|
|
var labelsOnline = d.online.map(prepareLabel(null, 11, 8, true));
|
2017-11-05 17:23:40 +00:00
|
|
|
|
var labelsOffline = d.offline.map(prepareLabel(config.icon.offline.color, 9, 5, false));
|
|
|
|
|
var labelsNew = d.new.map(prepareLabel(config.map.labelNewColor, 11, 8, true));
|
|
|
|
|
var labelsLost = d.lost.map(prepareLabel(config.icon.lost.color, 11, 8, true));
|
2015-04-20 00:51:27 +00:00
|
|
|
|
|
|
|
|
|
var labels = []
|
2016-05-22 12:51:30 +00:00
|
|
|
|
.concat(labelsNew)
|
|
|
|
|
.concat(labelsLost)
|
|
|
|
|
.concat(labelsOnline)
|
|
|
|
|
.concat(labelsOffline);
|
2015-04-20 00:51:27 +00:00
|
|
|
|
|
2016-05-22 11:23:43 +00:00
|
|
|
|
var minZoom = this.options.minZoom;
|
|
|
|
|
var maxZoom = this.options.maxZoom;
|
2015-04-20 00:51:27 +00:00
|
|
|
|
|
2016-05-22 11:23:43 +00:00
|
|
|
|
var trees = [];
|
2015-04-20 00:51:27 +00:00
|
|
|
|
|
2016-05-22 11:23:43 +00:00
|
|
|
|
var map = this._map;
|
2015-04-20 00:51:27 +00:00
|
|
|
|
|
|
|
|
|
function nodeToRect(z) {
|
2017-01-29 23:51:08 +00:00
|
|
|
|
return function (n) {
|
|
|
|
|
var p = map.project(n.position, z);
|
2017-02-06 00:50:08 +00:00
|
|
|
|
return { minX: p.x - nodeRadius, minY: p.y - nodeRadius, maxX: p.x + nodeRadius, maxY: p.y + nodeRadius };
|
2016-05-22 11:23:43 +00:00
|
|
|
|
};
|
2015-04-20 00:51:27 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (var z = minZoom; z <= maxZoom; z++) {
|
2016-05-22 11:23:43 +00:00
|
|
|
|
trees[z] = rbush(9);
|
|
|
|
|
trees[z].load(labels.map(nodeToRect(z)));
|
2015-04-20 00:51:27 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-01-29 23:51:08 +00:00
|
|
|
|
labels = labels.map(function (n) {
|
2015-04-20 00:51:27 +00:00
|
|
|
|
var best = labelLocations.map(function (loc) {
|
2017-01-29 23:51:08 +00:00
|
|
|
|
var offset = calcOffset(n.offset, loc);
|
|
|
|
|
var i;
|
2015-04-20 00:51:27 +00:00
|
|
|
|
|
2017-02-08 19:51:10 +00:00
|
|
|
|
for (i = maxZoom; i >= minZoom; i--) {
|
2017-01-29 23:51:08 +00:00
|
|
|
|
var p = map.project(n.position, i);
|
|
|
|
|
var rect = labelRect(p, offset, loc, n, minZoom, maxZoom, i);
|
|
|
|
|
var candidates = trees[i].search(rect);
|
2015-04-20 00:51:27 +00:00
|
|
|
|
|
2016-05-22 12:51:30 +00:00
|
|
|
|
if (candidates.length > 0) {
|
2016-05-22 11:23:43 +00:00
|
|
|
|
break;
|
2016-05-22 12:51:30 +00:00
|
|
|
|
}
|
2015-04-20 00:51:27 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-01-29 23:51:08 +00:00
|
|
|
|
return { loc: loc, z: i + 1 };
|
|
|
|
|
}).filter(function (k) {
|
|
|
|
|
return k.z <= maxZoom;
|
2015-04-20 00:51:27 +00:00
|
|
|
|
}).sort(function (a, b) {
|
2016-05-22 11:23:43 +00:00
|
|
|
|
return a.z - b.z;
|
|
|
|
|
})[0];
|
2015-04-20 00:51:27 +00:00
|
|
|
|
|
2015-04-21 14:28:06 +00:00
|
|
|
|
if (best !== undefined) {
|
2017-01-29 23:51:08 +00:00
|
|
|
|
n.offset = calcOffset(n.offset, best.loc);
|
|
|
|
|
n.minZoom = best.z;
|
|
|
|
|
n.anchor = best.loc;
|
|
|
|
|
|
|
|
|
|
for (var i = maxZoom; i >= best.z; i--) {
|
|
|
|
|
var p = map.project(n.position, i);
|
|
|
|
|
var rect = labelRect(p, n.offset, best.loc, n, minZoom, maxZoom, i);
|
|
|
|
|
trees[i].insert(rect);
|
2015-04-21 14:28:06 +00:00
|
|
|
|
}
|
2015-04-20 00:51:27 +00:00
|
|
|
|
|
2017-01-29 23:51:08 +00:00
|
|
|
|
return n;
|
2016-05-22 12:51:30 +00:00
|
|
|
|
}
|
2017-01-29 23:51:08 +00:00
|
|
|
|
return undefined;
|
|
|
|
|
}).filter(function (n) {
|
|
|
|
|
return n !== undefined;
|
2016-05-22 12:51:30 +00:00
|
|
|
|
});
|
2015-04-20 00:51:27 +00:00
|
|
|
|
|
2016-05-22 11:23:43 +00:00
|
|
|
|
this.margin = 16;
|
2015-07-07 19:28:44 +00:00
|
|
|
|
|
2016-05-22 12:51:30 +00:00
|
|
|
|
if (labels.length > 0) {
|
2017-01-29 23:51:08 +00:00
|
|
|
|
this.margin += labels.map(function (n) {
|
|
|
|
|
return n.width;
|
2016-05-22 11:23:43 +00:00
|
|
|
|
}).sort().reverse()[0];
|
2016-05-22 12:51:30 +00:00
|
|
|
|
}
|
2015-04-20 00:51:27 +00:00
|
|
|
|
|
2016-05-22 11:23:43 +00:00
|
|
|
|
this.labels = rbush(9);
|
|
|
|
|
this.labels.load(labels.map(mapRTree));
|
2015-04-20 00:51:27 +00:00
|
|
|
|
|
2016-05-22 11:23:43 +00:00
|
|
|
|
this.redraw();
|
2015-04-17 21:54:19 +00:00
|
|
|
|
},
|
2017-03-14 18:25:11 +00:00
|
|
|
|
createTile: function (tilePoint) {
|
|
|
|
|
var tile = L.DomUtil.create('canvas', 'leaflet-tile');
|
2015-04-17 21:54:19 +00:00
|
|
|
|
|
2016-05-22 11:23:43 +00:00
|
|
|
|
var tileSize = this.options.tileSize;
|
2017-03-14 18:25:11 +00:00
|
|
|
|
tile.width = tileSize;
|
|
|
|
|
tile.height = tileSize;
|
|
|
|
|
|
|
|
|
|
if (!this.labels) {
|
|
|
|
|
return tile;
|
|
|
|
|
}
|
|
|
|
|
|
2016-05-22 11:23:43 +00:00
|
|
|
|
var s = tilePoint.multiplyBy(tileSize);
|
|
|
|
|
var map = this._map;
|
2017-02-08 22:32:17 +00:00
|
|
|
|
bodyStyle = window.getComputedStyle(document.querySelector('body'));
|
|
|
|
|
labelShadow = bodyStyle.backgroundColor.replace(/rgb/i, 'rgba').replace(/\)/i, ',0.7)');
|
2015-04-17 21:54:19 +00:00
|
|
|
|
|
|
|
|
|
function projectNodes(d) {
|
2016-05-22 11:23:43 +00:00
|
|
|
|
var p = map.project(d.label.position);
|
2015-04-17 21:54:19 +00:00
|
|
|
|
|
2016-05-22 11:23:43 +00:00
|
|
|
|
p.x -= s.x;
|
|
|
|
|
p.y -= s.y;
|
2015-04-19 10:22:09 +00:00
|
|
|
|
|
2017-01-29 23:51:08 +00:00
|
|
|
|
return { p: p, label: d.label };
|
2015-04-17 21:54:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-02-05 01:34:09 +00:00
|
|
|
|
var bbox = helper.getTileBBox(s, map, tileSize, this.margin);
|
2016-05-22 11:23:43 +00:00
|
|
|
|
var labels = this.labels.search(bbox).map(projectNodes);
|
2017-03-14 18:25:11 +00:00
|
|
|
|
var ctx = tile.getContext('2d');
|
2015-04-17 21:54:19 +00:00
|
|
|
|
|
2016-05-22 11:23:43 +00:00
|
|
|
|
ctx.lineWidth = 5;
|
2016-07-23 12:52:19 +00:00
|
|
|
|
ctx.strokeStyle = labelShadow;
|
2016-05-22 11:23:43 +00:00
|
|
|
|
ctx.miterLimit = 2;
|
2015-04-17 21:54:19 +00:00
|
|
|
|
|
|
|
|
|
function drawLabel(d) {
|
2016-05-22 11:23:43 +00:00
|
|
|
|
ctx.font = d.label.font;
|
|
|
|
|
ctx.textAlign = d.label.anchor[0];
|
|
|
|
|
ctx.textBaseline = d.label.anchor[1];
|
2017-02-08 22:32:17 +00:00
|
|
|
|
ctx.fillStyle = d.label.fillStyle === null ? bodyStyle.color : d.label.fillStyle;
|
2015-04-21 14:28:06 +00:00
|
|
|
|
|
2016-05-22 12:51:30 +00:00
|
|
|
|
if (d.label.stroke) {
|
2016-05-22 11:23:43 +00:00
|
|
|
|
ctx.strokeText(d.label.label, d.p.x + d.label.offset[0], d.p.y + d.label.offset[1]);
|
2016-05-22 12:51:30 +00:00
|
|
|
|
}
|
2015-04-21 14:28:06 +00:00
|
|
|
|
|
2016-05-22 11:23:43 +00:00
|
|
|
|
ctx.fillText(d.label.label, d.p.x + d.label.offset[0], d.p.y + d.label.offset[1]);
|
2015-04-17 21:54:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
2015-04-20 00:51:27 +00:00
|
|
|
|
labels.filter(function (d) {
|
2017-03-14 18:25:11 +00:00
|
|
|
|
return tilePoint.z >= d.label.minZoom;
|
2016-05-22 11:23:43 +00:00
|
|
|
|
}).forEach(drawLabel);
|
2017-03-14 18:25:11 +00:00
|
|
|
|
|
|
|
|
|
return tile;
|
2015-04-17 21:54:19 +00:00
|
|
|
|
}
|
2016-05-22 11:23:43 +00:00
|
|
|
|
});
|
2016-05-22 12:51:30 +00:00
|
|
|
|
});
|