我正在将 map 从使用 mapbox.js 转换为 mapbox-gl.js 的过程中,并且在绘制一个以英里或米为半径而不是像素的圆时遇到了麻烦。这个特定的圆圈用于显示从中心点到任何方向的距离区域。

以前,我可以使用以下内容,然后将其添加到图层组中:

// 500 miles = 804672 meters
L.circle(L.latLng(41.0804, -85.1392), 804672, {
    stroke: false,
    fill: true,
    fillOpacity: 0.6,
    fillColor: "#5b94c6",
    className: "circle_500"
});

我在Mapbox GL中发现的唯一documentation如下:
map.addSource("source_circle_500", {
    "type": "geojson",
    "data": {
        "type": "FeatureCollection",
        "features": [{
            "type": "Feature",
            "geometry": {
                "type": "Point",
                "coordinates": [-85.1392, 41.0804]
            }
        }]
    }
});

map.addLayer({
    "id": "circle500",
    "type": "circle",
    "source": "source_circle_500",
    "layout": {
        "visibility": "none"
    },
    "paint": {
        "circle-radius": 804672,
        "circle-color": "#5b94c6",
        "circle-opacity": 0.6
    }
});

但这会以像素为单位渲染圆,该圆不会随着缩放而缩放。 Mapbox GL当前是否有一种方法可以渲染一个基于距离和缩放比例的圆形(或多个)的图层?

我目前正在使用Mapbox GL v0.19.0。

最佳答案

详细介绍Lucas' answer,我想出了一种估计参数的方法,以便根据一定的度量标准大小绘制圆。

该 map 支持0到20之间的缩放级别。假设我们将半径定义如下:

"circle-radius": {
  stops: [
    [0, 0],
    [20, RADIUS]
  ],
  base: 2
}

由于我们定义了最小缩放级别(0)和最大缩放级别(20)的值,因此 map 将在所有缩放级别上渲染圆。对于介于两者之间的所有缩放级别,其半径为(大约)RADIUS/2^(20-zoom)。因此,如果我们将RADIUS设置为与度量值匹配的正确像素大小,则对于所有缩放级别,我们都会获得正确的半径。

因此,我们基本上是采用将米转换为缩放级别20的像素大小的转换因子。当然,该因子取决于纬度。如果我们在最大缩放级别20下测量赤道上一条水平线的长度,并除以该线所跨越的像素数,则得出的系数约为0.075m / px(米/像素)。应用1 / cos(phi)的墨卡托纬度比例因子,我们可以为任何纬度获得正确的米/像素比:
const metersToPixelsAtMaxZoom = (meters, latitude) =>
  meters / 0.075 / Math.cos(latitude * Math.PI / 180)

因此,将RADIUS设置为metersToPixelsAtMaxZoom(radiusInMeters, latitude)将使我们得到一个大小正确的圆圈:
"circle-radius": {
  stops: [
    [0, 0],
    [20, metersToPixelsAtMaxZoom(radiusInMeters, latitude)]
  ],
  base: 2
}

关于mapbox-gl-js - 使用Mapbox GL JS绘制半径为英里/米的圆,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37599561/

10-12 18:14