Fix projection (mercator) and centering

main
Chandler Swift 2024-03-05 23:27:09 -06:00
parent 31cd14cd86
commit 70c954d4fa
Signed by: chandlerswift
GPG Key ID: A851D929D52FB93F
1 changed files with 19 additions and 4 deletions

View File

@ -126,7 +126,7 @@
const cities = await response.json();
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_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) {
console.error("Unable to find state in shapes");
}
@ -169,14 +169,21 @@
const ctx = canvas.getContext("2d");
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) {
// TODO: this just works for MN, and not very well at that
return [(pt[0]+98)*80, 600-(pt[1]-42)*80];
pt = mercator(pt)
return [scale * (pt[0] - x_offset), canvas.height - (scale * (pt[1] - y_offset))];
}
ctx.beginPath();
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)) {
ctx.lineTo(...transform(coord));
}
@ -194,6 +201,14 @@
}).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
function find_bounds(coords) {
return [