block by mbostock 10024231

Swiss Cantons & Lakes

Full Screen

This example shows how to create canton boundaries consistent with lake boundaries using topojson-merge. To avoid losing information, --no-quantization is used when creating the initial unmerged topologies. Data from interactivethings/swiss-maps.

index.html

<!DOCTYPE html>
<meta charset="utf-8">
<style>

.boundary {
  fill: none;
  stroke: #fff;
  stroke-linejoin: round;
  stroke-linecap: round;
}

.feature--canton {
  fill: #bbb;
}

.feature--lake {
  fill: steelblue;
  fill-opacity: .8;
}

.feature :hover {
  fill: orange;
}

</style>
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="//d3js.org/topojson.v1.min.js"></script>
<script>

var width = 960,
    height = 500;

var color = d3.scale.category20c();

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

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height);

d3.json("ch.json", function(error, ch) {
  if (error) throw error;

  svg.append("g")
      .attr("class", "feature feature--canton")
    .selectAll("path")
      .data(topojson.feature(ch, ch.objects.cantons).features)
    .enter().append("path")
      .attr("d", path);

  svg.append("g")
      .attr("class", "feature feature--lake")
    .selectAll("path")
      .data(topojson.feature(ch, ch.objects.lakes).features)
    .enter().append("path")
      .attr("d", path);

  svg.append("path")
      .datum(topojson.mesh(ch, ch.objects.cantons, function(a, b) { return a !== b; }))
      .attr("class", "boundary boundary--cantons")
      .style("stroke-width", "1px")
      .attr("d", path);
});

</script>

Makefile

.PHONY: all clean

GENERATED_FILES = \
	ch.json

all: ch.json

clean:
	rm -rf -- $(GENERATED_FILES) build

build/VEC200_Commune.%:
	mkdir -p build
	curl -o $@ -3 'https://raw.githubusercontent.com/interactivethings/swiss-maps/2.1.0/src/V200/$(notdir $@)'

build/cantons.shp: $(addprefix build/VEC200_Commune.,shp dbf prj shx)
	rm -f -- $@
	ogr2ogr -f 'ESRI Shapefile' -where 'COUNTRY = "CH"' $@ $<

build/lakes.shp: build/cantons.shp
	rm -f -- $@
	ogr2ogr -f 'ESRI Shapefile' -where 'SEENR < 9999 AND SEENR > 0' $@ $<

build/cantons-unmerged.json: build/cantons.shp
	node_modules/.bin/topojson \
		-o $@ \
		--no-quantization \
		--id-property=+KANTONSNR \
		-- cantons=$<

build/lakes-unmerged.json: build/lakes.shp
	node_modules/.bin/topojson \
		-o $@ \
		--no-quantization \
		--id-property=+SEENR \
		-- lakes=$<

build/%.json: build/%-unmerged.json
	node_modules/.bin/topojson-merge \
		-o $@ \
		--in-object=$* \
		--out-object=$* \
		-- $<

ch.json: build/lakes.json build/cantons.json
	node_modules/.bin/topojson \
		-o $@ \
		--width=960 \
		--height=500 \
		--margin=10 \
		--simplify=.5 \
		-- $^

package.json

{
  "name": "anonymous",
  "version": "0.0.1",
  "private": true,
  "dependencies": {
    "topojson": ">=1.6.5 <2"
  }
}