gvSIG permite trabajar con múltiples y diferentes tipos de capas, de manera que cada una, según su naturaleza, tiene unas propiedades y comportamiento que no tienen porqué coincidir con las de otro tipo. En cambio, todas las capas, al menos teóricamente, pueden estar en un reducido número de estados simultáneos. A cada conjunto posible de estados simultáneos se les denomina estatus.
A nivel genérico, el estatus de una capa está definido en la clase FLayerStatus del proyecto libFMap, como se observa en el diagrama 1.
Así, se observa como la clase abstracta con la implementación común para todas las capas, FLyrDefault, contiene y utiliza una instancia de tipo FLayerStatus que representa el estatus actual en que puede estar cualquier tipo de capa.
En la práctica, una capa dada solo podrá estar en un subconjunto de los posibles estatus, teniendo en cuenta su naturaleza.
El estatus de una capa almacena la información de las excepciones que se puedan ir produciendo cuando se utiliza el driver asociado a ella, este tipo de excepción es DriverException.
Estado | Activo [1] |
---|---|
Activa | No |
Visible | Sí |
Disponible | Sí |
Sucia | No |
En TOC | Sí |
Editándose | No |
Puede escribirse | No |
Caché de capas dibujadas | No |
[1] | "Activo" equivale a "true" a nivel de programación. |
En este apartado se han colocado unos ejemplos visuales con los que un usuario podría conocer el estado de la capa/s con la que está trabajando en gvSIG:
Toda capa utilizada en gvSIG hereda de la clase FlyrDefault, que implementa la declaración genérica y común de capa: el interfaz FLayer .
FlyrDefault, es una clase abstracta, con métodos genéricos para trabajar con capas definidos en la interfaz FLayer, métodos genéricos para trabajar con drivers (para utilizar la capa), definidos en la interfaz Driver, y otros métodos propios.
FLayer, incluye los métodos necesarios para trabajar con proyecciones, definidos en la interfaz Projected, con otros para trabajar con capas.
Por otro lado, es posible tener una colección de capas como nodo de un árbol de capas, y así poder trabajar con distintos niveles. Para ello, se definió la clase FLayers, que hereda de FlyrDefault, e implementa la interfaz LayerCollection con los métodos para trabajar con un conjunto de capas.
Dado que las capas de un mismo nodo pueden ser de distinto tipo, FLayers implementa, por compatibilidad, las interfaces InfoByPoint y VectorialData. Así, es posible que algunas capas trabajen con datos vectoriales, por ello se implementa la interfaz VectorialData; y/o a la vez es posible que soporten la operación de obtención de información a partir de un punto, por ello se implementa la interfaz InfoByPoint.
El siguiente diagrama muestra gráficamente lo explicado, sin entrar en detalles acerca de métodos ni atributos, pero sí listeners que se pueden asociar a una capa, con los correspondientes eventos que pueden recibir, y los tipos de excepciones que se pueden llegar a lanzar en caso de producirse algún error trabajando con una capa:
Permite obtener la proyección actual de la capa, o reproyectar a partir de unas coordenadas de transformación.
Define la funcionalidad básica para trabajar con cualquier tipo de capa:
Ubicado en la biblioteca libDriverManager, define un método para que todos los drivers puedan devolver su nombre identificativo.
Mientras que FLayer es una definición de funcionalidad genérica para cualquier tipo de capa, FlyrDefault representa la capa genérica de la que se particularizará para WMS, WCS, raster, vectorial, capa de texto, colección de capas, etc.
Posee la misma funcionalidad que FLayer, y además agrega:
Define métodos para trabajar con una colección de capas:
Define un método para obtener información de un área de tolerancia centrada en un punto de la capa o capas.
Permite utilizar el patrón software Visitor con la lógica que indica cómo procesar datos vectoriales. Además permite procesar todas las geometrías, solo aquellas indicadas, o solo aquellas que corten el perímetro de un rectángulo determinado.
Representa un conjunto genérico de capas (FLayer). Posee el mismo comportamiento que FLyrDefault, pero adaptándolo para soportar un árbol de nodos que puede ser cada uno, una sola capa, u otro conjunto (otro nodo de tipo FLayers). Además, incluye la funcionalidad de LayerCollection, InfoByPoint, y VectorialData, y permite:
El diagrama anterior nos muestra los tipos de excepciones que puede lanzar por defecto cualquier tipo de capa, siempre que se haya producido algún tipo de error. Se indica aquí un breve resumen de cada uno de ellas:
[1] | Marshall es como se denomina al proceso por el que un objecto se serializa usando XML, es decir, devuelve su información de modo que se pueda transmitir por una conexión, o persistir en un fichero o memoria, siguiendo el estándar XML para estructurar dicha información. Al proceso inverso se le denomina Unmarshall. |
gvSIG pinta usando el patrón "SingleWorketThread".
Las peticiones de dibujado se encolan y se envían a un único thread que lanza el dibujado con un objeto de tipo Cancellable para permitir interrumpir ese dibujado.
El thread de pintado va recibiendo comandos de pintado e inmediatamente se pone a pintar en segundo plano sobre una imagen en memoria. Frecuentemente, y para observar el progreso (porque puede llegar a tardar varios segundos en terminarlo) MapContext renderiza esa imagen y se muestra en pantalla. Esto es cada 400 milisegundos (y a partir de v1.2 será configurable de manera que se puede ver el progreso en tiempo real) y en el momento en que el thread ha terminado de pintar.
El dibujado de las capas lo hace MapContext. MapContext puede pintar sobre un Graphics2D que provenga de una imagen (caso de las peticiones del MapControl) o sobre un Graphics2D que venga de otro sitio (por ejemplo al imprimir). MapContext tiene una colección FLayers, y cada capa tiene un método draw. Para terminar, existe un "StrategyManager" que, en función del tipo de capa, escoge una estrategia de pintado u otra (patrón "Strategy"). Las estrategias de pintado están en el paquete "operations", dentro de libFMap, y las más interesantes son ShpStrategy y DBStrategy.
Por otra parte, si se observa el interfaz de las capas (FLayers) se verá que el método draw (que dibuja cada capa) tiene un argumento Cancellable que tiene un método isCanceled(). Cuando se ha cancelado el pintado (sea por un zoom, un pan o cualquier otro evento que comporte que lo que hay actualmente ya no es válido y debe de recalcularse) entonces isCanceled() devuelve true. En cualquier otro caso devuelve false.
La agilización de la cancelación se realiza dentro de cada una de las iteraciones que se hace en el método draw y posteriores llamadas internas, comprobando que isCanceled() es true, y si lo es, se aborta todo el proceso y entonces se sale del método del draw, si no lo es, se continua con el renderizando. Si se cancela el pintado de todas las capas de manera encadenada, la petición de draw del MapContext se termina, haciendo que se atienda a la siguiente (la que ha provocado que Mapcontext se invalide y que cancel.isCanceled() devuelva true).
Que el cancelado sea inmediato o no, depende del tipo de capas y de la implementación del método draw de ellas. La mayor parte de las capas tienen en cuenta el Cancelable, pero hay algunas que no lo pueden comprobar e inevitablemente ejecutan su método draw íntegro aunque el resultado no se llegue a mostrar en pantalla.
El método isWritable() de una capa devuelve true si el driver en el que se apoya la capa devuelve true:
public boolean isWritable() {
VectorialDriver drv = getSource().getDriver();
if (!drv.isWritable())
return false;
// VectorialEditableAdapter vea = (VectorialEditableAdapter) lyrVect
// .getSource();
if (drv instanceof IWriteable)
{
IWriter writer = ((IWriteable)drv).getWriter();
if (writer != null)
{
if (writer instanceof ISpatialWriter)
return true;
}
}
return false;
}
En este apartado se describe brevemente los principales tipos de capas que, heredando de FLayer, FLyrDefault, o, FLayers, se implementan en la librería libFMap o en algún otro proyecto de gvSIG . Pulsa aquí para visualizar el diagrama 2 en grande.
Nombre | Ubicación [1] | Descripción |
---|---|---|
FFeatureLyrArcIMS | extArcIMS | Capa de tipo FLyrVect con soporte de cancelación de proceso de cargado, reimplementada para soportar las particularidades del servicio ArcIMS (Arc Internet Map Server): protocolo, estructura de datos, y su manipulación, teniendo una capa de tipo vectorial. |
FFeatureLyrArcIMSCollection | extArcIMS | Capa de tipo FLayers que la reimplementa para soportar un conjunto de capas de tipo FFeatureLyrArcIMS. |
FLayers | libFMap | Capa que representa una colección genérica de capas, e implementa el código necesario para trabajar con ellas. |
FLayerFileVectorial | libFMap | Capa de tipo FLyrVect utilizada para cargar ficheros con información vectorial. |
FLayerGenericVectorial | libFMap | Capa de tipo FLyrVect con un driver asociado. |
FLayerVectorialDB | libFMap | Capa que extiende de FLyrVect utilizada para capas que utilicen JDBC, como son PostGIS, MySQL, Oracle Spatial, etc ... |
FLyrAnnotation | libFMap | Capa de tipo FLyrVect utilizada para representar anotaciones textuales. Mantiene el tamaño de las geometrías dibujadas independientemente del zoom. |
FLyrGT2 | libFMap | Capa de tipo FlyrSecuential utilizada para pruebas. |
FLyrGT2_old | libFMap | Capa de tipo FLyrDefault utilizada para pruebas. |
FLyrRaster | libFMap | Antigua capa para trabajar con imágenes raster, que era ofrecida por la librería libFMap. De tipo FLyrDefault reimplementada para soportar operaciones propias de imágenes raster. Permite además:
|
FLyrRasterSE | extRasterTools-SE | Sustituye a la antigua FlyrRaster, y deja de estar en la librería libFMap. Aporta multitud de mejoras para dar soporte a la gran cantidad de formatos raster existentes. |
FLyrSecuential | libFMap | Definición abstracta de capa con soporte para datos vectoriales, y con una tabla de datos alfanuméricos asociada. |
FLyrText | libFMap | Capa de tipo FLyrDefault que acaba dibujando una serie de FShape's de formas geométricas creados a partir de la información de alto, ancho, posición, y rotación del contenido de una capa vectorial de tipo FLyrVect. |
FLyrVect | libFMap | Capa vectorial genérica: tiene soporte para edición, selección, reproyección, índices vectoriales, leyendas, datos alfanuméricos, acceso aleatorio a datos vectoriales, información por punto, e impresión. Además se le puede establecer la estrategia de recorrido, manipulación y pintado de sus features, y consultar por área rectangular, punto y shape. También realiza un ''marshall''[2] de su información, para poder ser salvarda en un fichero ".gvp" de gvSIG y así restaurarla posteriormente. |
FLyrWCS | extWCS | Capa de tipo FLyrDefault adaptada a las particularidades de WCS (Web Coverage Service), y comportándose como una capa de tipo raster. |
FLyrWFS | extWFS2 | Capa de tipo FLyrDefault adaptada a las particularidades de WFS (Web Feature Service), y comportándose como una capa de tipo vectorial. |
FLyrWMS | extWMS | Capa de tipo FLyrDefault adaptada a las particularidades de WMS (Web Map Service), y comportándose como una capa de tipo raster. |
FRasterLyrArcIMS | extArcIMS | Capa de tipo FLyrDefault con soporte de cancelación de proceso de cargado, reimplementada para soportar las particularidades del servicio ArcIMS (Arc Internet Map Server): protocolo, estructura de datos, y su manipulación, teniendo una capa de tipo raster. |
GraphicLayer | libFMap | Capa con ítems gráficos, que son geometrías con un símbolo y manejadores asociados. Los ítems internos son independientes entre sí, y pueden ser seleccionados separadamente. Utiliza un bit set para definir los ítems que se seleccionan. Y aquellos que sean seleccionados, se dibujarán con manejadores, que según la implementación particular de cada uno, pueden mover el ítem, centrarlo, hacer pinzamientos sobre puntos, etc. |
[1] | La columna "Ubicación" indica en qué proyecto está declarada la capa. |
[2] | Marshall es como se denomina al proceso por el que un objecto se serializa usando XML, es decir, devuelve su información de modo que se pueda transmitir por una conexión, o persistir en un fichero o memoria, siguiendo el estándar XML para estructurar dicha información. Al proceso inverso se le denomina Unmarshall. |