Revision 426 2.1/trunk/doc/Fase 1/dt-visor-3d.rst
dt-visor-3d.rst | ||
---|---|---|
17 | 17 |
:backlinks: none |
18 | 18 |
|
19 | 19 |
.. sectnum:: |
20 |
:depth: 2
|
|
20 |
:depth: 1
|
|
21 | 21 |
:start: 1 |
22 | 22 |
|
23 | 23 |
.. |year| date:: %Y |
... | ... | |
47 | 47 |
Introducción |
48 | 48 |
============= |
49 | 49 |
|
50 |
Este documento detalla el diseño técnico del nuevo visor 3D basado en la librería NASA WW SDK para gvSIG 2.1+. Para más información consulte: |
|
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. |
|
51 | 52 |
|
52 |
* http://worldwind.arc.nasa.gov/java/ |
|
53 |
* http://goworldwind.org/ |
|
53 |
Este documento detalla el diseño técnico de la fase 1 del nuevo visor 3D basado en la librería NASA WW SDK para gvSIG 2.1+. Para más información consulte: |
|
54 | 54 |
|
55 |
El diseño técnico tendrá en cuenta el análisis de requisitos y el análisis funcional realizados. En primer lugar se detallarán el API y las implementaciones de los diferentes módulos del proyecto. |
|
55 |
* http://worldwind.arc.nasa.gov/java/ |
|
56 |
* http://goworldwind.org/ |
|
56 | 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 |
|
|
57 | 63 |
Diseño técnico |
58 | 64 |
===================== |
59 | 65 |
|
60 |
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á el API e implementación de la librería y las extensiones del plugin.
|
|
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.
|
|
61 | 67 |
|
62 |
Ejemplo de casos de uso
|
|
68 |
Ejemplo de caso de uso |
|
63 | 69 |
------------------------------- |
64 | 70 |
|
65 |
A partir de una vista 2D, se desea representar la información cargada en la vista 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). Al pulsar sobre uno de los botones, el plugin accederá a la información de la vista activa mediante la obtención del MapContext y la servirá a la librería NASA WW SDK mediante View3DPanel#add(FLayer layer). El panel obtendrá la capa equivalente mediante el View3DManager#getWWLayer(FLayer, loadMode) y la añadirá a un objeto gov.nasa.worldwind.Model. Cuando todas las capas hayan sido añadidas, se creará el visor mediante View3DSwingManager#createView3DPanel(MapContext, mode).
|
|
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 (si no lo indica se cargarán con los modos de carga por defecto).
|
|
66 | 72 |
|
67 |
Además de las dos extensiones 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().
|
|
73 |
Las capas dependiendo del tipo puede cargarse del siguiente modo:
|
|
68 | 74 |
|
69 |
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. |
|
75 |
* Las capas vectoriales pueden cargarse como "Capa vectorial rasterizada" o "Capa vectorial con simbología 3D". 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" o "Capa raster como elevación". 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". |
|
70 | 77 |
|
71 |
LIB API |
|
72 |
-------- |
|
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, mode). El modo 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. |
|
73 | 79 |
|
74 |
.. note:: |
|
75 |
Los métodos deben lanzar excepciones hacia el nivel más alto de la librería. Como no esta definido el API de excepciones no indico que tipo de excepciones pueden lanzar los métodos. |
|
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(). |
|
76 | 81 |
|
77 |
Este es el API de la librería del visor 3D, la cual esta basada en el modelo de implementación simple API/IMPL.
|
|
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.
|
|
78 | 83 |
|
79 |
* Project: org.gvsig.view3d/org.gvsig.view3d.lib/org.gvsig.view3d.lib.api |
|
80 |
* Package: or.gvsig.view3d.lib.api |
|
84 |
Para más información acerca de las funcionalidades consultar el análisis funcional indicado en `Introducción`_. |
|
81 | 85 |
|
82 |
View3DManager |
|
83 |
********************************************* |
|
84 |
|
|
85 |
Proveerá las siguientes operaciones: |
|
86 |
|
|
87 |
* getWWLayer(FLayer layer, int loadMode) : gov.nasa.worldwind.layers.Layer |
|
88 |
|
|
89 |
A partir de una capa de gvSIG y un modo de carga se obtiene una capa nativa de la librería World Wind. Existen 4 modos de carga: raster imagen, raster elevación, vectorial rasterizada y vectorial 3d. Dependiendo del modo de carga se obtendrá una capa nativa u otra. |
|
90 |
|
|
91 |
|
|
92 |
DataReader |
|
93 |
********************************************* |
|
94 |
|
|
95 |
Proveerá las siguientes operaciones: |
|
96 |
|
|
97 |
* canRead(Object sourceFile) : boolean |
|
98 |
|
|
99 |
Determina si la fuente de datos se puede acceder o no. Puede recibir como parámetro un objeto del tipo File, java.net.URL, String o java.io.InputStream. |
|
100 |
|
|
101 |
* read(Object sourceFile) : gov.nasa.worldwind.layers.Layer |
|
102 |
|
|
103 |
A partir de una fuente de datos crea una capa gov.nasa.worldwind.layers.Layer. |
|
104 |
|
|
105 |
|
|
106 | 86 |
SWING API |
107 | 87 |
---------- |
108 | 88 |
|
... | ... | |
111 | 91 |
* Project: org.gvsig.view3d/org.gvsig.view3d.swing/org.gvsig.view3d.swing.api |
112 | 92 |
* Package: or.gvsig.view3d.swing.api |
113 | 93 |
|
114 |
View3DSwingManager
|
|
94 |
View3DManager |
|
115 | 95 |
******************** |
116 | 96 |
|
117 |
* createView3DPanel(int mode) : View3DPanel
|
|
97 |
* createView3DPanel(MapContext theMapContext, TYPE type) : View3DPanel
|
|
118 | 98 |
|
119 |
Crea un panel con el componente para dibujar la información en 3D y lo configura dependiendo del modo indicado. Existen dos modos posibles View3DMode.SPHERE y View3DMode.FLAT.
|
|
99 |
Crea un objeto View3DPanel pasándole como parámetro el MapContext y el tipo de panel.
|
|
120 | 100 |
|
121 |
* createView3DPanel(MapContext theMapContext, int mode) : View3DPanel |
|
122 |
|
|
123 |
Crea un panel con el componente para dibujar la información en 3D a partir de un MapContext y lo configura dependiendo del modo indicado. Existen dos modos posibles View3DMode.SPHERE y View3DMode.FLAT. |
|
124 |
|
|
125 |
|
|
126 |
View3DPanel extends JPanel |
|
101 |
View3DPanel |
|
127 | 102 |
**************************** |
128 | 103 |
|
129 |
Clase abstracta que extiende de JPanel. Como JPanel no tiene una interfaz definida, crearemos una clase abstracta que implementará la vista del visor (tamaño, inicialización de componentes...) y definirá el API de nuestro componente. Se añadirá los siguientes métodos definidos pero sin implementarlos.
|
|
104 |
Define el API del visor 3D.
|
|
130 | 105 |
|
131 |
* add(FLayer layer) : void |
|
106 |
* add(FLayer layer, LOADMODE loadMode) : void
|
|
132 | 107 |
|
133 |
A partir de la capa que recibe como parámetro, obtiene la capa equivalente en la librería World Wind y la añade..
|
|
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.
|
|
134 | 109 |
|
135 |
* add(FLayers layers) : void
|
|
110 |
* getMapContext() : MapContext
|
|
136 | 111 |
|
137 |
A partir de la colección de capas, obtiene las capas equivalentes en la librería World Wind y las añade respetando el orden.
|
|
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.
|
|
138 | 113 |
|
139 |
* getMapContext() : MapContext
|
|
114 |
* getType() : TYPE
|
|
140 | 115 |
|
141 |
Obtiene el MapContext asociado al panel. Del MapContext asociado se extrae la información necesaria para la representación de los datos en 3D y la sincronización de enfoques.
|
|
116 |
Obtiene el tipo del visor. Devuelve un objeto enum que puede ser TPYE.SPHERE o TYPE.FLAT (ver `TYPE`_).
|
|
142 | 117 |
|
143 | 118 |
* getVerticalExaggeration() : double |
144 | 119 |
|
... | ... | |
150 | 125 |
|
151 | 126 |
* remove(FLayer layer) : void |
152 | 127 |
|
153 |
Elimina la capa equivalente de la recibida como parámetro. |
|
128 |
Elimina la capa equivalente de la recibida como parámetro y actualiza el visor.
|
|
154 | 129 |
|
155 | 130 |
* removeAll() : void |
156 | 131 |
|
157 |
Elimina todas las capas cargadas. |
|
132 |
Elimina todas las capas cargadas y actualiza el visor.
|
|
158 | 133 |
|
159 | 134 |
* setMapContext(MapContext theMapContext) : void |
160 | 135 |
|
161 |
Establece el MapContext al visor.
|
|
136 |
Establece el MapContext al visor y recarga la información mediante reloadLayers().
|
|
162 | 137 |
|
163 | 138 |
* setVerticalExaggeration(double verticalExaggeration) : void |
164 | 139 |
|
... | ... | |
166 | 141 |
|
167 | 142 |
* show() : void |
168 | 143 |
|
169 |
Muestra el visor.
|
|
144 |
Invoca al WindowManager para mostrar el visor en modo ventana.
|
|
170 | 145 |
|
171 | 146 |
* showAtmosphere() : void |
172 | 147 |
|
... | ... | |
190 | 165 |
|
191 | 166 |
* synchronizeViewPorts() : void |
192 | 167 |
|
193 |
Sincroniza el viewPort de la vista 2D enlazada al visor con el enfoque del visor 3D.
|
|
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.
|
|
194 | 169 |
|
195 | 170 |
* hideAtmosphere() : void |
196 | 171 |
|
... | ... | |
212 | 187 |
|
213 | 188 |
Oculta la escala del mapa. |
214 | 189 |
|
190 |
TYPE |
|
191 |
************* |
|
215 | 192 |
|
216 |
LIB IMPL |
|
217 |
---------- |
|
193 |
Enumerado que representa los dos tipos posibles de un visor 3D. Los dos tipos son: TYPE.SPHERE y TYPE.FLAT. |
|
218 | 194 |
|
219 |
DefaultView3DManager implements View3dManager
|
|
220 |
****************************************************
|
|
195 |
LOADMODE
|
|
196 |
************** |
|
221 | 197 |
|
222 |
Implementación por defecto del manager View3DManager
|
|
198 |
Enumerado que representa los posibles modos de carga de las capas. Los modos de carga son cuatro: ELEVATION, RASTER, RASTERIZEDVEC, VECTORIAL.
|
|
223 | 199 |
|
224 |
DefaultVectorialDataReader implements DataReader
|
|
225 |
************************************************* |
|
200 |
AbstractView3DPanel extends JPanel implements View3DPanel
|
|
201 |
************************************************************
|
|
226 | 202 |
|
227 |
Implementación por defecto de la interfaz DataReader. Esta implementación se debe usar para acceder cuando la fuente de datos sea de tipo vectorial.
|
|
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.
|
|
228 | 204 |
|
229 |
DefaultRasterDataReader implements DataReader |
|
230 |
************************************************ |
|
231 |
|
|
232 |
Implementación por defecto de la interfaz DataReader. Esta implementación se debe usar para acceder cuando la fuente de datos sea de tipo raster. |
|
233 |
|
|
234 |
DefaultElevationDataReader implements DataReader |
|
235 |
************************************************ |
|
236 |
|
|
237 |
Implementación por defecto de la interfaz DataReader. Esta implementación se debe usar para acceder cuando la fuente de datos sea de tipo raster y el modo de carga elevación. |
|
238 |
|
|
239 |
|
|
240 | 205 |
SWING IMPL |
241 | 206 |
-------------- |
242 | 207 |
|
243 |
DefaultView3DSwingManager implements View3DSwingManager |
|
208 |
Este es la implementación 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. |
|
209 |
|
|
210 |
* Project: org.gvsig.view3d/org.gvsig.view3d.swing/org.gvsig.view3d.swing.impl |
|
211 |
* Package: or.gvsig.view3d.swing.impl |
|
212 |
|
|
213 |
DefaultView3DManager implements View3DManager |
|
244 | 214 |
******************************************************** |
245 | 215 |
|
246 |
Implementación por defecto del manager View3DSwingManager
|
|
216 |
Implementación por defecto del manager View3DManager |
|
247 | 217 |
|
248 |
DefaultView3DPanel extends View3DPanel |
|
218 |
DefaultView3DPanel extends AbstractView3DPanel
|
|
249 | 219 |
*************************************************** |
250 | 220 |
|
251 |
Implementación por defecto de los métodos descritos en la clase abstracta View3DPanel
|
|
221 |
Implementación por defecto de los métodos descritos en la interfaz View3DPanel.
|
|
252 | 222 |
|
253 |
View3D Plugin |
|
223 |
.. note:: |
|
224 |
TODO: Añadir información de como dar soporte a los diferentes modos de carga. |
|
225 |
|
|
226 |
View3D APP |
|
254 | 227 |
---------------- |
255 | 228 |
|
256 |
Plugin principal de la librería. Estará compuesto por tres extensiones: View3DExtension, RefreshView3DExtension y SynchronizeView3DExtension. Además, gestionará la persistencia de las opciones establecidas por el usuario. El plugin registrará las acciones mediante el config.xml y creará el instalable con los archivos JARs.
|
|
229 |
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:
|
|
257 | 230 |
|
258 |
View3DExtension |
|
259 |
************************ |
|
231 |
* org.gvsig.view3d.app |
|
260 | 232 |
|
261 |
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. |
|
233 |
* about |
|
234 |
* i18n |
|
235 |
* images |
|
236 |
* lib |
|
262 | 237 |
|
263 |
RefreshView3DExtension
|
|
264 |
************************
|
|
238 |
* dependencias comunes
|
|
239 |
* dependencias nativas de la plataforma
|
|
265 | 240 |
|
266 |
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(). |
|
241 |
* config.xml |
|
242 |
* package.info |
|
267 | 243 |
|
268 |
SynchronizeView3DExtension
|
|
269 |
****************************
|
|
244 |
Plugin common
|
|
245 |
************* |
|
270 | 246 |
|
271 |
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().
|
|
247 |
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.
|
|
272 | 248 |
|
249 |
* 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. |
|
250 |
* 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(). |
|
251 |
* 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(). |
|
252 |
|
|
273 | 253 |
Persistencia |
274 | 254 |
****************** |
275 | 255 |
|
256 |
.. note:: |
|
257 |
TODO: Apartado incompleto. Completar cuando se diseñe como integrar la propiedades dentro de la librería. |
|
258 |
|
|
276 | 259 |
Se creará un archivo llamado plugin-persistence.def que definirá la estructura de las preferencias. A priori las preferencias tendrán las siguientes propiedades: |
277 | 260 |
|
278 | 261 |
* Tamaño por defecto x : int |
... | ... | |
298 | 281 |
* View: determina la vista del usuario sobre el modelo. La vista se va modificando en base a los eventos de ususario que recibe. |
299 | 282 |
* SceneController: asocia la vista con el modelo. Controla el tiempo y el renderizado del modelo. |
300 | 283 |
|
301 |
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 transparente. La integración del plugin con la librería World Wind se ha diseñado del siguiente modo:
|
|
284 |
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:
|
|
302 | 285 |
|
303 | 286 |
* 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). |
304 | 287 |
* La configuración del globo se realiza al instanciar un objecto View3DPanel. Dependiendo del modo indicado como parámetro, el panel establece una configuración u otra. |
305 |
* La creación de las capas se realiza mediante View3DManager, el cual dependiendo del tipo de carga y el modo instancia una implementación de DataRaster u otra. Estas implementaciónes delegan en la librería World Wide la lectura y procesamiento de los datos de entrada para la creación de las capas WW. Las capas raster imagen usarán la implementación DefaultRasterDataReader, las capas de elevación usarán DefaultElevationDataReader y las capas vectoriales rasterizadas la implementación DefaultVectorialDataReader. |
|
306 | 288 |
|
289 |
.. note:: |
|
290 |
TODO: Apartado imcompleto. Cuando se defina el sopote de los modos de carga definir como se obtiene la capa WW a partir de una capa de gvSIG. |
Also available in: Unified diff