Tag Archives: Processing

Mapas interactivos y geovisualización con Unfolding

Un nuevo post sobre visualización de datos, esta vez aplicados a la geoinformación y la visualización de mapas interactivos.

En esta ocasión usaremos Unfolding, una libreria en Java basada en Processing (del cual ya hablamos en el anterior post) y de muy facil uso, aplicada en el desarrollo de mapas interactivos y visualización de datos con información geográfica.

El ejemplo que presentamos a contianución desarrolla una sencilla aplicación de escritorio en Java (con Java Swing) que muestra un mapa interactivo donde se marcan diferentes localizaciones que representan marcas de cervezas. Al hacer click sobre un marcador cualquiera, se muestra un pop-up con información adicional del marcador.

Asi que basicamente de lo que se trata es de:

  1. Mostrar el mapa.
  2. Colocar los marcadores sobre el mapa.
  3. Implementar la interacción con los marcadores (mostrar el pop-up).

1. Mostrar el mapa

Como se ha mencionado con anterioridad, Unfolding está basado en Processing y usa parte de su API para realizar ciertas acciones. Para empezar usa el PApplet que ya vimos en Processing como punto de inicio de la aplicación. Además, usa el método setup() para inicializar la apliación y el método draw() para ejecutarla, así como otros métodos ya vistos para configurar e inicializar la vista principal.

Por otro lado, Unfolding ofrece diferentes proveedores de mapas a disposición del usuario. Cada uno tiene sus condiciones de uso y restricciones. En el ejemplo que se presenta, se usará OpenStreetMap, que es bastante flexible y solo limitado por la carga de uso, sin muchas más restricciones. Una vez inicializado el mapa, establecemos una posición de origen mediante sus coordenadas geográficas de latitud y longitud.

El resultado sería este:

mapa_01

2. Colocar los marcadores sobre el mapa

Una vez tenemos el mapa, podemos proceder a crear los marcadores con la información pertinente asociada a cada uno y situarlos sobre el mapa.

Para ello lo que vamos a hacer es cargar cierta información de un fichero. Esa información contiene la localización geográfica en la que se colocará el marcador (longitud y latitud), el nombre del marcador y los datos asociados al marcador que se mostrarán posteriormente mediante un pop-up interactivo. Estos son los datos:

# Cervezas artesanas de España
# Ciudad, latitud, longitud, cerveza1-cerveza2-cerveza3-cerveza4
Salamanca,41.0,-5.6,Malasombra-Lega-Bizarra-Helmantica
Madrid,40.4,-3.7,La Virgen-Cibeles-Maravillas
Asturias,43.32,-5.9,Caleya

Vamos por pasos:

  • Cargamos los datos en una lista interna de DTOs (beans):

  •  Crear los marcadores:

La clase BirraMarker se extiende de SimplePointMarker y tiene unos atributos específicos que el mapa usará para situar y dibujar el marcador sobre él, como el icono (PImage img). También tiene un método draw() que se invoca para dibujar el marcador. Ahí se puede indicar la posición en la que se quiere dibujar la imagen asociada al marcador. Por ejemplo:

  • Añadimos los marcadores al mapa:

Como se ve en el ejemplo, se usan múltiples clases y APIs de Processing, como PImage, loadImage(), etc.

mapa_02

3. Mapa interactivo

Por último, haremos el mapa interactivo. La intención es que al hacer click con el ratón sobre cada marcador, se muestre un pop-up sobre él con información adicional. Al volver a hacer click, o hacer click en otro marcador, el pop-up desaparece. Además también queremos mostrar otro pop-up sobre cada marcador si se coloca el puntero sobre él, que desaparezca cuando éste se vaya. Aquí mostraremos el nombre del marcador.

Ámbos eventos podemos definirlos mediante la API del PApplet heredada de Processing. Este serái el método para el evento de click sobre el mapa:

Si no hay marcadores, devolvemos nulo, es decir, no hacemos nada. Si hay marcadores, primero deseleccionamos todos, ya que no admitimos selección múltiple en nuestro ejemplo. Despues detectamos cual es el primer marcador seleccionado en la posición del puntero (Marker m = birraMap.getFirstHitMarker(mouseX, mouseY)) y lo marcamos como tal (m.setSelected(true)).

El método para definir el evento de movimiento del ratón sería el siguiente:

El procedimiento es practicamente el mismo que en el caso anterior. Tan solo en lugar de establecer el marcador como seleccionado, se usa setHover(true).

Tan solo nos falta añadir al método draw() del marcador el código que permitirá dibujar los pop-ups en caso de que éste sea seleccionado o sobrevolado por el puntero. El método definitivo quedaría así:

