Well-placed labels can be the difference between a sloppy map and a beautiful one. Labels need to clearly identify features without obscuring the map.




The normal requirements for map labelling are to place labels as clearly as possible without any overlap. Regular maps just need to avoid label overlap for a single, fixed zoom level and rotation.




Good label placement is a hard problem that we solve for Mapbox GL. We need our label placements to work at any zoom and any rotation. We need labels placements to be continuous, so that labels don’t jump around when zooming or rotating. We need labels to be seamless across tiles. We need to support changing font sizes as you zoom. And it all needs to be fast.




Placement needs to support both horizontal labels, as well as curved labels which follow a line. Both types of labels need to behave smoothly when zooming and rotating. Labels can never overlap, even when rotating. Horizontal labels stay horizontal and curved labels rotate with the map. Labels are flipped to avoid being drawn upside down and curved labels smoothly slide along roads.




There is plenty of academic research on label placement, but most of this applies to maps with fixed rotation and with separate zoom levels. Dynamic maps with continuous zooming, panning, and rotation need a completely different approach. Our implementation expands on a paper by Been and Yap that establishes four ideal requirements for continuous and interactive labelling:


标签安置方面的学术研究很多,但大部分都适用于固定旋转和分立的缩放级别的地图。具有连续缩放、平移和旋转的动态地图需要完全不同的安置方法。我们的实现扩展了由Been Yap编写的论文,该论文为连续和交互式标签确立了四个理想要求:


  1. Labels should not disappear when zooming in or appear when zooming out.
  2. Labels should not disappear or appear when panning except when sliding out of view.
  3. Labels should not jump around, but instead should be anchored.
  4. Label placement should be deterministic, no matter how you got to the current view.
  1. 标签不应该在放大时消失,在缩小时出现。
  2. 标签不应该在平移时消失或出现,除非滑出视图。
  3. 标签不应该跳来跳去,而是应该被锚定。
  4. 标签的位置应该是确定的,无论你怎么到当前视图。

The paper provides guidance on implementing this for horizontal labels, but we go further by supporting rotation and curved labels.



  1. Our implementation has two steps:
  2.  Preprocessing
  3.  Rendering
  1. 我们的实现有两个步骤:
  2.  预处理
  3.  渲染

The rendering step needs to be fast so that Mapbox GL can rerender the entire map every frame for smooth interaction. Most of the placement
work happens in the preprocessing step:

  1.  Generate anchor points for each label.
  2.  Calculate the positions of individual glyphs relative to the anchors.
  3.  Calculate the zoom levels at which the labels and glyphs can be shown without overlap.
  4.  Calculate the rotation range in which the label can be shown.

渲染步骤需要足够快以便为了mapbox gl 能够在每一帧中都能重新渲染整个地图以达到顺滑的交互效果。大多数的安置个工作发生在预处理的步骤中:

  1.  为每个标签生成锚点。
  2.  计算各个字形相对于锚点的位置。
  3.  计算该标签和符号可以没有重叠显示的缩放级别。
  4.  计算可以显示标签的旋转范围。


Generating anchor points


Each label has an anchor. An anchor is the point at which a label is positioned when zooming or rotating.




Labels for point features have a single anchor, the point.




For lines, we want to show multiple labels so we interpolate along the line adding an anchor every x pixels. Distance between labels changes when zooming, so we add a minimum zoom level for each anchor to maintain appropriate spacing. Fewer labels are shown at lower zoom levels and more appear as you zoom in.




Generating positioned glyphs for each anchor

For each piece of text we already have a list of glyphs and their positions, but these positions need to be adjusted for curved labels.


During the render step we can only shift glyphs along a straight line. To draw curved text we need to add multiple copies of glyphs — one for each line segment a glyph appears on. Each of these glyphs have minimum and maximum zoom levels that hide the glyph when it slides off the end of a segment so that only one instance of each original glyph is shown at the same time.


Usually these glyphs are completely hidden when out of range, but here they are shown with a reduced opacity:



Restricting the zoom range

To avoid label collisions, we need to restrict the zoom level at which a label is first shown. As you zoom in, labels get spaced further apart, opening room for new labels. Once a label is shown, it will not be hidden as you zoom in.


We use an R-tree that contains already-placed labels to narrow down which labels might collide. We then calculate the
zoom level at which the two labels will fit side-by-side. It is safe to show the label for any zoom level higher than this one.


Horizontal-horizontal collision

There are eight possible angles at which a pair of horizontal labels could collide. Each of these possible collisions is checked with some trigonometry.





A curved-horizontal collision occurs when a corner of one label’s bounding box intersects an edge of the other label’s bounding box. For each of the eight bounding box corners, we calculate the angles at which a circle (formed by that point being rotated around the label’s anchor) intersects the edges of the other box. These are the angles at which a collision would begin and end.




Mapbox GL downloads vector tiles with data for the area and zoom level it is currently displaying. When new tiles are downloaded and their labels have been placed, an old tile’s label may need to be hidden to make way for a more important label. This will be handled in a resolution step that has not yet been implemented.

Mapbox GL下载当前显示范围和缩放级别的矢量瓦片。当新的瓦片下载完成,且它们的标签位置已经计算完成,一个旧的瓦片的标注可能需要隐藏让位给一个更重要的标签。这将在尚未实现的步骤由解析处理。

WEBGL学习网(WebGLStudy.COM)专注提供WebGL 、ThreeJS、BabylonJS等WEB3D开发案例源码下载。
1. 本站部分资源来源于用户上传和网络,如有侵权请邮件联系站长!我们将尽快处理。
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源打赏售价用于赞助本站提供的服务支出(包括不限服务器、网络带宽等费用支出)!
7.欢迎加QQ群学习交流:549297468 ,或者搜索微信公众号:WebGL学习网
WEBGL学习网 » mapbox.gl文字标注算法基本介绍[精华文章]



立即查看 了解详情