0

I am trying to make a static, interactive map of Wisconsin counties.

I am using Albers Equal Area Conic projection and I have tried .rotate, .center, .fitExtent, but whenever I add these into the code, the map completely disappears.

Anyone know what could be going on?

Here's the code:

var margin = {top: 20, left: 20, bottom: 20, right: 20}
    height = 600- margin.top - margin.bottom,
    width = 960 - margin.left - margin.right;

var svg2 = d3.select("#map2").append("svg")
    .attr("height", height)
    .attr("width", width)
  .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.right + ")");

d3.queue()
  .defer(d3.json, "WiscCountiesNoProjection.json")
  .await(ready);

var projection2 = d3.geoAlbers()
  .translate([width/3, height/1])
  .scale(4000)

var path2 = d3.geoPath()
  .projection(projection2)

function ready (error, data) {
  var counties = topojson.feature(data, data.objects.WiscCounties).features

  svg2.selectAll(".counties")
    .data(counties)
    .enter().append("path")
      .attr("class", "counties")
      .attr("d", path2)

}

And here is what it looks like:

Screenshot of the SVG with my crooked Wisconsin

altocumulus
  • 21,179
  • 13
  • 61
  • 84
Casey
  • 21
  • 4

1 Answers1

1

You don't go into the details of how you're calling the different methods, but here's a few general tips on how to work with them:

fitExtent or the short hand version fitSize should definitely make your object appear on the SVG if you're not applying any other transformations. A minimum working example would be:

const proj = d3.geoAlbers()
        .fitSize([width, height], wisconsin)

That should result in a nicely fitted, albeit not correctly rotated Wisconsin. If it doesn't, wisconsin is not a valid GeoJSON object, ie not a FeatureCollection, single Feature or geometric object.

enter image description here

The next question is how to fix the rotation. For conic projections, as I understand, you generally want to find the center of your object of interest and rotate by the inverse of the longitude. A very friendly StackOverflow user explained the details here: https://stackoverflow.com/a/41133970/4745643

In the case of Wisconsin the center of the state has a longitude of almost exactly -90°, so we do this:

const proj = d3.geoAlbers()
    .rotate([90, 0, 0])
    .fitSize([width, height], wisconsin)

Note that we're rotating the map before we fit the object into our SVG. As a general rule of thumb, you should apply spherical transforms before zooming and fitting your map (I shall follow up with a more detailed explanation in a moment).

That should leave you with a nicely rotated and fitted state:

enter image description here

zinfandel
  • 428
  • 5
  • 12