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