Skip to content

Commit

Permalink
add another hack to make collision boxes work labels in pitched views
Browse files Browse the repository at this point in the history
  • Loading branch information
ansis committed Jun 6, 2017
1 parent 734f195 commit 6a789ec
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 12 deletions.
5 changes: 5 additions & 0 deletions src/symbol/collision_box.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ const CollisionBoxArray = createStructArrayType({
{ type: 'Int16', name: 'anchorPointX' },
{ type: 'Int16', name: 'anchorPointY' },

// the offset of the box from the label's anchor point
{ type: 'Int16', name: 'offsetX' },
{ type: 'Int16', name: 'offsetY' },

// distances to the edges from the anchor
{ type: 'Int16', name: 'x1' },
{ type: 'Int16', name: 'y1' },
Expand All @@ -53,6 +57,7 @@ const CollisionBoxArray = createStructArrayType({

// the box is only valid for scales < maxScale.
// The box does not block other boxes at scales >= maxScale;
{ type: 'Float32', name: 'unadjustedMaxScale' },
{ type: 'Float32', name: 'maxScale' },

// the index of the feature in the original vectortile
Expand Down
16 changes: 12 additions & 4 deletions src/symbol/collision_feature.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class CollisionFeature {
}

} else {
collisionBoxArray.emplaceBack(anchor.x, anchor.y, x1, y1, x2, y2, Infinity, featureIndex, sourceLayerIndex, bucketIndex,
collisionBoxArray.emplaceBack(anchor.x, anchor.y, 0, 0, x1, y1, x2, y2, Infinity, Infinity, featureIndex, sourceLayerIndex, bucketIndex,
0, 0, 0, 0, 0);
}

Expand All @@ -75,7 +75,7 @@ class CollisionFeature {
// We calculate line collision boxes out to 150% of what would normally be our
// max size, to allow collision detection to work on labels that expand as
// they move into the distance
const nPitchPaddingBoxes = Math.floor(nBoxes / 4);
const nPitchPaddingBoxes = Math.floor(nBoxes / 2);

// offset the center of the first box by half a box so that the edge of the
// box is at the edge of the label.
Expand Down Expand Up @@ -111,8 +111,15 @@ class CollisionFeature {
let segmentLength = line[index].dist(line[index + 1]);

for (let i = -nPitchPaddingBoxes; i < nBoxes + nPitchPaddingBoxes; i++) {

// the distance the box will be from the anchor
const boxDistanceToAnchor = labelStartDistance + i * step;
const boxOffset = i * step;
let boxDistanceToAnchor = labelStartDistance + boxOffset;

// make the distance between pitch padding boxes bigger
if (boxOffset < 0) boxDistanceToAnchor += boxOffset;
if (boxOffset > labelLength) boxDistanceToAnchor += boxOffset - labelLength;

if (boxDistanceToAnchor < anchorDistance) {
// The line doesn't extend far enough back for this box, skip it
// (This could allow for line collisions on distant tiles)
Expand Down Expand Up @@ -162,7 +169,8 @@ class CollisionFeature {
}

collisionBoxArray.emplaceBack(boxAnchorPoint.x, boxAnchorPoint.y,
-boxSize / 2, -boxSize / 2, boxSize / 2, boxSize / 2, maxScale,
boxAnchorPoint.x - anchor.x, boxAnchorPoint.y - anchor.y,
-boxSize / 2, -boxSize / 2, boxSize / 2, boxSize / 2, maxScale, maxScale,
featureIndex, sourceLayerIndex, bucketIndex,
0, 0, 0, 0, 0);
}
Expand Down
26 changes: 18 additions & 8 deletions src/symbol/collision_tile.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,20 +66,20 @@ class CollisionTile {

const maxInt16 = 32767;
//left
collisionBoxArray.emplaceBack(0, 0, 0, -maxInt16, 0, maxInt16, maxInt16,
0, 0, 0, 0, 0, 0, 0, 0,
collisionBoxArray.emplaceBack(0, 0, 0, 0, 0, -maxInt16, 0, maxInt16, maxInt16,
0, 0, 0, 0, 0, 0, 0, 0, 0,
0);
// right
collisionBoxArray.emplaceBack(EXTENT, 0, 0, -maxInt16, 0, maxInt16, maxInt16,
0, 0, 0, 0, 0, 0, 0, 0,
collisionBoxArray.emplaceBack(EXTENT, 0, 0, 0, 0, -maxInt16, 0, maxInt16, maxInt16,
0, 0, 0, 0, 0, 0, 0, 0, 0,
0);
// top
collisionBoxArray.emplaceBack(0, 0, -maxInt16, 0, maxInt16, 0, maxInt16,
0, 0, 0, 0, 0, 0, 0, 0,
collisionBoxArray.emplaceBack(0, 0, 0, 0, -maxInt16, 0, maxInt16, 0, maxInt16,
0, 0, 0, 0, 0, 0, 0, 0, 0,
0);
// bottom
collisionBoxArray.emplaceBack(0, EXTENT, -maxInt16, 0, maxInt16, 0, maxInt16,
0, 0, 0, 0, 0, 0, 0, 0,
collisionBoxArray.emplaceBack(0, EXTENT, 0, 0, -maxInt16, 0, maxInt16, 0, maxInt16,
0, 0, 0, 0, 0, 0, 0, 0, 0,
0);
}

Expand Down Expand Up @@ -150,6 +150,16 @@ class CollisionTile {
box.bbox2 = x2;
box.bbox3 = y2;

// When the map is pitched the distance covered by a line changes.
// Adjust the max scale by (approximatePitchedLength / approximateRegularLength)
// to compensate for this.
const yStretch2 = yStretch;
const xSqr = box.offsetX * box.offsetX;
const ySqr = box.offsetY * box.offsetY;
const yStretchSqr = ySqr * yStretch2 * yStretch2;
const adjustmentFactor = Math.sqrt((xSqr + yStretchSqr) / (xSqr + ySqr)) || 1;
box.maxScale = box.unadjustedMaxScale * adjustmentFactor;

if (!allowOverlap) {
const blockingBoxes = this.grid.query(x1, y1, x2, y2);

Expand Down

0 comments on commit 6a789ec

Please sign in to comment.