I\'m in the process of converting a map from using mapbox.js to mapbox-gl.js, and am having trouble drawing a circle that uses miles or met
Elaborating on Lucas' answer, I've come up with a way of estimating the parameters in order to draw a circle based on a certain metric size.
The map supports zoom levels between 0 and 20. Let's say we define the radius as follows:
"circle-radius": {
stops: [
[0, 0],
[20, RADIUS]
],
base: 2
}
The map is going to render the circle at all zoom levels since we defined a value for the smallest zoom level (0) and the largest (20). For all zoom levels in between it results in a radius of (approximately) RADIUS/2^(20-zoom). Thus, if we set RADIUS to the correct pixel size that matches our metric value, we get the correct radius for all zoom levels.
So we're basically after a conversion factor that transforms meters to a pixel size at zoom level 20. Of course this factor depends on the latitude. If we measure the length of a horizontal line at the equator at the max zoom level 20 and divide by the number of pixels that this line spans, we get a factor ~0.075m/px (meters per pixel). Applying the mercator latitude scaling factor of 1 / cos(phi), we obtain the correct meter to pixel ratio for any latitude:
const metersToPixelsAtMaxZoom = (meters, latitude) =>
meters / 0.075 / Math.cos(latitude * Math.PI / 180)
Thus, setting RADIUS to metersToPixelsAtMaxZoom(radiusInMeters, latitude) gets us a circle with the correct size:
"circle-radius": {
stops: [
[0, 0],
[20, metersToPixelsAtMaxZoom(radiusInMeters, latitude)]
],
base: 2
}