D3.js: geografías

Las coordenadas geoespaciales se utilizan a menudo para datos meteorológicos o de población. D3.js nos brinda tres herramientas para datos geográficos:

  • Paths - Producen los píxeles finales.

  • Projections - Convierten las coordenadas de la esfera en coordenadas cartesianas y

  • Streams - Aceleran las cosas.

Antes de aprender qué son las geografías en D3.js, debemos comprender los dos términos siguientes:

  • Ruta geográfica D3 y
  • Projections

Analicemos estos dos términos en detalle.

Ruta geográfica D3

Es un generador de rutas geográficas. GeoJSON genera una cadena de datos de ruta SVG o representa la ruta a un Canvas. Se recomienda un Canvas para proyecciones dinámicas o interactivas para mejorar el rendimiento. Para generar un generador de datos de ruta geográfica D3, puede llamar a la siguiente función.

d3.geo.path()

Aquí el d3.geo.path() La función de generador de ruta nos permite seleccionar qué proyección de mapa queremos usar para la traducción de coordenadas geográficas a coordenadas cartesianas.

Por ejemplo, si queremos mostrar los detalles del mapa de la India, podemos definir una ruta como se muestra a continuación.

var path = d3.geo.path()
svg.append("path")
   .attr("d", path(states))

Proyecciones

Las proyecciones transforman la geometría poligonal esférica en geometría poligonal plana. D3 proporciona las siguientes implementaciones de proyección.

  • Azimuthal - Las proyecciones azimutales proyectan la esfera directamente sobre un plano.

  • Composite - Compuesto consta de varias proyecciones que se componen en una sola pantalla.

  • Conic - Proyecta la esfera en un cono y luego desenrolla el cono en el plano.

  • Cylindrical - Las proyecciones cilíndricas proyectan la esfera sobre un cilindro contenedor y luego desenrollan el cilindro sobre el plano.

Para crear una nueva proyección, puede utilizar la siguiente función.

d3.geoProjection(project)

Construye una nueva proyección a partir del proyecto de proyección sin formato especificado. La función de proyecto toma la longitud y latitud de un punto dado en radianes. Puede aplicar la siguiente proyección en su código.

var width = 400
var height = 400
var projection = d3.geo.orthographic() 
var projections = d3.geo.equirectangular()
var project = d3.geo.gnomonic()
var p = d3.geo.mercator()
var pro = d3.geo.transverseMercator()
   .scale(100)
   .rotate([100,0,0])
   .translate([width/2, height/2])
   .clipAngle(45);

Aquí, podemos aplicar cualquiera de las proyecciones anteriores. Analicemos brevemente cada una de estas proyecciones.

  • d3.geo.orthographic()- La proyección ortográfica es una proyección azimutal adecuada para mostrar un solo hemisferio; el punto de perspectiva está en el infinito.

  • d3.geo.gnomonic() - La proyección gnomónica es una proyección azimutal que proyecta grandes círculos como líneas rectas.

  • d3.geo.equirectangular()- El equirrectangular es la proyección geográfica más simple posible. La función de identidad. No es de áreas iguales ni conforme, pero a veces se usa para datos ráster.

  • d3.geo.mercator() - La proyección esférica de Mercator es comúnmente utilizada por bibliotecas de mapas en mosaico.

  • d3.geo.transverseMercator() - La proyección transversal de Mercator.

Ejemplo de trabajo

Creemos el mapa de la India en este ejemplo. Para hacer esto, debemos seguir los siguientes pasos.

Step 1 - Apply styles - Agreguemos estilos en el mapa usando el siguiente código.

<style>
   path {
      stroke: white;
      stroke-width: 0.5px;
      fill: grey;
   }
   
   .stateTN { fill: red; }
   .stateAP { fill: blue; }
   .stateMP{ fill: green; }
</style>

Aquí, hemos aplicado colores particulares para los estados TN, AP y MP.

Step 2 - Include topojson script - TopoJSON es una extensión de GeoJSON que codifica la topología, que se define a continuación.

