gvsig-3d / 2.1 / trunk / doc / Fase 1 / dt-visor-3d.rst @ 429
History | View | Annotate | Download (16.1 KB)
1 |
================================================================= |
---|---|
2 |
Visor 3D básico que integra Nasa WW SDK |
3 |
================================================================= |
4 |
|
5 |
------------------- |
6 |
Diseño técnico |
7 |
------------------- |
8 |
|
9 |
:Company: gvSIG Association |
10 |
:Author: DiSiD Corporation, S.L. |
11 |
:Revision: $Rev: $ |
12 |
:Date: $Date: $ |
13 |
:Copyright: All rigths reserved |
14 |
|
15 |
.. contents:: |
16 |
:depth: 2 |
17 |
:backlinks: none |
18 |
|
19 |
.. sectnum:: |
20 |
:depth: 1 |
21 |
:start: 1 |
22 |
|
23 |
.. |year| date:: %Y |
24 |
|
25 |
.. header:: |
26 |
|
27 |
.. class:: headertable |
28 |
|
29 |
+-----------------------+-------------------------+ |
30 |
|.. class:: left |.. class:: right | |
31 |
| | | |
32 |
| Diseño técnico |###Page### | |
33 |
+-----------------------+-------------------------+ |
34 |
|
35 |
|
36 |
.. footer:: |
37 |
|
38 |
.. include:: <isonum.txt> |
39 |
|
40 |
.. class:: left |
41 |
|
42 |
*Visor 3D básico que integra Nasa WW SDK - Diseño técnico* |
43 |
|
44 |
|copy| |year| ** |
45 |
|
46 |
|
47 |
Introducción |
48 |
============= |
49 |
|
50 |
.. note:: |
51 |
Este documento esta en continua construcción. A medida que se avance en el proyecto se irá añadiendo nueva información y refinando la existente. |
52 |
|
53 |
Este documento detalla el diseño técnico de las funcionalidades definidas y la arquitectura del nuevo visor 3D basado en la librería NASA WW SDK para gvSIG 2.1+. Para más información consulte: |
54 |
|
55 |
* http://worldwind.arc.nasa.gov/java/ |
56 |
* http://goworldwind.org/ |
57 |
|
58 |
El diseño técnico tendrá en cuenta el análisis de requisitos y el análisis funcional realizados en: |
59 |
|
60 |
* http://devel.gvsig.org/svn/gvsig-3d/2.1/trunk/doc/re-visor-3d.rst |
61 |
* http://devel.gvsig.org/svn/gvsig-3d/2.1/trunk/doc/af-visor-3d.rst |
62 |
|
63 |
Diseño técnico |
64 |
===================== |
65 |
|
66 |
Para tener un poco del contexto del diseño técnico, se expone como debería de funcionar de forma resumida el visor 3D. Seguidamente se detallará como se estructura la librería y la arquitectura de plugins. |
67 |
|
68 |
Ejemplo de caso de uso |
69 |
------------------------------- |
70 |
|
71 |
A partir de una vista 2D, se desea representar la información cargada de forma tridimensional. Para ello, el usuario dispondrá de dos entradas de menú / botones para crear los dos tipos de visores: esférico y plano (View3DExtension, una única extensión para dos acciones). Pero antes de crear el visor 3D, el usuario debe indicar como se deben de cargar las capas mediante las propiedades de cada capa (si no se indica se cargarán con los modos de carga por defecto). |
72 |
|
73 |
Las capas dependiendo del tipo puede cargarse del siguiente modo: |
74 |
|
75 |
* Las capas vectoriales pueden cargarse como "Capa vectorial rasterizada" (LOADMODE.RASTERIZEDVEC) o "Capa vectorial con simbología 3D" (LOADMODE.VECTORIAL). El modo de carga "Capa vectorial rasterizada" toma la información vectorial y crea una imagen (proceso de rasterización) y la carga en el visor 3D. El modo de carga "Capa vectorial con simbología 3D" carga la capa usando simbología 3D. Este último modo de carga no se aboradará a priori. Si el usuario no indica el modo de carga de una capa vectorial por defecto se cargará como "Capa vectorial rasterizada". |
76 |
* Las capas raster puede cargarse como "Capa raster como imagen" (LOADMODE.RASTER) o "Capa raster como elevación" (LOADMODE.ELEVATION). El modo de carga "Capa raster como imagen" toma el raster y lo representa teselado en el visor 3D mientras que el modo de carga "Capa raster como elevación" toma el raster e interpreta los datos para crear una elevación en la superficie del terreno. Si el usuario no indica el modo de carga de una capa raster por defecto se cargará como "Capa raster como imagen". |
77 |
|
78 |
Una vez definidos los modos de carga de las capas, el usuario debe pulsar sobre uno de los botones para crear un visor. Al pulsar, el plugin obtendrá la vista activa en ese momento. Con la vista activa se obtendrá el MapContext mediante IView#getMapControl().getMapContext(). Una vez obtenido el MapContext se creará un nuevo visor mediante View3DManager#createView3DPanel(mapContext, type). El tipo dependerá de la acción ejecutada por el usuario. Al crear el visor, este automáticamente añade las capas del MapContext mediante View3DPanel#add(layer, loadMode). Sólo queda invocar el método View3DPanel#show() para mostrar el visor. |
79 |
|
80 |
Además de la extensión para la creación de visores, el usuario también dispondrá de una extensión llamada RefreshView3DExtension para la actualización de los datos del visor activo con los posibles cambios efectuados sobre la vista 2D. La extensión ejecutará el método View3DPanel#reloadLayers(). |
81 |
|
82 |
Y finalmente, existirá una última extensión llamada SynchronizeView3DExtension que permitirá al usuario sincronizar los enfoques de la vista 2D y el visor 3D asociado a la vista. Se accederá al ViewPort del MapContext asociado para sincronizarlo con el enfoque del visor 3D. |
83 |
|
84 |
Para más información acerca de las funcionalidades consultar el análisis funcional indicado en `Introducción`_. |
85 |
|
86 |
SWING API |
87 |
---------- |
88 |
|
89 |
Este es el API de la interfaz de usuario de la librería del visor 3D, la cual esta basada en el modelo de implementación simple API/IMPL. |
90 |
|
91 |
* Project: org.gvsig.view3d/org.gvsig.view3d.swing/org.gvsig.view3d.swing.api |
92 |
* Package: or.gvsig.view3d.swing.api |
93 |
|
94 |
View3DManager |
95 |
******************** |
96 |
|
97 |
* createView3DPanel(MapContext theMapContext, TYPE type) : View3DPanel |
98 |
|
99 |
Crea un objeto View3DPanel pasándole como parámetro el MapContext y el tipo de panel. |
100 |
|
101 |
View3DPanel |
102 |
**************************** |
103 |
|
104 |
Define el API del visor 3D. |
105 |
|
106 |
* add(FLayer layer, LOADMODE loadMode) : void |
107 |
|
108 |
A partir de la capa que recibe como parámetro y en base al modo de carga obtiene la capa equivalente en la librería World Wind y la añade al visor. |
109 |
|
110 |
* getMapContext() : MapContext |
111 |
|
112 |
Obtiene el MapContext asociado al visor. Del MapContext asociado se extrae la información necesaria para la representación de los datos en 3D y la sincronización de enfoques. |
113 |
|
114 |
* getType() : TYPE |
115 |
|
116 |
Obtiene el tipo del visor. Devuelve un objeto enum que puede ser TPYE.SPHERE o TYPE.FLAT (ver `TYPE`_). |
117 |
|
118 |
* getVerticalExaggeration() : double |
119 |
|
120 |
Obtiene la exageración vertical del visor. |
121 |
|
122 |
* reloadLayers() : void |
123 |
|
124 |
Elimina las capas cargadas. Accede al MapContext asociado al visor y carga de nuevo las capas. Se usa para actualizar el visor con los posibles cambios realizados sobre la vista 2D. |
125 |
|
126 |
* remove(FLayer layer) : void |
127 |
|
128 |
Elimina la capa equivalente de la recibida como parámetro y actualiza el visor. |
129 |
|
130 |
* removeAll() : void |
131 |
|
132 |
Elimina todas las capas cargadas y actualiza el visor. |
133 |
|
134 |
* setMapContext(MapContext theMapContext) : void |
135 |
|
136 |
Establece el MapContext al visor y recarga la información mediante reloadLayers(). |
137 |
|
138 |
* setVerticalExaggeration(double verticalExaggeration) : void |
139 |
|
140 |
Establece las exageración vertical del visor. |
141 |
|
142 |
* show() : void |
143 |
|
144 |
Invoca al WindowManager para mostrar el visor en modo ventana. |
145 |
|
146 |
* showAtmosphere() : void |
147 |
|
148 |
Muestra la atmósfera si el visor es esférico. |
149 |
|
150 |
* showNortIndicator() : void |
151 |
|
152 |
Muestra el indicador del norte. |
153 |
|
154 |
* showMiniMap() : void |
155 |
|
156 |
Muestra el minimapa. |
157 |
|
158 |
* showScale() : void |
159 |
|
160 |
Muestra la escala de la capa. |
161 |
|
162 |
* showStarBackgroundLayer() : void |
163 |
|
164 |
Muestra el fondo de estrellas. |
165 |
|
166 |
* synchronizeViewPorts() : void |
167 |
|
168 |
Obtiene el ViewPort de la vista y realiza las transformaciones necesarias para el enfoque del visor 3D muestra la misma región. Hay que tener en cuenta si la opción "Animación en la sincronización de enfoques" esta marcada o no. En caso de que este marcada la sincronización se debe animar, en caso contrario, no. |
169 |
|
170 |
* hideAtmosphere() : void |
171 |
|
172 |
Oculta la atmósfera en visores esféricos. |
173 |
|
174 |
* hideMiniMap() : void |
175 |
|
176 |
Oculta el minimapa. |
177 |
|
178 |
* hideStarBackgroundLayer() : void |
179 |
|
180 |
Oculta el fondo de estrellas. |
181 |
|
182 |
* hideNorthIndicator() : void |
183 |
|
184 |
Oculta el indicador del norte. |
185 |
|
186 |
* hideScale() : void |
187 |
|
188 |
Oculta la escala del mapa. |
189 |
|
190 |
TYPE |
191 |
************* |
192 |
|
193 |
Enumerado que representa los dos tipos posibles de un visor 3D. Los dos tipos son: SPHERE y FLAT. |
194 |
|
195 |
LOADMODE |
196 |
************** |
197 |
|
198 |
Enumerado que representa los posibles modos de carga de las capas. Los modos de carga son cuatro: ELEVATION, RASTER, RASTERIZEDVEC, VECTORIAL. |
199 |
|
200 |
AbstractView3DPanel extends JPanel implements View3DPanel |
201 |
************************************************************ |
202 |
|
203 |
Clase abstracta que extiende de JPanel. Esta clase abstracta no implementa ninguno de lo métodos de la interfaz View3DPanel, sólo implementa el código relacionado con la instanciación y creación de los componentes de la vista. La implementación por defecto del API recae sobre la clase DefaultView3DPanel. |
204 |
|
205 |
LayerConverter |
206 |
**************** |
207 |
|
208 |
Interfaz que permite convertir una capa gvSIG en una capa WW. Este proceso dependende del tipo de capa y el modo de carga definido. |
209 |
|
210 |
* convert(FLayer layer) : gov.nasa.worldwind.layers.Layer |
211 |
|
212 |
Método que a partir de una capa gvSIG obtiene la capa equivalente en WW. |
213 |
|
214 |
SWING IMPL |
215 |
-------------- |
216 |
|
217 |
Este es la implementación de la interfaz de usuario de la librería del visor 3D. |
218 |
|
219 |
* Project: org.gvsig.view3d/org.gvsig.view3d.swing/org.gvsig.view3d.swing.impl |
220 |
* Package: or.gvsig.view3d.swing.impl |
221 |
|
222 |
DefaultView3DManager implements View3DManager |
223 |
******************************************************** |
224 |
|
225 |
Implementación por defecto del manager View3DManager |
226 |
|
227 |
DefaultView3DPanel extends AbstractView3DPanel |
228 |
*************************************************** |
229 |
|
230 |
Implementación por defecto de los métodos descritos en la interfaz View3DPanel. Esta clase tendrá asociado un MapContext que permitirá obtener información acerca del enfoque, eschuchar enventos de cambio sobre capas y enfoque, versionado... |
231 |
|
232 |
* public DefaultView3DPanel(MapContext mapContext, TYPE type); |
233 |
|
234 |
Constructor que permite instancia un nuevo visor 3D a partir de un MapContext y el tipo. Este constructor invocará a super(type) para la creación e inicialización de los componentes del visor. Además, también accederá a las capas del mapContext para añadirlas al componente de la librería WW. Para añadir una capa al componente WW es necesaria una transformación (LayerConverter#convert(layer)) de la capa gvSIG a una capa WW en base al modo de carga asociado espeficicado por el usuario. |
235 |
|
236 |
DefaultRasterLayerConverter implements LayerConverter |
237 |
********************************************************** |
238 |
|
239 |
Implementación por defecto para convertir capas FLyrRaster de gvSIG en capas SurfaceImageLayer de WW. Se usará el API del objeto FLyrRaster para la conversión. El objeto SurfaceImageLayer permite añadir imágenes mediante dos modos: ruta al archivo y como BufferedImage. Al añadir una imagen a una capa SurfaceImageLayer, la librería WW automáticamente obtiene el proveedor necesario para la lectura de la imagen, la carga y la tesela por lo que no es necesario realizar ninguna acción previa antes de añadir la imagen. La carga de la imagen se debe realizar en un hilo nuevo para no bloquear gvSIG usando TaskStatus. |
240 |
|
241 |
Se puede encontrar un ejemplo de como cargar imagenes en una capa SurfaceImageLayer: |
242 |
|
243 |
http://worldwind31.arc.nasa.gov/svn/tags/2.0.0/WorldWind/src/gov/nasa/worldwindx/examples/SurfaceImageViewer.java |
244 |
|
245 |
.. note:: |
246 |
A priori parace más sencillo usar el path de la imagen que obtener un objecto BufferedImage a partir de la capa raster. |
247 |
|
248 |
DefaultWMSLayerConverter implements LayerConverter |
249 |
********************************************************** |
250 |
|
251 |
.. note:: |
252 |
TODO en fases posteriores |
253 |
|
254 |
DefaultElevationLayerConverter implements LayerConverter |
255 |
*********************************************************** |
256 |
|
257 |
.. note:: |
258 |
TODO en fases posteriores |
259 |
|
260 |
DefaultVectorialLayerConverter implements LayerConverter |
261 |
*********************************************************** |
262 |
|
263 |
.. note:: |
264 |
TODO en fases posteriores |
265 |
|
266 |
View3D APP |
267 |
---------------- |
268 |
|
269 |
Este es el módulo donde se encuentran los diferentes plugins de la librería. Se deben implementar en total cinco plugins. Por un lado, habrá un plugin llamada **org.gvsig.view3d.app.common** el cual contiene todas las extensiones de la librería y los paneles de preferencias de aplicación y de propiedades de vista. Ademas, debe de tener las dependencias comunes a todas las plataformas y el archivo de configuración "config.xml" para la creación de las entradas de menú y botones en gvSIG. Por otro lado, debe de haber un plugin por cada plataforma el cual no debe de contener ninguna clase debido a que ya se encuentran en el plugin "common". Este plugin solo debe de gestionar las dependendencias nativas con la plataforma correspondiente y preparar el empaquetado JAR para que se despliegue como si fuera un plugin normal usando el archivo de configuración del plugin org.gvsig.view3d.app.common asi como sus dependencias junto con las dependencias nativas. El resultado esperado debería ser: |
270 |
|
271 |
* org.gvsig.view3d.app |
272 |
|
273 |
* about |
274 |
* i18n |
275 |
* images |
276 |
* lib |
277 |
|
278 |
* dependencias comunes |
279 |
* dependencias nativas de la plataforma |
280 |
|
281 |
* config.xml |
282 |
* package.info |
283 |
|
284 |
Plugin common |
285 |
************* |
286 |
|
287 |
El plugin common (org.gvsig.view3d.app.common) estará compuesto por tres extensiones: View3DExtension, RefreshView3DExtension y SynchronizeView3DExtension. Además, gestionará la persistencia de las opciones establecidas por el usuario. |
288 |
|
289 |
* View3DExtension: extensión de Andami asociada a dos acciones: "create-flat-view3d" y "create-spherical-view3d". Esta extensión deberá estar siempre visible y activa solo cuando se active una vista 2D con un capa o más. Las dos acciones obtendrán la instancia del View3DSwingManager, crearán el panel, añadirán las capas de la vista activa, y lo mostrarán. |
290 |
* RefreshView3DExtension: extensión de Andami asociada a la acción: "refresh-view3d". Esta extensión deberá estar visible cuando se active un visor 3D y siempre activa. La extensión obtendrá la instancia de tipo View3DPanel y ejecutará la operación View3DPanel#reloadLayers(). |
291 |
* SynchronizeView3DExtension: extensión de Andami asociada a la acción: "synchronize-view3d". Esta extensión deberá estar visible cuando se active una vista3D y siempre activa. La extensión obtendrá la instancia de tipo View3DPanel y ejecutará la operación View3DPanel#synchronizeViewPorts(). |
292 |
|
293 |
Persistencia |
294 |
************* |
295 |
|
296 |
.. note:: |
297 |
TODO en fases posteriores. Definir panales y gestión de preferencias. |
298 |
|
299 |
Integración con la librería NASA WW SDK |
300 |
---------------------------------------- |
301 |
|
302 |
World Wind es una colección de componentes que de forma interactiva muestran información geográfica en 3D. Las aplicaciones o applets que usen la librería deberá integrar uno o más componentes dentro de su interfaz gráfica. World wind sigue el siguiente esquema: |
303 |
|
304 |
.. image:: ../images/world-wind-diagram.png |
305 |
|
306 |
* Globe: representa la forma del planeta y el terreno. Contiene un Tessellator el cual es el encargado de generar el terreno. |
307 |
* Layer: las capas añaden las imagenes, objectos u otra información al globo. La capas se ajustan a la forma del globo y se mueven junto a el cuando el usuario navega por el espacio tridimensional. |
308 |
* Model: junta el globo y las capas. |
309 |
* View: determina la vista del usuario sobre el modelo. La vista se va modificando en base a los eventos de ususario que recibe. |
310 |
* SceneController: asocia la vista con el modelo. Controla el tiempo y el renderizado del modelo. |
311 |
|
312 |
Se pretende crear una nivel de abstracción que ofrezca a los consumidores de la librería la funcionalidades descritas en el análisis funcional de forma que no tengan que interactuar con la librería WW. La integración del plugin con la librería World Wind se ha diseñado del siguiente modo: |
313 |
|
314 |
* El componente View3DPanel integra un componente WorldWindowGLJPanel. WorldWindowGLJPanel es autocontenido y su propósito es servir la aplicación WorldWind mostrando el modelo definido (globo y capas). |
315 |
* La librería posee unos archivos de configuración en XML que son cargados cuando la librería se registra. Estos archivos de configuración por un lado definen la clases que implementan los distintos servicios que ofrece la librería y por otro las capas que se cargan por defecto al crear un modelo básico. |
316 |
* Además de esta configuración, es necesario configurar unos parámetros espeficios para crear un WorldWindowGLJPanel esférico o plano. Esta configuración se realiza al instanciar un objecto View3DPanel. Dependiendo del modo indicado como parámetro, se establece una configuración u otra. |
317 |
* La obtención de las capas WW a partir de capas de gvSIG se realiza mediante la clase LayerConverter la cual permite obtener la capa equivalente en WW a partir de una capa de gvSIG para añadirla a las capas del modelo WW. |