TopoJSON es una extensión de GeoJSON que introduce un nuevo tipo Topology que contiene objetos GeoJSON que codifica topologías.
Las geometrías se definen a partir de segmentos de líneas compartidas llamadas arcos. Las reglas topológicas exigen que los polígonos compartan una frontera común sin huecos ni superposiciones entre ellos. TopoJSON aprovecha estas reglas de modo que si dos polígonos comparten frontera (arco) entonces TopoJSON representa una única vez la frontera eliminando así redundancias. Gracias a la eliminación de redundancias y a la cuantificación de las coordenadas un fichero TopoJSON puede llegar a ser un 80% más pequeño que su equivalente en GeoJSON.
Un ejemplo sencillo para entender cómo funciona
Dada una forma sencilla cerca de las coordenadas de latitud=0° y longitud=0° donde tenemos dos polígonos, identificados con el color rojo y verde respectivamente:
Su representación en GeoJSON es la siguiente:
{ "type": "FeatureCollection", "crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84"} }, "features": [ { "type": "Feature", "properties": {"ID": 1}, "geometry": { "type": "Polygon", "coordinates": [[[0, 1],[0, 0],[1, 0],[1, 1],[0, 1]]] } }, { "type": "Feature", "properties": {"ID": 2}, "geometry": { "type": "Polygon", "coordinates": [[[1, 1],[1, 0],[2, 0],[2, 1],[1, 1]]] } } ] }
En su transformación a TopoJSON se definen tres arcos identificados con el color verde, azul y rojo, donde el arco en color rojo es un arco compartido por los otros dos polígonos.
Su representación en TopoJSON queda como sigue:
{ "type": "Topology", "crs": { "type": "name", "properties": {"name": "urn:ogc:def:crs:OGC:1.3:CRS84"} }, "transform": { "scale": [1,1], "translate": [0,0] }, "arcs": [ [[1,1],[0,-1]], [[1,0],[-1,0],[0,1],[1,0]], [[1,1],[1,0],[0,-1],[-1,0]] ], "objects": { "2cuadrados": { "type": "GeometryCollection", "geometries": [{ "arcs": [[0,1]], "type": "Polygon", "properties": {"ID": 1} }, { "arcs": [[2,-1]], "type": "Polygon", "properties": {"ID": 2} }] } } }
- Línea 7: Para simplificar en el ejemplo no se ha aplicado una transformación lineal. El propósito de la transformación es cuantificar las posiciones para obtener una serialización más eficiente, mediante la representación de posiciones como números enteros.
- Línea 11: Aquí se definen los arcos. En este caso hay 3 arcos. En cada uno de estos arcos la primera coordenada es cuantificada y el resto está definida respecto al punto anterior. El primer arco (rojo) va de la posición 1,1 a la 1,0. El segundo arco (verde) empieza en 1,0 y termina en 1,1 y el tercer arco (azul) empieza en 1,1 y termina en 1,0
- Línea 19: Aquí se definen las geometrías. En este caso hay 2 geometrías. Cada una una de ellas se componen de varios arcos. La primera geometria se compone del arco [0] (rojo) y del arco [1] (verde). La segunda geometría se componen del arco [2] (azul) y del arco [-1] (rojo). El [-1] indica que la secuencia de las coordenadas en el arco debe ser invertida antes de la unión. Para evitar la ambigüedad con cero, se utiliza complemento a uno, de modo que [-1] representa el arco invertido [0] y así sucesivamente.
Exportar a TopoJSON
A continuación enumero algunas herramientas que permiten exportar a TopoJSON.
Topojson
Topojson es una herramienta de línea de comandos que permite los siguente formatos de entrada:
- .json GeoJSON or TopoJSON
- .shp ESRI shapefile
- .csv comma-separated values (CSV)
- .tsv tab-separated values (TSV)
Para instalar la herramienta necesitarás Node.js. Instala mediante NPM:
npm install -g topojson
Ejemplo básico que convierte el fichero GeoJSON input.json a un fichero TopoJSON output.json:
topojson -o output.json input.json
Mapshaper
Mapshaper es una herramienta online, que ademas podemos instalar y manejar desde la línea de comandos (mas información en una entrada anterior) que permite simplificar geometrías y exportar, entre otros formatos a TopoJSON.
Ejemplo básico que convierte el fichero GeoJSON input.json a un fichero TopoJSON output.json:
mapshaper input.json -o output.json format=topojson
Distillery
Distillery es una sencilla herramienta online que admite GeoJSON como formato de entrada, opcionalmente simplificar geometrías y exportar a TopoJSON.
Geojson.io
Geojson.io es otra herramienta online avanzada para la edición GeoJSON con multitud de opciones, entre ellas la de exportar, entre otros formatos, a TopoJSON
Utilizar TopoJSON en Leafleft
En un artículo anterior expliqué cómo crear un mapa con GeoJSON y Leafleft. Leafleft no soporta TopoJSON y será necesario transformar TopoJSON a GeoJSON. Para hacer esto, descarga la libreria topojson desde aquí y referenciala. Es posible que necesites referenciar también a jQuery:
<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script> <script src="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script> <script type="text/javascript" src="topojson.min.js"></script>
Despues utiliza/adapta el siguiente código que descarga y transforma a GeoJSON:
// Transform topojson to geojson. // Copyright (c) 2013 Ryan Clark L.TopoJSON = L.GeoJSON.extend({ addData: function(jsonData) { if (jsonData.type === "Topology") { for (key in jsonData.objects) { geojson_ = topojson.feature(jsonData, jsonData.objects[key]); L.GeoJSON.prototype.addData.call(this, geojson_); } } else { L.GeoJSON.prototype.addData.call(this, jsonData); } } }); var geojson = new L.TopoJSON(undefined, { style: style, onEachFeature: onEachFeature }); $.getJSON('mytopojson.topojson').done(addTopoData); function addTopoData(topoData){ geojson.addData(topoData); geojson.addTo(map); }