带插值的数据驱动文本大小? [Mapbox-gl-js]

Data-driven text-size with Interpolation? [Mapbox-gl-js]

我正在努力实现更好的文本大小调整,相信通过插值,我也许能够将我当前的文本标签更新为更高效的格式。目前我们正在创建 "static text",本质上我们获得了特定缩放级别的理想文本大小,然后在每个缩放级别使用停止缩放它,如下所示:


'text-size': {
    "stops": [
        [10, 0],
        [11, ((Math.pow(2, 11 - map.getZoom()) * uniqueFonts[i]))],
        [12, ((Math.pow(2, 12 - map.getZoom()) * uniqueFonts[i]))],
        [13, ((Math.pow(2, 13 - map.getZoom()) * uniqueFonts[i]))],
        [14, ((Math.pow(2, 14 - map.getZoom()) * uniqueFonts[i]))],
        [15, ((Math.pow(2, 15 - map.getZoom()) * uniqueFonts[i]))],
        [16, ((Math.pow(2, 16 - map.getZoom()) * uniqueFonts[i]))],
        [17, ((Math.pow(2, 17 - map.getZoom()) * uniqueFonts[i]))],
        [18, ((Math.pow(2, 18 - map.getZoom()) * uniqueFonts[i]))],
        [19, ((Math.pow(2, 19 - map.getZoom()) * uniqueFonts[i]))],
        [20, ((Math.pow(2, 20 - map.getZoom()) * uniqueFonts[i]))],
        [21, ((Math.pow(2, 21 - map.getZoom()) * uniqueFonts[i]))],
        [22, ((Math.pow(2, 22 - map.getZoom()) * uniqueFonts[i]))],
        [23, ((Math.pow(2, 23 - map.getZoom()) * uniqueFonts[i]))],
        [24, ((Math.pow(2, 24 - map.getZoom()) * uniqueFonts[i]))],
        [25, ((Math.pow(2, 25 - map.getZoom()) * uniqueFonts[i]))],
        [26, ((Math.pow(2, 26 - map.getZoom()) * uniqueFonts[i]))],
        [27, ((Math.pow(2, 27 - map.getZoom()) * uniqueFonts[i]))],
        [28, ((Math.pow(2, 28 - map.getZoom()) * uniqueFonts[i]))],
        [29, ((Math.pow(2, 29 - map.getZoom()) * uniqueFonts[i]))],
        [30, ((Math.pow(2, 30 - map.getZoom()) * uniqueFonts[i]))]
    ]
}

现在效果很好,我们得到的文本即使在缩放时也保持相同大小。我们有一些多边形,我们希望将我们的文本限制在其中,这使我们能够根据多边形本身来保持文本的大小。因此用多边形缩放文本。

这种方法的缺点是我们需要为每个独特的字体大小创建一个标签层。由于您无法在一站内使用“{textSize}”或 ["get"、"textsize"] 引用功能特定字体,因此我们不得不进行调整。但是随着我们最初实现标签后添加的插值代码,现在看来这可能是可能的。

在启用插值的情况下执行以下操作在一定程度上有效。但它似乎不适用于所有缩放级别。它似乎在缩放 15+ 时按预期工作,但之前的任何缩放都奇怪。下面是使用插值方法的代码:


'text-size': [
    "interpolate", ["linear"], ["zoom"],
    10, 0,
    11, [ "*", [ "^", [ "-", 11, map.getZoom()], 2], ["get", "textsize"]],
    12, [ "*", [ "^", [ "-", 12, map.getZoom()], 2], ["get", "textsize"]],
    13, [ "*", [ "^", [ "-", 13, map.getZoom()], 2], ["get", "textsize"]],
    14, [ "*", [ "^", [ "-", 14, map.getZoom()], 2], ["get", "textsize"]],
    15, [ "*", [ "^", [ "-", 15, map.getZoom()], 2], ["get", "textsize"]],
    16, [ "*", [ "^", [ "-", 16, map.getZoom()], 2], ["get", "textsize"]],
    17, [ "*", [ "^", [ "-", 17, map.getZoom()], 2], ["get", "textsize"]],
    18, [ "*", [ "^", [ "-", 18, map.getZoom()], 2], ["get", "textsize"]],
    19, [ "*", [ "^", [ "-", 19, map.getZoom()], 2], ["get", "textsize"]],
    20, [ "*", [ "^", [ "-", 20, map.getZoom()], 2], ["get", "textsize"]],
    21, [ "*", [ "^", [ "-", 21, map.getZoom()], 2], ["get", "textsize"]],
    22, [ "*", [ "^", [ "-", 22, map.getZoom()], 2], ["get", "textsize"]],
    23, [ "*", [ "^", [ "-", 23, map.getZoom()], 2], ["get", "textsize"]],
    24, [ "*", [ "^", [ "-", 24, map.getZoom()], 2], ["get", "textsize"]],
    25, [ "*", [ "^", [ "-", 25, map.getZoom()], 2], ["get", "textsize"]],
    26, [ "*", [ "^", [ "-", 26, map.getZoom()], 2], ["get", "textsize"]],
    27, [ "*", [ "^", [ "-", 27, map.getZoom()], 2], ["get", "textsize"]],
    28, [ "*", [ "^", [ "-", 28, map.getZoom()], 2], ["get", "textsize"]],
    29, [ "*", [ "^", [ "-", 29, map.getZoom()], 2], ["get", "textsize"]],
    30, [ "*", [ "^", [ "-", 30, map.getZoom()], 2], ["get", "textsize"]],
]

