-
-
Save tpreusse/6e81ae2feb01bdb9a824eeb84807c85c to your computer and use it in GitHub Desktop.
D3 function for fitting a projection to geodata
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import d3 from 'd3'; | |
export const fitProjection = (projection, data, box, center) => { | |
// get the bounding box for the data - might be more efficient approaches | |
let left = Infinity; | |
let bottom = -Infinity; | |
let right = -Infinity; | |
let top = Infinity; | |
// reset projection | |
projection.scale(1).translate([0, 0]); | |
data.features.forEach((feature) => { | |
d3.geo.bounds(feature).forEach((coords) => { | |
const [x, y] = projection(coords); | |
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 | |
const width = (bb) => (bb[1][0] - bb[0][0]); | |
const height = (bb) => (bb[1][1] - bb[0][1]); | |
const aspect = (bb) => width(bb) / height(bb); | |
const startbox = [[left, top], [right, bottom]]; | |
const widthDetermined = aspect(startbox) > aspect(box); | |
const scale = widthDetermined ? | |
// scale determined by width | |
width(box) / width(startbox) : | |
// scale determined by height | |
height(box) / height(startbox); | |
// set x translation | |
let transX = box[0][0] - startbox[0][0] * scale; | |
// set y translation | |
let transY = box[0][1] - startbox[0][1] * scale; | |
// 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]); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment