Skip to content

Commit

Permalink
hide labels that don't fit on the line
Browse files Browse the repository at this point in the history
  • Loading branch information
ansis committed Jun 9, 2017
1 parent 14cb98e commit 3738aef
Showing 1 changed file with 27 additions and 12 deletions.
39 changes: 27 additions & 12 deletions src/symbol/projection.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ const mat4 = require('@mapbox/gl-matrix').mat4;
const vec4 = require('@mapbox/gl-matrix').vec4;
const symbolSize = require('./symbol_size');

const offscreenPoint = new Point(-Infinity, -Infinity);

module.exports = {
updateLineLabels: updateLineLabels,
getLabelPlaneMatrix: getLabelPlaneMatrix,
Expand Down Expand Up @@ -140,12 +138,8 @@ function updateLineLabels(bucket, posMatrix, painter, isText, labelPlaneMatrix,
vec4.transformMat4(anchorPos, anchorPos, posMatrix);

// Don't bother calculating the correct point for invisible labels.
// Hide them by moving them offscreen. We still need to add them to the buffer
// because the dynamic buffer is paired with a static buffer that doesn't get updated.
if (!isVisible(anchorPos, symbol, clippingBuffer, painter)) {
for (let i = symbol.numGlyphs; i > 0; i--) {
addGlyph(offscreenPoint, 0, dynamicLayoutVertexArray);
}
hideGlyphs(symbol.numGlyphs, dynamicLayoutVertexArray);
continue;
}

Expand Down Expand Up @@ -178,8 +172,18 @@ function updateLineLabels(bucket, posMatrix, painter, isText, labelPlaneMatrix,
glyphsBackward.push(glyph);
}
}
processDirection(glyphsForward, 1, flip, symbol, lineVertexArray, dynamicLayoutVertexArray, labelPlaneMatrix, fontScale);
processDirection(glyphsBackward, -1, flip, symbol, lineVertexArray, dynamicLayoutVertexArray, labelPlaneMatrix, fontScale);

const returnGlyphs = [];
if (
processDirection(returnGlyphs, glyphsForward, 1, flip, symbol, lineVertexArray, labelPlaneMatrix, fontScale) &&
processDirection(returnGlyphs, glyphsBackward, -1, flip, symbol, lineVertexArray, labelPlaneMatrix, fontScale)) {
for (const glyph of returnGlyphs) {
addGlyph(glyph.point, glyph.angle, dynamicLayoutVertexArray);
}
} else {
hideGlyphs(symbol.numGlyphs, dynamicLayoutVertexArray);
continue;
}
}

if (isText) {
Expand All @@ -189,7 +193,7 @@ function updateLineLabels(bucket, posMatrix, painter, isText, labelPlaneMatrix,
}
}

function processDirection(glyphs, dir, flip, symbol, lineVertexArray, dynamicLayoutVertexArray, labelPlaneMatrix, fontScale) {
function processDirection(returnGlyphs, glyphs, dir, flip, symbol, lineVertexArray, labelPlaneMatrix, fontScale) {
assert(symbol.lineLength > 1);

let prev = project(new Point(symbol.anchorX, symbol.anchorY), labelPlaneMatrix);
Expand Down Expand Up @@ -225,7 +229,8 @@ function processDirection(glyphs, dir, flip, symbol, lineVertexArray, dynamicLay
// If the current segment doesn't have enough remaining space, iterate forward along the line.
// Since all the glyphs are sorted by their distance from the anchor you never need to iterate backwards.
// This way line vertices are projected at most once.
while (offsetX >= segmentDistance + previousDistance && Math.abs(vertexIndex) < numVertices) {
while (offsetX >= segmentDistance + previousDistance) {
if (Math.abs(vertexIndex) >= numVertices) return false;
previousDistance += segmentDistance;
prev = next;
next = project(lineVertexArray.get(vertexStartIndex + vertexIndex), labelPlaneMatrix);
Expand All @@ -237,10 +242,20 @@ function processDirection(glyphs, dir, flip, symbol, lineVertexArray, dynamicLay
// The point is on the current segment. Interpolate to find it.
const segmentInterpolationT = (offsetX - previousDistance) / segmentDistance;
const p = next.sub(prev)._mult(segmentInterpolationT)._add(prev);
addGlyph(p, segmentAngle, dynamicLayoutVertexArray);
returnGlyphs.push({ point: p, angle: segmentAngle });
}
return true;
}

const offscreenPoint = new Point(-Infinity, -Infinity);

// Hide them by moving them offscreen. We still need to add them to the buffer
// because the dynamic buffer is paired with a static buffer that doesn't get updated.
function hideGlyphs(num, dynamicLayoutVertexArray) {
for (let i = 0; i < num; i++) {
addGlyph(offscreenPoint, 0, dynamicLayoutVertexArray);
}
}
function addGlyph(p, angle, dynamicLayoutVertexArray) {
dynamicLayoutVertexArray.emplaceBack(p.x, p.y, angle);
dynamicLayoutVertexArray.emplaceBack(p.x, p.y, angle);
Expand Down

0 comments on commit 3738aef

Please sign in to comment.