3

I have a geoJSON file I'm trying to render using d3 but am having difficulty targeting the correct features for projection.

Currently I've been working quite a bit with the us.json file found in many of the d3 examples but the map I'm currently working on uses United States "Commuting Zones" (CZ's) instead of land, states, or counties.

I'm used to calling

topojson.feature(us, us.objects.states)

to display the correct layer however my file is not organized into objects and does not have multiple layers. Here is an excerpt from the geoJSON file I'm attempting to use:

{"type":"FeatureCollection","bbox":[-120.30602148510043,6.667736880597216,-70.95829310710806,34.46308750538215],"features":[{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-83.802805983004,22.64602264051764],[-83.8080569412408,22.638128812605782],

Here is my code that is unsuccessful at rendering:

d3.json("CZ90.zip.geojson", function(error, us) {
    if (error) throw error;

    d3.select("svg").append("path")
        .datum(topojson.feature(us, us.CZ90))
        .attr("d", d3.geo.path());
});

Since there are no objects I've omitted the ".object" and when I drop the file into Mapshaper it renders correctly with a layer titled "CZ90" which is how I got to writing "us.CZ90" instead of "us.objects.states"

I realize I'm calling "topojson.feature" instead of something geoJSON specific but I've also been unable to successfully convert the file to topoJSON in Mapshaper without losing the projection type/info.

What is the correct way to target this layer in the .datum call?

This whole issue would also be solved if I could locate a topoJSON file like the us.json that includes a commuting zones layer!

MatOwen11
  • 71
  • 1
  • 10

2 Answers2

3

Ended up getting some help from a developer friend of mine and the answer was so much simpler than my question made it out to be.

Seems as though d3.json() is natively suited to read the structure of my geoJSON file without using datum() All that was needed was to call:

d3.json("CZ90.zip.geojson", function(error, geoData) {
    d3.select("svg").append("path")
        .attr("d", path(geoData));
}

Note: this is using d3.v4

Here is the full script that was able to successfully render the map:

<!DOCTYPE html>
<meta charset="utf-8">
<style>
    path {
      fill: #ccc;
      stroke: #fff;
      stroke-linejoin: round;
    }
</style>

<svg width="960" height="500"></svg>
<script src="//d3js.org/d3.v4.min.js"></script>

<script>

var width = 960;
var height = 620;

var chosenProjection = d3.geoMercator()
  .scale(600)
  .translate([1300, 450])

  var path = d3.geoPath()
    .projection(chosenProjection);

d3.json("CZ90.zip.geojson", function(error, geoData) {

  d3.select("svg").append("path")
      .attr("d", path(geoData));
});

</script>

Hope this helps someone else stuck on such a simple roadblock!

MatOwen11
  • 71
  • 1
  • 10
0

I may be missing something here, but if you take a look at the topojson documentation, you'll note that topojson.feature:

Returns the GeoJSON Feature or FeatureCollection for the specified object in the given topology. If the specified object is a GeometryCollection, a FeatureCollection is returned, and each geometry in the collection is mapped to a Feature. Otherwise, a Feature is returned.

And in the d3 documentation you'll note that a d3 geopath:

Renders the given object, which may be any GeoJSON feature

So in regards to:

I realize I'm calling "topojson.feature" instead of something geoJSON specific

You are using something geoJSON specific already, you would only use topojson.js to convert your topoJSON back to geoJSON so that it can be used in a D3 map. So in response to your question:

What is the correct way to target this layer in the .datum call?

The correct way is to simply use:

.datum(us) // feature collection or single feature

This will append a single path, but if you want to append multiple paths with the same dataset (say for different coloring or mouse interaction):

.data(us.features) // feature collection
Andrew Reid
  • 37,021
  • 7
  • 64
  • 83
  • Apologies for my late response, appreciate the help! Finally getting around to posting the answer that I found for this issue below. – MatOwen11 Jul 18 '17 at 00:12