Skip to content

Commit

Permalink
projections wip
Browse files Browse the repository at this point in the history
  • Loading branch information
neocarto committed Dec 3, 2024
1 parent c1a4fef commit 6ca10b4
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 0 deletions.
16 changes: 16 additions & 0 deletions src/projection/hoaxiaoguang.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { geoHufnagel } from "d3-geo-projection";
const d3 = Object.assign({}, { geoHufnagel });

// Approximative projection of HoaXiaoguang (thanks to Fil/@recifs)

export function HoaXiaoguang() {
const projection = d3
.geoHufnagel()
.a(0.8)
.b(0.35)
.psiMax(50)
.ratio(1.6)
.angle(90)
.rotate([110, -200, 90]);
return projection;
}
12 changes: 12 additions & 0 deletions src/projection/polar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { geoAzimuthalEquidistant } from "d3-geo";
const d3 = Object.assign({}, { geoAzimuthalEquidistant });

export function Polar() {
const projection = d3
.geoAzimuthalEquidistant()
.scale(190)
.rotate([0, -90])
.clipAngle(150);

return projection;
}
76 changes: 76 additions & 0 deletions src/projection/spilhaus.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// Thanks to Torben Jansen.
// See https://observablehq.com/@toja/spilhaus-world-ocean-map-in-a-square

//import * as d3geo from "d3-geo";
import { geoProjection } from "d3-geo";
const d3 = Object.assign({}, { geoProjection });

function ellipticF(phi, m) {
const { abs, atan, ln, PI: pi, sin, sqrt } = Math;
const C1 = 10e-4,
C2 = 10e-10,
TOL = 10e-6;
const sp = sin(phi);

let k = sqrt(1 - m),
h = sp * sp;

// "complete" elliptic integral
if (h >= 1 || abs(phi) === pi / 2) {
if (k <= TOL) return sp < 0 ? -Infinity : Infinity;
(m = 1), (h = m), (m += k);
while (abs(h - k) > C1 * m) {
k = sqrt(h * k);
(m /= 2), (h = m), (m += k);
}
return sp < 0 ? -pi / m : pi / m;
}
// "incomplete" elliptic integral
else {
if (k <= TOL) return ln((1 + sp) / (1 - sp)) / 2;
let g, n, p, r, y;
(m = 1), (n = 0), (g = m), (p = m * k), (m += k);
y = sqrt((1 - h) / h);
if (abs((y -= p / y)) <= 0) y = C2 * sqrt(p);
while (abs(g - k) > C1 * g) {
(k = 2 * sqrt(p)), (n += n);
if (y < 0) n += 1;
(p = m * k), (g = m), (m += k);
if (abs((y -= p / y)) <= 0) y = C2 * sqrt(p);
}
if (y < 0) n += 1;
r = (atan(m / y) + pi * n) / m;
return sp < 0 ? -r : r;
}
}

function ellipticFactory(a, b, sm, sn) {
let m = Math.asin(Math.sqrt(1 + Math.min(0, Math.cos(a + b))));
if (sm) m = -m;

let n = Math.asin(Math.sqrt(Math.abs(1 - Math.max(0, Math.cos(a - b)))));
if (sn) n = -n;

return [ellipticF(m, 0.5), ellipticF(n, 0.5)];
}

//export function Spilhaus() {
const { abs, max, min, sin, cos, asin, acos, tan } = Math;

function spilhausSquareRaw(lambda, phi) {
let a, b, sm, sn, xy;
const sp = tan(0.5 * phi);
a = cos(asin(sp)) * sin(0.5 * lambda);
sm = sp + a < 0;
sn = sp - a < 0;
b = acos(sp);
a = acos(a);

return ellipticFactory(a, b, sm, sn);
}

export function Spilhaus() {
return d3
.geoProjection(spilhausSquareRaw)
.rotate([-66.94970198, 49.56371678, 40.17823482]);
}
20 changes: 20 additions & 0 deletions src/projection/stringtod3proj.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import * as d3geo from "d3-geo";
import * as d3geoprojection from "d3-geo-projection";
const d3 = Object.assign({}, d3geo, d3geoprojection);

export function stringtod3proj(string) {
let str = string;
str = str.replace(/\s/g, "");

if (str.substring(0, 6) !== "d3.geo") {
if (str.indexOf(".") === -1) {
str += "()";
} else {
str = str.replace(".", "().");
}
str = "d3.geo" + str;
}

const createProjection = new Function("d3", `return (${str})`);
return createProjection(d3);
}

0 comments on commit 6ca10b4

Please sign in to comment.