Leaflet.TimeDimension: ¡esto se anima!

 

 

Biel Frontera

ICTS SOCIB

ICTS SOCIB. Sistema de observación multiplataforma

caption

http://www.socib.eu

Sistema multiplataforma con tres subsistemas principales:

  • Infraestructura de observación y monitorización: estaciones fijas (boyas oceanográficas, estaciones costeras, estaciones meterológicas); float de gliders (planeadores submarinos), drifters (perfiladores y de superfíce); buque oceanográfico, Radar HF.
  • Modelización y predicción: sistema de predicción del Mediterráneo occidental (corrientes, temperaturas, salinidad y nivel del mar); predicción de meteo-tsunamis ("rissagues") en Ciutadella; predicción de oleaje en el mar Balear.
  • Centro de datos: gestión de los datos para garantizar su calidad y la interoperabilidad.

Leaflet.Timedimension en acción

caption

caption

caption

Leaflet.TimeDimension

Add time dimension capabilities on a Leaflet map.

Leaflet.TimeDimension. Componentes

  • L.TimeDimension: Gestiona el tiempo de un mapa o de una capa (o varias)
    • lista de tiempos posibles
    • tiempo actual
    • métodos para modificar la lista de tiempos y el tiempo actual
    • eventos: tiempo modificado (timeload), nuevo tiempo en proceso de carga (timeloading)

Leaflet.TimeDimension. Componentes

  • L.TimeDimension.Layer: Capa/Layer que será sincronizada en función del tiempo del mapa.
    • Clase abstracta.
    • Dos clases derivadas incluídas en el plugin: L.TimeDimension.Layer.WMS y L.TimeDimension.Layer.GeoJSON
    • Pensada para que un desarrollador pueda crear su propia clase (ver exemplos L.TimeDimension.Layer.CircleLabelMarker y L.TimeDimension.Layer.SODAHeatMap)
    • Las capas derivadas deben implementar los métodos: _onNewTimeLoading, isReady y _update

Leaflet.TimeDimension. Componentes

  • L.Control.TimeDimension: Control para gestionar los cambios de tiempo y animación (play-pause, atrás, siguiente, slider de tiempo, indicador de tiempo actual, etc)
    • Se puede configurar qué elementos del control se tienen que mostrar
  • L.TimeDimension.Player: Componente para gestionar las animaciones.
    • Opciones: velocidad de la animación, buffer, loop
    • Eventos: running, waiting, animationfinished...

Leaflet.Timedimension: ejemplos básicos de código

Ejemplo básico con una capa WMS:

var map = L.map('map', {
    timeDimension: true,
    timeDimensionControl: true,
});

var oceanForecastingWMS = "http://thredds.socib.es/thredds/wms/operational_models/oceanographical/hydrodynamics/model_run_aggregation/wmop/wmop_best.ncd";

var temperatureLayer = L.tileLayer.wms(oceanForecastingWMS, {
    layers: 'temp',
    format: 'image/png',
    transparent: true,
    styles: 'boxfill/sst_36'
});

var temperatureTimeLayer = L.timeDimension.layer.wms(temperatureLayer, {
    updateTimeDimension: true,
}).addTo(map);

Comentarios sobre WMS

  • Se puede obtener la dimensión temporal de una capa a partir del método GetCapabilities
<Layer queryable="1">
    <Name>adt</Name>
    <Title>sea_surface_height_above_geoid</Title>
    <Abstract>Absolute Dynamic Topography</Abstract>
    <LatLonBoundingBox minx="-5.9375" maxx="36.9375" miny="30.0625" maxy="45.9375"/>
    <BoundingBox SRS="EPSG:4326" minx="-5.9375" maxx="36.9375" miny="30.0625" maxy="45.9375"/>
    <Dimension name="time" units="ISO8601"/>
    <Extent name="time" multipleValues="1" current="1" default="2016-05-23T00:00:00.000Z">
          2014-01-07T00:00:00.000Z,2014-01-09T00:00:00.000Z,2014-01-10T00:00:00.000Z,...
    </Extent>
 </Layer>

Leaflet.Timedimension: ejemplos básicos de código

Ejemplo básico con una capa GeoJSON:

var map = L.map('map', {
    timeDimension: true,
    timeDimensionControl: true,
});

$.getJSON('data/example.geojson', function(data) {
    var geoJsonLayer = L.geoJson(data);

    var geoJsonTimeLayer = L.timeDimension.layer.geoJson(geoJsonLayer, {
        updateTimeDimension: true,
        duration: 'PT20M',
    });

    geoJsonTimeLayer.addTo(map);

    map.fitBounds(geoJsonLayer.getBounds());
});

