[GIS] Can Leaflet be used to show 360° panoramic images

cubemapleafletpanorama

Google's Marzipano makes the task of creating VR tours extremely simple. It is possible to take the Marzipano output and customize it – to an extent. However, Leaflet with its pleathora of plugins and the ease of creating custom layers offers a far higher degree of customization. What is not clear to me is whether I can use 360° panoramic images such as this one in Leaflet by somehow specifying the coordinate system and then serving up the right "tiles" from my own server.

Quite apart from the coordinate system and tiling problem it is not clear to me that Leaflet can be made to produce the smooth panning effect that Marzipano delivers. What for instance happens when you reach 180°? In a panorama view you want to smoothly transition to show whatever happens to be at/around -180° rather than the tile server serving up a blank "not found" tile.

I'd be most obliged to anyone who might be able to tell me if this is at all possible with Leaflet.

Best Answer

Can leaflet be used to show 360 panoramic images?

Yes, but the result is probably not what you wanted/expected.

For example, I can take this image from the Panellum examples page, which is a full panorama in equirectangular projection...

equirectangular projection panorama

...add it to a Leaflet map so it repeats horizontally using a bit of Leaflet trickery...

var map = new L.Map('leaflet', {
    center: [0, 0],
    zoom: -3,
    minZoom: -6,
    crs: L.CRS.Simple
});

L.tileLayer('https://pannellum.org/images/alma.jpg', {
    tileSize: L.point(4096,2048),
    bounds: [[0,-Infinity],[2048,Infinity]],
    attribution: '<a href="https://pannellum.org">Panellum</a>',
    maxNativeZoom: 0,
    minNativeZoom: 0,
    minZoom: -6
}).addTo(map);

... and Leaflet will display it (as in this working demo), and the user can zoom and pan it:

Leaflet displaying equirectangular panorama

At this point it's important to remark that Leaflet only works with flat images and performs no reprojection, so the (lack of) distortion is (very) noticeable. Compare that to how the same example in Panellum looks like:

equirectangular projection using Panellum

...and now, the curb, which showed as a curved line, is now straight! (as expected!). But, why?

Because the panorama images are projected to make them flat. In GIS terms, what you have is an image/map in equirectangular projection, like...

equirectangular map

...and then you project that into a sphere...

globe

...and then put a camera on the center of the sphere to get the right point of view. So when you're exploring a 360° panorama, you're not panning a flat image - you're rotating a (virtual) camera inside a (virtual) sphere.

In practical terms, panorama viewers tend to work with cube maps and/or skyboxes. Instead of a sphere, a cube is used (and instead of just one flat image, six azimuthal projections are used).

Leaflet could be able to display cubeface textures (e.g. ignoring the "top" and the "bottom" one and horizontally repeating the remaining 4) but, again, only in a flat way.

e.g. using the images from the Panellum cubemap example and applying even more Leaflet trickery so the x tile coordinate repeats every 4 tiles...

var cubemaptiles = L.tileLayer('https://pannellum.org/images/wyman-park-playground-cubic/face{x}.jpg', {
    tileSize: L.point(1704,1704),
    bounds: [[0,-Infinity],[1704,Infinity]],
    attribution: '<a href="https://pannellum.org/documentation/examples/cube-map/">Panellum</a>',
    maxNativeZoom: 0,
    minNativeZoom: 0,
    minZoom: -6
});

cubemaptiles.getTileUrl = function getTileUrl(coords) {
    coords.x = coords.x % 4;
    if (coords.x < 0) coords.x += 4;
    return L.TileLayer.prototype.getTileUrl.call(this, coords);
}

cubemaptiles.addTo(map);

...one can get something like this working demo...

Leaflet displaying a partial cubemap

...it should be obvious that there are noticeable artefacts on the tile boundaries (namely, the straight lines of the shadows clash against each other), as expected. The distortion is similar to having maps in gnomonic projections next to each other, e.g.

earth cubemap

Leaflet can display cubemap textures, but I'll argue that it's not the best tool for the job.