source: Dev/trunk/d3/src/geo/albers.js @ 76

Last change on this file since 76 was 76, checked in by fpvanagthoven, 14 years ago

d3

File size: 3.0 KB
Line 
1// Derived from Tom Carden's Albers implementation for Protovis.
2// http://gist.github.com/476238
3// http://mathworld.wolfram.com/AlbersEqual-AreaConicProjection.html
4
5d3.geo.albers = function() {
6  var origin = [-98, 38],
7      parallels = [29.5, 45.5],
8      scale = 1000,
9      translate = [480, 250],
10      lng0, // d3_radians * origin[0]
11      n,
12      C,
13      p0;
14
15  function albers(coordinates) {
16    var t = n * (d3_radians * coordinates[0] - lng0),
17        p = Math.sqrt(C - 2 * n * Math.sin(d3_radians * coordinates[1])) / n;
18    return [
19      scale * p * Math.sin(t) + translate[0],
20      scale * (p * Math.cos(t) - p0) + translate[1]
21    ];
22  }
23
24  function reload() {
25    var phi1 = d3_radians * parallels[0],
26        phi2 = d3_radians * parallels[1],
27        lat0 = d3_radians * origin[1],
28        s = Math.sin(phi1),
29        c = Math.cos(phi1);
30    lng0 = d3_radians * origin[0];
31    n = .5 * (s + Math.sin(phi2));
32    C = c * c + 2 * n * s;
33    p0 = Math.sqrt(C - 2 * n * Math.sin(lat0)) / n;
34    return albers;
35  }
36
37  albers.origin = function(x) {
38    if (!arguments.length) return origin;
39    origin = [+x[0], +x[1]];
40    return reload();
41  };
42
43  albers.parallels = function(x) {
44    if (!arguments.length) return parallels;
45    parallels = [+x[0], +x[1]];
46    return reload();
47  };
48
49  albers.scale = function(x) {
50    if (!arguments.length) return scale;
51    scale = +x;
52    return albers;
53  };
54
55  albers.translate = function(x) {
56    if (!arguments.length) return translate;
57    translate = [+x[0], +x[1]];
58    return albers;
59  };
60
61  return reload();
62};
63
64// A composite projection for the United States, 960x500. The set of standard
65// parallels for each region comes from USGS, which is published here:
66// http://egsc.usgs.gov/isb/pubs/MapProjections/projections.html#albers
67// TODO allow the composite projection to be rescaled?
68d3.geo.albersUsa = function() {
69  var lower48 = d3.geo.albers();
70
71  var alaska = d3.geo.albers()
72      .origin([-160, 60])
73      .parallels([55, 65]);
74
75  var hawaii = d3.geo.albers()
76      .origin([-160, 20])
77      .parallels([8, 18]);
78
79  var puertoRico = d3.geo.albers()
80      .origin([-60, 10])
81      .parallels([8, 18]);
82
83  function albersUsa(coordinates) {
84    var lon = coordinates[0],
85        lat = coordinates[1];
86    return (lat < 25
87        ? (lon < -100 ? hawaii : puertoRico)
88        : (lat > 50 ? alaska : lower48))(coordinates);
89  }
90
91  albersUsa.scale = function(x) {
92    if (!arguments.length) return lower48.scale();
93    lower48.scale(x);
94    alaska.scale(x * .6);
95    hawaii.scale(x);
96    puertoRico.scale(x * 1.5);
97    return albersUsa.translate(lower48.translate());
98  };
99
100  albersUsa.translate = function(x) {
101    if (!arguments.length) return lower48.translate();
102    var dz = lower48.scale() / 1000,
103        dx = x[0],
104        dy = x[1];
105    lower48.translate(x);
106    alaska.translate([dx - 400 * dz, dy + 170 * dz]);
107    hawaii.translate([dx - 190 * dz, dy + 200 * dz]);
108    puertoRico.translate([dx + 580 * dz, dy + 430 * dz]);
109    return albersUsa;
110  };
111
112  return albersUsa.scale(lower48.scale());
113};
114
115var d3_radians = Math.PI / 180;
Note: See TracBrowser for help on using the repository browser.