Mapping proximity using a threshold filter is a continuation of my experiments in to visualising the tube network. My previous experiment used Google Maps and its shape drawing tools to visualise proximity. This version tries a different approach using the Canvas object and simple image filters.
There are three parts to this experiment: the map, which is just a static image; the gradient image, which I’ll call the heat map; and a threshold filter written in javascript. The threshold filter is applied to the heat map and turns all pixels above a certain colour blue, and all below transparent.
This is a crop of the heat map, created in Photoshop using simple gradient fills and layer blends. Each spot is centered on a tube station. The colours in the gradient map neatly to the RGB components of a pixel colour, meaning the gradient moves smoothly from #FFFFFF, #FFFF00, #FF0000 to #000000. The values of each channel are added together giving a total of 765 levels for the threshold filter.
In order to composite the effect on top of the map I’ve used a Canvas object. Canvas has a few methods to directly affect its pixel data, the two I’ve used it getImageData and putImageData, which return and set the image an arrays of pixel data. This allows you to create something like a rudimentary pixel shader. For a threshold filter you simply need to clamp pixels either side of a given value to a specific colour. Here’s a stripped down version of how it works:
// Load an image and extract the pixel data
var imageData;
var img = new Image();
img.src = "gradient.png";
img.onload = function() {
// Get image data from the canvas context
imageData = context.getImageData(0, 0, canvas.width, canvas.height);
runFilter();
};
function runFilter() {
// Each pixel takes up 4 entries in the array using the RGBA format
var originPixels = imageData.data;
var filterPixels = imageData.data;
for (var i = 0; i < originPixels.length; i += 4) {
r = originPixels[i];
g = originPixels[i+1];
b = originPixels[i+2];
filterPixels[i] = filterPixels[i+1] = 0; // Red/Green channels
filterPixels[i+2] = 255; // Blue
filterPixels[i+3] = ((r + g + b) >= amount) ? 96 : 0; // Alpha
}
// Dump filtered pixel data to the canvas
canvasContext.putImageData(filterData, 0, 0);
}
See the source of the actual experiment page for the rest of the code. With further work I hope to be able to generate the heat map from the geographic data I used in the previous experiment, and the canvas threshold filter integrated into Google Map overlays.






The Android framework’s 

