Empleo del formato TopoJSON en aplicaciones web mapping

El formato TopoJSON es una extensión de GeoJSON.(Fuente)

TopoJSON es mucho más ligero que GeoJSON y codifica topologías. Esto implica que en algunas circunstancias sea más aconsejable utilizar TopoJSON. En este artículo veremos algunas características del formato y sobre todo, cómo lo podemos utilizar en una aplicación webmapping, a partir de GeoServer y OpenLayers.

Características del formato

La principal característica del formato TopoJSON es que codifica topologías.

Podemos definir la topología como las relaciones que se establecen entre un elemento geográfico con los otros elementos que lo rodean. Según esto, cuando dos polígonos representan elementos geográficos adyacentes en un mapa, las reglas topológicas típicas exigen que estos polígonos compartan una frontera común sin huecos ni superposiciones entre ellos.

No todos los formatos soportan topología, no lo hacen, por ejemplo, el formato shapefile o el GeoJSON.

Una característica del formato TopoJSON como consecuencia de la aplicación de la topología, es que su tamaño es mucho menor y por lo tanto más rápido de descargar por las aplicaciones web mapping.

Hay varias aplicaciones en línea que nos permiten convertir formatos GIS como shp o Geoserver a TopoJSON. También podemos hacerlo mediante algún SIG de escritorio como QGIS.

Los arcos

TopoJSON define un nuevo tipo del que carece GeoJSON, se trata de “Topology”. En lugar de representar líneas, lo que hace es utilizar arcos. Se definen unos arcos y unos arcos compartidos que son los elementos de “contacto” entre las geometrías. Cada arco está definido por sus coordenadas cuantificadas. La cuantificación es una transformación lineal que consiste en una escala y una traslación que convierte las coordenadas con parte decimal en números enteros. Estas transformaciones son las que nos darán la representación final del objeto geométrico.

GeoJSON vs TopoJSON

Para ilustrar lo que hemos indicado, hasta el momento vamos a crear una figura formada por dos cuadrados y ver cómo sería en formato GeoJSON y en formato TopoJSON. Para dibujar las geometrías y exportarlas a los formatos JSON utilizaremos la herramienta geojson.io

El contenido del archivo GeoJSON es:

{"type":"FeatureCollection", 
"features":[ 
{"type":"Feature", 
"properties":{}, 
"geometry":{ 
"type":"Polygon", 
"coordinates":[[[0,0],[25,0],[25,25],[0,25],[0,0]]]}}, 
{"type":"Feature", 
"properties":{}, 
"geometry":{ 
"type":"Polygon", 
"coordinates":[[[25,0],[50,0],[50,25],[25,25],[25,0]]]}} ]}

Los mismos datos en formato TopoJSON son:

{"type":"Topology", 
"objects":{"collection":{ 
"type":"GeometryCollection", 
"geometries":[{ 
"type":"Polygon", 
"arcs":[[0,1]]}, 
{"type":"Polygon", 
"arcs":[[2,-1]]}]}}, 
"arcs":[[[5000,0],[0,9999]],[[5000,9999],[-5000,0],[0,-9999],[5000,0]],[[5000,0],[4999,0],[0,9999],[-4999,0]]], 
"transform":{ 
"scale":[0.005000500050005001,0.0025002500250025004], 
"translate":[0,0]}, 
"bbox":[0,0,50,25] }

En este ejemplo, como se trata de figuras muy sencillas, no se aprecia la reducción de tamaño de TopoJSON respecto a GeoJSON. En otros caos más realistas las reducciones de tamaño son muy importantes, llegando casi al 80%.

En el código anterior podemos ver algunas de las características del formato. Vemos el tipo: Topology y como las geometrías se compone unas matrices de arcos. El arco 1 está repetido lo que indica que es un elemento en común de las geometrías, pero aparece con signo menos. Un índice negativo indica que la secuencia de las coordenadas en el arco debe ser invertida antes de la unión.

Generación de TopoJSON con GeoServer

GeoServer puede producir teselas vectoriales en tres formatos: GeoJSON, TopoJSON y MapBox Vector (MVT). Para ello, el primer paso es la instalación de la extensión Vector Tiles en GeoServer.

Una vez instalada la extensión, podremos definir los formatos de las capas vectoriales en GeoServer activando las opciones correspondientes en el apartado Cacheado de Teselas de las capas:

Una vez que lo tengamos, lo guardamos y podremos utilizar la capa en formato TopoJSON.

Mostrar el TopoJSON en OpenLayers

OpenLayers dispone de un clase específica para trabajar con TopoJSON.

