This is the second of a two-part series about creating a map in SVG based on Swiss geographical data. Each part contains a certain step of the process:

- Converting shapefiles to GeoJSON/TopoJSON with node
- Creating a bivariate choropleth map with d3-geo and LV95 coordinates

The result of that process you can see and interact with on srf.ch

At the end of part one we ended up with a TopoJSON file that was at a reasonable file size. We now want to display this on our web page.

#### Working with d3-geo

I won’t go into great detail of the basics of `d3-geo`

. There are plenty of resources (here, here or here). Instead we’ll focus on how Swiss coordinates are different to work with.

The Swiss coordinate system has one key difference to others: **it is already flat**. What do I mean by that? While `lat`

and `long`

describe degrees on a globe, the Swiss coordinates `X`

and `Y`

describe a position on a normal plane:

So with most coordinate systems you need a projection like `geoMercator`

to map coordinates from a sphere to a flat screen. This is not needed if you work with Swiss coordinates.

To draw our municipalities onto our svg we can set up the following variables:

```
// this is the upper left and lower right corner of all of Switzerland
// you can copy these values from the end of the topojson file or anywhere else, really
const bbox = {
x1: 2485432,
x2: 2833839,
y1: 1075269,
y2: 1295934
}
const x = scaleLinear()
.range([ 0, width ])
.domain([ bbox.x1, bbox.x2 ])
const y = scaleLinear()
.range([ 0, height ])
// invert top and bottom
.domain([ bbox.y2, bbox.y1 ])
const projection = geoTransform({
point: function (px, py) {
this.stream.point(x(px), y(py))
}
})
const path = geoPath().projection(projection)
```

We really just set up two linear scales for positioning points left and right.

The most important part here is what happens inside of `geoTransform`

. The function is a helper that let’s us construct our own projection function. (Another example by mbostock here).

In there we just return for every coordinate `cx`

and `cy`

the corresponding pixel position generated by our linearScales `x`

and `y`

(Thx to @LucGuillemot for showing me this).

With the `feature`

function from `topojson-client`

we convert our TopoJSON back into GeoJSON. The rest is really straight forward `d3`

code. We pass our `path`

function to the attribute `'d'`

that will draw our polygons onto the svg:

```
// convert the TopoJSON back to GeoJSON
const geoJson = topojsonFeature(
topoJson,
topoJson.objects.municipalities
)
// and add one path per municipality to the svg
svg
.selectAll('path')
.data(geoJson.features)
.enter()
.append('path')
.attr('class', 'feature')
.style('fill', 'steelblue')
.attr('d', path)
```

For brevity, I omitted some parts of the code. You can find the whole code in this github repository.

The color of each municipality is just `steelblue`

at the moment but yay 😊 we have a map – and it uses LV95 coordinates!