DISEÑO STYLING (LEYENDAS)

1.- Descripción de la solución propuesta

Se me ocurre que en lugar de que una leyenda SLD sea una colección "plana" de símbolos, debería ser un árbol. De esta manera, podemos trabajar con símbolos complejos (compuestos de otros símbolos). Cuando se quiera generar el SLD a partir de una leyenda nuestra, se recorre el árbol en profundidad, escribiendo solo los nodos finales. Si se quiere obtener la leyenda de un SLD, obtendremos un árbol "plano", solo con nodos finales.

La lectura/escritura de un SLD no es una tarea crítica. Da igual si se hace rápido o no, así que he optado por usar Geotools2, y traducir los símbolos que entrega la clase SLDTransformer. Con esto ya tenemos un parser, y solo necesitamos traducir nuestros símbolos a los símbolos de GT2. Nosotros implementaremos los símbolos típicos que gestiona GT2, y el resto de ampliaciones, si se pueden exportar bien, y si no, se pone algo por defecto.

Además, no tenemos ningún servidor libre que implemente bien SLD todavía.

El patrón escogido es el Composite => una colección de símbolos también implementa la interfaz del símbolo.

Para que un desarrollador pueda crear un símbolo que se comporte de una manera especial, el símbolo debería tener una llamada para dibujar un shape. Por tanto, habría que cambiar el sistema de dibujado un poco, que no sea una clase "FGraphicUtilities" la que dibuja, sino que sea el símbolo el responsable del dibujado.

La idea es que a un símbolo simple le pasa el graphics, un Shape y una matriz de transformación, y te dibuja en el graphics. Dependiendo del tipo de símbolo que sea, ya estará preparado para pintar polígonos con relleno, líneas, puntos o etiquetas. Para eso, montamos una herencia con clases como FSymbolPolygon, FSymbolLine, FSymbolPoint, FSymbolPoint, FSymbolLabelPoint, FSymbolLabelLine, FSymbolLabelPolygon. Es decir, cuando creas un símbolo, ya sabes para qué lo quieres (para puntos, líneas, etc).

Para conseguir la extensibilidad con los símbolos, es decir, que un desarrollador implemente su símbolo especial, le pondremos al interfaz símbolo una función que devuelva la clase de un panel que sirva para especificar ese símbolo. Es decir, el desarrollador suministra, además del símbolo, la clase que devolverá ese símbolo. Esta clase será un panel extendido que devolverá el símbolo. A la hora de dar a escoger al usuario los símbolos que puede seleccionar, miraremos los símbolos que devuelvan algo coherente (una clase instanciable) con esa llamada. Si no se suministra esa clase, no damos la posiblidad de escoger el símbolo especial.

Para cada tipo de símbolo que suministramos nosotros, daremos una clase panel para ese símbolo.

Para aclarar más las cosas:

Un símbolo tendrá una función getShapeType que indicará si es adecuado para renderizar puntos, líneas o polígonos. En función del tipo de shape de una capa, cuando le demos al botón de leyenda, aparecerán solo los símbolos que sean adecuados a ese tipo de shape. Por ejemplo, si la capa es de puntos, solo aparecerán símbolos aplicables a los puntos. Si la capa es mixta, el usuario podrá seleccionar a qué tipo de shape le está poniendo el símbolo. (Un combo box con algo como "Ver símbolos para puntos", "líneas", "polígonos"). Dentro de la ventana de "Selector de símbolo", habrá una zona con los símbolos de la librería, un "preview", una zona de botones con los botones de OK, Cancel, Save... y Propiedades, y una zona de opciones comunes a todos los símbolos de la clase seleccionada. Las opciones comunes son:

- Para puntos: Color, tamaño, ángulo

- Para líneas: Color, ancho

- Para polígonos: Fill color, outline width, outline color

Cuando apretamos al botón de Propiedades de símbolo, entramos en otro formulario con 4 zonas: Preview, Layers y Properties. La zona de Layers controla los diferentes símbolos que componen el nuestro (al pintar, se dibuja primero el de más abajo y se va subiendo). La zona Properties empieza con un combo box llamado "Tipo de símbolo". Este combo se tiene que rellenar en tiempo real a partir de las clases que implementen el interfaz IFSymbol adecuado a lo que pretendemos dibujar. Por ejemplo, en ArcGis y para polígonos, este combo muestra "Gradient Fill Symbol", "Line Fill Symbol", "Marker Fill Symbol", "Picture Fill Symbol", "Simple Fill Symbol" (ordenados alfabéticamente). Nosotros vamos a implementar por ahora Simple Fill Symbol y Line Fill Symbol, pero el resto no debería costar mucho.

Los tipo de símbolo para línea en ArcGis son:

- Simple Line: Color, Estilo (solido, dashed, dotted, dash-dot, dash-dot-dot), Grosor

- Cartographic Line: Tiene 3 pestañas (Cartographic Line, Template y Line Properties). En la primera pestaña puedes fijar el color, grosor y "Line caps" (Butt, Round y Square) y "Line Joins" (Mitter, Round, Bevel). En la pestaña de template, el pattern que va a usar la línea, y en la pestaña de Line Properties, el offset y los "decoradores" (cómo termina la línea (con flecha, círculo, etc)).

- Hash Line Symbol (en realidad, se parece a una mezcla de una simple sólida + otra dashed). Lo único es que la capa de dashed puede girar sus tramitos con un ángulo de rotación) Creo que por ahora no hace falta implementarlo en gvSIG.

- Marker Line Symbol. Además de los mismo que en Cartographic Line, una pestaña para seleccionar el símbolo que quieres que se repita.

- Picture Line Symbol. Esta la podemos implementar como una imagen que recuperas de disco, y la usas para crear un TexturePaint.

Para Polígono:

- Simple Fill Symbol: Una pestaña con el color de Fondo, el outline color, el grosor del outline y un botón para seleccionar el tipo de línea que abre la ventana "Symbol Selector" mostrando todos los tipos de línea disponibles.

- Line Fill Symbol: Una pestaña con el color del tramado, 3 números con el ángulo, el offset y la separación, y 2 botones que llaman al "Symbol Selector" para seleccionar el tipo de línea a usar con el tramado y con el outline.

- Marker Fill Symbol. Una pestaña (no 2 como en ArcGis) con el color del símbolo, un botón para el tipo de símbolo a emplear, el outline, si lo quieres matricial o aleatorio, el offset en x e y, y la separación en x e y.

- Picture Fill: Usar una imagen para montar un TexturePaint

- Gradient Fill: Fijar el outline, la rampa de colores, si lo quieres linear o circular y el ángulo.

Para puntos:

- Character Marker Symbol: 2 pestañas, una con Color, Carácter, Fuente, Tamaño, Ángulo, Offset y otra con la máscara, donde podemos fijar el halo (con o sin halo, y si es con halo, fijar el color y el tamaño).

- Picture Marker Symbol: Escoges la imágen de un fichero, y le puedes fijar el tamaño. (Quizás alguna vez se puede necesitar fijar también la rotación y el offset).

- Single Marker Symbol: Color, Estilo (Círculo, cuadrado, cruz, X, rombo), tamaño, use outline, outline size, offset (x e y). También con pestaña de máscara.

 

Propuesta de Diagrama de Objetos: