Fix projection (mercator) and centering
This commit is contained in:
parent
31cd14cd86
commit
70c954d4fa
23
index.html
23
index.html
|
@ -126,7 +126,7 @@
|
||||||
const cities = await response.json();
|
const cities = await response.json();
|
||||||
await state_shape_data_request; // We can't draw until this is in
|
await state_shape_data_request; // We can't draw until this is in
|
||||||
const state_shape = state_shape_data.features.find(f => f.properties.NAME.toLowerCase() == stateName.toLowerCase());
|
const state_shape = state_shape_data.features.find(f => f.properties.NAME.toLowerCase() == stateName.toLowerCase());
|
||||||
const state_bounds = find_bounds(state_shape.geometry.coordinates[0]);
|
const state_mercator_adjusted_bounds = find_bounds(state_shape.geometry.coordinates[0].map(mercator));
|
||||||
if (!state_shape) {
|
if (!state_shape) {
|
||||||
console.error("Unable to find state in shapes");
|
console.error("Unable to find state in shapes");
|
||||||
}
|
}
|
||||||
|
@ -169,14 +169,21 @@
|
||||||
const ctx = canvas.getContext("2d");
|
const ctx = canvas.getContext("2d");
|
||||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||||
|
|
||||||
|
const [minx, maxx, miny, maxy] = state_mercator_adjusted_bounds;
|
||||||
|
const height_scale = (canvas.height - 8) / (maxy - miny);
|
||||||
|
const width_scale = (canvas.width - 8) / (maxx - minx);
|
||||||
|
const scale = Math.min(height_scale, width_scale);
|
||||||
|
|
||||||
|
const y_offset = miny - (canvas.height / scale - (maxy - miny)) / 2;
|
||||||
|
const x_offset = minx - (canvas.width / scale - (maxx - minx)) / 2;
|
||||||
|
|
||||||
function transform(pt) {
|
function transform(pt) {
|
||||||
// TODO: this just works for MN, and not very well at that
|
pt = mercator(pt)
|
||||||
return [(pt[0]+98)*80, 600-(pt[1]-42)*80];
|
return [scale * (pt[0] - x_offset), canvas.height - (scale * (pt[1] - y_offset))];
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.moveTo(...transform(state_shape.geometry.coordinates[0][0]))
|
ctx.moveTo(...transform(state_shape.geometry.coordinates[0][0]))
|
||||||
console.log(transform(state_shape.geometry.coordinates[0][0]))
|
|
||||||
for (let coord of state_shape.geometry.coordinates[0].slice(1)) {
|
for (let coord of state_shape.geometry.coordinates[0].slice(1)) {
|
||||||
ctx.lineTo(...transform(coord));
|
ctx.lineTo(...transform(coord));
|
||||||
}
|
}
|
||||||
|
@ -194,6 +201,14 @@
|
||||||
}).mount();
|
}).mount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function mercator(pt) {
|
||||||
|
const radians_from_eq = Math.abs(Math.PI/180 * pt[1]);
|
||||||
|
// https://en.wikipedia.org/wiki/Mercator_projection#Derivation
|
||||||
|
const y_radians = Math.log(Math.tan(Math.PI/4 + radians_from_eq/2));
|
||||||
|
const y_degrees = 180/Math.PI * y_radians;
|
||||||
|
return [pt[0], y_degrees];
|
||||||
|
}
|
||||||
|
|
||||||
// returns minx, maxx, miny, maxy
|
// returns minx, maxx, miny, maxy
|
||||||
function find_bounds(coords) {
|
function find_bounds(coords) {
|
||||||
return [
|
return [
|
||||||
|
|
Loading…
Reference in a new issue