block by jeremycflin 7ea27d3473b6d22766dc654727459e42

A plugin for raster reprojection in d3

Full Screen

A plugin for raster reprojection in d3

Here is a demo of a simple d3 plugin to reproject (warp) a raster image using d3.

I was motivated to make it because I could not get gdalwarp to produce nice reprojections of rasters when the target projection had the antimeridian inside the picture, e.g. in a rotated orhographic projection (showing Earth’s “back side”). The gdalwarp utility typically leaves a thin sliver unpainted close to the antimeridian, which shows up as a transparent line along the antimeridian.

How to use the plugin

The plugin behind this demo (see below, or in the GitHub repo) is only a proof of concept, not ready for production. But it illustrates that we can easily create a pretty neat API for raster reprojection, something like this:


var dstCanvas = d3.select('#warped').node();
var srcProj = d3.geoEquirectangular(),
    dstProj = d3.geoOrthographic(),

var world = {type: 'Sphere'},

// Fit the whole world inside the destination canvas
dstProj.fitSize([dstCanvas.width, dstCanvas.height]], world);

var warp = d3.geoWarp()
    .srcProj(srcProj)
    .dstProj(dstProj)
    .dstContext(dstContext);

var srcImg = d3.select('#src').node();

srcImg.onload = function () {
    // The source image is known to contain the whole world.
    // Of course, this can be hard coded if the image size is known.
    srcProj.fitSize([srcImg.width, srcImg.height], world);

    warp(srcImg);
}

srcImg.src = 'path/to/source/dataset.png';

Notes on implementation

The projection.fitExtent method (new in d3-geo v1.2.0) makes it easy to fit a d3 geoProjection to an image containing a map. The fitted projection object can then be used to sample the source image at some geographical coordinates without working out the conversion between image pixels and geographical coordinates.

No big assumptions are made about the source and destination projections. I only require that the destination projection is invertible. The source projection and the destination projection’s inverse are called for each pixel in the destination raster. This is not fast, but it’s simple :) As you can probably see from the poor animation frame rate on this page, the algorithm is not really useful for animated on-the-fly reprojection.

In this example, the source image is in equirectangular projection which is pretty typical for geographical raster datasets.

So far I only implemented nearest neighbor resampling, but other algorithms should be relatively straightforward to add.

forked from mukhtyar‘s block: A plugin for raster reprojection in d3

index.html

d3-geo-warp.js