You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
98 lines
3.0 KiB
98 lines
3.0 KiB
import {geoProjectionMutator as projectionMutator} from "d3-geo";
|
|
import {acos, asin, atan2, cos, degrees, epsilon, halfPi, max, min, pi, radians, sin, sqrt, tan} from "./math.js";
|
|
|
|
function wagnerFormula(cx, cy, m1, m2, n) {
|
|
function forward(lambda, phi) {
|
|
var s = m1 * sin(m2 * phi),
|
|
c0 = sqrt(1 - s * s),
|
|
c1 = sqrt(2 / (1 + c0 * cos(lambda *= n)));
|
|
return [
|
|
cx * c0 * c1 * sin(lambda),
|
|
cy * s * c1
|
|
];
|
|
}
|
|
|
|
forward.invert = function(x, y) {
|
|
var t1 = x / cx,
|
|
t2 = y / cy,
|
|
p = sqrt(t1 * t1 + t2 * t2),
|
|
c = 2 * asin(p / 2);
|
|
return [
|
|
atan2(x * tan(c), cx * p) / n,
|
|
p && asin(y * sin(c) / (cy * m1 * p)) / m2
|
|
];
|
|
};
|
|
|
|
return forward;
|
|
}
|
|
|
|
export function wagnerRaw(poleline, parallels, inflation, ratio) {
|
|
// 60 is always used as reference parallel
|
|
var phi1 = pi / 3;
|
|
|
|
// sanitizing the input values
|
|
// poleline and parallels may approximate but never equal 0
|
|
poleline = max(poleline, epsilon);
|
|
parallels = max(parallels, epsilon);
|
|
// poleline must be <= 90; parallels may approximate but never equal 180
|
|
poleline = min(poleline, halfPi);
|
|
parallels = min(parallels, pi - epsilon);
|
|
// 0 <= inflation <= 99.999
|
|
inflation = max(inflation, 0);
|
|
inflation = min(inflation, 100 - epsilon);
|
|
// ratio > 0.
|
|
// sensible values, i.e. something that renders a map which still can be
|
|
// recognized as world map, are e.g. 20 <= ratio <= 1000.
|
|
ratio = max(ratio, epsilon);
|
|
|
|
// convert values from boehm notation
|
|
// areal inflation e.g. from 0 to 1 or 20 to 1.2:
|
|
var vinflation = inflation/100 + 1;
|
|
// axial ratio e.g. from 200 to 2:
|
|
var vratio = ratio / 100;
|
|
// the other ones are a bit more complicated...
|
|
var m2 = acos(vinflation * cos(phi1)) / phi1,
|
|
m1 = sin(poleline) / sin(m2 * halfPi),
|
|
n = parallels / pi,
|
|
k = sqrt(vratio * sin(poleline / 2) / sin(parallels / 2)),
|
|
cx = k / sqrt(n * m1 * m2),
|
|
cy = 1 / (k * sqrt(n * m1 * m2));
|
|
|
|
return wagnerFormula(cx, cy, m1, m2, n);
|
|
}
|
|
|
|
export default function wagner() {
|
|
// default values generate wagner8
|
|
var poleline = 65 * radians,
|
|
parallels = 60 * radians,
|
|
inflation = 20,
|
|
ratio = 200,
|
|
mutate = projectionMutator(wagnerRaw),
|
|
projection = mutate(poleline, parallels, inflation, ratio);
|
|
|
|
projection.poleline = function(_) {
|
|
return arguments.length ? mutate(poleline = +_ * radians, parallels, inflation, ratio) : poleline * degrees;
|
|
};
|
|
|
|
projection.parallels = function(_) {
|
|
return arguments.length ? mutate(poleline, parallels = +_ * radians, inflation, ratio) : parallels * degrees;
|
|
};
|
|
projection.inflation = function(_) {
|
|
return arguments.length ? mutate(poleline, parallels, inflation = +_, ratio) : inflation;
|
|
};
|
|
projection.ratio = function(_) {
|
|
return arguments.length ? mutate(poleline, parallels, inflation, ratio = +_) : ratio;
|
|
};
|
|
|
|
return projection
|
|
.scale(163.775);
|
|
}
|
|
|
|
export function wagner7() {
|
|
return wagner()
|
|
.poleline(65)
|
|
.parallels(60)
|
|
.inflation(0)
|
|
.ratio(200)
|
|
.scale(172.633);
|
|
}
|
|
|