1 #pragma once
2 
3 #include <mbgl/geometry/anchor.hpp>
4 #include <mbgl/text/shaping.hpp>
5 #include <mbgl/tile/geometry_tile_data.hpp>
6 #include <mbgl/geometry/feature_index.hpp>
7 
8 #include <vector>
9 
10 namespace mbgl {
11 
12 class CollisionBox {
13 public:
CollisionBox(Point<float> _anchor,Point<float> _offset,float _x1,float _y1,float _x2,float _y2,float _signedDistanceFromAnchor=0,float _radius=0)14     CollisionBox(Point<float> _anchor, Point<float> _offset, float _x1, float _y1, float _x2, float _y2, float _signedDistanceFromAnchor = 0, float _radius = 0) :
15         anchor(std::move(_anchor)), offset(_offset), x1(_x1), y1(_y1), x2(_x2), y2(_y2), used(true), signedDistanceFromAnchor(_signedDistanceFromAnchor), radius(_radius) {}
16 
17     // the box is centered around the anchor point
18     Point<float> anchor;
19 
20     // the offset of the box from the label's anchor point
21     Point<float> offset;
22 
23     // distances to the edges from the anchor
24     float x1;
25     float y1;
26     float x2;
27     float y2;
28 
29     // Projected box geometry: generated/updated at placement time
30     float px1;
31     float py1;
32     float px2;
33     float py2;
34 
35     // Projected circle geometry: generated/updated at placement time
36     float px;
37     float py;
38     bool used;
39 
40     float signedDistanceFromAnchor;
41     float radius;
42 };
43 
44 class CollisionFeature {
45 public:
46 
47     // for text
CollisionFeature(const GeometryCoordinates & line,const Anchor & anchor,const Shaping & shapedText,const float boxScale,const float padding,const style::SymbolPlacementType placement,const IndexedSubfeature & indexedFeature_,const float overscaling)48     CollisionFeature(const GeometryCoordinates& line,
49                      const Anchor& anchor,
50                      const Shaping& shapedText,
51                      const float boxScale,
52                      const float padding,
53                      const style::SymbolPlacementType placement,
54                      const IndexedSubfeature& indexedFeature_,
55                      const float overscaling)
56         : CollisionFeature(line, anchor, shapedText.top, shapedText.bottom, shapedText.left, shapedText.right, boxScale, padding, placement, indexedFeature_, overscaling) {}
57 
58     // for icons
59     // Icons collision features are always SymbolPlacementType::Point, which means the collision feature
60     // will be viewport-rotation-aligned even if the icon is map-rotation-aligned (e.g. `icon-rotation-alignment: map`
61     // _or_ `symbol-placement: line`). We're relying on most icons being "close enough" to square that having
62     // incorrect rotation alignment doesn't throw off collision detection too much.
63     // See: https://github.com/mapbox/mapbox-gl-js/issues/4861
CollisionFeature(const GeometryCoordinates & line,const Anchor & anchor,optional<PositionedIcon> shapedIcon,const float boxScale,const float padding,const IndexedSubfeature & indexedFeature_)64     CollisionFeature(const GeometryCoordinates& line,
65                      const Anchor& anchor,
66                      optional<PositionedIcon> shapedIcon,
67                      const float boxScale,
68                      const float padding,
69                      const IndexedSubfeature& indexedFeature_)
70         : CollisionFeature(line, anchor,
71                            (shapedIcon ? shapedIcon->top() : 0),
72                            (shapedIcon ? shapedIcon->bottom() : 0),
73                            (shapedIcon ? shapedIcon->left() : 0),
74                            (shapedIcon ? shapedIcon->right() : 0),
75                            boxScale,
76                            padding,
77                            style::SymbolPlacementType::Point,
78                            indexedFeature_, 1) {}
79 
80     CollisionFeature(const GeometryCoordinates& line,
81                      const Anchor&,
82                      const float top,
83                      const float bottom,
84                      const float left,
85                      const float right,
86                      const float boxScale,
87                      const float padding,
88                      const style::SymbolPlacementType,
89                      IndexedSubfeature,
90                      const float overscaling);
91 
92     std::vector<CollisionBox> boxes;
93     IndexedSubfeature indexedFeature;
94     bool alongLine;
95 
96 private:
97     void bboxifyLabel(const GeometryCoordinates& line, GeometryCoordinate& anchorPoint,
98                       const int segment, const float length, const float height, const float overscaling);
99 };
100 
101 } // namespace mbgl
102