[GIS] D3: center a map feature using correct latitude and longitude, without rotation

d3javascriptlatitude longitude

The following is a map of Chicago which I've created in D3.js, and the JS code to render it.

I had a very hard time centering Chicago within my viewfinder (the white box). After much trial and error, I was finally able to make it work, with the long/lat of [8.25, 41.88205] and a rotation of [92.35, .5, -4], using the Albers projection. This seems weird to me, since the long/lat of Chicago should be [87.627815, 41.88205].

So, my questions are: what is up with the 8.25 longitude? Why doesn't D3 center Chicago on my screen simply with the long/lat of [87.627815, 41.88205]? And why do I need to apply the rotation at all?

BTW, the community_areas_sm.geojson file comes off the City of Chicago website, and contains correct long/lat values.

D3 map of Chicago

<script>
var width = 600,
    height = 750

var svg = d3.select("#map").append("svg")
    .attr("width", width)
    .attr("height", height)

var map = d3.json(
    "/static/data/community_areas_sm.geojson", function(error, map) {
        if (error) return console.error(error)

        var proj = d3.geo.albers()
            .center([8.25, 41.88205])
            .parallels([40, 45])
            .scale(105000)
            .rotate([92.35, .5, -4])
            .translate([width / 2, height / 2])

        svg.selectAll("path")
            .data(map.features)
            .enter().append("path")
            .attr("d", d3.geo.path().projection(proj))
        }
    )
</script>

Best Answer

Rotation is necessary because d3.geo.albers defaults to centering on the middle of the US (center and rotate are used in that block but they match the defaults).

I haven't seen a clear explanation of this in the d3 docs but here's what I've pieced together using d3.geo for various things: use rotate to spin the globe to your area of interest. Most of the time (all the time?) this means changing longitude only. The longitude sent to rotate should be the longitude you want to be the center of your map AKA the central meridian. After rotate, you can shift the center of your map in either direction but it's common to specify longitude as 0 (since your map is already where you want it in the x direction) and use latitude to shift your map's center north or south. You can see this in the Let's Make a Map tutorial.

As for the latitude of 8.25, I think that's getting the map back to Chicago after rotating in three directions ([92.35, .5, -4]). I don't know enough to give a mathematical explanation but that's my guess.

If you create your projection like so:

var proj = d3.geo.albers()
  .center([0, 41.83])
  .rotate([87.65, 0])
  .parallels([40, 45])
  .scale(30000)
  .translate([w / 2, h / 2])

you'll be centered on Chicago.

Related Question