# How do I map a Mollweide projection onto a sphere?

I have this Mollweide projection of the Earth circa 600 million years ago (http://jan.ucc.nau.edu/~rcb7/370moll.jpg).(1)

I want to map this onto a sphere. My results have big black splotches in the Pacific Ocean and the continents are distorted, because the code I used also mapped the black corners of the image to the sphere. I need to map just the central ellipse. What sort of code should I use? Perhaps I need to first convert the image to an equirectangular projection.

(1) Image credit: Ron Blakey, NAU Geology

I know it's been more than two years since the question was asked but please allow me to answer nevertheless for future reference.

According to Wikipedia articles on Mollweide and equirectangular projections, the function mollweidetoequirect that converts the former to the latter can be constructed as follows:

lat[y_, rad_:1] := ArcSin[(2 theta[y, rad] + Sin[2 theta[y, rad]])/Pi];
mollweidetoequirect[{x_, y_}] := {lon[x, y], lat[y]};


where lonzero and radius are chosen to be zero and one, respectively, for the transformation function. This means that the left-hand border of a transformed image will correspond to the meridian, and that we're going to use the texture on a unit sphere. For a sphere of radius $R$, the abscissae of a Mollweide image are in $[-2 R \sqrt{2}, 2 R \sqrt{2}]$ and the ordinates in $[-R \sqrt{2}, R \sqrt{2}]$.

To transform a map image, we need ImageForwardTransformation (not ImageTransformation) and tell Mathematica the ranges of coordinates of the image in both directions.

mollweide = Import["http://jan.ucc.nau.edu/~rcb7/370moll.jpg"]
equirect = ImageForwardTransformation[
mollweide,
mollweidetoequirect,
DataRange -> {{-2 Sqrt[2], 2 Sqrt[2]}, {-Sqrt[2], Sqrt[2]}},
PlotRange -> All
]


To map the texture onto a sphere, we need a plotting function that allows us to use TextureCoordinateFunction. There are quite a few to choose from, but because our equirectangular coordinates are in the form of {longitude, latitude}, the most convenient plotting function would be the one that allows us to use the spherical coordinates for TextureCoordinateFunction. According to its documentation, the only option is SphericalPlot3D:

globe[texture_] := SphericalPlot3D[
1,
{theta, 0, Pi},
{phi, 0, 2 Pi},
PlotStyle -> Directive[Texture[texture]],
TextureCoordinateFunction -> ({#5, -#4} &),
Mesh -> None,
Lighting -> "Neutral",
Axes -> False,
Boxed -> False
];
globe[equirect]


According to the documentation of TextureCoordinateFunction, #4 stands for θ and #5 for φ. But it's not clear what convention Mathematica uses for the spherical coordinates. The documentation of SphericalPlot3D suggests that θ is the polar angle (which corresponds to latitude) and φ the azimuthal angle (which corresponds to longitude), hence {#5, -#4}. The minus sign is needed because the vertical axis of image data is in the reverse direction of the usual y-axis.

Here's another example using an image of the cosmic microwave background taken by PLANCK, which is often shown in the Mollweide projection.

mollweide = Import["http://www.esa.int/var/esa/storage/images/esa_multimedia/images/2013/03/planck_cmb/12583930-4-eng-GB/Planck_CMB.jpg"]
equirect = ImageForwardTransformation[
mollweide,
mollweidetoequirect,
DataRange -> {{-2 Sqrt[2], 2 Sqrt[2]}, {-Sqrt[2], Sqrt[2]}}
];
globe[equirect]


The option PlotRange -> All is omitted to remove some more white space.

• Thanks! But what's the semicolon at rad_:1 for? I couldn't find any documentation on this. – Yukterez Dec 3 '15 at 21:59
• @СимонТыран You're welcome. For the colon: reference.wolfram.com/language/tutorial/… – Taiki Dec 3 '15 at 23:04

It might be better to start from the rectangular global maps that are available here and then use part of the method proposed by PlatoManiac.

This is the earth in early Devonian time:

map = Import["http://jan.ucc.nau.edu/~rcb7/400marect.jpg"];
pic = SphericalPlot3D[1, {u, 0, Pi}, {v, 0, 2 Pi}, Mesh -> None,
TextureCoordinateFunction -> ({#5, 1 - #4} &),
PerformanceGoal -> "Quality", PlotStyle -> Directive[Texture[map]],
Lighting -> "Neutral", Axes -> False, RotationAction -> "Clip",
Boxed -> False]


There should be a way to transform your original image into an image that corresponds to an equirectangular projection by using ImageTransformation[].