Como habíamos creado anteriormente nuestra capa mediante GeoServer, ahora podemos utilizarla en OpenLayers al igual que las otras capas vectoriales (GeoJSON y MVT)

var vector = new ol.layer.Vector({ 
    source: new ol.source.Vector({ 
       format: new ol.format.TopoJSON(), 
       url: 'http://localhost:8080/geoserver/topp/wms?service=WMS&version=1.1.0&request=GetMap&layers=topp%3Astates&bbox=-124.73142200000001%2C24.955967%2C-66.969849%2C49.371735&width=768&height=330&srs=EPSG%3A4326&styles=&format=application%2Fjson%3Btype%3Dtopojson' }), 
       style: new ol.style.Style({ 
       fill: new ol.style.Fill({ 
           color: 'brown'}), 
       stroke: new ol.style.Stroke({ 
            color: 'gray' 
            }) 
       }) 
});

Como podemos ver en el código anterior, utilizamos la clase ol.source.Vector para crear la capa vectorial y en format, utilizamos ol.format.TopoJSON para indicar cuál es el formato que vamos a utilizar. En el parámetro url indicamos la ruta que contiene los datos de nuestro mapa, que como vemos en este ejemplo se encuentra en un servidor local. Creamos también un estilo para representar la capa.

El código completo es el siguiente:

<!doctype html> 
<html lang="en"> 
<head> <!-- Openlayers --> 
    <script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.5.0/build/ol.js" type="text/javascript"></script> 
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.5.0/css/ol.css" type="text/css"> 

    <style> #map{ width:100%; 
        height: 400px; 
        box-shadow: 5px 5px 5px #888; 
        } 
    </style> 

<title>OpenLayers TopoJSON</title> 
</head> 
<body> 
<h2>ol - WFS</h2> 

<div id="map" ></div> 
<script type="text/javascript"> 

    var osm = new ol.layer.Tile({ source: new ol.source.OSM() }); 
    
    var vector = new ol.layer.Vector({ 
        source: new ol.source.Vector({ 
        format: new ol.format.TopoJSON(), 
        url: 'http://localhost:8080/geoserver/topp/wms?service=WMS&version=1.1.0&request=GetMap&layers=topp%3Astates&bbox=-124.73142200000001%2C24.955967%2C-66.969849%2C49.371735&width=768&height=330&srs=EPSG%3A4326&styles=&format=application%2Fjson%3Btype%3Dtopojson' }), 
        style: new ol.style.Style({ 
            fill: new ol.style.Fill({ 
                color: 'brown'}), 
            stroke: new ol.style.Stroke({ 
                color: 'gray' }) 
            }) 
        }); 
    
    var map = new ol.Map({ 
        layers: [osm, vector], 
        target: 'map', 
        view: new ol.View({ 
            center: ol.proj.fromLonLat([-4.72, 41.66]), 
            zoom: 2 }) }); 
</script> 
</body> 
</html>

Y el mapa que obtenemos es el siguiente:

topoJSON en OpenLayers

Let’s connect!

Date de alta en nuestra newsletter y te enviaremos nuestra propuesta con las mejores
Soluciones GIS basadas en software libre

Tan solo una vez al mes recibirás las últimas novedades del sector GIS y de nuestros cursos

5 comentarios en «Empleo del formato TopoJSON en aplicaciones web mapping»

  1. Hace ya tiempo hice pruebas con topojson.
    Y analizando un poco su lógica para geometrías de la tipo malla(grid) ,como la primera imagen de ejemplo , no es recomendable ya que no solo almacena de manera independiente cada arco sino que también almacena la caja envolvente de la geometría (bbox)
    Por tanto estamos por un lado guardando la geometría original como tal (bbox) y por otro lado la geometría independiente de cada arco.
    Para geometrías más reales si se aprecia optimización de almacenamiento.

    Lo ideal para realmente optimizar los datos para sería hacer uso de formatos binarios como el pbf .

    Saludos

    Responder
    • Hola Emilo:
      Gracias por tu comentario. En el ejemplo que se pone se trata de comparar TopoJSON con GeoJSON, para entender un poco la lógica del formato, pero como bien dices en ese caso concreto, TopoJSON no aporta ninguna ventaja. En otros casos si puede suponer una ventaja.
      Saludos.

      Responder
  2. Así es como se difunden las mentiras… Topojson no es una extensión de geojson, es otra especificación independiente, ajena y diferente, la unos relación que tiene con geojson es que ambos usan json para la representación de los datos… Es como decir que que ‘gml es una extensión de kml pero que…’

    Favor de no aventar ‘verdades’ falsas a la ligera, que luego estás crecen como hongos en otros foros y luego es difícil contrarrestar la mala información

    Responder

Deja un comentario