1

Here's an example of my problem. Eventually this is going to have county/zipcode info drawn on it.

I create a projection and a geo path:

var projection = d3.geo.albersUsa()
  .scale(width * 1.3)
  .translate([width / 2, height / 2]);

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

However when I try to add state borders... this happens:

enter image description here

#state-borders {
    fill: none;
    stroke: #333;
    stroke-width: 1.5px;
    stroke-linejoin: round;
    stroke-linecap: round;
    pointer-events: none;
}


svg.append('path')
  .datum(topojson.mesh(states, states.objects.states, function(a, b) { return a !== b; }))
.attr('id', 'state-borders')
.attr('d', path);

I've looked at other examples and they all seem to be doing something similar, I can't figure out what I am doing wrong. Its almost like the stroke-livejoin isnt working at all.

Andrew Reid
  • 37,021
  • 7
  • 64
  • 83
user603680
  • 63
  • 1
  • 5

1 Answers1

0

Your geographic data is already projected; it does not need to be projected again. A projection takes unprojected points on a 3d globe and projects them to a 2d space, doing this on data that is already 2d won't work.

Your data doesn't comprise of 3d points (with a coordinate space measured in degrees), but rather has 2d points (with a coordinate space measured in pixels). So we can just use an identity transform as there is no need to modify/project/transform the coordinates. In d3v4+ we could use:

var path = d3.geoPath(); // default projection is an identity

But with d3v3, the default projection of a geo path is AlbersUsa. So we need to explicitly state we don't want a projection:

var path = d3.geo.path().projection(null);

This gives us a working fiddle.

That this file is pre-pojected is not immediately self evident. Generally a map that looks like a ball of yarn is a good indicator that you are projecting already projected data.

Now we may have new problems, working with pre-projected geometry can make sizing difficult, more so in d3v3 - this file is intended for a 960x600 viewport. To automatically scale and center a map based on its features see this quesion, several of the answers are meant for v3 of d3 (a,b). But this gets much easier with the fitSize method that you can use in d3v4+, as described in this answer. And for more of a discussion of working pre-projected geometry there is this question. If you intend on overlaying features on top of the preprojected geometry you are probably best to find an unprojected US topo/geojson to simplify things, as discussed here.

Andrew Reid
  • 37,021
  • 7
  • 64
  • 83
  • Thank you. I was doing the projection because it was the only way I had yet figured out how to scale the map to the size I wanted. Sadly I am stuck on d3v3 for the foreseeable future. I am going to do some more reading on some of the additional stuff you posted now. – user603680 Oct 22 '19 at 17:34