Skip to content

Commit f2c2c42

Browse files
committed
Better fix for d3.geo.conicConformal.
Rather than clamping latitudes to ±(π/2 - ε), we preserve infinite coordinates and correct the issue where 0 * Infinity resulted in NaN; instead we substitute 0, which appears to fix the problem in d3#1802. Includes tests and a fix for the inverse projection.
1 parent fa55eea commit f2c2c42

4 files changed

Lines changed: 22 additions & 17 deletions

File tree

d3.js

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4595,17 +4595,12 @@
45954595
}, n = φ0 === φ1 ? Math.sin(φ0) : Math.log(cosφ0 / Math.cos(φ1)) / Math.log(t(φ1) / t(φ0)), F = cosφ0 * Math.pow(t(φ0), n) / n;
45964596
if (!n) return d3_geo_mercator;
45974597
function forward(λ, φ) {
4598-
if (F > 0) {
4599-
if (φ < -halfπ + ε) φ = -halfπ + ε;
4600-
} else {
4601-
if (φ > halfπ - ε) φ = halfπ - ε;
4602-
}
46034598
var ρ = F / Math.pow(t(φ), n);
4604-
return [ ρ * Math.sin(n * λ), F - ρ * Math.cos(n * λ) ];
4599+
return [ ρ * Math.sin(n * λ) || 0, F - (ρ * Math.cos(n * λ) || 0) ];
46054600
}
46064601
forward.invert = function(x, y) {
46074602
var ρ0_y = F - y, ρ = d3_sgn(n) * Math.sqrt(x * x + ρ0_y * ρ0_y);
4608-
return [ Math.atan2(x, ρ0_y) / n, 2 * Math.atan(Math.pow(F / ρ, 1 / n)) - halfπ ];
4603+
return [ Math.atan(x / ρ0_y) / n, 2 * Math.atan(Math.pow(F / ρ, 1 / n)) - halfπ ];
46094604
};
46104605
return forward;
46114606
}

d3.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/geo/conic-conformal.js

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,18 @@ function d3_geo_conicConformal(φ0, φ1) {
1313
if (!n) return d3_geo_mercator;
1414

1515
function forward(λ, φ) {
16-
if (F > 0) { if (φ < -halfπ + ε) φ = -halfπ + ε; }
17-
else { if (φ > halfπ - ε) φ = halfπ - ε; }
1816
var ρ = F / Math.pow(t(φ), n);
1917
return [
20-
ρ * Math.sin(n * λ),
21-
F - ρ * Math.cos(n * λ)
18+
ρ * Math.sin(n * λ) || 0,
19+
F - (ρ * Math.cos(n * λ) || 0)
2220
];
2321
}
2422

2523
forward.invert = function(x, y) {
2624
var ρ0_y = F - y,
2725
ρ = d3_sgn(n) * Math.sqrt(x * x + ρ0_y * ρ0_y);
2826
return [
29-
Math.atan2(x, ρ0_y) / n,
27+
Math.atan(x / ρ0_y) / n,
3028
2 * Math.atan(Math.pow(F / ρ, 1 / n)) - halfπ
3129
];
3230
};

test/geo/conic-conformal-test.js

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,20 @@ suite.addBatch({
1717
"Svalbard": [[ 3.13977663, 61.55241523], [ 483.99106549, 103.34182093]],
1818
"Tierra del Fuego": [[ -35.62300462, -60.29317484], [ 295.79559728, 507.67642324]],
1919
"Tokyo": [[ 33.38709832, 79.49539834], [ 504.49928992, 42.36530945]],
20-
"the South Pole": [[ 0.00000000, -85.00000000], [ 480.00000000, 1446.12378227]],
21-
"the North Pole": [[ 0.00000000, 85.00000000], [ 480.00000000, 19.84318514]]
20+
"the South Pole": [[ 0.00000000, -90.00000000], [ 480.00000000, Infinity]],
21+
"the North Pole": [[ 0.00000000, 90.00000000], [ 480.00000000, -34.99529321]]
22+
}),
23+
"parallels([0°, -60°])": projectionTestSuite({
24+
topic: function(projection) { return projection().parallels([0, -60]); }
25+
}, {
26+
"Null Island": [[ 0.00000000, 0.00000000], [ 480.00000000, 250.00000000]],
27+
"Honolulu, HI": [[ -21.01262744, 82.63349103], [ 248.39124508, -649.96173174]],
28+
"San Francisco, CA": [[ -46.16620803, 77.04946507], [ 111.38073983, -281.46645354]],
29+
"Svalbard": [[ 3.13977663, 61.55241523], [ 496.92487516, -51.64965196]],
30+
"Tierra del Fuego": [[ -35.62300462, -60.29317484], [ 434.44451342, 400.78745879]],
31+
"Tokyo": [[ 33.38709832, 79.49539834], [ 782.19072440, -419.22243596]],
32+
"the South Pole": [[ 0.00000000, -90.00000000], [ 480.00000000, 534.99529404]],
33+
"the North Pole": [[ 0.00000000, 90.00000000], [ 480.00000000, -97309246408.21453857]] // ≈∞
2234
}),
2335
"translated to 0,0 and at scale 1": projectionTestSuite({
2436
topic: function(projection) { return projection().translate([0, 0]).scale(1); }
@@ -29,8 +41,8 @@ suite.addBatch({
2941
"Svalbard": [[ 3.13977663, 61.55241523], [ 0.02660710, -0.97772119]],
3042
"Tierra del Fuego": [[ -35.62300462, -60.29317484], [ -1.22802935, 1.71784282]],
3143
"Tokyo": [[ 33.38709832, 79.49539834], [ 0.16332860, -1.38423127]],
32-
"the South Pole": [[ 0.00000000, -85.00000000], [ 0.00000000, 7.97415855]],
33-
"the North Pole": [[ 0.00000000, 85.00000000], [ 0.00000000, -1.53437877]]
44+
"the South Pole": [[ 0.00000000, -90.00000000], [ 0.00000000, Infinity]],
45+
"the North Pole": [[ 0.00000000, 90.00000000], [ 0.00000000, -1.89996862]]
3446
})
3547
}
3648
});

0 commit comments

Comments
 (0)