01L'idée en une phraseThe idea in one sentence
Avec Window to Mars, j'ai voulu ouvrir une fenêtre en temps réel sur la planète Mars : on y suit la position réelle des rovers (Perseverance, Curiosity) et de l'hélicoptère Ingenuity, on explore leurs panoramas 360°, et on survole le cratère Jezero en 3D, le tout à partir de données publiques de la NASA que j'ai assemblées dans un navigateur.
With Window to Mars, I wanted to open a real-time window onto the planet Mars: you follow the actual positions of the rovers (Perseverance, Curiosity) and of the Ingenuity helicopter, explore their 360° panoramas, and fly over Jezero crater in 3D, all from public NASA data that I assembled inside a browser.
02La pile techniqueThe tech stack
J'ai tout fait tourner dans le navigateur, sans serveur applicatif. Je télécharge une seule fois les données lourdes (panoramas de centaines de Mo) via des scripts Python, je les redimensionne, puis je les sers en statique. Le reste (fond de carte, imagerie des survols 3D), je le charge en direct depuis les serveurs de la NASA.
I run everything in the browser, with no application server. I download the heavy assets (panoramas of hundreds of MB) once via Python scripts, resize them, then serve them statically. The rest (base map, 3D-flyover imagery) I load live from NASA servers.
| BriqueComponent | OutilTool | RôleRole |
|---|---|---|
| Carte 2D2D map | Leaflet 1.9 | Tuiles de Mars, projection, zoom, marqueursMars tiles, projection, zoom, markers |
| Viewer 360°360° viewer | Pannellum 2.5 | Panoramas équirectangulairesEquirectangular panoramas |
| 3D temps réelReal-time 3D | Three.js r128 | Globe d'intro + survols aériensIntro globe + aerial flyovers |
| Traitement imageImage processing | Canvas API | Ciel, colorisation, assemblage de tuilesSky, colorization, tile stitching |
| TéléchargementsDownloads | Python + Pillow | Panoramas haute résolutionHigh-resolution panoramas |
03Représenter Mars à plat : le casse-tête des projectionsShowing Mars flat: the projection puzzle
Mars est une sphère ; un écran est plat. Pour afficher une planète, il faut projeter la sphère sur un plan, et il existe plusieurs façons, incompatibles entre elles :
EPSG:4326 (« plate carrée ») : longitude = axe X, latitude = axe Y. Simple, mais déforme près des pôles. Web-Mercator : la projection des cartes web classiques, qui « étire » les hautes latitudes.
Mon choix : EPSG:4326, car la meilleure mosaïque nette de Mars (le CTX, ~5 m/px) est servie ainsi. La couche couleur HiRISE (25 cm/px), elle, est en Web-Mercator : je la recompose sur un canvas puis je la place aux bonnes coordonnées. Je comble les trous du CTX avec la mosaïque Viking (232 m/px).
Mars is a sphere; a screen is flat. To display a planet you must project the sphere onto a plane, and there are several, mutually incompatible ways:
EPSG:4326 ("plate carrée"): longitude = X axis, latitude = Y axis. Simple, but distorts near the poles. Web-Mercator: the projection of classic web maps, which "stretches" high latitudes.
My choice: EPSG:4326, because the sharpest Mars mosaic (CTX, ~5 m/px) is served that way. The HiRISE color layer (25 cm/px) is in Web-Mercator: I recompose it on a canvas then place it at the right coordinates. I fill CTX gaps with the Viking mosaic (232 m/px).
04Les cartes essayées puis abandonnéesMaps we tried and dropped
J'ai exploré beaucoup de sources. Voici l'historique honnête de mes essais, impasses comprises, souvent le plus instructif.
I explored many sources. Here's the honest history of what I tried, dead ends included, often the most instructive part.
| SourceSource | VerdictVerdict | RaisonReason |
|---|---|---|
| Mosaïque CTXCTX mosaic ~5 m/px | ✅ | Nette, fiable, servie en 4326, CORS ouvertSharp, reliable, served in 4326, CORS-open |
| HiRISE couleurHiRISE color 25 cm/px | ✅ | Résolution exceptionnelle (corridor + texture 3D)Outstanding resolution (corridor + 3D texture) |
| Viking MDIM21 | ✅ | Comble les trous du CTX (couleur globale)Fills CTX gaps (global color) |
| MNT MOLA globalGlobal MOLA DEM | ✕ | Trop grossier : Jezero ≈ 3 pixels de largeToo coarse: Jezero ≈ 3 pixels wide |
| Trek subset / WMTS DEM | ✕ | Endpoints en 404, pas de CORS en direct404 endpoints, no live CORS |
| MNT HiRISE de JezeroJezero HiRISE DEM | ✕ | Fichier source unique de ~10 GoSingle ~10 GB source file |
| Panoramas FU BerlinFU Berlin panoramas | ✕ | Format tuiles non récupérable + reconstructions protégées (droits)Tile format not retrievable + copyrighted reconstructions |
05Tracer les déplacements des trois explorateursTracing the three explorers
Trois engins, trois jeux de coordonnées réelles : Perseverance (64 étapes, sols 13→1921), Curiosity (61 étapes, sols 3→4957), Ingenuity (73 vols, 0→72).
Un tracé joli sans le fausser
Relier des points par des segments droits donne un tracé anguleux. J'utilise donc une spline de Catmull-Rom centripète : une courbe qui passe exactement par tous les points réels, mais avec des transitions douces, et qui, en version « centripète », évite les boucles et dépassements dans les virages serrés (piège classique des Bézier naïves). Le tracé est joli mais fidèle : jamais je ne fais passer l'engin là où il n'est pas allé.
Three craft, three sets of real coordinates: Perseverance (64 waypoints, sols 13→1921), Curiosity (61 waypoints, sols 3→4957), Ingenuity (73 flights, 0→72).
A pretty trace without falsifying it
Joining points with straight segments looks jagged. So I use a centripetal Catmull-Rom spline: a curve passing exactly through every real point, but with smooth transitions, and, in its "centripetal" form, avoiding loops and overshoot on sharp turns (a classic trap of naive Béziers). The trace is pretty but faithful: I never route the craft through a place it didn't visit.
06Les panoramas 360°The 360° panoramas
Perseverance, Mastcam-Z (52 panoramas) : les panoramas 360° officiels, sols 3 à 1775, de vraies photos NASA affichées telles quelles.
Curiosity, Mastcam (25 panoramas) : j'en ai recensé sur toute la mission, du sol 2 (atterrissage) au sol 4741, avec Rocknest (« milliard de pixels »), dune de Namib, Murray Buttes, Vera Rubin Ridge, Glen Torridon (« 1,8 milliard de pixels »)… J'identifie chacun par son numéro PIA, je le géolocalise par interpolation sur le tracé réel, et je le récupère en haute résolution (originaux > 29 000 px) via un script multi-sources.
Perseverance, Mastcam-Z (52 panoramas): the official 360° panoramas, sols 3 to 1775, real NASA photos shown as-is.
Curiosity, Mastcam (25 panoramas): I compiled these across the whole mission, from sol 2 (landing) to sol 4741, with Rocknest (the "billion-pixel"), Namib Dune, Murray Buttes, Vera Rubin Ridge, Glen Torridon (the "1.8-billion-pixel")… I identify each by its PIA number, geolocate it by interpolation on the real track, and fetch it in high resolution (originals > 29,000 px) via a multi-source script.
07Ingenuity : vraies photos + survols 3D « maison »Ingenuity: real photos + home-made 3D flyovers
Ingenuity est un hélicoptère : il n'a jamais pris de panoramas 360° au sol. J'ai donc combiné, dans sa section, 5 vraies photos aériennes couleur (caméra RTE, géolocalisées par vol) et 8 survols aériens 360° que j'ai reconstruits en 3D.
Comment je fabrique un survol
1. Texture = imagerie réelle. À l'ouverture, je vais chercher en direct les tuiles HiRISE couleur (25 cm/px) autour du point de vol et je les assemble (~2,3 km de terrain).
2. Relief = reconstruit depuis l'ombrage. Le vrai MNT n'étant pas accessible, je dérive un relief basse fréquence de la luminance (l'ombrage encode les pentes), que je lisse pour éviter tout faux pic.
3. Rendu = Three.js. Terrain drapé, lumière rasante (bump map), ciel martien, brume d'horizon ; caméra à l'altitude du vol, regard 360°.
Ingenuity is a helicopter: it never took ground-level 360° panoramas. So in its section I combined 5 real color aerial photos (RTE camera, geolocated by flight) and 8 aerial 360° flyovers that I reconstructed in 3D.
How I build a flyover
1. Texture = real imagery. On opening, I fetch live the HiRISE color tiles (25 cm/px) around the flight point and stitch them (~2.3 km of terrain).
2. Relief = reconstructed from shading. Since the real DEM isn't reachable, I derive a low-frequency relief from luminance (shading encodes slopes), which I smooth to avoid false peaks.
3. Rendering = Three.js. Draped terrain, raking light (bump map), Martian sky, horizon haze; camera at flight altitude, 360° look-around.
08Reconstruire un ciel martienRebuilding a Martian sky
Les panoramas de la NASA arrivent souvent avec un cache noir en haut (la caméra ne photographie pas le zénith). J'ai écrit une fonction qui détecte ce cache, échantillonne la vraie couleur du ciel au-dessus de l'horizon, la remplace par un dégradé beige/rosé cohérent, et bouche colonne par colonne les trous résiduels. Enfin, je fais démarrer la vue centrée sur le sol/l'horizon pour mettre en avant le paysage réel.
NASA panoramas often arrive with a black matte at the top (the camera doesn't shoot the zenith). I wrote a function that detects it, samples the true sky color above the horizon, replaces it with a coherent beige/pink gradient, and fills residual holes column by column. Finally, I open the view centered on the ground/horizon to foreground the real landscape.
09Crédits & sourcesCredits & sources
Toute l'imagerie provient de missions publiques. La NASA est créditée comme source ; ces crédits n'impliquent aucun endossement du projet par la NASA ou ses partenaires.
All imagery comes from public missions. NASA is credited as the source; these credits imply no endorsement of the project by NASA or its partners.
CTX, NASA/JPL/MSSS/The Murray Lab (Caltech) · HiRISE, NASA/JPL/Univ. Arizona · Viking MDIM21, NASA/USGS · MOLA, NASA/GSFC · Mastcam-Z, NASA/JPL-Caltech/ASU/MSSS · Mastcam & Navcam, NASA/JPL-Caltech/MSSS · Ingenuity RTE, NASA/JPL-Caltech
10Licence, éthique & démarche éducativeLicense, ethics & educational mission
Window to Mars est un projet ouvert, à visée éducative : je veux rendre l'exploration de Mars accessible à partir de données scientifiques réelles. Trois principes ont guidé chacune de mes décisions :
1. Fidélité aux données. Je n'invente ni position, ni image, ni relief.
2. Transparence des reconstructions. Je crédite explicitement le ciel et le relief 3D comme des reconstructions.
3. Respect du travail d'autrui. J'ai renoncé aux panoramas de FU Berlin plutôt que de ré-héberger le travail 3D d'une autre équipe.
Window to Mars is an open, educational project: I want to make the exploration of Mars accessible from real scientific data. Three principles guided every one of my decisions:
1. Faithfulness to the data. I invent no position, image or landform.
2. Transparency about reconstructions. I explicitly credit the sky and 3D relief as reconstructions.
3. Respect for others' work. I gave up FU Berlin's panoramas rather than re-host another team's 3D work.