Skip to content

Instantly share code, notes, and snippets.

@shawnbot
Last active August 29, 2015 14:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shawnbot/69a713cc4ef753c574db to your computer and use it in GitHub Desktop.
Save shawnbot/69a713cc4ef753c574db to your computer and use it in GitHub Desktop.
Weird topology artifacts
<!DOCTYPE html>
<html lang="en">
<head>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://d3js.org/topojson.v1.min.js"></script>
<style>
body {
margin: 0;
padding: 1em;
}
p {
margin: 0 0 1em 0;
}
svg {
max-width: 960px;
}
path.feature {
fill: yellow;
fill-opacity: .05;
stroke: red;
}
path.mesh {
fill: none;
stroke: #69c;
}
</style>
</head>
<body>
<p>
These maps demonstrate a peculiar rendering artifact of
<a target="_top" href="https://github.com/18F/eiti-data/blob/fa02b34b9f67d72474abda8d0cc319ef7d6a09d4/output/geo/offshore.json">this
offshore US areas topology</a>. The <b style="color: red">red</b> lines
are the GeoJSON geometries extracted with <tt>topojson.feature()</tt>,
and the <b style="color: #69c">bluish</b> ones are the topological meshes
courtesy of <tt>topojson.mesh()</tt>, with a slight offset to make them
more visible. The features are also drawn with a very transparent yellow
fill to make overlaps more obvious.
</p>
<p>
As you can see, the state boundaries from
<a target="_top" href="https://github.com/18F/eiti-data/blob/gh-pages/output/geo/us-states-simple.json">this
topology</a> look great in the first map:
</p>
<svg id="onshore"></svg>
<p>
In this map, however, you can see two things: First, that all of the
features are being drawn on top of each other across the outer clip
extent of the projection. Second, you can see that the
<tt>topojson.feature()</tt> is producing polygons with rings that
coincide with <i>each</i> of the <a target="_top" href="https://github.com/mbostock/d3/wiki/Geo-Projections#albersUsa">Albers USA</a>
clip extents for the lower 48, Alaska and Hawaii:
</p>
<svg id="offshore"></svg>
</body>
<script>
var proj = d3.geo.albersUsa();
var path = d3.geo.path()
.projection(proj);
d3.json('us-states.json', function(error, onshore) {
if (error) return alert(error.responseText);
var states = render('#onshore', onshore);
d3.json('offshore.json', function(error, offshore) {
if (error) return alert(error.responseText);
var regions = render('#offshore', offshore);
var height = document.body.getBoundingClientRect().height;
d3.select(self.frameElement).style('height', ~~height + 'px');
});
});
function render(selector, collection) {
var meshes = [];
var features = [];
if (collection.type === 'Topology') {
features = Object.keys(collection.objects)
.reduce(function(features, key) {
var obj = collection.objects[key];
var feature = topojson.feature(collection, obj);
var mesh = topojson.mesh(collection, obj);
mesh.id = key;
meshes.push(mesh);
return features.concat(feature.features);
}, []);
} else {
features = collection.features;
}
var svg = d3.select(selector)
.attr('viewBox', '0 0 960 510');
svg.selectAll('path.feature')
.data(features)
.enter()
.append('path')
.attr('class', 'feature')
.attr('id', function(d) { return d.id; })
.attr('d', path);
svg.selectAll('path.mesh')
.data(meshes)
.enter()
.append('path')
.attr('class', 'mesh')
.attr('transform', 'translate(4,4)')
.attr('id', function(d) { return d.id; })
.attr('d', path);
return features;
}
</script>
</html>
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.
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