Hoy he visto que desde @MappingGIS han sacado un artículo sobre una librería para operaciones espaciales hecha en Javascript. Y nos viene genial para seguir completando el visor que hicimos sobre Leaflet en los anteriores post.
Para toda la información sobre la librería y los usos de esta librería con más en profundidad, visitar su artículo: Turf: Análisis espacial en la web
Desde aquí, vamos a comenzar con el visor que dejamos de Cities_Europe_leaflet.zip
Añadimos el acceso a la librería con la línea siguiente dentro del <head> de nuestra página index.html:
<script type="text/javascript" src="https:////api.tiles.mapbox.com/mapbox.js/plugins/turf/v2.0.2/turf.min.js"></script>
Recordamos que todo el código Javascript que hace referencia al mapa lo encontramos en js/leaf-demo.js
Recordar también que nosotros tenemos toda nuestra info de puntos es una variable llamada geodata, en el fichero data/cities_europe.js. Vamos a intentar hacer algo con toda esta nube de puntos. Empezamos con nuestra vista así:
Todos los métodos que voy a comentar y muchísimos más los podéis encontrar en la API de Turf, bien explicados y con sus respectivos ejemplos.
Una de las operaciones espaciales que tenemos es el convexHull, el polígono mínimo que engloba todos los puntos. Podemos calcularlo simplemente pasando los puntos geodata a la operación convex de turf, quedando así (todo esto después del código donde creamos nuestro mapa):
var convexHull = turf.convex(geodata); L.geoJson(convexHull).addTo(map);
Y como lo añadimos a la vista del mapa quedaría así:
Podemos crear una cuadrícula de hexágonos dentro de nuestro boundary box:
var bbox = [-10,30,75,60]; var cellWidth = 500; var units = 'miles'; var hexgrid = turf.hexGrid(bbox, cellWidth, units); L.geoJson(hexgrid).addTo(map);
Para el último ejemplo de isolines podríamos crear unos puntos aleatorios como usan en su web para los ejemplos:
var points = turf.random('point', 100, { bbox: [0, 30, 20, 50] });
Pero nosotros vamos a aprovechar para darle un valor aleatorio a la Z de los puntos que ya tenemos en geodata. Para ello usamos:
for (var i = 0; i < geodata.features.length; i++) { geodata.features[i].properties.z = Math.random() * 10; } var breaks = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; var isolined = turf.isolines(geodata, 'z', 15, breaks); L.geoJson(isolined).addTo(map);
Quedando así (no es bonito al ser valores aleatorios, pero para visualizarlo sobra):
En resumen, nuestro código en leaf-demo.js quedaría así, en el cual visualizaríamos los tres ejemplos juntos anteriores:
var bounds = L.latLngBounds([30, -10], [60, 75]); var map = L.map( 'map', { center: [50, 10], minZoom: 2, zoom: 5, zoomControl: false, maxBounds: bounds }); // Example: convexHull var convexHull = turf.convex(geodata); L.geoJson(convexHull).addTo(map); // Example: hexgrid var bbox = [-10,30,75,60]; var cellWidth = 500; var units = 'miles'; var hexgrid = turf.hexGrid(bbox, cellWidth, units); L.geoJson(hexgrid).addTo(map); // Example: Isolines /* var points = turf.random('point', 100000, { bbox: [-10,30,75,60] }); */ for (var i = 0; i < geodata.features.length; i++) { geodata.features[i].properties.z = Math.random() * 10; } var breaks = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; var isolined = turf.isolines(geodata, 'z', 15, breaks); L.geoJson(isolined).addTo(map); // Previous code L.marker([50, 10]).addTo(map); L.tileLayer( 'http://a.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: 'OpenStreetMap', }).addTo( map ); var geojsonMarkerOptions = { radius: 5, fillColor: "#ff7800", color: "#000", weight: 1, opacity: 1, fillOpacity: 0.8 }; L.geoJson(geodata, { pointToLayer: function (feature, latlng) { return L.circleMarker(latlng, geojsonMarkerOptions); } }).addTo(map);
Agradecer a Mappinggis por el artículo, no conocía esta librería.
Un saludo y espero que os sean estos ejemplos de utilidad.
Os podéis descargar el ejemplo completo desde aquí.
Muy buen artículo, este complemento el nuestro con alguna herramienta de análisis espacial más.