由于此插值没有按预期工作,我很好奇我是否做错了什么?在文本大小上使用数据驱动样式时,有没有办法模仿上述停止行为?如果可以怎么办?

所以我已经想通了。当我应该使用 ['exponential', 2] 时,我使用了 ['linear']。我还需要从 1,0 开始,下一个值为 Math.ceil(map.getZoom()) + 1。所以对于我的 map.getZoom() 返回为 ~13.5,它看起来像下面这样:

'text-size': [
        "interpolate", ["exponential", 2], ["zoom"],
        1, 0,
        15, [ "*", [ "^", [ "-", 15, map.getZoom()], 2], ["get", "font"]],
        16, [ "*", [ "^", [ "-", 16, map.getZoom()], 2], ["get", "font"]],
        17, [ "*", [ "^", [ "-", 17, map.getZoom()], 2], ["get", "font"]],
        18, [ "*", [ "^", [ "-", 18, map.getZoom()], 2], ["get", "font"]],
        19, [ "*", [ "^", [ "-", 19, map.getZoom()], 2], ["get", "font"]],
        20, [ "*", [ "^", [ "-", 20, map.getZoom()], 2], ["get", "font"]],
        21, [ "*", [ "^", [ "-", 21, map.getZoom()], 2], ["get", "font"]],
        22, [ "*", [ "^", [ "-", 22, map.getZoom()], 2], ["get", "font"]],
        23, [ "*", [ "^", [ "-", 23, map.getZoom()], 2], ["get", "font"]],
        24, [ "*", [ "^", [ "-", 24, map.getZoom()], 2], ["get", "font"]],
        25, [ "*", [ "^", [ "-", 25, map.getZoom()], 2], ["get", "font"]],
        26, [ "*", [ "^", [ "-", 26, map.getZoom()], 2], ["get", "font"]],
        27, [ "*", [ "^", [ "-", 27, map.getZoom()], 2], ["get", "font"]],
        28, [ "*", [ "^", [ "-", 28, map.getZoom()], 2], ["get", "font"]],
        29, [ "*", [ "^", [ "-", 29, map.getZoom()], 2], ["get", "font"]],
        30, [ "*", [ "^", [ "-", 30, map.getZoom()], 2], ["get", "font"]],
]

只是添加到@Stooky 的回答中。这在放大时非常有效。但在缩小时效果不佳。我希望文本与缩放保持相对大小。就像您放大和缩小 AutoCAD 时一样。我必须为该缩放选择最佳缩放级别和字体大小。然后我从那开始上下工作。我对此的最佳缩放级别是 17。我还更改了其他一些东西。

'text-size':[
    'interpolate', ['linear'], ['zoom'],
    14, 1,
    15, 2,
    16, 4,
    16.5, 8,
    17, 14,
    18, 16,
    18.5, [ "*", [ "^", [ "-", 18.5, map.getZoom()], 1.5], 14],
    19, [ "*", [ "^", [ "-", 19, map.getZoom()], 1.5], 14],
    20, [ "*", [ "^", [ "-", 20, map.getZoom()], 1.5], 14],
    21, [ "*", [ "^", [ "-", 21, map.getZoom()], 1.5], 14],
    30,24
]

如果有一种方法可以使用代码生成此列表,但不确定算法是什么,那就太好了。

也许是这样的功能...

'text-size': ZoomBasedTextSizes([optimum-font-size], [optimum-zoom-level]);