# Map projection converter

2024

Python

GLSL

A blazing fast, shader based image projection converter. Converts between the equirectangular and mercator projections. Can be used via a CLI or directly in Python. Check it out on on GitHub!

fragment_to_equirectangular.glsl

```
vec2 equi_to_merc(float u, float v)
{
// uv to equirectangular
float lat = remap(u, 0, 1, 0, 2 * M_PI);
float lon = remap(v, 0, 1, -M_PI * 0.5, M_PI * 0.5);
// equirectangular to mercator
float x = lat;
float y = log(tan(M_PI / 4 + lon / 2));
// mercator to uv
x = remap(x, 0, 2 * M_PI, 0, 1);
y = remap(y, -M_PI, M_PI, 0, 1);
return vec2(x, y);
}
```

Using the moderngl python library, the converter runs the input image through a remapping shader. The shaders transform uv coordinates to latitude and longitude and then convert between the two projections.

Additionally, this implementation can also render with either nearest or linear texture sampling, letting you choose between a sharp or interpolated upscaling.

cpu_render.py

```
def equi_to_merc(u, v):
# uv to equirectangular
lat = remap(u, 0, 1, 0, 2 * math.pi)
lon = remap(v, 0, 1, -math.pi * 0.5, math.pi * 0.5)
# equirectangular to mercator
x = lat
lon = clamp(lon, -MERC_MAX_LON, MERC_MAX_LON)
y = math.log(math.tan(math.pi / 4 + lon / 2))
# mercator to uv
x = remap(x, 0, 2 * math.pi, 0, 1)
y = remap(y, -math.pi, math.pi, 0, 1)
# clamp
x = clamp(x, 0, 1)
y = clamp(y, 0, 1)
return (x, y)
```

A CPU implementation using the Pillow library exists as a fallback, although with obvious downsides of poor performance and scalability.