\definecolor{fondo}{RGB}{192,230,231}

\definecolor{gray97}{gray}{.97}
\definecolor{gray75}{gray}{.75}
\definecolor{gray45}{gray}{.45}


\lstset{ language=Java,
     frame=Ltb,
     framerule=0pt,
     aboveskip=0.5cm,
     framextopmargin=3pt,
     framexbottommargin=3pt,
     framexleftmargin=0.4cm,
     framesep=0pt,
     rulesep=.4pt,
     backgroundcolor=\color{fondo},
     rulesepcolor=\color{black},
     %
     stringstyle=\ttfamily,
     showstringspaces = false,
     basicstyle=\small\ttfamily,
     commentstyle=\color{gray45},
     keywordstyle=\bfseries,
     %
     numbers=left,
     numbersep=15pt,
     numberstyle=\tiny,
     numberfirstline = false,
     breaklines=true,
   }

\section{Acceso y representación de información con variable temporal}\label{sec:cuatrode}

\subsection{Objetivos}

El objetivo de este estudio es dotar a \emph{gvSIG} \footnote{\url{http://www.gvsig.org/}} \emph{desktop} algunas funcionalidades para gestionar sistemas de sensores usando estándares de interoperabilidad definidos por la \emph{OGC} \footnote{\url{http://www.opengeospatial.org/}} \cite{Ogc94-OGC} y desarrollada por el \emph{SWE} \footnote{\url{http://www.opengeospatial.org/projects/groups/sensorweb}} (grupo de trabajo \emph{sensor web enablement}). En este contexto se requiere poder recuperar información, visualizarla y procesarla filtrando por la variable temporal tanto en datos vectoriales como raster. Para la consecución de este objetivo y en la primera parte de este documento se requiere un análisis previo del manejo de este tipo de información en otras aplicaciones y una definición de los objetivos a alcanzar. Posteriormente se realiza un análisis de su manejo para los distintos tipos de datos.

En la segunda parte del documento se describe más detalladamente los trabajos llevados a cabo tanto de diseño como de implementación en la la librería de acceso a datos (\emph{DAL}) para añadir este soporte. Además se describe la forma en la que se integra el soporte para la carga de datos desde el formato \emph{NetCDF} tanto ráster como vectorial con la posibilidad de incorporar datos temporales.


\subsection{Estudio del soporte de temporal}

\subsubsection{Estado del arte}

\paragraph{Gestión de tiempo en MapServer}  

Para tener una capa válida \emph{WMS} \cite{Ogc06-OWMSIS} con soporte de tiempo el usuario debe definir una serie de metadatos a nivel de capa:

\begin{itemize}
\item {\bf wms timeextent:} rango de tiempo que representa la capa
\item {\bf wms timeitem:} Nombre de la base de datos donde está la información de tiempo
\item {\bf wms timedefault:} valor de tiempo usado por defecto para esa capa
\end{itemize}

\begin{lstlisting}
LAYER
  NAME "earthquakes"
  METADATA
    "wms_title"    "Earthquakes"
    "wms_timeextent" "2004-01-01/2004-02-01"
    "wms_timeitem" "TIME"
    "wms_timedefault" "2004-01-01 14:10:00"
  END
  TYPE POINT
  STATUS ON
  DATA "quakes"
  CLASS
    ..
  END
END
\end{lstlisting}

Cuando se manda una petición \emph{WMS}, esta debe llevar especificada la información de tiempo. MapServer \footnote{\url{http://mapserver.org/}} soporta varias formas:
\begin{itemize}
\item {\bf single value:} por ejemplo: ...\&TIME=2004-10-12\&... 
\item {\bf multiple values:} por ejemplo: ...\&TIME=2004-10-12, 2004-10-13, 2004-10-14\&... 
\item {\bf single range value:} por ejemplo: ...\&TIME=2004-10-12/2004-10-13\&... 
\item {\bf multiple range values:} por ejemplo: ...\&TIME=2004-10-12/2004-10-13, 2004-10-15/2004-10-16\&... 
\end{itemize}

\paragraph{\emph{NetCDF} (Network Common Data Format)}

\emph{NetCDF} \footnote{\url{http://www.unidata.ucar.edu/software/netcdf/}} es un formato abstracto para matrices multidimensionales diseñado en el \emph{Unidata Program Center} en Builder, Colorado. Este formato permite la representación de datos escalares, vectoriales y la representación de mallas irregulares. El modelo clásico de \emph{NetCDF} consiste en variables, dimensiones y atributos. Estos son los componentes de un \textbf{Dataset} o conjunto de datos.

Las variables son vectores n-dimensionales y estas pueden ser de tipo básicos (\emph{char, byte, short, int, float, double}). Estas variables son usadas para almacenar la mayor parte de los datos. Un valor escalar es tratado como un vector de una dimensión. Las variables tienen un nombre, un tipo de dato, y una forma descrita por su lista de dimensiones. Además puede tener atributos asociados que pueden ser añadidos o editados después de la creación de esta.

Las dimensiones describen los ejes de los vectores de datos. Una dimensión tiene un nombre y una longitud y puede ser usada para representar una dimensión física real, por ejemplo, tiempo, longitud, latitud o altura. Una dimensión ilimitada puede ser expandida en cualquier momento. Normalmente las dimensiones son fijadas cuando son definidas al principio y a no ser que sea una dimensión ilimitada esta no puede ser variada posteriormente. Las operaciones soportadas por una dimensión son: crear pasando el nombre y la longitud, obtener el ID a partir de su nombre, obtener el nombre a partir de su ID y renombrar la dimensión.

Los atributos son valores escalares (vectores de una dimensión) los cuales pueden ser asociados o bien a una variable o a un fichero completo. Estos atributos son usados para almacenar metadatos y son identificados por el nombre o ID de la variable que representan.

Hay 6 tipos de dato soportados en la versión inicial (\emph{char, byte, short, int, float, and double}), pero a partir de la v4.0 se añaden otros tipos diferentes (\emph{unsigned int types, strings, compound types, variable length arrays, enums, opaque}).

El interfaz \emph{NetCDF} soporte varias formas de acceso directo a los datos en un dataset abierto.

\begin{itemize}
\item Acceso a todos los elementos
\item Acceso a los elementos de forma individual, especificado por un vector de índices
\item Acceso a secciones del vector, especificado por un vector de índices  y un vector de conteo.
\item Acceso a secciones del vector subsampleadas, especificado por un vector de índices , un vector de conteo y un vector de pasos.
\item Acceso a secciones del vector mapeadas, especificado por un vector de índices , un vector de conteo, un vector de pasos y un vector de índices de mapeo
\end{itemize}

Los 4 tipos de vectores (\emph{index vector, count vector, stride vector and index mapping vector}) cada uno tiene un elemento por cada dimensión de la variable. Si la variable es escalar esos vectores se ignorarán.

A partir de \emph{NetCDF}4 los ficheros pueden organizar variables, dimensiones y atributos en grupos jerárquicos. Los grupos son como directorios en un sistema de ficheros excepto en que están todos en un mismo fichero. Cada grupo actúa como un \emph{NetCDF} entero en el modelo clásico. Un fichero contiene al menos un grupo (\emph{root}) y cada uno tendrá un ncid (identificador) diferente. El uso de los grupos es opcional. Los atributos globales son globales al grupo y no al fichero. Las posibles aplicaciones de un grupo podrían ser: organizar un gran número de variables, proporcionar un espacio de nombres para múltiples usos de los mismos nombres para dimensiones, atributos y variables, modelizar grandes jerarquías o metadatos, etc....

Los grupos son una de las ventajas que aporta el uso de \emph{NetCDF}. Un pequeño subconjunto de datos de un gran \textbf{Dataset} puede ser accedido de forma eficiente sin necesidad de leer los datos anteriores. 

Otra característica de \emph{NetCDF} es la Entrada/salida en paralelo, esto quiere decir que puede haber varios procesos leyendo o escribiendo en un mismo dataset en paralelo. Para aprovechar esta característica hay que crear y abrir el \textbf{Dataset} con funciones especificas para esto.

\subsubsection{Gestión de tiempo para datos GIS}

\paragraph{Objetivos en la gestión de tiempo de datos GIS}

Soporte de tiempo significa que el acceso a los datos a través de la librería \emph{DAL} \footnote{(Data Access Library) Librería de acceso a datos de \emph{gvSIG}} debería proporcionar un \emph{API} que permita al consumidor acceder a los datos con información temporal y permitir al proveedor seleccionar esta información. Desde un punto de vista vectorial significa que un almacén de datos solo devuelve el conjunto de geometrías que tienen información en la columna temporal y esta coincide con la selección del usuario. En la parte ráster devolverá la información de la capa que esté dentro del intervalo de tiempo seleccionado.

\paragraph{Tiempo en vectorial}

Desde un punto de vista vectorial la columna con información temporal contendrá un lista de pares de valores (\emph{Time, Value}). Esta columna debe ser integrada en \emph{DAL} y puede ser usada por el consumidor para acceder a la información temporal. Para ello habrá que construir una herramienta para que desde el interfaz de usuario se pueda crear un filtro para seleccionar un instante de tiempo o intervalo.

El tiempo puede ser comparado con una dimensión espacial. Cuando un usuario cambia la extensión de una vista, moviendola con la herramienta \emph{pan} o haciendo zoom se recupera un conjunto de información para las capas que están cargadas en la vista. Si la capa es vectorial solo el conjunto de \emph{features} contenidas es esta vista es visualizado. Si la capa es raster solo una parte de la cobertura es mostrada.


\begin{figure}[!h] 
    		\centering 
    		\includegraphics[scale=1]{images/spatialFilter1.png} 
		\label{fig:prode_spatialFilter}
		\caption{Zoom a una capa}
\end{figure}

\newpage

Internamente se está creando un objeto \textbf{DataQuery} \footnote{Objeto que representa una consulta de datos en \emph{DAL}} con un filtro espacial que es mandado a todos los almacenes de datos que están cargados en la vista. Si el almacén de datos es de \emph{features} usará este filtro para decidir que \emph{features} están dentro de la extensión seleccionada y que \emph{features} están fuera.


\begin{figure}[!h] 
    		\centering 
    		\includegraphics[scale=1]{images/spatialFilterVectorial.png} 
		\label{fig:prode_spatialFilterVectorial}
		\caption{Zoom a una capa vectorial}
\end{figure}

\newpage

\paragraph{Tiempo en ráster}

Si el almacén es de ráster usará el filtro para decidir que parte de la cobertura está dentro de la extensión de la vista y que parte está fuera.

\begin{figure}[!h] 
    		\centering 
    		\includegraphics[scale=1]{images/spatialFilterRaster.png} 
		\label{fig:prode_spatialFilterRaster}
		\caption{Zoom a una capa raster}
\end{figure}

\newpage

Esta aproximación para gestionar filtros es muy similar a la gestión de filtros temporales. Es posible crear filtros temporales (por instante y por periodo) que puede se usados por un \textbf{DataStore} \footnote{Objeto que representa un almacén de datos de cualquier tipo (raster, vectorial, BD, etc...) en \emph{DAL}}, \footnote{\url{http://gvsig-desktop.forge.osor.eu/downloads/pub/projects/gvSIG-desktop/docs/reference/org.gvsig.fmap.dal/2.0.0/apidoc/org/gvsig/fmap/dal/DataStore.html}} para devolver un conjunto de esta información. Si el almacén es de vectorial el resultado de el \textbf{DataQuery} temporal es un subconjunto de \emph{features} que son contenidas en el filtro temporal. Este filtro solo puede ser aplicado si el almacén tiene información sobre el tiempo de todas las \emph{features}.

\begin{figure}[!h] 
    		\centering 
    		\includegraphics[scale=1]{images/temporalVectorialFilter.png} 
		\label{fig:prode_temporalVectorialFilter}
		\caption{Filtro temporal a una capa vectorial}
\end{figure}

\newpage

Si el almacén es ráster el resultado de una consulta temporal es exactamente la imagen que está contenida en el filtro. En este caso el almacén tiene que tener varias imágenes y la información acerca el periodo de tiempo de cada uno de ellos.

\begin{figure}[!h] 
    		\centering 
    		\includegraphics[scale=1]{images/temporalRasterFilter.png} 
		\label{fig:prode_temporalRasterFilter}
		\caption{Filtro temporal a una capa ráster}
\end{figure}

\paragraph{Tipos de datos}

Uno de los estudios realizados para el soporte de tiempo es el uso de \emph{Joda-Time} \footnote{\url{http://joda-time.sourceforge.net/}} como soporte nativo de tipo tiempo. Esta es una librería Java que proporciona una sustitución para las clases de tiempo de \emph{Java}. Permite el uso de múltiples sistemas de calendario proporcionando un \emph{API} simple. El calendario proporcionado por defecto es el ISO-8601 \footnote{\url{http://www.iso.org/iso/support/faqs/faqs_widely_used_standards/widely_used_standards_other/date_and_time_format.htm}} teniendo otros disponibles como el Gregoriano, Budista, Juliano, Coptic, Etiope e Islamico.

Los principales tipos en Joda utilizables en \emph{gvSIG} serían:

\begin{itemize}
\item {\bf Instant:} Es un instante de tiempo continuo especificado como un número de milisegundos desde el 1 de enero de 1970.
\item {\bf Partial:} Representación parcial de fecha y tiempo. No está referenciada a una zona sino que representa la posición de un instante en una línea de tiempo continua.
\item {\bf Interval:} Representa un intervalo de tiempo desde un milisegundo a otro instante
\item {\bf Period:} Representa un periodo de tiempo definido. Por ejemplo, 3 años, 5 meses, 2 días, 7 horas,...
\item {\bf Duration:} Representa la duración de una medida temporal en milisegundos. A menudo se obtiene de un Intervalo. 
\end{itemize}

Por razones de implementación y a lo largo de este análisis se decide no utilizar directamente el \emph{API} ofrecida por \emph{Joda-Time} sino que parece más adecuado aplicar un patrón \emph{facade} para construir un API propia que acceda a la librería por debajo, abstrayendo de esta forma a \emph{DAL} del uso directo de la librería. De esta forma se puede usar en un futuro cualquier otra implementación del uso de fechas con un impacto mínimo en toda la librería.

Aparecen de esta forma las clases principales que representa tiempo:

\begin{itemize}
\item {\bf TimeValue:} Clase base para todas las que representan tiempo
\item {\bf TimeInstant:} Es un primitiva de tiempo cuya duración es menor que la resolución de la escala de tiempo,
\item {\bf TimePeriod:} Representa un periodo temporal definido por años, meses, días, horas, etc...
\item {\bf TimeInterval:} Representa una extensión de tiempo. Las funciones principales de un intervalo de tiempo en DAL serán:
\begin{lstlisting}
public long getStart();
public long getEnd();
public boolean included(long date);
public boolean included(Date date);
public boolean intersects(TimeInterval timeInterval);
public boolean intersects(long startTimeInterval, long endTimeInterval);
public boolean intersects(Date startTimeInterval, Date endTimeInterval);
public TimeDuration getDuration();
public void setStart(long start);
public void setEnd(long end);  
public void extend(TimeInterval timeInterval);
\end{lstlisting}
\end{itemize}

\subsection{Soporte de tiempo en \emph{DAL}}

Esta sección intenta desarrollar el análisis sobre la incorporación de tiempo a la librería de acceso a datos (\emph{DAL}).

\subsubsection{Definición de un API de gestión}

Un \textbf{DataStore} tiene un método \textbf{getDataSet} que es usado para recuperar un subconjunto de datos teniendo en cuenta las propiedades y restricciones contenidas en la petición (\textbf{DataQuery}). En un \textbf{DataStore} vectorial hay métodos y utilidades para crear una petición. Con la incorporación del soporte temporal se añaden nuevos parámetros a la petición para filtrar por tiempo una geometría. Este ejemplo recupera todas las features de un almacén de datos que son validos en el instante dado.

%\lstset{language=Java, backgroundcolor=\color{fondo}, basicstyle=\footnotesize,  stringstyle=\ttfamily}

\begin{lstlisting}
FeatureQuery featureQuery = featureStore.createFeatureQuery();
featureQuery.setFeatureType(featureType);
featureQuery.setFilter(new SpatialFilter(new Instant("01-03-2010 10:15")));
FeatureSet features = featureStore.getFeatureSet(featureQuery);
\end{lstlisting}

Un almacén de datos ráster funciona de forma similar a uno vectorial. Tendrá utilidades para recuperar un conjunto de coberturas:

\begin{lstlisting}
RasterQuery rasterQuery = rasterStore.createRasterQuery();  
rasterQuery.setTime(new Instant("01-03-2010 10:15"));
RasterSet rasters = rasterStore.query(rasterQuery);
\end{lstlisting}

\subsubsection{Adaptación al soporte vectorial}

En este apartado se explica la remodelación necesaria para adaptar el \emph{API} de \emph{DAL} vectorial para el soporte temporal. La principal idea es que un \textbf{FeatureType} tiene un atributo temporal que es usado para aplicar las peticiones temporales. 


{\bf FeatureType}

\begin{lstlisting}
public FeatureAttributeDescriptor getDefaultTimelAttribute()
//ONLY IF IS NECCESSARY: public String[] getTimeAttributeNames();
//ONLY IF IS NECCESSARY: public int[] getTimeAttributeIndexes();
//ONLY IF INS NECCESSARY: FeatureAttributeDescriptor[] getTimeAttributes();
//ONLY IF INS NECCESSARY: boolean isTime();
\end{lstlisting}

{\bf EditableFeatureType}

Se añade un método para asignar un nuevo atributo temporal

\begin{lstlisting}
public void setDefaultTimeAttributeName(String name);
\end{lstlisting}

{\bf FeatureAttributeDescriptor}

Se añade un método para conocer si el atributo tiene información temporal o no

\begin{lstlisting}
public boolean isTime(); 
\end{lstlisting}

{\bf EditableFeatureAttributeDescriptor}

Tiene un método para fijar si el atributo contiene información de tiempo

\begin{lstlisting}
public void setIsTime(boolean isTime);
\end{lstlisting}

{\bf FeatureStore}

Usando los metadatos es posible añadir un intervalo temporal para todas las \emph{features} contenidas en un almacén de datos

{\bf Feature}

\begin{lstlisting}
public TimeValuePairList getTimeValuePairList(int index);
public TimeValuePairList getTimeValuePairList(String name);
public ReadableInstant getTimeInstant(int index);
public ReadableInstant getTimeInstant(String name);
public ReadablePartial getTimePartial(int index);
public ReadablePartial getTimePartial(String name);
public ReadableInterval getTimeInterval(int index);
public ReadableInterval getTimeInterval(String name);
public ReadablePeriod getTimePeriod(int index);
public ReadablePeriod getTimePeriod(String name);
\end{lstlisting}

{\bf EditableFeature}

\begin{lstlisting}
public void setTimeValuePairList(String attributeName, TimeValuePairList timeValuePairList);
public void setTimeValuePairList(int attributePosition, TimeValuePairList timeValuePairList); 
public void setTimeInstant(String attributeName, ReadableInstant timeInstant);
public void setTimeInstant(int attributePosition, ReadableInstant timeInstant);  
public void setTimePartial(String attributeName, ReadablePartial timePartial);
public void setTimePartial(int attributePosition, ReadablePartial timePartial);  
public void setTimeInterval(String attributeName, ReadableInterval timeInterval);
public void setTimeInterval(int attributePosition, ReadableInterval timeInterval);  
public void setTimePeriod(String attributeName, ReadablePeriod timePeriod);
public void setTimePeriod(int attributePosition, ReadablePeriod timePeriod);  
\end{lstlisting}

{\bf TimeValuePairList}

\begin{lstlisting}
public int getTimeValuePairCount();
public Object getTimeAt(int index);
//public ReadableInstant getTimeInstantAt(int index);
//public ReadablePartial getTimePartialAt(int index);
//public ReadableInterval getTimeIntervalAt(int index);
//public ReadablePeriod getTimePeriodAt(int index);
public Object getValueAt(int index);
public Object get(Object time);
public Object getLastValue();
public ReadableDuration getTimeDuration();
public EditableTimeValuePairList getEditable();
\end{lstlisting}

{\bf EditableTimeValuePairList}

\begin{lstlisting}
public void deleteTimeValuePairs();
public void deleteTimeValuePairAt(int index);
public void addTimeValuePair(Object time, Object value);
public void addTimeValuePairAt(int index, Object time, Object value);
public void setTimeAt(int index, Object time);
//public void setTimeInstantAt(int index, ReadableInstant timeInstant);
//public void setTimePartialAt(int index, ReadableInstant timePartial);
//public void setTimeIntervalAt(int index, ReadableInstant timeInterval);
//public void setTimePeriodAt(int index, ReadableInstant timePeriod);
public void setValueAt(int index, Object value);
public void setValuePairAt(int index, Object time, Object value)
public TimeValuePairList getNotEditableCopy();
\end{lstlisting}

\paragraph{Persistencia vectorial con \emph{NetCDF}}

\emph{NetCDF} es un contenedor de datos con capacidad para almacenar datos raster y vectorial. En este caso se ha diferenciado ambos tipos en dos proveedores de datos diferentes debido a las fuertes diferencias existentes entre ambos. Para soporte vectorial se creará un proyecto \emph{org.gvsig.netcdf} que incluye una librería de acceso a los datos \emph{org.gvsig.netcdf.lib} y una extensión ligada a la aplicación destino, que este caso es \emph{gvSIG} \emph{org.gvsig.netcdf.app.extension}.

La librería consta de cuatro clases diferentes:

\begin{itemize}
\item {\bf NetCDFFileSystemServerProvider:} el proveedor es usado por el \textbf{DataServerExplorer} \footnote{\url{http://gvsig-desktop.forge.osor.eu/downloads/pub/projects/gvSIG-desktop/docs/reference/org.gvsig.fmap.dal/2.0.0/apidoc/org/gvsig/fmap/dal/DataServerExplorer.html}} para seleccionar que ficheros soportados pueden ser abiertos. Este proveedor está basado en un \textbf{FilesystemServerExplorerProvider} \footnote{\url{http://gvsig-desktop.forge.osor.eu/downloads/pub/projects/gvSIG-desktop/docs/reference/org.gvsig.fmap.dal.file/2.0.0/apidocs/org/gvsig/fmap/dal/serverexplorer/filesystem/spi/FilesystemServerExplorerManager.html}}. Esto significa que no tiene que definir sus propios parámetros en una clase diferente.
\item {\bf NetCDFStoreProvider:} el proveedor de datos es usado por el \textbf{DataStore} para leer datos vectoriales de un fichero \emph{NetCDF}.
\item {\bf NetCDFStoreParameters:} parámetros usados para la carga de un fichero \emph{NetCDF}.
\item {\bf NetCDFLibrary:} La librería registra el \textbf{NetCDFFileSystemServerProvider} en el \textbf{FilesystemServerExplorerManager} \footnote{\url{http://gvsig-desktop.forge.osor.eu/downloads/pub/projects/gvSIG-desktop/docs/reference/org.gvsig.fmap.dal.file/2.0.0/apidocs/org/gvsig/fmap/dal/serverexplorer/filesystem/spi/FilesystemServerExplorerManager.html}} y también registra el \textbf{NetCDFStoreProvider} y sus parámetros asociados \textbf{NetCDFStoreParameters} en el \textbf{DataManager} \footnote{\url{http://gvsig-desktop.forge.osor.eu/downloads/pub/projects/gvSIG-desktop/docs/reference/org.gvsig.fmap.dal/2.0.0/apidoc/org/gvsig/fmap/dal/DataManager.html}}.
\end{itemize}

\subsubsection{Adaptación al soporte ráster}

Este apartado tratará de plasmar el análisis realizado para incorporar un \emph{API} que de soporte al acceso de datos ráster filtrando por variable temporal. La principal idea es que aparece un nuevo proveedor de datos \textbf{TimeSeriesProvider} que está compuesto por una lista de otros proveedores \textbf{RasterDataProvider} y cada uno de estos constituye los datos en un instante de tiempo. Este nuevo proveedor de datos será capaz de gestionar el formato con extensión \emph{.tsf} \emph{(time serial format)}. Cuando un usuario cargue este tipo de formato, este contendrá la ruta a las imágenes que componen la serie temporal o al fichero de datos multitemporal. Esto quiere decir, que este formato gestionará series temporales independientemente de que este formado por un solo fichero multitemporal o por múltiples ficheros ráster con una estructura clásica.

Para la selección de tiempo se dispondrá de un interfaz contenido en los parámetros de este nuevo proveedor de datos:

\begin{lstlisting}
public void selectNextInstant();
public void selectPrevInstant();
public void goTo(int position);
public int getFieldTime();
public void setFieldTime(int timePosInList);
public String getStringTime();
....
\end{lstlisting}

Se necesita definir otra interfaz para definir la información relativa al tiempo. Esta representa la información contenida en una serie de datos y está asociada a un proveedor de datos cualquiera.

\begin{lstlisting}
public interface TimeSeries {
	public void selectSerial(String name);
	public void selectSerial(int pos);
	public String getName();
	public String getDescription();
	public void createNewTime(Time time) throws ParseException;
	public void createNewTimeValue(String value) throws ParseException;

	public void createNewTimeInterval(String dateA, String dateB) throws ParseException;
	public void createNewTimeValue(double value) throws ParseException;
	public void createNewTimeInterval(double a, double b) throws ParseException;
	public int getNumberOfSerials();
	public ArrayList<?> getTimeList();
}
\end{lstlisting}


La recuperación de información ráster usando la variable temporal quedaría de esta forma:

\begin{lstlisting}
RasterQuery rasterQuery = tRasterStore.createRasterQuery();  
rasterQuery.setTime(new Instant("01-03-2010 10:15"));
RasterSet rasters = tRasterStore.query(rasterQuery);
\end{lstlisting}

Selección por instante parcial

\begin{lstlisting}
RasterQuery rasterQuery = tRasterStore.createRasterQuery();   
rasterQuery.setTime(new Partial(152438));
RasterSet rasters = tRasterStore.getRasterSet(rasterQuery);
\end{lstlisting}

Selección por intervalo

\begin{lstlisting}
RasterQuery rasterQuery = tRasterStore.createRasterQuery();  
rasterQuery.setTime(new Interval("01-03-2010 10:15", "15-04-2010 10:15"));
RasterSet rasters = tRasterStore.getRasterSet(rasterQuery);
\end{lstlisting}

\paragraph{Motivación de la refactorización de la librería ráster}

A la hora de introducir información temporal a las capas ráster nos encontramos con alguna problemática que hay que resolver previamente:

\begin{itemize}
\item La librería (\emph{libRaster} \footnote{Librería de acceso a datos ráster de \emph{gvSIG} en versiones anteriores a la 2.0}) sobre la que se desea realizar el estudio que está estabilizada se encuentra co\-rri\-en\-do en una versión de la aplicación obsoleta.
\item La arquitectura necesita cambios para adaptarse a futuras versiones y para alojar el soporte de datos 4D.
\end{itemize}

Debido a estos problemas se decide realizar un análisis previo para la refactorización de clases de dicha librería que nos lleve a solucionar ambos problemas de golpe.
La nueva arquitectura de integración propuesta pasa por definir las tareas y separarlas en tres fases bien definidas:

\begin{itemize}
\item {\bf 1-} Separar perfectamente el \emph{API} de la implementación, donde esta última pueda ser sustituida sin cambios en el interfaz. 
\item {\bf 2-} Integración dentro de la estructura de la librería de acceso a datos (\emph{DAL}). Esta integración permite disponer de un interfaz común para el levantamiento de capas sean ráster o vectoriales. Teniendo posteriormente métodos específicos dependiente del tipo de dato utilizado.
\item {\bf 3-} Soporte de la información 4D dentro de la nueva arquitectura.
\end{itemize}

No es objeto de este documento definir el trabajo de análisis y arquitectura realizado sobre \emph{libRaster} por lo que no se explicará. 

%Se puede encontrar alguna documentación de trabajo en 
%\footnote{\url{https://gvsig.org/web/production/proyectos/raster/docs/papers-and-drafts/incorporacion-de-servicios-%%raster-a-dal/}} y en
%\footnote{\url{https://gvsig.org/web/production/proyectos/raster/docs/papers-and-drafts/apuntes-sobre-el-api-de-libraster/gvsig_document_view}}

El resultado final de este trabajo que sirve como base al estudio de una arquitectura 4D puede verse reflejado en el diagrama \ref{fig:prode_refactoringRaster}:

\begin{figure}[!h] 
    		\centering 
    		\includegraphics[scale=0.75]{images/Diagrama_Raster.png} 
		\caption{Refactoring sobre libRaster para la incorporación posterior de T \label{fig:prode_refactoringRaster}}
\end{figure}


\paragraph{Inclusión del soporte temporal sobre la arquitectura raster}

Existe una estructura básica de datos que es susceptible de ser interrogada para obtener matrices de datos ráster. Esta es \textbf{DefaultMultiRasterDataStore}, que hereda de \textbf{AbstractRasterDataStore}. Esta estructura representa una imagen ráster compuesta de múltiples bandas de similares características (tamaño y tipo de dato). La fuente de dichas bandas puede estar en distintos ficheros.

Para poder leer una matriz de datos ráster en un instante de tiempo dado debería ser necesario introducir esta información en la petición de datos. Para que no sea necesario dar esta información en cada petición lo que se hará es asignar los datos de tiempo al \textbf{DataStore} y a partir de ese momento cualquier consulta que se haga tanto de datos como de metadatos será relativa al instante requerido. En caso de existir información temporal pero no está definida en el instante dado entonces proporcionaría en instante de tiempo anterior más próximo.

Para la selección del instante de tiempo dentro de un almacén de datos se crea un nuevo interfaz \textbf{TRasterStore} que contiene esta capacidad y del cual hereda cualquier almacén de datos ráster. Su forma principal de asignar el tiempo de la serie que queremos recuperar es a través de un método \emph{setTime} donde se asignará un objeto \textbf{SerialInfo} para indicar el instante de tiempo seleccionado.

Un almacén de datos contendrá la información de la serie temporal a la que pertenece a través de un objeto asociado llamado \textbf{TimeSerials}. Esta información puede ser persistida junto con la imagen. \emph{gvSIG} dispone de la posibilidad de guardar metadatos junto a las imágenes en un fichero (rmf). Un nuevo bloque de datos que contenga la información de las series temporales será guardado en este fichero. Por su parte los almacenes de datos deben incorporar la posibilidad de salvar y recuperar esta información a partir de un método estándar en \emph{gvSIG} para esta tarea. El trabajo consistirá en implementar un serializador que escriba y recupere las series del fichero de metadatos.

Finalmente, y a más bajo nivel aparece un nuevo proveedor de datos para series de imágenes raster con información de tiempo asociada llamado \textbf{TimeSeriesProvider} el cual devolverá la información de la imagen cuyo instante de tiempo haya sido seleccionado. 

\newpage

\begin{figure}[!h] 
    		\centering 
    		\includegraphics[scale=0.6]{images/Diagrama_TRaster.png} 
		\caption{Incorporación de T sobre la arquitectura de ráster \label{fig:prode_TRaster}}
\end{figure}

\paragraph{Mosaicos y series temporales}

Para la selección de datos raster por la variable temporal es necesaria una estructura de datos que soporte dicha selección. Además debe quedar integrada con otras funcionalidades que consideren las series temporales como un todo y sobre las cuales se puedan realizar una serie de operaciones. Para dar soporte a todo esto aparece un nuevo tipo de cobertura denominada mosaico. Un mosaico es una capa formada por múltiples fuentes de datos a las que se accede a cada una con su propio proveedor. Las imágenes que componen un mosaico puede solapar o no y será la estructura la encargada de resolver los problemas de solapamiento. Este nuevo tipo debería contener las siguientes características:

\begin{itemize}

\item Una única visión de todas las imágenes como una sola o por separado.

\item El mosaico debe tener una proyección propia. En una primera aproximación se presupone que las imágenes que pasan a formar parte del mosaico están ya en la proyección correcta. Si no es así el usuario debería reproyectarlas previamente. En posteriores iteraciones un mosaico debería ser capaz de convertir las imágenes que lo forman a su proyección.

\item El mosaico debe tener un tamaño de píxel propio e independiente de las distintas fuentes.

\item Debe permitir seleccionar elementos por hora y fecha.

\item Debe poder visualizarse con rapidez. Para ello se generarán piramides y teselas de las partes del mosaico o de este completo.

\item Debe poderse calcular o consultar propiedades básicas tales como \emph{bounding box}, tamaño en píxeles, estadísticas, histograma.

\item Tiene que ser posible en caso de de tratarde de modelos digitales del terreno la aplicación de tablas de color y permitir la posibilidad de aplicar alguna ya existente.

\item Tiene que poder resolver conflictos para áreas superpuestas entre las imágenes que forman el mosaico. Se propondrán distintos métodos para ello como son:

\begin{itemize}
\item {\bf Primero:} Se usa siempre el raster que está encima en el orden en el que se creó.
\item {\bf Último:} Se usa siempre el raster que está debajo en el orden en el que se creó.
\item {\bf Combinado:} El valor de la celda de salida de las áreas superpuestas es una combinación de los valores que se superponen. Este valor se determina a partir de un algoritmo de ponderación basado en la distancia, que depende de la distancia del píxel al borde dentro del área superpuesta.
\item {\bf Medio:} Determina el valor de píxel promedio.
\item {\bf Mínimo:} Se usa el menor valor de los que intervienen.
\item {\bf Máximo:} Se usa el mayor valor de los que intervienen.
\end{itemize}

\item Ha de ser capaz de corregir colores entre las imágenes para ayudar a generar el mosaico como una sola imagen uniforme en caso de que las imágenes que los componen sean RGB. En una primera aproximación se propone el método de correspondencia de histogramas para la corrección. En este método se busca la coincidencia entre el histograma del área superpuesta de referencia y el área superpuesta de origen y, a continuación, aplica la transformación de color a los datos de origen.

\end{itemize}

\textbf{Creación de mosaicos}

Los mosaicos se crearán a partir de capas simples ya existentes a las que se le agregarán otras. Todas los proveedores de un mosaico deben coincidir en el tipo de dato del raster que contiene y en número de bandas. Por ejemplo, podemos crear mosaicos de \emph{MDTs} de tipo \emph{float} o mosaicos de imágenes \emph{RGB} pero no es posible mezclarlas. En el momento de la creación del mosaico el usuario debe decidir los siguientes puntos necesarios para toda la vida del mosaico: 

\begin{itemize}
\item La proyección.
\item El tamaño de píxel.
\item El método de resolución de conflictos en el solape.
\item El método de corrección de color.
\end{itemize}

\textbf{Teselado de mosaicos}

Una vez creado un mosaico se podrá visualizar este con las opciones escogidas. Para la visualización de un mosaico completo se generará la caché de teseleas correspondiente al mosaico. Cada tesela generada en caché se hará con los valores de corrección de color y solape calculados. Es por esto que cualquier cambio en esta información hará que la caché que ya se haya generado tenga que ser descartada y volver a generarse con los nuevos valores.

Para la selección de rangos temporales pueden obtenerse una o varias imágenes del mosaico. Para cada conjunto de imágenes seleccionado se generará la caché de teselas correspondiente a estas con las propiedades de corrección de color y solape seleccionadas.

El cambio de las propiedades de visualización de una de las imágenes o de todas hará que la caché de teselas deba regerarse. Los cambios en las propiedades que hacen que la caché de teselas deba regenerarse con las siguientes:

\begin{itemize}
\item La interpretación de color de una de las imágenes (orden de visualizado de bandas).
\item La tabla de color de una de las imágenes o de todo el mosaico.
\item Algún filtro de visualización (transparencia, realce, ajuste de color, etc...).
\item El método de corrección de color.
\item El método de solape
\end{itemize}

Al variar las propiedades de una de las imágenes del mosaico solo se deberían descartar las capas de la caché en las que intervenga dicha imagen. Para ello debe llevarse un control de dichas propiedades cuando se crea el mosaico y detectar cuando se modifican, para así poder descartar las capas de la caché.

Como se comentó en el documento 5.1 de H9, el nombrado de las capas en la caché de teselas se hace a través de una cadena \emph{MD5} formada por la información de nombre de capa, tipo de archivo, tamaño de la matriz, tamaño de tesela en píxeles, número de niveles, \emph{EPSG}, y tamaño del fichero. 

En este nuevo tipo de proveedor es necesaria más información para generar el nombre ya que no se está almacenando datos de un solo fichero sino de un conjunto de estos. Para esto, el nombre de capa que se le pasa a la caché de teselas será una cadena MD5 formada por la siguiente información: lista de nombres de las capas que la componen, método de corrección de color, método de solape. 

\textbf{Nivel de resolución real}

La caché de teselas genera los niveles de resolución a partir de los ficheros fuente. El tamaño por pixel de la imagen original (en este caso el mosaico completo) puede coincidir o no con la resolución de algún nivel de la caché. Esto quiere decir que los niveles son interpolaciones de los datos reales. 

Para visualizar datos raster esta interpolación es válida, pero no lo es tanto si queremos hacer operaciones con mosaicos de datos que sean modelos digitales de terreno donde el valor exácto de cada píxel es importante. Cuando se solicitan datos con escala real de un mosaico se presenta el problema que no es posible devolver los datos reales ya que todos los niveles de caché están interpolados. 

Para la solución de este problema se propone la generación de un nivel de resolución real el cual se vaya rellenando a medida que se soliciten datos en el que se generarán teselas con la resolución real de la imagen y sin interpolar la información. Siempre que se solicite un buffer de datos con tamaño de píxel real se obtendrá de este nivel.

\textbf{Formato de los mosaicos}

Se define un nuevo tipo de formato que se denominará \emph{.mrf} \emph{(mosaic raster format)}. Este será cargado como si fuera un formato nativo y contendrá la lista de ficheros que forman el mosaico. Un usuario deberá poder crear un mosaico y salvarlo como un fichero de este tipo.


Definición del fichero \emph{.mrf}

<?xml version=1.0 encoding=ISO-8859-15 ?>
<MosaicRasterFormat>

\hspace{1cm} <Name>Katrina</Name>

\hspace{1cm} <Description>Evolución del huracan katrina</Description>

\hspace{2cm} <URIS>

\hspace{3cm} <URI>../files/o5-434453.ecw</URI> 

\hspace{3cm} <URI>../files/o5-434454.ecw</URI> 

\hspace{3cm} <URI>../files/o5-434455.ecw</URI> 

\hspace{3cm} <URI>../files/o5-434456.ecw</URI> 

\hspace{2cm} </URIS>

</MosaicRasterFormat>

\paragraph{Metadatos ráster con la incorporación de serie temporal}

Para la incorporación de la información de serie sobre un ráster debe llevar adjunto los datos de esta. Esta información será añadida a los metadatos de la imagen que están en formato \emph{XML} en un fichero que tiene el mismo nombre de la imagen con la extensión \emph{.rmf}. La estructura de este bloque de metadatos es muy similar a la del fichero \emph{.tsf} y será la siguiente:

\newpage

<TimeSeries>

\hspace{1cm}<SerialElement>

\hspace{2cm} <Name>Katrina</Name>

\hspace{2cm} <Description>Evolución del huracan katrina</Description>

\hspace{2cm} <SourceType>1</SourceType> //Single value, multiple values, single range, multiple range 

\hspace{2cm} <DataType>1</DataType> //Date, Numeric

\hspace{2cm} <Dates> 

\hspace{3cm} <Date>28/8/2005-6:10:00</Date> 

\hspace{2cm} </Dates>

\hspace{2cm} </SerialElement>

</TimeSeries>

La información de las series a las que está adscrito el ráster se cargará cuando sea solicitada y no cuando se levante la capa para evitar tiempos de espera y memoria ocupada innecesaria.


\paragraph{Funcionalidades de librería}

Con las nuevas estructuras de datos, libRaster es enriquecida con funcionalidades de acceso temporal:

\begin{itemize}
\item {\bf Crear proveedor de datos para serie temporal:} Los proveedores de datos que se crean por defecto en ráster no son útiles y será necesario crear un proveedor específico que pueda estar formado por uno o varios incluidos dentro de el.
\item {\bf Cargar proveedor de datos para serie temporal:} Una capa ráster debe poder saber cuando se carga un proyecto que la capa es de tipo temporal y como crear ese tipo de almacén de datos asociado a esta.
\item {\bf Crear una serie temporal:} A partir de un fichero multitemporal o múltiples ficheros en disco debe ser posible crear una serie temporal que contenga la información de tiempo incluida en los metadatos o que esté definida por el usuario
\item {\bf Recuperar datos de un instante:} Una vez seleccionado un instante las consultas de datos serán relativas a ese momento.
\item {\bf Recuperar datos de un intervalo:} Una vez seleccionado un instante por intervalo las consultas de datos serán relativas a ese momento.
\item {\bf Salvar información de series de un \emph{DataStore} a sus metadatos:} Persistencia de las series asociadas a un fichero. Debe de ser posible escribir en los metadatos este tipo de información.
\item {\bf Recuperar información de series de un \emph{DataStore} a sus metadatos:} Persistencia de las series asociadas a un fichero. Debe de ser posible recuperar de los metadatos este tipo de información.
\end{itemize}


\paragraph{Funcionalidades de usuario}

El objetivo final de la tarea es integrar a nivel de la aplicación cliente una serie de funcionalidades útiles para el manejo y aprovechamiento de la información temporal. A nivel de usuario y de cara al cliente que vaya a consumir los servicios se expondrán las siguientes funcionalidades:

\begin{itemize}
\item {\bf Crear serie temporal:} Poder asignar a una serie de imágenes la información de tiempo.
\item {\bf Cargar serie temporal:} Cargar una serie de imágenes con su información de tiempo en la vista 2D y 3D de \emph{gvSIG}.
\item {\bf Barra de tiempo para seleccionar un instante:} Integración dentro de la interfaz gráfica un componente para selección de un instante temporal.
\item {\bf Animación de la serie:} Generación de animaciones a partir de la información temporal.
\item {\bf Aplicación de procesos para el instante de tiempo seleccionado:} Posibilidad de aplicar procesamiento para los datos del instante de tiempo seleccionado.
\end{itemize}


\paragraph{Persistencia ráster con \emph{NetCDF}}

Como se ha visto en la parte de almacenamiento de datos en \emph{NetCDF} podemos guardar información ráster en este tipo de contenedor y aprovechar la característica de almacenamiento de datos multidimensionales. Además de poder acceder a los datos a través de la variable temporal también permite el acceso a datos a través de otros tipo de variables. Para cada una de ellas debe ser posible seleccionar la variable Z en la cual está la información seleccionada. 

Como información básica debe ser posible visualizar algunos metadatos útiles para cada variable que tiene el contenedor. De esta forma, y con las necesidades básicas definidas es posible diseñar un pequeño interfaz para la selección manual de los datos del contenedor que queremos visualizar en cada instante. 

Para la estructura de proyecto se seguirá la recomendación para los proyectos soportados de forma oficial en \emph{gvSIG} 2.0

\begin{itemize}

\item {\bf org.gvsig.raster.netcdf:} Proyecto base donde estará todo lo relacionado con \emph{NetCDF}. Este proyecto estará alojado en un repositorio propio (\emph{SVN}) donde puede tener mantenedores independientes con permisos de escritura.

\item {\bf org.gvsig.raster.netcdf.app:} Extensión sobre \emph{gvSIG} para el soporte de este formato. Aquí debe ir el código relacionado con \emph{gvSIG} y de interfaz de usuario necesario.

\item {\bf org.gvsig.raster.netcdf.io}: Proveedor de datos \emph{NetCDF} donde se dota de un interfaz para la entrada salida de este tipo de formato. Este se apoya sobre la librería java proporcionada por el proyecto \emph{netCDF-java}

\end{itemize}

Para la lectura de datos se propone una estructura consistente en separar la parte proveedora de datos, consulta de información del contenedor, parámetros al contenedor y parte de aplicación. 

\begin{itemize}

\item {\bf Provider:} Proporciona los datos de acuerdo a los parámetros pasados desde el cliente

\item {\bf Explorer:} Aporta información sobre el contenedor de datos (que tipo de ficheros acepta, los parámetros necesarios para su utilización, etc...)

\item {\bf Parameters:} Parámetros pasados desde el cliente para las consultas de datos (extensión, ancho y alto en píxeles, etc...).

\item {\bf extensión de \emph{gvSIG}:} Parte cliente. Accede a la información proporcionada por el proveedor de datos. 

\end{itemize}

\begin{figure}[!h] 
    		\centering 
    		\includegraphics[scale=0.45]{images/netCDF-Diagram.jpg} 
		\caption{Arquitectura del proveedor de datos \emph{NetCDF} \label{fig:prode_netCDF-Diagram}}
\end{figure}

\newpage

En la integración a nivel de usuario y como trabajo previo a la integración con todo el interfaz de manejo de información temporal definido en este estudio y en el AEI 8.8 se diseña e implementa un interfaz de usuario para la selección de los parámetros descritos.

Este interfaz nos debe permitir la posibilidad de seleccionar la variable de tipo \emph{Grid} que queramos visualizar. Además debe mostrar el instante temporal de dicha variable así como la Z en la que están los datos. A nivel informativo se puede visualizar cualquier tipo de variable contenida en el fichero y la información básica asociada a esta que aparece en una tabla. Esta información entre otra aporta el número de dimensiones, tipo de dato, descripción, etc...

\begin{figure}[!h] 
    		\centering 
    		\includegraphics[scale=0.75]{images/netcdf-ui.jpg} 
		\caption{Interfaz de usuario para la selección de variables \emph{Grid} en \emph{NetCDF} \label{fig:prode_netCDF-ui}}
\end{figure}

\newpage

\subsubsection{Visualización en gvSIG 3D de datos ráster con variable temporal}

En este apartado se valorará la incorporación de visualización temporal en el
globo virtual \emph{gvSIG 3D}. Es necesario analizar la inclusión de datos 4D tanto en
formato vectorial como en formato raster, además de estudiar posibles
implementaciones del grafo de escena de manera que la visualización continúe
siendo interactiva y fluida. Este formato de datos puede albergar volúmenes
bastante grandes, por lo que el correcto manejo de la memoria y la generación
de un grafo de escena óptimos se revelan claves en este punto.    

El objetivo claro es poder visualizar información 4D, tanto en un instante de
tiempo como en un intervalo temporal. De este modo se puede analizar la
variación de los datos en el tiempo desde una perspectiva tridimensional. Sin
embargo para que la navegación sea fluida se deberá poner especial atención en
el momento de construir el grafo de escena. 

Se debe tener en cuenta que las necesidades de un visualizador 3D distan mucho
de las de un visualizador 2D, por lo que el acceso a datos utilizado por gvSIG
2D podría ser insuficiente para cubrir las necesidades de \emph{gvSIG 3D}. Se
propopone la separación entre acceso a datos para su análisis y acceso a datos
para su visualización, reutilizando siempre que se pueda, el acceso a datos de
\emph{gvSIG 2D}. 

En una primera aproximación se va a utilizar el acceso a datos implementado
para \emph{gvSIG 2D}, de manera que se pueda hacer uso de las estructuras de caché
planteadas anteriormente. Pese a que el acceso a caché es más rápido que la
generación bajo demanda de teselas, ésta puede no ser suficiente para poder
visualizar una animación fluida de datos temporales en 3D. Por ello en una
segunda fase se procederá a implementar estructuras de datos propias en la
librería núcleo de \emph{gvSIG 3D: OSGVirtualPlanets (OSGVP)}.

En la siguiente sección se describirá la estrategia a seguir para el acceso a
datos mediante la primera aproximación. 

\paragraph{Primera aproximación: Utilizando el acceso a datos del visualizador 2D} 


\begin{figure}[!h] 
    		\centering 
    		\includegraphics[scale=0.5]{images/osgvpLayerManagement.jpg} 
		\caption{Estructura de datos utilizada en osgVirtualPlanets
para el manejo de capas de terreno\label{fig:prode_osgvpLM}}
\end{figure}

La estructura de datos actual en \emph{OSGVP}, que se puede ver en la figura
(\ref{fig:prode_osgvpLM}), es casi suficiente para implementar la primera
aproximación. El modelo se construye en torno a la entidad Terreno
(\textbf{Terrain}). Cada Terreno tiene asociado un manejador de capas
(\textbf{LayerManager}) que contiene referencias a todas las capas asociadas a
un terreno. Cada una de estas capas contiene una cola de eventos
(\textbf{EventQueue}), que es utilizada para ejecutar peticiones de datos datos
cumpliendo la interfaz \textbf{JavaDataDriver}.          


\begin{figure}[!h] 
    		\centering 
    		\includegraphics[scale=0.5]{images/peticiondatos.jpg} 
		\caption{Diagrama de acceso/petición de datos utilizada en osgVirtualPlanets\label{fig:prode_osgvpPD}}
\end{figure}

Por otro lado, cada terreno tiene asociado una serie de \emph{tiles} en los que
se subdivide. Cada \emph{tile} es el encargado de hacer la petición de datos al
\textbf{LayerManager}, éste lo pondrá en la/s cola/s de eventos adecuada para
que las peticiones sean procesadas. Un \emph{tile} se asocia con un conjunto de
estados de capa y cada estado puede tener uno o varios atributos.


La secuencia de funcionamiento (véase Figura \ref{fig:prode_osgvpPD}) es la
siguiente:

\begin{itemize}
	\item{1) Añadir capa temporal: El usuario ha añadido una capa desde la
interfaz gráfica, esta señal se transmite al \textbf{LayerManager}.}
	\item{2) El manejador de capas detecta que es una capa temporal y
registra el driver adecuado para cargar la capa.}
	\item{3) En la siguiente fase de actualización del grafo de escena cada
tile visible actualiza su estado, determinando si necesita datos o no.}
	\item{4) En caso necesario se genera una petición de datos con la
extensión adecuada, esa petición se manda al manejador de capas.}
	\item{5) La petición se añade a la cola de eventos de salida que posee
el driver.}
	\item{6) Esa petición se devuelve a gvSIG para que éste provea de
datos.}
	\item{7) Una vez procesada la petición la aplicación devuelve los datos
demandados, encolando una petición en la cola de eventos de entrada del
driver.}
	\item{8) Se actualiza el estado de la capa y se aplican los datos al
tile.}

\end{itemize}

A priori los únicos cambios necesarios para la primera aproximación serían
definir un nuevo tipo de capa \textbf{TemporalLayer} y registrar el driver para
poder hacer las peticiones de manera ordenada. 

Con esta estructura y haciendo uso de la caché para \emph{netCDF} explicada
anteriormente podríamos obtener una visualización de archivos temporales sin
muchos inconvenientes, pese a que no se podrían realizar animaciones de datos
en 3D sí se podría estudiar cada instante de tiempo por separado. 