Comentarios sobre GeoJSON

  • Según la especificación GeoJSON, la coordenadas de una geometría sólo pueden tener hasta tres dimensiones: longitud, latitud y elevación.

  • Es decir, no existe una forma estándard de informar sobre sobre la información temporal en el formato GeoJSON.

  • Leaflet.TimeDimension busca las entre las siguientes propiedades del objeto para obtener la información temporal: time, times, coordTimes or linestringTimestamps

Leaflet.TimeDimension: ejemplos básicos de código

Interacciones con el tiempo

var map = L.map('map', {
    timeDimension: true,
    timeDimensionControl: true,
});

// Modify the current time 
map.timeDimension.setCurrentTime(new Date().getTime());

// Listen to timedimension events
// timeload: Fired when a all synced layers have been loaded/prepared for a new time (or timeout)
map.timeDimension.on('timeload', function(data) {
    // Example: update html elements when time is changed
    var currentDate = new Date(map.timeDimension.getCurrentTime()); // or data.time
    var dateElement = $("#date");
    dateElement.find('span.mapdate').html(currentDate.format("dd/mm/yyyy", true));
    dateElement.find('span.maptime').html(currentDate.format("HH:MM", true));
    dateElement.show();
});

Leaflet.Timedimension: ejemplos

15 ejemplos de uso en http://apps.socib.es/Leaflet.TimeDimension/examples/

caption

caption

caption

caption

caption

caption

caption

caption

Leaflet.TimeDimension integrado en folium!

  • Folium es un paquete de Python que permite manipular tus datos en Python, y visualizarlos en un mapa Leaflet desde un jupyter notebook.
import folium

geo_data = {
    "type": "FeatureCollection",
    "features": []
}

m = folium.Map([0, 3], zoom_start=2)
folium.GeoJson(geo_data).add_to(m)
m
In [1]:
import numpy as np
coordinates = [[[[lon-8*np.sin(theta), -47+6*np.cos(theta)] for
                 theta in np.linspace(0, 2*np.pi, 25)],
                [[lon-4*np.sin(theta), -47+3*np.cos(theta)] for theta
                 in np.linspace(0, 2*np.pi, 25)]] for
               lon in np.linspace(-150, 150, 7)]
geo_data = {
    "type": "FeatureCollection",
    "features": [
            {
                "type": "Feature",
                "geometry": {
                    "type": "Point",
                    "coordinates": [0, 0],
                    },
                "properties": {
                    "times": [1435708800000+12*86400000]
                    }
                },
            {
                "type": "Feature",
                "geometry": {
                    "type": "MultiPoint",
                    "coordinates": [[lon, -25] for
                                    lon in np.linspace(-150, 150, 49)],
                    },
                "properties": {
                    "times": [1435708800000+i*86400000 for
                              i in np.linspace(0, 25, 49)]
                    }
                },
            {
                "type": "Feature",
                "geometry": {
                    "type": "LineString",
                    "coordinates": [[lon, 25] for
                                    lon in np.linspace(-150, 150, 25)],
                    },
                "properties": {
                    "times": [1435708800000+i*86400000 for
                              i in np.linspace(0, 25, 25)]
                    }
                },
            {
                "type": "Feature",
                "geometry": {
                    "type": "MultiLineString",
                    "coordinates": [[[lon-4*np.sin(theta),
                                      47+3*np.cos(theta)] for theta
                                     in np.linspace(0, 2*np.pi, 25)]
                                    for lon in
                                    np.linspace(-150, 150, 13)],
                    },
                "properties": {
                    "times": [1435708800000+i*86400000 for
                              i in np.linspace(0, 25, 13)]
                    }
                },
            {
                "type": "Feature",
                "geometry": {
                    "type": "MultiPolygon",
                    "coordinates": coordinates,
                    },
                "properties": {
                    "times": [1435708800000+i*86400000 for
                              i in np.linspace(0, 25, 7)]
                    }
                },
        ],
    }
In [2]:
import folium
m = folium.Map([0, 3], zoom_start=2)
folium.GeoJson(geo_data).add_to(m)
m
Out[2]:
from folium import plugins

m = folium.Map([0, 3], zoom_start=2)
tgj = plugins.TimestampedGeoJson(geo_data)
m.add_children(tgj)
In [3]:
from folium import plugins

m2 = folium.Map([0, 3], zoom_start=2)
tgj = plugins.TimestampedGeoJson(geo_data)
m2.add_children(tgj)
Out[3]:

Leaflet.Timedimension es software libre

caption

https://github.com/socib/Leaflet.TimeDimension

Contribuciones a Leaflet.Timedimension

caption

Preguntas?

Gràcies! :-)

In [ ]: