MercatorGL
MercatorGL is a minimal library for calculating web mercator projections on a GPU using WebGL. It provides utilities to inject GLSL code for projecting longitude/latitude coordinates into already exisiting vertex shader code and calculate the uniforms it requires. MercatorGL focuses on numerical stability by performing most calculations at 64-bit precision, and switching to an "offset mode" at higher zoom levels (using a technique borrowed from
deck.gl).
let map = new mapboxgl.Map({
container: mapboxContainer,
style: "mapbox://styles/mapbox/streets-v9",
center: [-73.982130, 40.762896],
zoom: 15
});
// NOTE: MercatorGL works with both GLSL 1 and 3 shaders
let vs = `
#version 300 es
layout(location=0) in vec2 lngLatPosition;
void main() {
// mercator_gl_lngLatToClip function injected by injectMercatorGLSL().
// mercator_gl_lngLatToMercator and mercator_gl_mercatorToClip also available to do
// projection in multiple steps.
gl_Position = mercator_gl_lngLatToClip(position);
}
`;
let fs = `
#version 300 es
precision highp float;
uniform vec4 color;
out vec4 fragColor;
void main() {
fragColor = color;
}
`;
// Insert projection functions into vertex shader
let vertexShaderSource = injectMercatorGLSL(vs);
let fragmentShaderSource = fs;
// Create WebGL program from vertexShaderSource and fragmentShaderSource
let uniforms = {
// An application uniform, not used by MercatorGL
color: new Float32Array(1.0, 0.0, 0.0, 1.0);
};
// Uniforms used by MercatorGL are added to the map.
allocateMercatorUniforms(uniforms);
map.on("render", (e) => {
let center = map.getCenter().toArray();
let zoom = map.getZoom();
// Update the values of MercatorGL uniforms in the map (including projection matrix provided by Mapbox).
// The application must use the map to update program uniforms used by MercatorGL.
updateMercatorUniforms(uniforms, center, zoom, map.transform.projMatrix);
// Draw to canvas
});
MercatorGL can be used directly by downloading the
built source and loading it via a script tag:
<script src="js/mercator-gl.min.js"></script>
or it can be installed via
npm:
npm install mercator-gl
and loaded via ES6-style import
:
import MercatorGL from "mercator-gl";
Examples
Columns