Quick demo of getting regions into a world map. Not performant.
<!DOCTYPE html>
<meta charset="utf-8">
<style>
canvas {
background: #eee;
}
</style>
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="//d3js.org/topojson.v1.min.js"></script>
<body>
<script>
var width = 960,
height = 960;
var scale,
translate,
area; // minimum area threshold for simplification
var clip = d3.geo.clipExtent()
.extent([[0, 0], [width, height]]);
var simplify = d3.geo.transform({
point: function(x, y, z) {
if (z >= area) this.stream.point(x * scale + translate[0], y * scale + translate[1]);
}
});
var zoom = d3.behavior.zoom()
.translate([0, 0])
.scale(1)
.scaleExtent([1, 8]);
var canvas = d3.select("body").append("canvas")
.attr("width", width)
.attr("height", height);
var context = canvas.node().getContext("2d");
context.lineJoin = "round";
context.lineCap = "round";
var path = d3.geo.path()
.projection({stream: function(s) { return simplify.stream(clip.stream(s)); }})
.context(context);
d3.json("world.json", function(error, world) {
if (error) throw error;
topojson.presimplify(world);
var sphere = topojson.feature(world, world.objects.sphere),
land = topojson.feature(world, world.objects.land),
boundary = topojson.mesh(world, world.objects.countries, function(a, b) { return a !== b; }),
provinces = topojson.feature(world, world.objects.provinces);
canvas
.call(zoom.on("zoom", zoomed))
.call(zoom.event);
function zoomed() {
translate = zoom.translate();
scale = zoom.scale();
area = 1 / scale / scale;
context.clearRect(0, 0, width, height);
context.save();
context.beginPath();
path(sphere);
context.fillStyle = "#fff";
context.fill();
context.beginPath();
path(land);
context.fillStyle = "#000";
context.fill();
context.beginPath();
path(boundary);
context.strokeStyle = "#f00";
context.stroke();
provinces.features.forEach(function(province) {
context.beginPath();
path(province);
context.fillStyle = d3.rgb(Math.random() * 255, Math.random() * 255, Math.random() * 255).toString();
context.fill();
})
context.restore();
}
});
d3.select(self.frameElement).style("height", height + "px");
</script>
GENERATED_FILES = \
world.json
all: $(GENERATED_FILES)
clean:
rm -rf -- %(GENERATED_FILES)
.PHONY: all clean
build/ne_10m_admin_0_countries.zip:
mkdir -p $(dir $@)
curl -o $@ 'http://www.naturalearthdata.com/download/10m/cultural/$(notdir $@)'
build/ne_10m_admin_0_countries.shp: build/ne_10m_admin_0_countries.zip
unzip -d $(dir $@) $<
touch $@
build/ne_10m_admin_1_states_provinces.zip:
mkdir -p $(dir $@)
curl -o $@ 'http://www.naturalearthdata.com/download/10m/cultural/$(notdir $@)'
build/ne_10m_admin_1_states_provinces.shp: build/ne_10m_admin_1_states_provinces.zip
unzip -d $(dir $@) $<
touch $@
world.json: build/ne_10m_admin_1_states_provinces.shp build/ne_10m_admin_0_countries.shp sphere.json
node_modules/.bin/topojson \
-p gn_a1_code -q 1e5 --simplify-proportion 0.1 \
--projection='width = 960, height = 960, d3.geo.mercator() \
.translate([width / 2, height / 2]) \
.scale((width - 1) / 2 / Math.PI)' \
-- \
provinces=build/ne_10m_admin_1_states_provinces.shp \
countries=build/ne_10m_admin_0_countries.shp \
sphere=sphere.json | \
node_modules/.bin/topojson-merge \
--io countries \
--oo land \
-o $@
{
"name": "anonymous",
"version": "0.0.1",
"private": true,
"dependencies": {
"topojson": "1"
}
}
{
"type": "Sphere"
}