diff --git a/js/geo/transform.js b/js/geo/transform.js index 6dea5be0bf3..e786434132c 100644 --- a/js/geo/transform.js +++ b/js/geo/transform.js @@ -454,6 +454,15 @@ class Transform { mat4.rotateZ(m, m, this.angle); mat4.translate(m, m, [-this.x, -this.y, 0]); + const circumferenceOfEarth = 2 * Math.PI * 6378137; + + mat4.scale(m, m, [1, 1, + // scale vertically to meters per pixel (inverse of ground resolution): + // (2^z * tileSize) / (circumferenceOfEarth * cos(lat * π / 180)) + (Math.pow(2, this.zoom) * this.tileSize) / + (circumferenceOfEarth * Math.abs(Math.cos(this.center.lat * (Math.PI / 180)))), + 1]); + this.projMatrix = m; // matrix for conversion from location to screen coordinates diff --git a/js/render/draw_fill_extrusion.js b/js/render/draw_fill_extrusion.js index 44039cf0521..ca8e62243f4 100644 --- a/js/render/draw_fill_extrusion.js +++ b/js/render/draw_fill_extrusion.js @@ -162,7 +162,13 @@ function drawExtrusion(painter, source, layer, coord) { setPattern(image, tile, coord, painter, program, true); } - setMatrix(program, painter, coord, tile, layer); + painter.gl.uniformMatrix4fv(program.u_matrix, false, painter.translatePosMatrix( + coord.posMatrix, + tile, + layer.paint['fill-extrusion-translate'], + layer.paint['fill-extrusion-translate-anchor'] + )); + setLight(program, painter); for (const segment of buffers.segments) { @@ -171,21 +177,6 @@ function drawExtrusion(painter, source, layer, coord) { } } -function setMatrix(program, painter, coord, tile, layer) { - const zScale = Math.pow(2, painter.transform.zoom) / 50000; - - painter.gl.uniformMatrix4fv(program.u_matrix, false, mat4.scale( - mat4.create(), - painter.translatePosMatrix( - coord.posMatrix, - tile, - layer.paint['fill-extrusion-translate'], - layer.paint['fill-extrusion-translate-anchor'] - ), - [1, 1, zScale, 1]) - ); -} - function setLight(program, painter) { const gl = painter.gl; const light = painter.style.light; diff --git a/test/js/ui/map.test.js b/test/js/ui/map.test.js index 02ab9957afe..38c44c052a1 100755 --- a/test/js/ui/map.test.js +++ b/test/js/ui/map.test.js @@ -382,10 +382,15 @@ test('Map', (t) => { function toFixed(bounds) { const n = 10; return [ - [bounds[0][0].toFixed(n), bounds[0][1].toFixed(n)], - [bounds[1][0].toFixed(n), bounds[1][1].toFixed(n)] + [normalizeFixed(bounds[0][0], n), normalizeFixed(bounds[0][1], n)], + [normalizeFixed(bounds[1][0], n), normalizeFixed(bounds[1][1], n)] ]; } + + function normalizeFixed(num, n) { + // workaround for "-0.0000000000" ≠ "0.0000000000" + return parseFloat(num.toFixed(n)).toFixed(n); + } }); t.test('#setMaxBounds', (t) => {