Skip to content

Instantly share code, notes, and snippets.

@shawnbot
Last active September 26, 2019 06:50
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shawnbot/e6a857780ec2fe6002f7 to your computer and use it in GitHub Desktop.
Save shawnbot/e6a857780ec2fe6002f7 to your computer and use it in GitHub Desktop.
Leaflet + D3 Albers USA projection

This is an attempt to get Leaflet working with D3's Albers USA projection.

This first stab works deceptively well: the coordinates are at least self-consistent, so centering, panning and zooming work as expected. There are some problems, though:

  1. The d3.geo.albersUsa() projection appears to return null for coordinates that don't fall within its parallels, which Leaflet doesn't like.
  2. Likely related, something in Leaflet's bounding box calculation for the US GeoJSON produces NaNs and fails.
  3. The D3 projection's scale(.25) is a stab in the dark that makes the US approximately the right size at zoom 3, but is most certainly wrong.

In general, it's not clear whether we should be transforming D3's projection (which, according to the docs, doesn't support translation anyway) or Leaflet's transformation (currently a noop).

<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/leaflet.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/leaflet.css">
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
#map { width: 100%; height: 100%; }
</style>
</head>
<body>
<div id="map"></div>
<script src="map.js"></script>
</body>
var proj = d3.geo.albersUsa()
// .translate([0, 0])
.scale(.5);
var AlbersProjection = {
project: function(latLng) {
var point = proj([latLng.lng, latLng.lat]);
return point ?
new L.Point(point[0], point[1]) :
new L.Point(0, 0);
},
unproject: function(point) {
var latLng = proj.invert([point.x, point.y]);
return new L.LatLng(latLng[1], latLng[0]);
}
}
var AlbersCRS = L.extend({}, L.CRS, {
projection: AlbersProjection,
transformation: new L.Transformation(1, 0, 1, 0),
infinite: true
});
var center = [37.8, -96];
var map = new L.Map('map', {crs: AlbersCRS})
.setView(center, 3);
var layer;
d3.json("states.json", function(error, data) {
if (error) return console.error(error);
layer = L.geoJson(data, {
style: {
color: '#000',
weight: 1,
fillOpacity: 1,
fillColor: '#fff'
}
})
.addTo(map);
// map.fitBounds(layer.getBounds());
});
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment