El Formato TopoJSON

El formato GeoJSON es redundante. Los vértices de dos países contiguos están escritos dos veces, y podrían no coincidir exactamente, creando artefactos en el mapa.

Mike Bostock creó el formato TopoJSON, que define formas en términos de arcos (fronteras) entre formas. Esto elimina redundancia y además agrega información de topología de las formas, dos formas que comparten un arco son vecinas. Los archivos TopoJSON usualmente pesan menos del 10% que su contraparte GeoJSON. En nuestro caso, el archivo GeoJSON pesa 4.4 M, el archivo TopoJSON pesa sólo 600K.

var t = { "type": "Topology", "objects": { "countries": { "type": "GeometryCollection", "geometries": [ { "type": "Polygon", "properties": { "admin": "Aruba", "continent": "North America", "sov_a3": "NL1" }, "arcs": [[0]] }, { // other geometries... } ] } }, "arcs": [ [ [3058, 5901], [ 0, -2], [ -1, 1], [ -2, 4], [ -2, 2], [ 1, 3], [ 0, 1], [ 2, -2], [ 2, -5], [ 0, -2] ], [ // other arcs... ] ], "transform": { "scale": [ 0.036003600360036005, 0.01736158967459246 ], "translate": [ -180, -89.99892578124998 ] } };

El paquete TopoJSON está compuesto de una libería JavaScript y de un programa.

TopoJSON (Programa)

El programa topojson permite convertir archivos GeoJSON en sus equivalentes TopoJSON. Tiene opciones para convertir proyecciones, eliminar o agregar atributos, entre otros. También puede convertir archivos ESRI en TopoJSON directamente.

// Convierte el archivo countries.geojson a TopoJSON // topojson -o countries.topojson -p sov_a3 countries.geojson

TopoJSON.js (libería)

La librería TopoJSON convierte objetos en formato TopoJSON en GeoJSON, que puede ser usado para graficar y usar proyecciones. Además de convertir a GeoJSON, la librería TopoJSON permite identificar vecinos de un feature particular.

Usando el formato TopoJSON

var width = 600, height = 300; var projection = d3.geo.equirectangular() .scale(width / (2 * Math.PI)) .translate([width / 2, height / 2]); var pathGenerator = d3.geo.path().projection(projection); var geojson, topodata; d3.json('/src/data/countries.topojson', function(error, data) { if (error) { console.error(error); } topodata = data; var div = d3.select('#ejemplo-f03'), svg = div.selectAll('svg').data([data]); svg.enter().append('svg'); svg.attr('width', width).attr('height', height); svg.exit().remove(); // Convierte los datos a GeoJSON geojson = topojson.feature(data, data.objects.countries); // Una vez convertidos los archivos, es como si hubieramos usado GeoJSON var pathCountries = svg.selectAll('path.country').data(geojson.features); pathCountries.enter().append('path') .classed('country', true); pathCountries .attr('d', pathGenerator); pathCountries.exit().remove(); });