update portal-names plugin to avoid drawing labels that overlap

might tweak a bit more...
This commit is contained in:
Jon Atkins
2013-09-26 22:51:06 +01:00
parent ab1edace7b
commit 92d04bdff6

View File

@ -20,13 +20,22 @@
// use own namespace for plugin // use own namespace for plugin
window.plugin.portalNames = function() {}; window.plugin.portalNames = function() {};
window.plugin.portalNames.NAME_WIDTH = 80;
window.plugin.portalNames.NAME_HEIGHT = 23;
window.plugin.portalNames.labelLayers = {}; window.plugin.portalNames.labelLayers = {};
window.plugin.portalNames.labelLayerGroup = null; window.plugin.portalNames.labelLayerGroup = null;
window.plugin.portalNames.setupCSS = function() { window.plugin.portalNames.setupCSS = function() {
$("<style>").prop("type", "text/css").html('' $("<style>").prop("type", "text/css").html(''
+'.plugin-portal-names{' +'.plugin-portal-names{'
+'font-size:11px;color:#FFFFBB;text-align:center;line-height:12px;' +'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;' +'text-shadow:1px 1px #000,1px -1px #000,-1px 1px #000,-1px -1px #000, 0 0 5px #000;'
+'pointer-events:none;' +'pointer-events:none;'
+'}' +'}'
@ -51,31 +60,96 @@ window.plugin.portalNames.removeLabel = function(guid) {
} }
window.plugin.portalNames.addLabel = function(guid, latLng) { window.plugin.portalNames.addLabel = function(guid, latLng) {
window.plugin.portalNames.removeLabel(guid); var previousLayer = window.plugin.portalNames.labelLayers[guid];
if (!previousLayer) {
var d = window.portals[guid].options.details; var d = window.portals[guid].options.details;
var portalName = d.portalV2.descriptiveText.TITLE; var portalName = d.portalV2.descriptiveText.TITLE;
var label = L.marker(latLng, { var label = L.marker(latLng, {
icon: L.divIcon({ icon: L.divIcon({
className: 'plugin-portal-names', className: 'plugin-portal-names',
iconAnchor: [50,0], iconAnchor: [window.plugin.portalNames.NAME_WIDTH/2,0],
iconSize: [100,24], iconSize: [window.plugin.portalNames.NAME_WIDTH,window.plugin.portalNames.NAME_HEIGHT],
html: portalName html: portalName
}), }),
guid: guid, guid: guid,
}); });
window.plugin.portalNames.labelLayers[guid] = label; window.plugin.portalNames.labelLayers[guid] = label;
label.addTo(window.plugin.portalNames.labelLayerGroup); label.addTo(window.plugin.portalNames.labelLayerGroup);
}
} }
window.plugin.portalNames.updatePortalLabels = function() {
if (Object.keys(window.portals).length > 1000) {
// too manuy portals to handle quickly - clear all
window.plugin.portalNames.labelLayerGroup.clear();
window.plugin.portalNames.labelLayers = {};
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.latLngToLayerPoint(p.getLatLng());
portalPoints[guid] = point;
}
}
var coveredPortals = {};
for (var guid in portalPoints) {
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 portalPoints) {
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());
}
}
var setup = function() { var setup = function() {
window.plugin.portalNames.setupCSS(); window.plugin.portalNames.setupCSS();
window.plugin.portalNames.labelLayerGroup = new L.LayerGroup(); window.plugin.portalNames.labelLayerGroup = new L.LayerGroup();
window.addLayerGroup('Portal Names', window.plugin.portalNames.labelLayerGroup, true); window.addLayerGroup('Portal Names', window.plugin.portalNames.labelLayerGroup, true);
window.addHook('portalAdded', window.plugin.portalNames.portalAdded); window.addHook('mapDataRefreshEnd', window.plugin.portalNames.updatePortalLabels);
window.map.on('overlayadd overlayremove', window.plugin.portalNames.updatePortalLabels);
} }
// PLUGIN END ////////////////////////////////////////////////////////// // PLUGIN END //////////////////////////////////////////////////////////