This exampe shows the temperature at 840 hPa and the geopotential height at 850 hPa from the GFS model (date 27/7/2016).
The idea is showing how to use the d3-marching-squares library as in the previous example, but adding isolines.
The colors represent the temperature and the lines the geopotential height. The example should have a scale, but the d3-legend library doesn’t seem to work with d3 v4. The isolines should be labaled too, and this is a quite difficult task.
The example is created with npm and browserify, so if you want to play a little with it:
Now you can see the changed page.
<!DOCTYPE html>
<meta charset="utf-8">
<body>
<div id="map"></div>
<script src="bundle.js"></script>
var d3_selection = require("d3-selection");
var d3_geo = require("d3-geo");
var d3_request = require("d3-request");
var d3_marching_squares = require("d3-marching-squares");
var topojson = require("topojson");
var GeoTIFF = require("geotiff");
var d3_scale_chromatic = require("d3-scale-chromatic");
var width = 680,
height = 500;
var projection = d3_geo.geoAzimuthalEqualArea()
.rotate([-55.5, -24])
.scale(1100);
var canvas = d3_selection.select("body").append("canvas")
.attr("width", width)
.attr("height", height);
var context = canvas.node().getContext("2d");
var path = d3_geo.geoPath()
.projection(projection)
.context(context);
d3_request.request("tz850.tiff")
.responseType('arraybuffer')
.get(function(error, tiffData){
d3_request.json("world-110m.json", function(error, topojsonData) {
var tiff = GeoTIFF.parse(tiffData.response);
var image = tiff.getImage();
var rasters = image.readRasters();
var tiepoint = image.getTiePoints()[0];
var pixelScale = image.getFileDirectory().ModelPixelScale;
var geoTransform = [tiepoint.x, pixelScale[0], 0, tiepoint.y, 0, -1*pixelScale[1]];
var zData = new Array(image.getHeight());
var tempData = new Array(image.getHeight());
for (var j = 0; j<image.getHeight(); j++){
zData[j] = new Array(image.getWidth());
tempData[j] = new Array(image.getWidth());
for (var i = 0; i<image.getWidth(); i++){
zData[j][i] = rasters[0][i + j*image.getWidth()];
tempData[j][i] = rasters[1][i + j*image.getWidth()];
}
}
var countries = topojson.feature(topojsonData, topojsonData.objects.countries);
context.beginPath();
context.strokeStyle = "#000";
path(countries);
context.fill();
var intervalsTemp = [14,17,20,23,26,29, 35, 38];
var bandsTemp = d3_marching_squares.isobands(tempData, geoTransform, intervalsTemp);
bandsTemp.features.forEach(function(d, i) {
context.beginPath();
context.globalAlpha = 0.9;
context.fillStyle = d3_scale_chromatic.interpolateRdBu(1-(i/(bandsTemp.features.length-1)));
path(d);
context.fill();
});
var countries = topojson.feature(topojsonData, topojsonData.objects.countries);
context.beginPath();
context.strokeStyle = "#000";
context.lineWidth = 1.5;
context.globalAlpha = 0.5;
path(countries);
context.stroke();
var intervalsZ = [1400, 1420, 1440, 1460, 1480, 1500, 1520, 1540];
var linesZ = d3_marching_squares.isolines(zData, geoTransform, intervalsZ);
linesZ.features.forEach(function(d, i) {
context.beginPath();
context.strokeStyle = "#000";
context.lineWidth = 2;
context.globalAlpha = 1;
path(d);
context.stroke();
});
});
});
{
"name": "isobandsisolines",
"version": "1.0.0",
"description": "",
"main": "draw.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"d3-geo": "^1.1.1",
"d3-marching-squares": "0.0.4",
"d3-request": "^1.0.1",
"d3-scale-chromatic": "^1.0.1",
"d3-selection": "^1.0.0",
"d3-svg-legend": "^1.12.0",
"geotiff": "^0.3.3",
"topojson": "^1.6.26"
}
}