-
Notifications
You must be signed in to change notification settings - Fork 2.3k
/
Copy pathcollision_box.js
79 lines (70 loc) · 3.25 KB
/
collision_box.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
'use strict';
var StructArrayType = require('../util/struct_array');
var util = require('../util/util');
var Point = require('point-geometry');
/**
* A collision box represents an area of the map that that is covered by a
* label. CollisionFeature uses one or more of these collision boxes to
* represent all the area covered by a single label. They are used to
* prevent collisions between labels.
*
* A collision box actually represents a 3d volume. The first two dimensions,
* x and y, are specified with `anchor` along with `x1`, `y1`, `x2`, `y2`.
* The third dimension, zoom, is limited by `maxScale` which determines
* how far in the z dimensions the box extends.
*
* As you zoom in on a map, all points on the map get further and further apart
* but labels stay roughly the same size. Labels cover less real world area on
* the map at higher zoom levels than they do at lower zoom levels. This is why
* areas are are represented with an anchor point and offsets from that point
* instead of just using four absolute points.
*
* Line labels are represented by a set of these boxes spaced out along a line.
* When you zoom in, line labels cover less real world distance along the line
* than they used to. Collision boxes near the edges that used to cover label
* no longer do. If a box doesn't cover the label anymore it should be ignored
* when doing collision checks. `maxScale` is how much you can scale the map
* before the label isn't within the box anymore.
* For example
* lower zoom:
* https://cloud.githubusercontent.com/assets/1421652/8060094/4d975f76-0e91-11e5-84b1-4edeb30a5875.png
* slightly higher zoom:
* https://cloud.githubusercontent.com/assets/1421652/8060061/26ae1c38-0e91-11e5-8c5a-9f380bf29f0a.png
* In the zoomed in image the two grey boxes on either side don't cover the
* label anymore. Their maxScale is smaller than the current scale.
*
*
* @class CollisionBoxArray
* @private
*/
var CollisionBoxArray = module.exports = new StructArrayType({
members: [
// the box is centered around the anchor point
{ type: 'Int16', name: 'anchorPointX' },
{ type: 'Int16', name: 'anchorPointY' },
// distances to the edges from the anchor
{ type: 'Int16', name: 'x1' },
{ type: 'Int16', name: 'y1' },
{ type: 'Int16', name: 'x2' },
{ type: 'Int16', name: 'y2' },
// the box is only valid for scales < maxScale.
// The box does not block other boxes at scales >= maxScale;
{ type: 'Float32', name: 'maxScale' },
// the index of the feature in the original vectortile
{ type: 'Uint32', name: 'featureIndex' },
// the source layer the feature appears in
{ type: 'Uint16', name: 'sourceLayerIndex' },
// the bucket the feature appears in
{ type: 'Uint16', name: 'bucketIndex' },
// rotated and scaled bbox used for indexing
{ type: 'Int16', name: 'bbox0' },
{ type: 'Int16', name: 'bbox1' },
{ type: 'Int16', name: 'bbox2' },
{ type: 'Int16', name: 'bbox3' },
{ type: 'Float32', name: 'placementScale' }
]});
util.extendAll(CollisionBoxArray.prototype.StructType.prototype, {
get anchorPoint() {
return new Point(this.anchorPointX, this.anchorPointY);
}
});