mapbox.gl文字標註算法基本介紹

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.安全

 

好的標註位置能夠做爲潦草的地圖和漂亮的地圖之間的區別。標籤須要清晰地識別要素而不模糊地圖。app

 

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.less

 

地圖標註的正常要求是儘量清晰地放置標籤,而不須要重疊。正常地圖只須要對一個單一的固定縮放級別和旋轉來避免標籤重疊。ide

 

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.字體

 

好的標註安置是咱們解決的一個難題。咱們須要咱們的標籤放置在任何縮放和任何旋轉中都能正常展現。咱們須要標註安置是漸進型的,這樣標籤不至於在旋轉、縮放時跳來跳去。咱們須要標註在瓦片上上無縫地鏈接。當你縮放時,咱們須要支持更改字體大小。並且一切都須要快速。ui

 

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.this

 

安置須要同時支持水平文字標註和沿着一條曲線彎曲的標註。兩種類型的標籤都須要在縮放和旋轉時表現得很平滑。標籤永遠不能重疊,即便旋轉時也不能重疊。水平標籤保持水平且曲線標籤隨着地圖旋轉。文本標註會被翻轉以免被渲染成字頭向下(文字倒置)的狀況,彎曲的標籤沿着道路平滑滑動。idea

 

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:spa

 

標籤安置方面的學術研究不少,但大部分都適用於固定旋轉和分立的縮放級別的地圖。具備連續縮放、平移和旋轉的動態地圖須要徹底不一樣的安置方法。咱們的實現擴展了由Been Yap編寫的論文,該論文爲連續和交互式標籤確立了四個理想要求:rest

 

  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.

 

對於線,咱們想顯示多個標籤,因此咱們沿着這條線對個x像素的都插入一個錨點。縮放時標籤之間的距離發生變化,所以咱們爲每一個錨添加最小縮放級別以保持適當的間距。較少的標籤顯示在較低縮放級別,而且隨着您縮放的時候出現更多。

 

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.

咱們使用一個r樹,它包含已經放置的標籤來減小可能會碰撞的標籤。而後計算兩個標籤將並排安裝的縮放級別。對於任何縮放級別高於此的級別下顯示這個標籤是安全的。

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.

當一個標籤的邊框的角與另外一個標籤的邊框的邊緣相交時,出現了彎曲水平碰撞。對於八個包圍盒角的每一個角落,咱們計算了一個圓(由該點旋轉圍繞標籤的錨)相交於另外一個盒子的邊緣的一些角度。這些就是碰撞開始和結束的角度。

 

Seamlessness

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下載當前顯示範圍和縮放級別的矢量瓦片。當新的瓦片下載完成,且它們的標籤位置已經計算完成,一箇舊的瓦片的標註可能須要隱藏讓位給一個更重要的標籤。這將在還沒有實現的步驟由解析處理。

相關文章
相關標籤/搜索