<script src = "http://d3js.org/topojson.v0.min.js"></script>

Podemos incluir este script en nuestra codificación.

Step 3 - Define variables - Agregue variables en su secuencia de comandos, utilizando el siguiente código.

var width = 600;
var height = 400;
var projection = d3.geo.mercator()
   .center([78, 22])
   .scale(680)
   .translate([width / 2, height / 2]);

Aquí, el ancho de SVG es 600 y la altura es 400. La pantalla es un espacio bidimensional y estamos tratando de presentar un objeto tridimensional. Entonces, podemos distorsionar gravemente el tamaño / forma de la tierra usando eld3.geo.mercator() función.

El centro se especifica [78, 22], esto establece el centro de la proyección en la ubicación especificada como una matriz de dos elementos de longitud y latitud en grados y devuelve la proyección.

Aquí, el mapa se ha centrado en 78 grados oeste y 22 grados norte.

La escala se especifica como 680, esto establece el factor de escala de la proyección en el valor especificado. Si no se especifica la escala, devuelve el factor de escala actual, cuyo valor predeterminado es 150. Es importante tener en cuenta que los factores de escala no son consistentes entre las proyecciones.

Step 4 - Append SVG - Ahora, agregue los atributos SVG.

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

Step 5 - Create path - La siguiente parte del código crea un nuevo generador de ruta geográfica.

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

Aquí, el generador de ruta (d3.geo.path ()) se usa para especificar un tipo de proyección (.projection), que se definió anteriormente como una proyección de Mercator usando la proyección variable.

Step 6 - Generate data - indiatopo.json: este archivo contiene tantos registros que podemos descargar fácilmente desde el siguiente archivo adjunto.

Descargar indiatopo.json file

Una vez descargado el archivo, podemos agregarlo a nuestra ubicación D3. El formato de muestra se muestra a continuación.

{"type":"Topology","transform":{"scale":[0.002923182318231823,0.0027427542754275428],
"translate":[68.1862,8.0765]},"objects":
{"states":{"type":"GeometryCollection",
"geometries":[{"type":"MultiPolygon","id":"AP","arcs":
[[[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,
25,26,27,28,29,30,31,32,33,34]],[[35,36,37,38,39,40,41]],[[42]],
[[43,44,45]],[[46]],[[47]],[[48]],[[49]],[[50]],[[51]],[[52,53]],
[[54]],[[55]],[[56]],[[57,58]],[[59]],[[60]],[[61,62,63]],[[64]],
[[65]],[[66]],[[67]],[[68]],[[69]],[[-41,70]],
[[71]],[[72]],[[73]],[[74]],[[75]]],
"properties":{"name":"Andhra Pradesh"}},{"type":"MultiPolygon",
"id":"AR","arcs":[[[76,77,78,79,80,81,82]]],
"properties":{"name":"Arunachal Pradesh"}},{"type":"MultiPolygon",
"id":"AS","arcs":[[[83,84,85,86,87,88,89,90,
91,92,93,94,95,96,97,98,99,100,101,102,103]],
[[104,105,106,107]],[[108,109]]], ......

........................................

Step 7 - Draw map - Ahora, lea los datos del indiatopo.json archivar y dibujar el mapa.

d3.json("indiatopo.json", function(error, topology) {
   g.selectAll("path")
   .data(topojson.object(topology, topology.objects.states)
   .geometries)
   .enter()
   .append("path")
   .attr("class", function(d) { return "state" + d.id; })
   .attr("d", path)
});

Aquí, cargaremos el archivo TopoJSON con las coordenadas del mapa de India (indiatopo.json). Luego declaramos que vamos a actuar sobre todos los elementos de la ruta en el gráfico. Se define como, g.selectAll ("ruta"). Luego, extraeremos los datos que definen los países del archivo TopoJSON.

.data(topojson.object(topology, topology.objects.states)
   .geometries)

Finalmente, lo agregaremos a los datos que vamos a mostrar usando el .enter() y luego agregamos esos datos como elementos de ruta usando el .append(“path”) método.