Created

Embed URL

HTTPS clone URL

SSH clone URL

You can clone with HTTPS or SSH.

Download Gist

D3 function for fitting a projection to geodata

View fitProjection.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
function fitProjection(projection, data, box, center) {
// get the bounding box for the data - might be more efficient approaches
var left = Infinity,
bottom = -Infinity,
right = -Infinity,
top = Infinity;
// reset projection
projection
.scale(1)
.translate([0, 0]);
data.features.forEach(function(feature) {
d3.geo.bounds(feature).forEach(function(coords) {
coords = projection(coords);
var x = coords[0],
y = coords[1];
if (x < left) left = x;
if (x > right) right = x;
if (y > bottom) bottom = y;
if (y < top) top = y;
});
});
// project the bounding box, find aspect ratio
function width(bb) {
return (bb[1][0] - bb[0][0])
}
function height(bb) {
return (bb[1][1] - bb[0][1]);
}
function aspect(bb) {
return width(bb) / height(bb);
}
var startbox = [[left, top], [right, bottom]],
a1 = aspect(startbox),
a2 = aspect(box),
widthDetermined = a1 > a2,
scale = widthDetermined ?
// scale determined by width
width(box) / width(startbox) :
// scale determined by height
height(box) / height(startbox),
// set x translation
transX = box[0][0] - startbox[0][0] * scale,
// set y translation
transY = box[0][1] - startbox[0][1] * scale;
console.log(startbox);
// center if requested
if (center) {
if (widthDetermined) {
transY = transY - (transY + startbox[1][1] * scale - box[1][1])/2;
} else {
transX = transX - (transX + startbox[1][0] * scale - box[1][0])/2;
}
}
return projection.scale(scale).translate([transX, transY])
}
Owner

Note: at the moment, this only works for Mercator projections.

boorad commented

dude, this saved my life... thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.