block by syntagmatic 2005817

Albers to Azimuthal

Full Screen

index.html

<!DOCTYPE html>
<html>
  <head>
    <title>Projection Demo</title>
    <script type='text/javascript' src='//mbostock.github.com/d3/d3.v2.js'></script>
    <style type='text/css'>
      body {
        margin:5px auto;
      }
      h1 {
        font:20px/20px "Helvetica Neue";
        margin:0;
      }
      p {
        color:#333;
        font:12px/15px "Helvetica Neue";
      }

      circle.albers {
        fill:#005982;
      }

      circle.ortho {
        fill:#971c20;
      }

      path.connect {
        fill:none;
        stroke-width:0.2;
        stroke:#aaa;
      }
    </style>
  </head>
  <body>
    <h2><span id='account-name'></span></h2>
    <h1>Albers to Orthographic Projection</h1>
    <p>Map projections are transformations between one shape to another,
    often a 2d surface like a screen or printout. Below is an albers projection
    alongside an orthographic (azimuthal) projection, and a mapping of points -
    every 10 degrees latitude and longitude, between the two.. This is made with <a href='//mbostock.github.com/d3/'>d3</a>. Adapted from <a href="//bl.ocks.org/1653763">Mercator to Orthographic</a></p>

    <div id='chart'></div>
    <script type='text/javascript' src='site.js'></script>
  </body>
</html>

site.js

// set multiple attrs with an object
var set_attrs = function(object, hash) {
  for (var key in hash) {
   object.attr(key, hash[key]);
 }
};

window.onload = function() {
  merc = d3.geo.mercator()
    .scale(400)
    .translate([200, 200]);

  albers = d3.geo.albers()
    .scale(60)
    .translate([180, 250]);

  ortho = d3.geo.azimuthal()
      .scale(140)
      .origin([-71.03, 0])
      .mode("orthographic")
      .translate([600, 200]);

  var merc_path = d3.geo.path()
    .projection(merc);

  var albers_path = d3.geo.path()
    .projection(albers);

  var ortho_path = d3.geo.path()
    .projection(ortho);

  var merc_attrs = {
    'class': 'merc',
    r: 1,
    transform: function(d) { return 'translate(' + merc(d).join(',') + ')'; }
  };

  var albers_attrs = {
    'class': 'albers',
    r: 1,
    transform: function(d) { return 'translate(' + albers(d).join(',') + ')'; }
  };

  var ortho_attrs = {
    'class': 'ortho',
    r: 1,
    transform: function(d) { return 'translate(' + ortho(d).join(',') + ')'; }
  };

  var connection_attrs = {
    'class': 'connect',
    'd': function(d) { return 'M' + albers(d).join(' ') + 'L' + ortho(d).join(' ') +  'z'; }
  };

  var w = 780,
      h = 500;

  var svg = d3.select("#chart").append("svg:svg")
    .attr("width",  w)
    .attr("height", h);

  var points = [];
  for (var lon = -180; lon < 180; lon += 10) {
      for (var lat = -90; lat < 90; lat += 10) {
          points.push([lon, lat]);
      }
  }

  svg.selectAll("circle.merc")
    .data(points)
    .enter()
    .append('svg:circle')
    .call(set_attrs, albers_attrs);

  var ortho_drawn = svg.selectAll("circle.ortho")
    .data(points)
    .enter()
    .append('svg:circle')
    .call(set_attrs, ortho_attrs);

  var connections = svg.selectAll("path.connect")
    .data(points)
    .enter()
    .append('svg:path')
    .call(set_attrs, connection_attrs);

  svg.on('mousemove', function() {
    var x = ((d3.event.pageX / w) * 360) - 180;
    var y = ((d3.event.pageY / h) * 360) - 180;

    ortho.origin([x, y]);

    ortho_drawn.attr('transform', function(d) {
      return 'translate(' + ortho(d).join(',') + ')';
    });
    connections.attr('d', function(d) {
      return 'M' + albers(d).join(' ') + 'L' + ortho(d).join(' ') +  'z';
    });
  });

};