Como se ve en el método, se usan los atributos selected y hover que se marcan en los métodos anteriores de eventos para determinar el estado del marcador. Hay que recordar que el método draw() se está invocando de forma contínua tal y como se usa en Processing.

Este sería el resultado final:

mapa_03

mapa_04

Podeis descargar el proyecto completo desde aquí. !Ahora a darle a los mapas!

Manipulación de imágenes con Processing

Dentro de un nuevo post sobre visualización gráfica y tenologías relacionadas, vamos a hacer una pequeña reseña en relación a una potente herramienta de manipulacion de imágenes y diseño gráfico.

No es ni más ni menos que el entorno y lenguaje de programación llamado PROCESSING. Este lenguaje está basado en Java y nos permite, de una manera muy sencilla y potente, relaizar diferentes manipulaciones sobre imágenes, desarrollar elementos gráficos, visualizaciones, interacciones y demás temas relacionados con el diseño gráfico y la visualización de datos.

Esta es la URL oficial de PROCESSING, donde se pueden encontrar tutoriales, ejemplos, distribuibles, etc.

Es una herramienta muy potente usada ampliamente en diferentes sectores como el arte, la visualización de datos, el desarrollo de software o incluso es la base de otros lenguajes de programación y entornos de desarrollo como Arduino.

Los dos ejemplos que se muestran a continuación son sencillas pruebas de lo que se puede hacer con Processing a la hora de manipular y analizar imágenes. Pero con Processing se pueden hacer muchas más cosas, como crear formas, textos, imágenes en 2D y 3D, etc. Se recomienda encarecidamente consultar la web oficial y repasar los tutoriales y ejemplos que alli se encuentran.

1. API de Processing

Como hemos dicho antes, Processing está basado en Java, asi que funciona de forma similar. Proporciona una API y una serie de classes que nos permiten trabajar con imágenes de forma sencilla desde cualquier programa o entorno de desarrollo.

Estos son algunos de los elemento de Processing que veremos en los siguientes ejemplos:

  • PApplet – es un applet Java del que extiende nuestra clase principal y que creará una ventana alrededor de nuestro contenido para una mejor visualización.
  • PImage – representa una imagen.
  • setUp() – inicializa la aplcicación.
  • draw() – es invocado de forma recurrente para refrescar el contenido de la aplicación.
  • loadImage() – carga una imagen en memoria.
  • image() – dibuja una imagen en las coordenadas que le indiquemos.

2. Estructuras básicas

Los elementos básicos de los que debe constar una aplicación implementada con Processing serían los siguientes:

  • El applet de Processing

Una alternativa a extender el applet e invocar nuestra aplicación como tal es usar esto dentro del metodo main:

  • El método setpUp() donde se inicializa nuestra aplicación

  • El método draw() que se invoca de forma repetida mientras la aplicación esté activa

  • Otros métodos de captura de eventos, como por ejemplo el siguiente

 

3. Manipulación de imágenes

Una vez tenemos las imagenes cargadas en memoria, podemos acceder a sus píxeles, a las propiedades de estos y usar la API de Processing para manipularlos.

Los píxeles se representan como un array unidimensional. Para acceder a un píxel basta con calcular el índice que le correspondería en ese array. Antes debemos cargar los píxeles de la imagen en cuestión usando la función loadPixels():

 El resultado es un valor numérico que representa al píxel (en función de su RGB, brillo, etc.).

Para modificarlo, podemos escribir un nuevo valor en el array. Despùés llamamos a la función updatePixels() para que vuelque los valores a la imagen de nuevo:

Existen una serie de métodos que podemos usar para determinar las diferentes propiedades de cada píxel, como son el rgb, el brillo, etc:

 

4. Dibujo

Aunque no forma parte de esta explicación, como se ha mencionado antes, Processing es una potente herramienta a la hora de realizar cualquier tipo de dibujo, diseño gráfico, etc. Por supuesto tiene un conjunto de funciones que nos permiten dibujar formas de manera sencilla:

Finalmente, con lo visto hasta aquí podríamos crear un par de funciones que modifiquen los píxeles de una imagen original para que, en un caso, los cambio a blanco o negro en función de su brillo, y en otro caso, los cambie por elipses de un tamaño determinado y del color del píxel. En este caso, en lugar de cambiar la imagen original, dibujamos dos nuevas imágenes. Puedes descargar el proyecto completo desde aqui.

El resultado sería algo como lo siguiente:

processing

A la izquierda, la imagen original, en el centro en blanco y negro, y a la derecha, con elipses de colores.

¡¡Ahora a jugar con Processing!!