Skip to content

Commit cac8883

Browse files
committed
Merge branch 'albers-usa-invert' of git://github.com/jasondavies/d3 into 3.1.0
2 parents a7294db + 4ce9bff commit cac8883

5 files changed

Lines changed: 106 additions & 10 deletions

File tree

d3.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5515,13 +5515,17 @@ d3 = function() {
55155515
var alaska = d3.geo.albers().rotate([ 160, 0 ]).center([ 0, 60 ]).parallels([ 55, 65 ]);
55165516
var hawaii = d3.geo.albers().rotate([ 160, 0 ]).center([ 0, 20 ]).parallels([ 8, 18 ]);
55175517
var puertoRico = d3.geo.albers().rotate([ 60, 0 ]).center([ 0, 10 ]).parallels([ 8, 18 ]);
5518+
var alaskaInvert, hawaiiInvert, puertoRicoInvert;
55185519
function albersUsa(coordinates) {
55195520
return projection(coordinates)(coordinates);
55205521
}
55215522
function projection(point) {
55225523
var lon = point[0], lat = point[1];
55235524
return lat > 50 ? alaska : lon < -140 ? hawaii : lat < 21 ? puertoRico : lower48;
55245525
}
5526+
albersUsa.invert = function(coordinates) {
5527+
return alaskaInvert(coordinates) || hawaiiInvert(coordinates) || puertoRicoInvert(coordinates) || lower48.invert(coordinates);
5528+
};
55255529
albersUsa.scale = function(x) {
55265530
if (!arguments.length) return lower48.scale();
55275531
lower48.scale(x);
@@ -5537,10 +5541,25 @@ d3 = function() {
55375541
alaska.translate([ dx - .4 * dz, dy + .17 * dz ]);
55385542
hawaii.translate([ dx - .19 * dz, dy + .2 * dz ]);
55395543
puertoRico.translate([ dx + .58 * dz, dy + .43 * dz ]);
5544+
alaskaInvert = d3_geo_albersUsaInvert(alaska, [ [ -180, 50 ], [ -130, 72 ] ]);
5545+
hawaiiInvert = d3_geo_albersUsaInvert(hawaii, [ [ -164, 18 ], [ -154, 24 ] ]);
5546+
puertoRicoInvert = d3_geo_albersUsaInvert(puertoRico, [ [ -67.5, 17.5 ], [ -65, 19 ] ]);
55405547
return albersUsa;
55415548
};
55425549
return albersUsa.scale(lower48.scale());
55435550
};
5551+
function d3_geo_albersUsaInvert(projection, extent) {
5552+
var a = projection(extent[0]), b = projection([ .5 * (extent[0][0] + extent[1][0]), extent[0][1] ]), c = projection([ extent[1][0], extent[0][1] ]), d = projection(extent[1]);
5553+
var dya = b[1] - a[1], dxa = b[0] - a[0], dyb = c[1] - b[1], dxb = c[0] - b[0];
5554+
var ma = dya / dxa, mb = dyb / dxb;
5555+
var cx = .5 * (ma * mb * (a[1] - c[1]) + mb * (a[0] + b[0]) - ma * (b[0] + c[0])) / (mb - ma), cy = (.5 * (a[0] + b[0]) - cx) / ma + .5 * (a[1] + b[1]);
5556+
var dx0 = d[0] - cx, dy0 = d[1] - cy, dx1 = a[0] - cx, dy1 = a[1] - cy, r0 = dx0 * dx0 + dy0 * dy0, r1 = dx1 * dx1 + dy1 * dy1;
5557+
var a0 = Math.atan2(dy0, dx0), a1 = Math.atan2(dy1, dx1);
5558+
return function(coordinates) {
5559+
var dx = coordinates[0] - cx, dy = coordinates[1] - cy, r = dx * dx + dy * dy, a = Math.atan2(dy, dx);
5560+
if (r0 < r && r < r1 && a0 < a && a < a1) return projection.invert(coordinates);
5561+
};
5562+
}
55445563
function d3_geo_albers(φ0, φ1) {
55455564
var sinφ0 = Math.sin(φ0), n = (sinφ0 + Math.sin(φ1)) / 2, C = 1 + sinφ0 * (2 * n - sinφ0), ρ0 = Math.sqrt(C) / n;
55465565
function albers(λ, φ) {

d3.min.js

Lines changed: 5 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/geo/albers-usa.js

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
// TODO composite invert
2-
3-
// A composite projection for the United States, 960x500. The set of standard
1+
// A composite projection for the United States, 960×500. The set of standard
42
// parallels for each region comes from USGS, which is published here:
53
// http://egsc.usgs.gov/isb/pubs/MapProjections/projections.html#albers
64
d3.geo.albersUsa = function() {
@@ -21,6 +19,10 @@ d3.geo.albersUsa = function() {
2119
.center([0, 10])
2220
.parallels([8, 18]);
2321

22+
var alaskaInvert,
23+
hawaiiInvert,
24+
puertoRicoInvert;
25+
2426
function albersUsa(coordinates) {
2527
return projection(coordinates)(coordinates);
2628
}
@@ -34,6 +36,10 @@ d3.geo.albersUsa = function() {
3436
: lower48;
3537
}
3638

39+
albersUsa.invert = function(coordinates) {
40+
return alaskaInvert(coordinates) || hawaiiInvert(coordinates) || puertoRicoInvert(coordinates) || lower48.invert(coordinates);
41+
};
42+
3743
albersUsa.scale = function(x) {
3844
if (!arguments.length) return lower48.scale();
3945
lower48.scale(x);
@@ -52,8 +58,52 @@ d3.geo.albersUsa = function() {
5258
alaska.translate([dx - .40 * dz, dy + .17 * dz]);
5359
hawaii.translate([dx - .19 * dz, dy + .20 * dz]);
5460
puertoRico.translate([dx + .58 * dz, dy + .43 * dz]);
61+
62+
alaskaInvert = d3_geo_albersUsaInvert(alaska, [[-180, 50], [-130, 72]]);
63+
hawaiiInvert = d3_geo_albersUsaInvert(hawaii, [[-164, 18], [-154, 24]]);
64+
puertoRicoInvert = d3_geo_albersUsaInvert(puertoRico, [[-67.5, 17.5], [-65, 19]]);
65+
5566
return albersUsa;
5667
};
5768

5869
return albersUsa.scale(lower48.scale());
5970
};
71+
72+
function d3_geo_albersUsaInvert(projection, extent) {
73+
var a = projection(extent[0]),
74+
b = projection([.5 * (extent[0][0] + extent[1][0]), extent[0][1]]),
75+
c = projection([extent[1][0], extent[0][1]]),
76+
d = projection(extent[1]);
77+
78+
var dya = b[1]- a[1],
79+
dxa = b[0]- a[0],
80+
dyb = c[1]- b[1],
81+
dxb = c[0]- b[0];
82+
83+
var ma = dya / dxa,
84+
mb = dyb / dxb;
85+
86+
// Find center of circle going through points [a, b, c].
87+
var cx = .5 * (ma * mb * (a[1] - c[1]) + mb * (a[0] + b[0]) - ma * (b[0] + c[0])) / (mb - ma),
88+
cy = (.5 * (a[0] + b[0]) - cx) / ma + .5 * (a[1] + b[1]);
89+
90+
// Radial distance² from center.
91+
var dx0 = d[0] - cx,
92+
dy0 = d[1] - cy,
93+
dx1 = a[0] - cx,
94+
dy1 = a[1] - cy,
95+
r0 = dx0 * dx0 + dy0 * dy0,
96+
r1 = dx1 * dx1 + dy1 * dy1;
97+
98+
// Angular extent.
99+
var a0 = Math.atan2(dy0, dx0),
100+
a1 = Math.atan2(dy1, dx1);
101+
102+
return function(coordinates) {
103+
var dx = coordinates[0] - cx,
104+
dy = coordinates[1] - cy,
105+
r = dx * dx + dy * dy,
106+
a = Math.atan2(dy, dx);
107+
if (r0 < r && r < r1 && a0 < a && a < a1) return projection.invert(coordinates);
108+
};
109+
}

test/geo/albers-test.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,7 @@ var suite = vows.describe("d3.geo.albers");
77

88
suite.addBatch({
99
"albers": {
10-
topic: function() {
11-
return d3.geo.albers();
12-
},
10+
topic: d3.geo.albers,
1311
"Arctic": function(albers) {
1412
var coords = albers([0, 85]);
1513
assert.inDelta(coords[0], 1031.393796, 1e-6);

test/geo/albers-usa-test.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
require("../env");
2+
3+
var vows = require("vows"),
4+
assert = require("../env-assert");
5+
6+
var suite = vows.describe("d3.geo.albersUsa");
7+
8+
suite.addBatch({
9+
"albersUsa": {
10+
topic: d3.geo.albersUsa,
11+
"Washington": equalInverse([-120.5, 47.5], [215.478997, 51.976493]),
12+
"San Francisco": equalInverse([-122.42, 37.78], [150.072677, 211.257829]),
13+
"Juneau, Alaska": equalInverse([-134.22, 58.43], [217.366590, 409.498517]),
14+
"Honolulu, Hawaii": equalInverse([-157.82, 21.30], [325.696002, 427.278824]),
15+
"San Juan, Puerto Rico": equalInverse([-66.07, 18.45], [909.159250, 456.394827])
16+
}
17+
});
18+
19+
suite.export(module);
20+
21+
function equalInverse(location, point) {
22+
return function(projection) {
23+
var projected;
24+
assert.inDelta(projected = projection(location), point, 1e-6);
25+
assert.inDelta(projection.invert(projected), location, 1e-6);
26+
assert.inDelta(projection(projection.invert(point)), point, 1e-6);
27+
};
28+
};

0 commit comments

Comments
 (0)