Skip to content

Instantly share code, notes, and snippets.

@turban
Last active April 14, 2016 13:11
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save turban/5866872 to your computer and use it in GitHub Desktop.
Save turban/5866872 to your computer and use it in GitHub Desktop.
UTM zones with D3.js

As the name implies, the Universal Transverse Mercator (UTM) projection is based on the cylindrical Transverse Mercator projection.

The UTM system divides the Earth between 80°S and 84°N latitude into 60 zones, each 6° of longitude in width. The zones are numbered from 1 to 60 proceeding east from the anitmeridian (180°).

This rotating Transverse Mercator projection shows the 60 UTM zones around the Earth. The projection has constant scale along the changing central meridian, and regions near it are mapped with low distortion. Just like on the regular Mercator projection, areas further away from the central meridian are increasingly distorted.

UTM is often used to show regions or countries with a greater north-south extent, like mainland Norway, which is usually depicted in UTM 33.

More information on thematic mapping blog.

Builds on http://bl.ocks.org/mbostock/5731808

<!DOCTYPE html>
<meta charset="utf-8">
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://d3js.org/topojson.v1.min.js"></script>
<script>
var width = 960,
height = 500;
// Returns UTM zome from longitude
var utmZone = d3.scale.linear()
.domain([-177, 177])
.rangeRound([1, 60])
.clamp(true);
var projection = d3.geo.transverseMercator()
.translate([width / 2, height / 2])
.scale(165)
.clipAngle(90);
var graticule = d3.geo.graticule()
.step([6, 8]);
var canvas = d3.select("body").append("canvas")
.attr("width", width)
.attr("height", height);
var context = canvas.node().getContext("2d");
var path = d3.geo.path()
.projection(projection)
.context(context);
d3.json("/mbostock/raw/4090846/world-110m.json", function(error, world) {
var land = topojson.feature(world, world.objects.land),
center = -180,
velocity = .015,
zone, zoneText, zoneStart, zoneEnd,
t0;
d3.timer(function() {
context.clearRect(0, 0, width, height);
projection.rotate([-center, 0]);
zone = utmZone(center);
zoneText = (1e15 + zone + "").slice(-2), // Add leading zero
zoneStart = -186 + zone * 6;
zoneEnd = zoneStart + 6;
t0 = Date.now();
render();
center += velocity * (Date.now() - t0);
if (center >= 180) { // New roundtrip
center = -180;
}
});
function render() {
context.beginPath();
path(land);
context.fillStyle = 'black';
context.fill();
context.beginPath();
path({
"type": "Polygon",
"coordinates": [[[zoneStart, 84], [zoneEnd, 84], [zoneEnd, -80], [zoneStart, -80], [zoneStart, 84]]]
});
context.fillStyle = "rgba(255, 255, 0, .5)";
context.fill();
context.beginPath();
path(graticule());
context.lineWidth = .5;
context.stroke();
context.beginPath();
context.fillStyle = "#eee";
context.strokeStyle = "black";
context.lineWidth = 1;
context.font = "bold 40px Verdana";
context.fillText(zoneText, width / 2 - 30, height / 2);
context.strokeText(zoneText, width / 2 - 30, height / 2);
}
});
</script>
@bodaniel
Copy link

A possible improvement: show the time zones when follwing the suns movement from east to west. This would make it a bit more educational.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment