Diseño de sistemas de sensorización y aplicaciones móviles para … · 2019. 9. 27. ·...
Transcript of Diseño de sistemas de sensorización y aplicaciones móviles para … · 2019. 9. 27. ·...
Diseño de sistemas de
sensorización y aplicaciones
móviles para la gestión y
monitorización de recursos y
servicios de playas y costa Grado en Ingeniería Informática
Trabajo Fin de Grado
Autor: Juan Pablo Melgarejo Zamora
Tutor/es: Virgilio Gilart Iglesias, Diego Marcos Jorquera
Septiembre 2018
1
Justificación y objetivos
El trabajo de fin de grado se enmarca en un proyecto multidisciplinar y muy
ambicioso, que surge de la colaboración entre el departamento de Ingeniería Civil
y el Departamento de Arquitectura y Tecnología de Computadores. Concretamente
hemos contado con la ayuda y colaboración de Luis Aragonés Pomares del
departamento de Ingeniería Civil, y de Virgilio Gilart Iglesias y Diego Marcos
Jorquera del Departamento de Arquitectura y Tecnología de Computadores.
La idea principal del proyecto consiste en resolver problemas ubicados en costas y
playas mediante el empleo de tecnologías emergentes como es el Internet of Things,
el empleo de dispositivos móviles, Big Data…
No existe ningún método de recolección de información automático ni que genere
indicadores sobre diferentes aspectos de calidad de playas, y es por ello que el
objetivo de nuestro proyecto es crear un sistema de adquisición de información
autónomo que proporcione información continua sobre diferentes características de
las playas.
2
Índice de contenido
Justificación y objetivos .................................................................................................................... 1
Introducción ...................................................................................................................................... 7
Estado del arte ................................................................................................................................... 8
Tecnologías ................................................................................................................................... 9
OpenCV ................................................................................................................................................... 9
Ionic ....................................................................................................................................................... 10
Git y Github ........................................................................................................................................... 12
Objetivos .......................................................................................................................................... 13
Metodología ..................................................................................................................................... 16
Análisis funcional ........................................................................................................................... 19
Casos de uso ................................................................................................................................ 19
Entidades de negocio ................................................................................................................. 31
Servicios candidatos ................................................................................................................... 34
Diseño .............................................................................................................................................. 35
Arquitectura ............................................................................................................................... 36
Mockups ...................................................................................................................................... 42
EER ............................................................................................................................................. 50
Servicios ...................................................................................................................................... 51
Implementación ............................................................................................................................... 73
Arquitectura implementada ...................................................................................................... 73
Aplicación móvil ......................................................................................................................... 75
Funcionamiento ..................................................................................................................................... 75
LoadingController .................................................................................................................................. 89
Geolocalización ..................................................................................................................................... 90
Google Maps .......................................................................................................................................... 90
Cámara ................................................................................................................................................... 93
Audio ..................................................................................................................................................... 93
Select Searchable ................................................................................................................................... 94
Contador de personas ................................................................................................................ 95
Sustraer fondo con BackgroundSubstractorMog2 ................................................................................. 95
Threshold ............................................................................................................................................... 96
3
Opening .................................................................................................................................................. 97
Closing ................................................................................................................................................... 98
Contours ................................................................................................................................................. 99
Moments .............................................................................................................................................. 100
Personas ............................................................................................................................................... 101
Operaciones para calcular la altura de una persona ............................................................................. 103
Pruebas y validación ..................................................................................................................... 108
API ............................................................................................................................................ 108
Cámara ..................................................................................................................................... 110
Aplicación móvil ....................................................................................................................... 111
Conclusiones .................................................................................................................................. 112
Referencias .................................................................................................................................... 113
4
Índice de figuras
Figura 1: Logotipo de OpenCV - https://opencv.org/ ........................................................................ 9
Figura 2: Logotipo de Ionic - http://www.phonegapspain.com/que-es-y-como-empezar-con-ionic-
framework/ ....................................................................................................................................... 10
Figura 3: Capas de Ionic - https://code.tutsplus.com/tutorials/ionic-from-scratch-what-is-ionic--
cms-29323 ........................................................................................................................................ 11
Figura 4: Logo de git - https://git-scm.com/..................................................................................... 12
Figura 5: Logo de GitHub - https://medium.com/@asfo/subiendo-miles-y-miles-de-archivos-a-
github-f%C3%A1cilmente-con-git-bash-e493d4a94fe0 .................................................................. 12
Figura 6: Captura de GitHub de la aplicación móvil. ....................................................................... 13
Figura 7: Modelo de procesos del sistema. ...................................................................................... 15
Figura 8: Modelo de desarrollo en cascada - https://openclassrooms.com/en/courses/4309151-
gestiona-tu-proyecto-de-desarrollo/4538221-en-que-consiste-el-modelo-en-cascada ..................... 18
Figura 9: Método de desarrollo Scrum - http://www.pmoinformatica.com/2018/01/certificacion-
scrum-master-profesional.html ........................................................................................................ 18
Figura 10: Diagrama de casos de uso. .............................................................................................. 30
Figura 11: Arquitectura de la aplicación. ......................................................................................... 37
Figura 12: Arquitectura de sensores inteligentes para adquisición de información de contexto de las
playas................................................................................................................................................ 38
Figura 13: Mockup de la pantalla incial. .......................................................................................... 42
Figura 14: Mockup de tus incidencias. ............................................................................................. 43
Figura 15: Mockup de creación de nueva incidencia. ...................................................................... 44
Figura 16: Mockup del menú de la aplicación. ................................................................................ 45
Figura 17: Mockup del mapa con incidencias. ................................................................................. 46
Figura 18: Mockup de la lista de indicadores................................................................................... 47
Figura 19: Mockup de incidencias filtradas por playa. .................................................................... 48
Figura 20: Mockup de los detalles de la incidencia. ........................................................................ 49
Figura 21: Mockup de la edición de perfil. ...................................................................................... 50
Figura 22: Mockup del diagrama entidad-relación. ......................................................................... 51
Figura 23: Caja de la Raspberry pi 3 con módulo de cámara. .......................................................... 74
Figura 24: Captura de la pantalla de carga de la aplicación. ............................................................ 75
Figura 25: Captura de permisos requeridos para usar la aplicación. ................................................ 76
Figura 26: Captura de la pantalla inicial de la aplicación. ............................................................... 77
Figura 27: Captura de la pantalla de registro de nuevos usuarios. ................................................... 78
Figura 28: Captura de la lista de incidencias. ................................................................................... 79
Figura 29: Captura de la creación de una nueva incidencia. ............................................................ 80
5
Figura 30: Captura del Select Search empleado para seleccionar playas. ........................................ 81
Figura 31: Captura de la previsualización de imágenes. .................................................................. 82
Figura 32: Captura del mensaje de seguridad para no dejar incidencias a medias. .......................... 83
Figura 33: Captura de los detalles de la incidencia. ......................................................................... 84
Figura 34: Captura del menú de la aplicación. ................................................................................. 85
Figura 35: Captura del mapa con las incidencias. ............................................................................ 86
Figura 36: Captura de la lista de indicadores de una playa. ............................................................. 87
Figura 37: Captura del filtrado de incidencias por playa. ................................................................ 88
Figura 38: Captura de edición de perfil del usuario. ........................................................................ 89
Figura 39: Captura del gesture handling cooperative. ...................................................................... 91
Figura 40: Captura donde se aprecian los marcadores juntos. ......................................................... 92
Figura 41: Captura donde se muestran los marcadores separados al acercarnos. ............................ 93
Figura 42: Ejemplo de sustracción de fondo. ................................................................................... 95
Figura 43: Ejemplo del threshold. .................................................................................................... 96
Figura 44: Ejemplo de opening. ....................................................................................................... 97
Figura 45: Ejemplo de closing. ........................................................................................................ 98
Figura 46: Ejemplo de findContours. ............................................................................................... 99
Figura 47: Ejemplo de moments para localizar el centroide. ......................................................... 100
Figura 48: Ejemplo del boundingRect que contiene a la persona. ................................................. 101
Figura 49: Ejemplo de las líneas superior, inferior y central. ........................................................ 102
Figura 50: Representación del ángulo que forma el centro de la cámara con la perpendicular al
suelo. .............................................................................................................................................. 103
Figura 51: Representación del ángulo I y de la cámara en detalle ................................................. 104
Figura 52: Representación de las variables necesarias para calcular la distancia a los pies .......... 105
Figura 53: Representación de las variables necesarias para calcular la distancia a la cabeza ........ 106
Figura 54: Acceso mediante ssh al servidor ................................................................................... 108
Figura 55: Acceso a la base de datos en el servidor. ...................................................................... 109
Figura 56: Proceso en funcionamiento ........................................................................................... 109
Figura 57: Cámara colocada en un entorno cerrado para realizar las pruebas. .............................. 110
6
Índice de tablas
Tabla 1: Caso de uso de detección de entradas y salidas de la playa y clasificación de la altura de
las personas. ..................................................................................................................................... 20
Tabla 2: Caso de uso de alta de ciudadano. ...................................................................................... 21
Tabla 3: Caso de uso de reporte de una incidencia. ......................................................................... 22
Tabla 4: Caso de uso de visualización de incidencias. ..................................................................... 23
Tabla 5: Caso de uso de visualización de incidencia en detalle. ...................................................... 24
Tabla 6: Caso de uso de visualización de mapa con incidencias. .................................................... 25
Tabla 7: Caso de uso de visualización de incidencias por playa. ..................................................... 26
Tabla 8: Caso de uso de modificación de valores de variables. ....................................................... 27
Tabla 9: Caso de uso de modificación de información de perfil. ..................................................... 28
Tabla 10: Caso de uso de modificación del estado de una incidencia. ............................................. 29
7
Introducción
Tradicionalmente, no hay un sistema o una metodología común para medir la
calidad de las playas, ni un estándar de índices. La tesis de Antonio Palazón consiste
en la propuesta de un conjunto de índices, y a partir del mismo, uno de los
problemas que surge es la actualización y disponibilidad de la información a partir
del cálculo de esos índices, denominados Key Beach Quality Indicators (KBQIs).
En éste proyecto haremos uso de las Tecnologías de Información y Comunicación
(TIC), puesto que serán una herramienta adecuada para llevar a cabo nuestro
propósito final.
Gracias a dichas tecnologías conseguiremos una gran cantidad de información, que
se procesará para obtener información sobre diversos aspectos relacionados con
playas y costas. En concreto, yo me centraré principalmente en dos partes, que serán
la adquisición de información mediante sensores y la aplicación móvil de
incidencias.
Los sensores serán colocados en los accesos, para de esta manera controlar el
número de personas que entran y salen de la playa y sus alturas. Con estos datos
será posible luego calcular el índice de saturación de la playa.
Por otra parte, la aplicación móvil servirá para enviar incidencias al servidor sobre
problemas que veamos en la playa o que deban mejorarse, y constará de una parte
de gestión y una para ciudadanos en general. La ventaja de realizar una aplicación
móvil radica en que los ciudadanos tienen una mayor probabilidad de enviar quejas
o incidencias cuando ven algo en el momento, y el gestor también gozará de una
serie de ventajas al usarlo, puesto que podrá modificar estados de incidencias y
actualizar variables desde la propia playa, sin necesidad de tener que utilizar un
ordenador para dicho fin.
8
Estado del arte
La propuesta de este proyecto va a ser realizar un sistema que nos permita obtener
la información necesaria para el cálculo de KBQIs de la manera más automática
posible. Una vez definidos los KBQIs, y determinadas las variables que los influyen
por parte de Antonio Palazón, es el momento de investigar sobre las dos ramas en
las que se ha centrado éste proyecto.
En primera instancia, se ha buscado mucha información sobre diferentes métodos
de desarrollo de aplicaciones, y se han descartado opciones que solo sirven para
una plataforma. En cambio se ha decidido un framework de desarrollo que nos
permitirá crear aplicaciones multiplataforma, y además está basado en Angular, lo
cual es de agradecer puesto que el compañero que realiza la aplicación web la
realiza con Angular.
Ha sido necesaria una búsqueda extensa en internet sobre diferentes métodos de
realizar tracking a personas, pero dado que debemos tener en cuenta que
disponemos de una capacidad de procesamiento limitado, debemos emplear
sistemas cuyo consumo de recursos sea el mínimo posible y esté optimizado al
máximo.
También se ha investigado mucho en cuanto al cálculo de la altura de una persona,
pero no se ha encontrado nada útil en internet, por lo que se ha debido implementar
todo esto realizando una serie de algoritmos que nos dan una aproximación de la
altura.
9
Tecnologías
A continuación pasaremos a describir las tecnologías que se han empleado para el
desarrollo del proyecto. De ellas cabe destacar OpenCV, biblioteca de visión
artificial que nos ha proporcionado los métodos necesarios para crear el contador
de personas. En cuanto a la app, hemos empleado Ionic como framework de
desarrollo, y el trabajo se ha ido almacenando y subiendo a un repositorio Git.
OpenCV
Figura 1: Logotipo de OpenCV - https://opencv.org/
OpenCV (Open Source Computer Vision) es una biblioteca de visión artificial y
machine learning, que se publica bajo una licencia BSD (Berkeley Software
Distribution), lo cual permite que se utilice tanto como para uso comercial como
académico [1].
Está escrita en C++, y se puede usar tanto en C++ como en Python, Java y Matlab, y
funciona en Linux, MacOs, Windows y Android. [2] Se ha usado en una gran
cantidad de aplicaciones en las principales compañías informáticas, como son IBM,
Google, Yahoo, etc, lo cual también nos da la seguridad de ser una biblioteca
realmente profesional y segura para nuestro objetivo. [3]
Disponemos, gracias a dicha biblioteca, de una gran cantidad de algoritmos
optimizados, y una documentación extensa y muy útil de cada uno de ellos, con
ejemplos de uso y descripciones muy útiles.
10
En nuestro caso, hemos decidido utilizar OpenCV con Python porque para nuestro
objetivo, que es detectar personas y realizarles un tracking para comprobar si entran
o salen de una playa, ofrece una serie de funcionalidades que cubren las necesidades
técnicas para alcanzar los objetivos planteados en el proyecto. Debemos tener en
cuenta también que al estar muy optimizado y ser rápido en sus operaciones, nos
permitirá usarlo en una Raspberry pi 3 bajo RaspbianOs. Esto es muy importante
también, puesto que la Raspberry dispone de una capacidad de procesamiento
limitada, y deberemos intentar reducir al mínimo la cantidad de operaciones para
que no se produzcan retrasos y overflows.
Ionic
Figura 2: Logotipo de Ionic - http://www.phonegapspain.com/que-es-y-como-empezar-con-ionic-framework/
Ionic es un framework de código abierto cuya función es ayudar a desarrollar
aplicaciones híbridas de una manera sencilla y eficiente [4]. Esto quiere decir que,
se desarrolla la aplicación una única vez, y se compila para diferentes sistemas
operativos de manera nativa.
Para dicha función, Ionic hace uso de HTML, CSS y JavaScript, además de emplear
Angular, lo cual hace más cómoda la programación, además de conseguir una mejor
optimización y aplicaciones más robustas. [5]
Para la compilación de las aplicaciones nativas, Ionic usa Apache Cordova, y al
combinar las dos obtenemos aplicaciones nativas con un look and feel nativo, lo
cual mejora mucho la experiencia de usuario. [6] Además, Cordova nos proporciona
11
una gran cantidad de plugins, que podemos añadir a nuestro proyecto para acceder
a la cámara, micrófono, geolocalización, etc.
Ionic posee también una Command Line Interface (CLI) basada en Node que resulta
muy cómoda y útil, puesto que permite realizar operaciones como generar páginas,
crear proyectos, etc [7] de una manera rápida y sencilla.
En la documentación de Ionic, disponemos de una gran cantidad de componentes
de alto nivel, los cuales nos ayudan a realizar una interfaz de una manera sencilla.
Disponemos de botones, alertas, modales, tarjetas y muchos más. [8] También se
proporcionan una serie de “ionicons”, que son iconos que se pueden añadir a
nuestro proyecto, para darle un aspecto más nativo todavía.
En nuestro caso hemos decidido hacer uso de Ionic debido a las grandes ventajas
que nos proporciona, y la fácil integración con el resto del proyecto que nos
proporciona, ya que son aplicaciones nativas, que se pueden compilar para
diferentes sistemas operativos, están basadas en Angular, [9] con lo cual serán
aplicaciones optimizadas y robustas, y también porque serán aplicaciones con una
interfaz nativa y cómoda para el usuario.
Figura 3: Capas de Ionic - https://code.tutsplus.com/tutorials/ionic-from-scratch-what-is-ionic--cms-29323
12
Git y Github
Figura 4: Logo de git - https://git-scm.com/
Figura 5: Logo de GitHub - https://medium.com/@asfo/subiendo-miles-y-miles-de-archivos-a-github-f%C3%A1cilmente-
con-git-bash-e493d4a94fe0
Git es un sistema de control de versiones que nos ayuda a mantener diferentes
versiones de nuestro proyecto [10] y tener un registro de cambios para poder hacer
rollbacks en caso de cometer algún error. Posee una gran cantidad de herramientas
y operaciones que podemos realizar en nuestros proyectos mediante comandos [11],
como la creación de ramas, subir los cambios a un servidor remoto, hacer commits,
fetch, merge…
En nuestro caso, como servidor remoto hemos usado Github, que nos añade una
gran cantidad de herramientas, además de las que nos proporciona Git [12]. Se han
utilizado estas tecnologías para mantener versiones de nuestro proyecto y poder
visualizarlas en la web [13], por dos motivos. El primero es que así tenemos acceso
en cualquier momento al repositorio, puesto que está online, y si tuviéramos algún
problema con nuestro ordenador, no perderíamos todo el trabajo realizado. El
segundo es que así podemos ir realizando commits, que tendremos disponibles en
la web en todo momento, con nombres significativos, para poder ver el código de
13
nuestro proyecto en diferentes momentos de tiempo, y ver los cambios que hemos
ido realizando sobre el mismo.
Figura 6: Captura de GitHub de la aplicación móvil.
Objetivos
Nos encontramos ante un proyecto cuyo objetivo general consiste en diseñar un
sistema que permita de la forma más desatendida posible obtener información que
nos servirá para el cálculo de KBQIs. De ésta manera facilitamos la disponibilidad
de la información en tiempo real actualizada.
Será de gran importancia también que la información esté disponible en todo
momento en internet, para de ésta manera tanto ciudadanos como gestor puedan
acceder a consultar dicha información desde cualquier lugar y en cualquier
momento.
14
Debemos tener en cuenta que hay una gran cantidad de la población que tiene
problemas para entender la manera en la que funciona la tecnología, cosa que
debemos tener muy presente en todo momento para que la aplicación sea fácil de
usar e invite a los usuarios a participar activamente en todo momento.
En cuanto a los objetivos específicos nos centraremos en dos elementos:
- El primer elemento será un sistema de adquisición de información mediante
sensores, que enviará información automáticamente para la actualización de
los KBQIs. Dicho sistema se encargará de seguir la trayectoria de las personas
que entran y salen de un acceso de la playa, con el fin de determinar su
trayectoria, y por tanto, si entran o salen. Además, se creará un algoritmo
que, mediante una serie de cálculos, determinará la altura de la persona, para
indicar además de si entra o si sale de la playa, si la persona es adulta o si es
un niño.
- Por otra parte, se desarrollará una aplicación móvil. Dicha aplicación móvil
permitirá a los ciudadanos enviar incidencias geolocalizadas sobre una
playa, y le permitirá añadir tanto imágenes como audios, que puede tomar
con el teléfono móvil. Además el ciudadano tendrá la opción de ver un mapa
con las incidencias que se encuentran pendientes, filtrar incidencias por
playa para ver su estado, o averiguar los indicadores de una playa. El gestor
podrá además editar los valores de las variables y cambiar de estado las
incidencias.
15
Figura 7: Modelo de procesos del sistema.
Para el desarrollo del proyecto se ha seguido el modelos de procesos del sistema
localizado en la figura superior, gracias al cual monitorizaremos las playas
mediante sensores, datos que nos proporciona el usuario en las aplicaciones web y
móvil, y recursos externos. Todo eso se procesará y se crearán una serie de
indicadores, de los cuales se guardará un histórico.
Para cumplir dichos objetivos durante el desarrollo, la ejecución del plan de trabajo
se va a realizar mediante el uso de Scrum, puesto que nos proporciona una serie de
herramientas y feedback que serán de gran ayuda, y además, al ser éste proyecto
un proyecto que evoluciona y cambia con el tiempo, nos permitirá adaptarnos a
dichos cambios.
Además, se han seguido otras metodologías, como ha sido el empleo de una
arquitectura orientada a servicios, sobre los cuales se han realizado posteriormente
los documentos RAML que nos proporcionan una descripción con toda la
información necesaria para entender el funcionamiento de cada servicio.
Monitoring Processing Notification
Store Provisioning
USER
External
resources
Sensors
User data
Variables KBQI
KBQI
KBQI
Data
Alert
BEACH
MODEL
16
Metodología
El ciclo de vida del software, es una parte fundamental y necesaria para gestionar
correctamente un proyecto software [14]. También llamado proceso para el
desarrollo del software [15], consiste en definir una serie de fases o pasos que
nuestro proyecto deberá seguir para asegurarnos que nuestro proyecto cumple los
requisitos y verifica los procesos que se han seguido para desarrollar el software
[16].
Es importante el uso de un ciclo de vida, puesto que, si no planificamos nada y
desarrollamos directamente, será muy complicado detectar errores y se perderá
mucho tiempo en ello, con lo que, además, la calidad del software no será buena.
Encontramos dos agrupaciones de modelos de ciclo de vida, que son la planificación
predictiva y la predicción adaptativa.
- La planificación predictiva es aquella en la que se desarrollan las fases de
manera ordenada, una detrás de otra [17]. Se hace una realiza inicial muy
grande, con el fin de averiguar todo lo posible sobre el proyecto desde el
comienzo del mismo. Es imprescindible investigar mucho para no pasar por
alto ningún requisito, y tener cuidado de que los requisitos que definimos
están definidos correctamente [18]. Se planifica todo desde el inicio, con lo
cual es un problema si hay que realizar algún cambio, y es que dicho modelo
soporta muy mal los cambios
- La planificación adaptativa es diferente, puesto que no se planifica todo el
proceso de desarrollo como en la predictiva desde el inicio, sino que se van
realizando una serie de iteraciones o sprints. No significa que no se
planifique, se planifica también, pero de una manera diferente, y en lugar de
secuenciar todo el conjunto de tareas, se secuencia un subconjunto. Es un
enfoque que proporciona agilidad, y provoca que introducir cambios sea más
17
sencillo. Dentro de los adaptativos se encuentran los iterativos y los ágiles.
La ventaja es que se produce una retroalimentación al equipo en cada
iteración [19]. En dicha planificación se tiene más en cuenta al cliente, y
debemos tener en cuenta que el final es concreto, y que la franja temporal se
mantiene, por lo que todas las iteraciones deben tener esa duración.
En nuestro caso, hemos encontrado que fue más útil utilizar una planificación
adaptativa ágil, dado que nuestro proyecto ha sido un proyecto vivo y se han ido
introduciendo cambios cada poco tiempo, con lo cual, nos hemos tenido que ir
adaptando a las necesidades del “cliente”.
Concretamente, hemos utilizado Scrum, modelo ágil útil para proyectos cambiantes
y complicados, y gracias al cual estaremos en contacto con el cliente y lo iremos
incluyendo en nuestro proyecto, mostrándole y enseñándole lo que hemos ido
haciendo constantemente. De esta manera, el cliente sabrá en todo momento lo que
estamos haciendo y nos podrá ir diciendo lo que quiere que hagamos a
continuación, o si alguna cosa ha cambiado.
Scrum ha sido una gran idea, debido a las necesidades cambiantes, y es que, si
hubiéramos usado un modelo en cascada, modelo sobre el cual una etapa no puede
comenzar hasta que haya finalizado la anterior, habría sido imposible introducir
cambios. Por este motivo no nos habría servido un desarrollo en cascada, puesto
que semana a semana han ido cambiando, y ha sido más cómodo para nosotros ir
enseñando cosas y verificando que es lo que el cliente quería.
En las Figuras 8 y 9 podemos ver una comparación de ambas mediante imágenes,
en las que se ve la diferencia entre un modelo en cascada y Scrum.
18
Figura 8: Modelo de desarrollo en cascada - https://openclassrooms.com/en/courses/4309151-gestiona-tu-proyecto-de-
desarrollo/4538221-en-que-consiste-el-modelo-en-cascada
Figura 9: Método de desarrollo Scrum - http://www.pmoinformatica.com/2018/01/certificacion-scrum-master-
profesional.html
19
Análisis funcional
En este apartado nos centraremos en la parte de análisis del sistema software. Dicha
fase es de gran importancia, puesto que es en la que averiguamos las necesidades
del cliente, y servirá de base para realizar todo el trabajo posterior, gracias a la
documentación que habremos realizado.
Como se describe en la tesis de Antonio Palazón, los índices requieren de diferentes
acciones para que se pueda modificar su valor final, por lo tanto, nos hemos
encargado de dar el soporte tecnológico y establecer las funcionalidades para dichos
índices. Un ejemplo de esto sería el índice de saturación, puesto que es necesario
que haya una descripción del caso de uso de aumentar o reducir las personas de la
playa, puesto que en última instancia, lo que desencadenará dicha secuencia de
acciones, será una modificación del índice de saturación de la playa. En los índices
se vio interesante que la opinión de los usuarios se contemplase, puesto que la
aplicación móvil genera mucha información, y cuando se produce una incidencia,
la gente busca un sitio donde poder indicarlo.
Casos de uso
Un caso de uso sirve para describir los pasos que se llevarán a cabo entre el sistema
y una serie de actores para llevar a cabo una tarea. Su utilidad reside en la capacidad
que nos proporciona para captar los requisitos que el sistema deberá implementar
posteriormente.
Nombre Detectar entradas y salidas de la playa y clasificar
las alturas de las personas
Descripción El sistema deberá comportarse tal como se describe
en el siguiente caso de uso cuando un ciudadano
entre o salga de la playa
Precondición Iniciar el sensor inteligente.
Secuencia Paso Acción
20
Normal 1 El usuario al aparecer en el rango del sensor
se registra
2 El sistema detecta si su trayectoria es de
entrada o salida de la playa
3 El sistema calcula su altura y la clasifica
4 El sistema envía los datos registrados para su
procesamiento
Postcondición Se actualiza el indicador de saturación perteneciente
a la playa.
Excepciones Paso Acción
1
Rendimiento Paso Cota de tiempo
2 10 segundos
3 2 segundos
4 3 segundos
Frecuencia esperada 300 veces / día
Importancia Vital
Urgencia Inmediatamente
Tabla 1: Caso de uso de detección de entradas y salidas de la playa y clasificación de la altura de las personas.
Nombre Alta de Ciudadano
Descripción El sistema deberá comportarse tal como se describe
en el siguiente caso de uso cuando un ciudadano
quiera darse de alta en el sistema.
Precondición No estar registrado previamente.
Secuencia Paso Acción
21
Normal 1 El usuario solicita al sistema comenzar el
proceso de registro.
2 El sistema solicita al ciudadano su nombre,
correo electrónico y una contraseña.
3 El usuario deberá introducir los datos
solicitados.
4 El sistema almacena los datos del ciudadano
y el usuario ya podría iniciar sesión en el
sistema.
Postcondición El ciudadano ya dispone de una cuenta activa para
acceder al sistema.
Excepciones Paso Acción
4 Si los datos introducidos por el ciudadano
son incorrectos el sistema informara del error
al usuario, el cual deberá corregir los campos
erróneos.
Rendimiento Paso Cota de tiempo
3 30 segundos
Frecuencia esperada 10 veces / día
Importancia Vital
Urgencia Inmediatamente
Tabla 2: Caso de uso de alta de ciudadano.
Nombre Reportar una incidencia
Descripción El sistema deberá comportarse tal como se describe
en el siguiente caso de uso cuando un ciudadano
quiera reportar una incidencia.
Precondición El usuario debe haber iniciado sesión en el sistema.
22
Secuencia
Normal
Paso Acción
1 El usuario detecta algún tipo de problema en
la playa.
2 El usuario solicita al sistema comenzar el
proceso para reportar una incidencia.
3 El sistema solicita al usuario una descripción,
el tipo, una localización, la playa en la que se
ha producido y, opcionalmente, el usuario
puede proporcionar fotos y audios que
complementen su descripción.
4 El sistema recoge estos datos y crea la
incidencia en el sistema.
Postcondición La incidencia se registra en el sistema y es accesible
tanto para los gestores de playas como para los
ciudadanos.
Excepciones Paso Acción
3 Si se introduce algún campo de manera
errónea, el sistema informara al usuario, el
cual deberá corregir los errores introducidos.
Rendimiento Paso Cota de tiempo
3 Entre 2 y 5 minutos.
Frecuencia esperada 20 veces / día.
Importancia Vital
Urgencia Inmediatamente
Tabla 3: Caso de uso de reporte de una incidencia.
23
Nombre Visualizar tus incidencias
Descripción El sistema deberá comportarse tal como se describe
en el siguiente caso de uso cuando cualquier tipo de
usuario quiera visualizar todas las incidencias
registradas en el sistema.
Precondición El usuario debe haber iniciado sesión.
Secuencia
Normal
Paso Acción
1 El usuario solicita al sistema visualizar las
incidencias registradas.
2 Si se especifica algún filtro, el sistema
mostrará todas las incidencias que lo
cumplan.
3 Si no especifica ningún filtro, el sistema
mostrará todas las incidencias.
4 El usuario podrá ver las incidencias que le
proporcione el sistema.
5 Además, si el usuario lo solicita, el sistema le
mostrará los detalles de la incidencia que
indique el usuario.
Postcondición El usuario visualiza el listado de incidencias.
Excepciones Paso Acción
Ninguna
Rendimiento Paso Cota de tiempo
1
Frecuencia esperada 100 veces/día
Importancia Importante.
Urgencia Hay presión.
Tabla 4: Caso de uso de visualización de incidencias.
24
Nombre Visualizar incidencia en detalle.
Descripción El sistema deberá comportarse tal como se describe
en el siguiente caso de uso permitiendo a cualquier
tipo de usuario visualizar cualquier incidencia que
desee en detalle.
Precondición Haber iniciado sesión en el sistema.
Secuencia
Normal
Paso Acción
1 El usuario solicita visualizar una incidencia
en detalle.
2 El sistema muestra al usuario la información
sobre dicha incidencia.
Postcondición El usuario visualiza toda la información relativa a
una incidencia.
Excepciones Paso Acción
1
Rendimiento Paso Cota de tiempo
1 n segundos
Frecuencia esperada 20 veces / día
Importancia Vital
Urgencia Inmediatamente
Tabla 5: Caso de uso de visualización de incidencia en detalle.
Nombre Visualizar mapa con incidencias
Descripción El sistema deberá comportarse tal como se describe
en el siguiente caso de uso permitiendo a cualquier
tipo de usuario visualizar un mapa con las
incidencias registradas en el sistema
25
Precondición Haber iniciado sesión en el sistema.
Secuencia
Normal
Paso Acción
1 El usuario solicita visualizar el mapa con las
incidencias.
2 El sistema muestra al usuario dicho mapa, y
le permite ver el detalle de cada incidencia
haciendo click en el globo.
Postcondición El usuario visualiza todas las incidencias en un
mapa
Excepciones Paso Acción
1
Rendimiento Paso Cota de tiempo
1 2 segundos
Frecuencia esperada 20 veces / día
Importancia Vital
Urgencia Inmediatamente
Tabla 6: Caso de uso de visualización de mapa con incidencias.
Nombre Visualizar incidencias por playa
Descripción El sistema deberá comportarse tal como se describe
en el siguiente caso de uso permitiendo a cualquier
tipo de usuario visualizar una lista con todas las
incidencias que han sido publicadas en una playa.
Precondición Haber iniciado sesión en el sistema.
Secuencia
Normal
Paso Acción
1 El usuario solicita visualizar las incidencias
por playa
26
2 El sistema muestra al usuario una lista con
playas para que seleccione sobre qué playa
quiere ver dichas incidencias.
3 El usuario selecciona una playa de la lista
4 El sistema le muestra la lista de incidencias
que corresponden a dicha playa
Postcondición El usuario visualiza todas las incidencias
pertenecientes a una playa
Excepciones Paso Acción
1
Rendimiento Paso Cota de tiempo
3 5 segundos
Frecuencia esperada 20 veces / día
Importancia Vital
Urgencia Inmediatamente
Tabla 7: Caso de uso de visualización de incidencias por playa.
Nombre Modificar valores de variables
Descripción El sistema deberá comportarse tal como se describe
en el siguiente caso de uso concreto cuando un
gestor quiera modificar el valor de una variable
manualmente.
Precondición Haber iniciado sesión como gestor en el sistema.
Secuencia
Normal
Paso Acción
1 El gestor solicita al sistema los valores de las
variables de un indicador concreto.
27
2 El sistema muestra al gestor estos valores y
le permite modificar el necesario.
3 El gestor modifica el valor de la variable que
desee y posteriormente envía la información
al sistema.
4 El sistema almacena la información y
actualiza el valor del indicador al cual afecte
el cambio de variable.
Postcondición La variable y el indicador afectado quedan
actualizados.
Excepciones Paso Acción
1
Rendimiento Paso Cota de tiempo
3 30 segundos
Frecuencia esperada 10 veces / día
Importancia Importante
Urgencia Hay presión
Tabla 8: Caso de uso de modificación de valores de variables.
Nombre Modificar información de perfil.
Descripción El sistema deberá comportarse tal como se describe
en el siguiente caso de uso cuando cualquier tipo de
usuario quiera actualizar su información de perfil.
Precondición Haber iniciado sesión en el sistema.
Secuencia
Normal
Paso Acción
1 El usuario solicita al sistema acceder a su
información de perfil.
28
2 El sistema muestra al usuario su información
permitiéndole cambiar algunos campos.
3 El usuario cambiará los campos deseados y
enviará la información al sistema.
4 El sistema valida la información recibida y
actualiza la información de dicho usuario.
Postcondición El usuario tiene su información de perfil actualizada.
Excepciones Paso Acción.
4
Si los datos introducidos por el ciudadano
son incorrectos el sistema informará del error
al usuario, el cual deberá corregir los campos
erróneos.
Rendimiento Paso Cota de tiempo
3 30 segundos
Frecuencia esperada 5 veces por día.
Importancia Baja.
Urgencia Puede esperar.
Comentarios Lo único que no puede cambiar el usuario es su rol,
para ello deberá ponerse en contacto con nosotros.
Tabla 9: Caso de uso de modificación de información de perfil.
Nombre Modificar el estado de una incidencia.
Descripción El sistema deberá comportarse tal como se describe
en el siguiente caso de uso permitiendo al gestor
poder cambiar el estado de una incidencia.
29
Precondición La incidencia sobre la que se va a trabajar no debe
estar cerrada.
Secuencia
Normal
Paso Acción
1 El gestor obtiene una actualización acerca del
estado de una incidencia.
2 El gestor solicita al sistema poder cambiar el
estado de dicha incidencia.
3 El sistema muestra la incidencia y permite al
gestor modificar su estado.
4 El gestor modifica el estado y el sistema
almacena la información.
Postcondición La incidencia queda actualizada.
Excepciones Paso Acción
Ninguna.
Rendimiento Paso Cota de tiempo
3 10 segundos
Frecuencia esperada 10 veces por día.
Importancia Importante.
Urgencia Hay presión.
Comentarios Ninguno.
Tabla 10: Caso de uso de modificación del estado de una incidencia.
30
Un diagrama de casos de uso nos muestra la relación de los actores con los casos de
uso definidos previamente, y nos aporta una visión general de cómo funcionará el
sistema.
A continuación, podemos ver el diagrama de casos de uso de nuestra aplicación
móvil:
Figura 10: Diagrama de casos de uso.
31
Entidades de negocio
Las entidades representan objetos o conceptos reales, y se componen de una serie
de atributos que las definen. En nuestro sistema hemos definido las siguientes:
- Usuario: Entidad que representa a un usuario. Contendrá toda la
información personal de dicho usuario, que constará de su email, contraseña,
nombre, apellidos y un identificador único que se le asignará
automáticamente.
- Rol: Dicha entidad representa los roles que estarán disponibles en el sistema.
Los usuarios tendrán asignado un rol, que determinará las cosas que puede
realizar en el sistema, un ejemplo de roles sería por ejemplo ciudadano,
gestor y socorrista. Cada rol contendrá el nombre del mismo y un
identificador numérico.
- Incidencia: La entidad de Incidencia representa una incidencia, que es
enviada por un usuario y el gestor del sistema se encargará de revisar y
corregir. Cada incidencia tendrá su propio identificador único, una
descripción, una latitud y longitud para geoposicionarla, la fecha de
publicación de la misma, la playa a la que pertenece, el estado en el que se
encuentra, el tipo de incidencia que es y una serie de fotos y audios
asociados.
- Foto: Las incidencias mencionadas anteriormente podrán tener asociadas
fotos que ayuden al usuario a describirla de una manera más cómoda. Las
fotos constarán de un id de incidencia y una ruta, además de un id que la
identifica y diferencia de las otras.
- Audio: Las incidencias también podrán tener asociados audios, los cuales
serán muy útiles en algunos casos, puesto que permitirán a personas con
problemas de accesibilidad poder comunicarse de una manera cómoda
32
únicamente presionando un botón y describiendo el problema. Al igual que
las fotos, los audios constarán de un id de incidencia, una ruta y un id que
los diferencia.
- Tipo Incidencia: Habrán una serie de tipos de incidencia sobre las cuales el
usuario deberá seleccionar una, para poder catalogarlas en base a tipos, y que
sea más cómodo para el gestor diferenciar unas de otras. Un ejemplo de esto
podría ser accesos, señalizaciones, servicios, etc. Cada tipo de incidencia
tendrá como atributos un identificador único, el nombre del tipo y la
descripción que lo define.
- Estado Incidencia: Las incidencias también pasan por una serie de estados,
y el gestor se encargará de cambiar el estado de cada incidencia en caso de
arreglarla o rechazarla, por ejemplo. Los estados constarán de un
identificador único y un nombre que señala cómo se encuentra la incidencia.
- Playa: En el sistema también tendremos una serie de playas definidas, que
serán la base de las incidencias, puesto que cada incidencia debe ir
relacionada con una playa. Cada playa constará de un identificador único,
un nombre, latitud y longitud para poder geoposicionarla, una línea de
referencia, un área, un tipo de playa de acuerdo a la forma, y un tipo de playa
de acuerdo a la saturación. Además contará con indicadores y variables
asociadas, además de un histórico tanto de las variables como de los
indicadores.
- Tipo Playa Saturacion: Cada playa tendrá asignado un tipo de playa de
acuerdo a su saturación. Cada tipo de playa en función de la saturación
contendrá un id y un nombre que lo describa.
33
- Tipo Playa Forma: Nuestro sistema contará con una serie de formas, que se
le asignarán a las playas para diferenciar unas de otras. Cada uno estará
compuesto por el identificador único que lo identifica y un nombre.
- Indicador: Las playas tendrán una serie de indicadores asociados, que
proporcionarán información sobre diferentes aspectos de la playa. Los
indicadores estarán formados por un nombre, una descripción, un valor
numérico, un valor textual y la fecha en la que se ha producido la última
modificación.
- Variable: Cada indicador vendrá dado de una serie de cálculos sobre las
variables que se relacionan con el mismo. De la misma manera, una variable
tendrá un nombre, una descripción, un valor numérico, un valor textual, la
fecha que registra la última vez que dicha variable ha sido modificada, y el
id que identifica al indicador al que está asociada dicha variable.
- Histórico de indicadores: Deberemos mantener un histórico de cada cambio
que se produce en un indicador, puesto que de ésta manera siempre
podremos ver cómo ha avanzado dicho indicador con el paso del tiempo, o
ver como se encontraba la playa anteriormente. Cada histórico estará
formado por un identificador único, un nombre, una descripción, un valor
numérico, un valor textual y la fecha en la que se ha producido dicho cambio.
- Historico de Variables: De la misma forma, se tendrá un histórico de
variables, en la que se podrá observar el histórico de cada variable, con los
cambios que se han producido en las mismas. Los históricos de variables
estarán compuestos de un identificador que lo diferencia de los demás, un
nombre, una descripción, un valor numérico, un valor textual, la fecha en la
que se produce y el indicador al que está asociada la variable sobre la que
queremos registrar la información.
34
Servicios candidatos
Como vimos en la asignatura MTIS, la metodología para realizar un enfoque
orientado a servicios propuesta por Thomas Erl, consiste primero en un análisis de
los servicios candidatos, que son aquellos que finalmente podrán ser un servicio o
no, puesto que en una fase posterior se pueden eliminar o fusionar con otros [20].
De la lista de casos de uso obtendremos una serie de servicios candidatos que
definimos a continuación:
- Servicio que permita a los usuarios darse de alta en el sistema,
proporcionando sus datos y una contraseña de su elección.
- Servicio que permita a los usuarios que están dados de alta poder editar su
información de perfil.
- Servicio que permita a los usuarios autenticarse en el sistema, enviando su
email y su contraseña
- Servicio que nos devuelva una lista con todas las playas registradas en el
sistema.
- Servicio que permita a los usuarios reportar incidencias sobre problemas
localizados en costas y playas.
- Servicio que permita subir audios asociados a una incidencia.
- Servicio que permita subir fotos asociadas a una incidencia.
- Servicio que nos devuelva las incidencias que un usuario ha publicado en el
sistema.
- Servicio que nos proporcione los detalles de una incidencia.
35
- Servicio que nos devuelva la lista de tipos de incidencia que hay
almacenados en el sistema
- Servicio que nos devuelva la lista de estados de incidencia almacenados en
el sistema.
- Servicio que nos devuelva una lista de incidencias a las que se le ha asignado
un estado determinado.
- Servicio que nos devuelva una lista con las incidencias que se han registrado
en una playa concreta.
- Servicio que permita al gestor cambiar el estado de una incidencia.
- Servicio que nos devuelva una lista con todas las incidencias que se han
registrado en el sistema.
- Servicio que nos devuelva una lista con los indicadores de una playa.
- Servicio que permita al gestor actualizar variables.
Diseño
A continuación, pasaremos a describir la fase de diseño, una fase de gran
importancia en el desarrollo de un producto software. Se dará información sobre la
arquitectura que se ha seguido en el proyecto y se mostrarán los mockups que han
servido posteriormente para realizar la aplicación móvil. También se mostrará el
modelo entidad relación, se describirán los servicios usados y se presentarán los
documentos RAML que describen los métodos de la API empleados.
36
Arquitectura
La arquitectura del software indica la estructura global que seguirá nuestro sistema,
y la manera en la que las diferentes partes interactúan. Es el diseño de más alto
nivel, y define los componentes que llevan a cabo las tareas en nuestra aplicación
[21]. Consideramos la arquitectura como una parte muy importante, puesto que nos
proporciona una visión global del sistema, con lo cual describiremos a continuación
la arquitectura de nuestro sistema de gestión y monitorización de recursos de
costas.
Para la propuesta de proyecto, yo me he centrado en la aplicación móvil y en la
sensorización y clasificación de alturas.
Adquisición de información
Es muy importante para nuestro sistema la adquisición de la información necesaria,
las variables, para el posterior cálculo de los KBQIs (Key Beach Quality Indicator),
indicadores de calidad de playas.
Debemos tener en cuenta que dicha adquisición de variables es clave en nuestro
sistema, puesto que es la manera en la que se podrá determinar la calidad de una
playa. Es por ello que debe ser una adquisición automática y constante, sobre la cual
se hayan aplicado métodos para que no se produzcan pérdidas y llegue la
información de manera correcta. Además, la información no vendrá de una única
fuente, sino de una gran cantidad, y tendremos un sistema central que será el
encargado de procesar toda la información que le llegue.
Para ello se ha hecho uso de diferentes métodos, como será la adquisición de
información a través de sensores inteligentes y distribuidos, mediante aplicaciones
móviles y web, y mediante la conexión a aplicaciones y recursos externos.
37
En la siguiente figura podemos ver la arquitectura de nuestro sistema diferenciando
cada parte.
Figura 11: Arquitectura de la aplicación.
Sensores inteligentes
Primero pasaremos a definir el uso de los sensores inteligentes. Dichos sensores
proporcionarán variables que serán enviados al sistema para el cálculo de los
KBQIs. Los sensores funcionarán de forma autónoma, y proporcionarán la
información de manera fiable y continuada, y de manera totalmente automática.
Además, cabe destacar que dichos sensores tienen un coste muy bajo, y es muy fácil
añadir sensores a la playa, o a otras playas.
Cada sensor estará conectado a un dispositivo embebido, que le dará las
capacidades de comunicarse por internet y de procesar la información que el sensor
recibe, lo cual hará que el sistema central reciba información textual, puesto que
habrá sido procesado todo en el dispositivo embebido, y de esta manera le
ahorraremos cómputo al sistema central.
Los sensores inteligentes estarán compuestos de los módulos funcionales que
podemos ver a continuación.
Acquisition Module
External Resources
Smart Sensors Services
Mobil and Web Apps
UIProcessing Module
Persistence Module
Action
Notification ModuleMOM MOM
Action
Action
Action
Alert
Alert
Alert
Alert
Listener
Integration Agent
Integration Agent
Integration Agent
Variable Entity KBQI Entity
Coordination Module
Information System
Request.Response(Variable)
Notification(Variable)
Notification(Variable)
Variable Variable
Variable KBQI
KBQI
KBQI
KBQI
AlertMessage
Consumers
Context Variables Acquisition Module
Provisioning Service
REST API
Presentation Layer
B2B InteractionB2C Interaction
Service Logic
A
B
C D
KBQI
38
Figura 12: Arquitectura de sensores inteligentes para adquisición de información de contexto de las playas.
Primero de todo, puesto que hemos ahorrado costes en el sensor inteligente, no
disponemos de RTC (Real Time Clock), por lo cual se usará el protocolo NTP
(Network Time Protocol), para tener la fecha y hora de nuestro dispositivo
sincronizado con un servidor de tiempo, para que todas las peticiones y envío de
información se realice con la misma hora desde todos los sensores inteligentes, lo
cual es de gran importancia para poder conocer el estado de las playas en un
instante determinado.
Nuestro dispositivo constará de un setup component, gracias al cual nos podremos
conectar de manera remota, para poder configurar nuestro dispositivo, o poder
iniciar el programa con los parámetros necesarios en cada sensor inteligente.
También constaremos de un communication component, para el cual encontramos
dos variantes posibles.
- La primera opción es que necesitemos comprobar si la variable ha sufrido un
cambio desde la última lectura realizada. En dicho caso, el communication
component se comunicará con el optimization component, y le enviará el
dato recibido. Entonces, el optimization component se encargará de
comprobar si la nueva lectura coincide con la anterior o no. En caso
Smart Sensors Service
Communication
Optimizer
Persistence
Processing Message sender
Setup
Time Sync.
39
afirmativo, se la pasará al processing component, y en caso negativo se
descartará. Éste caso se daría por ejemplo en un sensor de temperatura del
agua, en el cual si no hay cambio no afectaría al sistema.
- Otra posible opción sería que, pese a no haber un cambio en la lectura, si se
afectara el sistema. Éste sería el caso de un contador de personas, por
ejemplo. Es por ello que el optimization component que usamos
anteriormente será opcional, y en este caso no se usará. Se enviará la
información directamente al processing component, que será el encargado
de cambiar algunas variables para adecuarlos a lo que se espera en nuestro
sistema central, transformándola en variables enriquecidas que nos servirán
para calcular KBQIs. Un ejemplo de dicha transformación sería, siguiendo el
ejemplo del contador de personas, la transformación del valor numérico en
metros de la altura, en una clasificación por edades.
Contaremos también con un persistence component, para que en casos en los que
no se pueda enviar la información, no se pierda, y se almacene en nuestro
dispositivo hasta que sea posible enviarla. Un simple ejemplo de esto sería por
ejemplo que no tuviéramos conexión a internet en el instante en que se realiza el
envío de información por cualquier motivo, dicha información que no ha podido
ser enviada se almacenará y se enviará cuando volvamos a tener conexión.
El message sender module es quien se encarga de indicar al persistence component
que la información ha llegado correctamente al sistema central, para, de esta
manera, liberar espacio en el persistence component. Debemos recordar que
contamos con dispositivos muy limitados, tanto en espacio de almacenamiento
como en computación, por lo que debe estar todo perfectamente optimizado para
que funcione correctamente.
Para el intercambio de datos hemos optado por emplear una notación estándar, que
en nuestro caso ha sido JSON, puesto que es texto ligero que se puede evaluar de
40
una manera muy sencilla en el sistema central, y todos los dispositivos utilizarán la
misma.
Cálculo de altura de personas
El sensor inteligente, además de detectar si entran o salen los usuarios, calcula la
altura para poder clasificar si la persona es adulto o niño.
Para dicho cálculo se tendrán que evaluar ángulos y píxels, calculando primero el
ángulo que forma la perpendicular del suelo con la perpendicular de la cámara, a
partir de eso obteniendo la distancia a los pies de la persona, para con la altura a la
que está la cámara poder determinar la distancia entre la proyección de la cámara
en el suelo con el usuario, y ya finalmente determinar la altura de dicho usuario.
External web application
En este caso, nos conectaremos a fuentes externas para obtener cierta información.
Dicha conexión se puede realizar mediante peticiones HTTP por ejemplo, y de esta
manera obtendremos variables necesarias para poder calcular los KBQIs. Todo esto
lo realizará el sistema principal a través de los integration agents, que se encuentran
en el módulo de adquisición. Dichos integration agents se parametrizarán y
programarán para que realicen las peticiones cuando sean necesarias. Una vez se ha
recibido el mensaje, los integration agents invocarán a los sistemas de
transformación de formato para que la información llegue correctamente y sea útil
para calcular los KBQIs. Una vez se transforma, se enviará al sistema de mensajería
que garantizará su entrega en el módulo de procesamiento.
41
Aplicaciones web y móvil
Se realizarán una serie de aplicaciones para conseguir más variables necesarias para
calcular los KBQIs. Serán 3: una aplicación móvil para los ciudadanos, una
aplicación móvil para gestores y una aplicación web.
- App móvil para que los ciudadanos puedan enviar incidencias. Esta
aplicación es de gran utilidad puesto que son los usuarios los que se encargan
de enviar la información de incidencias, que posteriormente servirá para el
cálculo de KBQIs, como por ejemplo pueden ser la accesibilidad, calidad de
los servicios ofertados, etc. La ventaja que este método nos proporciona es
que los propios usuarios se encargan de enviar las incidencias, con lo cual se
recibirán incidencias constantemente cuando haya algo por arreglar, algún
defecto o algo que no se ha hecho bien.
- App móvil para que los gestores puedan supervisar las playas. Los gestores
de playas también tendrán la opción de una app móvil con más
características. La utilidad de dicha app radica en que habrá ciertas cosas que
los gestores deberán medir o calificar, y les será más cómodo realizar en la
propia playa a medida que se van realizando análisis, en lugar de hacerlo
desde el ordenador en la web.
- Aplicaciones web para que los gestores tengan la posibilidad de realizar
ciertas operaciones que requieren una interfaz de usuario más extensa, con
cosas que no sería cómodo hacer desde un teléfono móvil, o que se harán una
vez cada mucho tiempo. Un claro ejemplo de esto sería dibujar la línea de
costa, puesto que no sería cómodo ni tendríamos la misma precisión en caso
de hacer esto desde el móvil. Otro ejemplo podría ser el cálculo de las
concesiones de la playa. En ambos deberemos obtener una ortofoto de un
servicio externo, y mediante una interfaz de diseño, dibujar la línea o la
sección de concesión con la cual posteriormente se modificarán los KBQIs.
42
Mockups
Figura 13: Mockup de la pantalla incial.
Inicialmente tenemos la página de login, donde tenemos la opción de hacer login,
crear una cuenta o loguearnos con google+.
43
Figura 14: Mockup de tus incidencias.
Una vez se ha hecho login, la aplicación nos lleva a una lista en la que encontramos
las incidencias que hemos publicado nosotros, o en caso de ser gestor, una lista con
todas las incidencias. Además desde aquí podemos crear nuevas incidencias.
44
Figura 15: Mockup de creación de nueva incidencia.
Si creamos una incidencia tendremos los campos definidos en la imagen anterior
para rellenar.
45
Figura 16: Mockup del menú de la aplicación.
Si desplazamos veremos la sidebar, nuestro menú con las cosas que podemos
realizar a través de la app.
46
Figura 17: Mockup del mapa con incidencias.
Dispondremos de un mapa con incidencias donde podremos ver las incidencias por
ubicaciones, además, podremos ver el detalle de la incidencia haciendo click en ella.
47
Figura 18: Mockup de la lista de indicadores.
También podemos ver los indicadores de la playa que seleccionemos, y en caso de
ser gestor, modificar variables de dichos indicadores.
48
Figura 19: Mockup de incidencias filtradas por playa.
Otra opción que tendrán los usuarios será la de filtrar incidencias por playa, para
poder ver las pertenecientes a una playa.
49
Figura 20: Mockup de los detalles de la incidencia.
El ciudadano podrá visualizar todas las incidencias en detalle, mientras que el
gestor además podrá cambiar el estado de las mismas.
50
Figura 21: Mockup de la edición de perfil.
Por último, tanto el ciudadano como gestor podrán editar su información de perfil.
EER
Un modelo entidad-relación es una herramienta para el modelado de datos que
permite representar las entidades relevantes de un sistema de información así como
sus interrelaciones y propiedades [22]. Resulta de gran utilidad porque nos
proporciona una visión general de todas las entidades que participan en el sistema
y cómo se relacionan unas con otras.
51
Figura 22: Mockup del diagrama entidad-relación.
Servicios
Tal y como vimos en la asignatura MTIS, el diseño orientado a servicios propuesto
por Tomas Erl, en su fase de diseño, consiste en establecer los contratos RAML, que
permiten escribir la especificación de las apis siguiendo un estándar [23].
52
Para obtener la información necesaria en nuestra app móvil, realizaremos
conexiones con una API que se encuentra alojada en un servidor proporcionada por
la Universidad de Alicante.
Para dicho fin, la API se ha dividido en una serie de ficheros con rutas, que llamarán
a los métodos del DAO para las operaciones en base de datos.
- usuarios.js: Aquí tenemos todos los relacionados con el usuario, además, en
este servicio se almacenará información relativa al usuario una vez se ha
autenticado en el sistema.
o POST /registro: Método mediante el cual un usuario podrá registrarse
en el sistema, enviando un JSON con su nombre, apellidos y email.
Nos devuelve el usuario que se ha creado, con todos los campos.
1. /registro:
2. post:
3. description: Registra a un usuario en el sistema
4. body:
5. application/json:
6. properties:
7. nombre:
8. description: Nombre del usuario
9. type: string
10. apellidos:
11. description: Apellidos del usuario
12. type: string
13. email:
14. description: Email del usuario
15. type: string
16. password:
17. description: Password del usuario
18. type: string
19. responses:
20. 200:
21. description: Usuario registrado correctamente en el
sistema
22. body:
23. application/json:
24. properties:
25. message:
26. description: mensaje
27. type: string
28. 409:
53
29. description: El usuario que se intenta registrar ya
existe en el sistema
30. body:
31. application/json:
32. type: string
33. example: Conflict
34. 500:
35. description: Error del servidor
36. body:
37. application/json:
38. type: string
39. example: Internal server error
o PUT /usuarios/:id: Método gracias al cual se podrán editar los datos
de un usuario del sistema. Se le enviará un JSON con nombre,
apellidos y email, y si alguno no coincide con el que hay guardado, lo
actualizará.
1. /usuarios/{id}: 2. uriParameters: 3. id: 4. description: Id del usuario del cual se actualiza la
información
5. type: integer 6. put: 7. description: Permite cambiar la información de perfil del
usuario
8. body: 9. application/json: 10. properties:
11. nombre:
12. description: Nombre del usuario
13. type: string
14. apellidos:
15. description: Apellidos del usuario
16. type: string
17. email:
18. description: Email del usuario
19. type: string
20. responses:
21. 200:
22. description: La actualización se ha producido
correctamente
23. body:
24. application/json:
25. properties:
26. id:
27. description: Id del usuario
28. type: integer
29. email:
30. description: Email del usuario
31. type: string
32. nombre:
33. description: Nombre del usuario
54
34. type: string
35. apellidos:
36. description: Apellidos del usuario
37. type: string
38. Rol_id:
39. description: Rol del usuario
40. type: integer
41. token:
42. description: Token de autenticación
43. type: string
44. 401:
45. description: El usuario que realiza la
petición no esta autorizado
46. body:
47. application/json:
48. type: string
49. example: Unathorized
50. 404:
51. description: No se encuentra el usuario a actualizar
52. body:
53. application/json:
54. type: string
55. example: Not found
56. 500:
57. description: Error del servidor
58. body:
59. application/json:
60. type: string
61. example: Internal server error
o POST /login: Método al cual se le enviará un JSON con email y
contraseña y nos devolverá si el usuario está registrado en el sistema,
y en caso de estarlo, todos sus campos (nombre, apellidos, id, rol y
token). Gracias al rol, sabremos si es un gestor o un ciudadano, para
mostrar unas cosas u otras, y el token servirá para que las peticiones
que el usuario haga al sistema no sean rechazadas, puesto que en cada
petición se debe enviar al servidor.
1. /login: 2. post: 3. description: Inicia la sesión de un usuario en el sistema 4. body: 5. application/json: 6. properties: 7. email: 8. description: Email del usuario 9. type: string 10. password:
11. description: Password del usuario
12. type: string
55
13. responses:
14. 200:
15. description: El inicio de sesión se ha realizado
correctamente
16. body:
17. application/json:
18. properties:
19. id:
20. description: Id del usuario
21. type: integer
22. email:
23. description: Email del usuario
24. type: string
25. nombre:
26. description: Nombre del usuario
27. type: string
28. apellidos:
29. description: Apellidos del usuario
30. type: string
31. Rol_id:
32. description: Rol del usuario
33. type: integer
34. token:
35. description: Token de autenticación
36. type: string
37.
38. 404:
39. description: El usuario intenta iniciar sesión no se
encuentra en el sistema
40. body:
41. application/json:
42. type: string
43. example: Not found
44. 500:
45. description: Error del servidor
46. body:
47. application/json:
48. type: string
49.
50. example: Internal server error
- playas.js: En este archivo únicamente encontraremos una petición GET a
/playas, el cual nos devolverá una lista con todas las playas que hay
registradas en el sistema con todos sus campos.
1. /playas: 2. get: 3. description: Devuelve el listado de playas registradas en el
sistema
4. responses: 5. 200: 6. description: Devuelve el listado de playas 7. body: 8. application/json:
56
9. properties: 10. array:
11. properties:
12. id:
13. description: Id de la playa
14. type: integer
15. nombre:
16. description: Nombre de la playa
17. type: string
18. provincia:
19. description: Provincia a la que pertenece
la playa
20. type: string
21. latitud:
22. description: Latitud en la que está
situada la playa
23. type: number
24. longitud:
25. description: Longitud en la que está
situada la playa
26. type: number
27. lineaReferencia:
28. description: Coordenadas de la linea de
referencia
29. type: string
30. area:
31. description: Área de la playa
32. type: number
33. tipoPlayaSaturacion_id:
34. description: Id del tipo de la playa en
función de la saturación
35. type: integer
36. tipoPlayaForma_id:
37. description: Id del tipo de la playa en
función de la forma
38. type: integer
39. 401:
40. description: El usuario que realiza la
petición no esta autorizado
41. body:
42. application/json:
43. type: string
44. example: Unathorized
45. 404:
46. description: No hay ninguna playa en la lista
47. body:
48. application/json:
49. type: string
50. example: Not found
51. 500:
52. description: Error del servidor
53. body:
54. application/json:
55. type: string
56. example: Internal server error
57
- incidencias.js: Contiene todos los servicios relacionados con las incidencias
o POST /incidencias: servirá para enviar al sistema una incidencia, pero
no irá incluida en dicha petición el envío de fotos y el de audios, que
se hará posteriormente. Nos devolverá la incidencia si se ha creado
correctamente y un error si no.
1. /incidencias: 2. post: 3. description: Crear una nueva incidencia 4. body: 5. application/json: 6. properties: 7. titulo: 8. description: Titulo de la incidencia 9. type: string 10. descripcion:
11. description: Descripcion de la incidencia
12. type: string
13. latitud:
14. description: Latitud en la que se ha generado la
incidencia
15. type: number
16. longitud:
17. description: Longitud en la que se ha generado la
incidencia
18. type: number
19. idUsuario:
20. description: Id del usuario que envia la
incidencia
21. type: integer
22. idTipoIncidencia:
23. description: Id del tipo de incidencia
24. type: integer
25. idPlaya:
26. description: Id de la playa
27. type: integer
28. responses:
29. 200:
30. description: Incidencia creada correctamente
31. body:
32. application/json:
33. properties:
34. message:
35. description: Mensaje
36. type: string
37. 401:
38. description: El usuario que realiza la
petición no esta autorizado
39. body:
40. application/json:
41. type: string
42. example: Unathorized
43. 500:
44. description: Error del servidor
58
45. body:
46. application/json:
47. type: string
48. example: Internal server error
o POST /incidencias/:id/subirAudio: Una vez se ha subido la incidencia,
nos la devuelve con su id, con lo cual ahora podemos, con el array de
audios, enviarlos uno a uno en bucle al servidor.
2. /incidencias/{id}/subirAudio: 3. uriParameters: 4. id: 5. description: Id de la incidencia 6. type: integer 7. post: 8. description: Subir un audio al servidor 9. body: 10. multipart/form-data:
11. description: Audio a subir
12. responses:
13. 200:
14. description: Audio subido correctamente
15. body:
16. application/json:
17. properties:
18. message:
19. description: Audio subido correctamente
20. type: string
21. 401:
22. description: El usuario que realiza la
petición no esta autorizado
23. body:
24. application/json:
25. type: string
26. example: Unathorized
27. 404:
28. description: No se encuentra la incidencia
29. body:
30. application/json:
31. type: string
32. example: Not found
33. 500:
34. description: Error del servidor
35. body:
36. application/json:
37. type: string
38. example: Internal server error
59
o POST incidencias/:id/subirFoto: De igual manera que en el método
anterior, ahora podemos subir fotos de una en una al servidor con el
id de la incidencia que hemos creado previamente.
1. /incidencias/{id}/subirFoto: 2. uriParameters: 3. id: 4. description: Id de la incidencia 5. type: integer 6. post: 7. description: Subir una foto al servidor 8. body: 9. multipart/form-data: 10. description: Foto a subir
11. responses:
12. 200:
13. description: Foto subida correctamente
14. body:
15. application/json:
16. properties:
17. message:
18. description: Foto subida correctamente
19. type: string
20. 401:
21. description: El usuario que realiza la
petición no esta autorizado
22. body:
23. application/json:
24. type: string
25. example: Unathorized
26. 404:
27. description: No se encuentra la incidencia
28. body:
29. application/json:
30. type: string
31. example: Not found
32. 500:
33. description: Error del servidor
34. body:
35. application/json:
36. type: string
37. example: Internal server error
o GET /incidencias/dameDeUsuario/:id: Nos devuelve un array que
contiene todas las incidencias que el usuario cuya id se envía como
parámetro URI ha publicado en el sistema.
1. /incidencias/dameDeUsuario/{id}: 2. uriParameters: 3. id: 4. description: Id del usuario
60
5. type: integer 6. get: 7. description: Obtenemos las incidencias del usuario 8. responses: 9. 200: 10. description: Incidencias de un usuario
11. body:
12. application/json:
13. properties:
14. array:
15. properties:
16. id:
17. description: Id de la incidencia
18. type: integer
19. titulo:
20. description: Titulo de la incidencia
21. type: string
22. descripcion:
23. description: Descripcion de la incidencia
24. type: string
25. fecha:
26. description: Fecha de la incidencia
27. type: datetime
28. latitud:
29. description: Latitud donde se ha enviado
la incidencia
30. type: number
31. longitud:
32. description: Longitud donde se ha enviado
la incidencia
33. type: number
34. estado:
35. description: Estado de la incidencia
36. type: string
37. tipo:
38. description: Tipo de incidencia
39. type: string
40. playa:
41. description: Nombre de la playa
42. type: string
43. TipoIncidencia_id:
44. description: Id del tipo de incidencia
45. type: string
46. Playa_id:
47. description: Id de la playa
48. type: integer
49. 401:
50. description: El usuario que realiza la
petición no esta autorizado
51. body:
52. application/json:
53. type: string
54. example: Unathorized
55. 404:
56. description: No se encuentra la incidencia
57. body:
58. application/json:
59. type: string
60. example: Not found
61. 500:
62. description: Error del servidor
61
63. body:
64. application/json:
65. type: string
66. example: Internal server error
o GET /incidencias/:id: Le enviamos como parámetro la id de la
incidencia sobre la cual queremos más información, y nos devuelve el
detalle de dicha incidencia, con todos sus campos.
1. /incidencias/{id}: 2. uriParameters: 3. id: 4. description: Id de la incidencia 5. type: integer 6. get: 7. description: Obtenemos una incidencia mediante su id 8. responses: 9. 200: 10. description: Detalle de incidencia
11. body:
12. application/json:
13. properties:
14. id:
15. description: Id de la incidencia
16. type: integer
17. titulo:
18. description: Titulo de la incidencia
19. type: string
20. descripcion:
21. description: Descripcion de la incidencia
22. type: string
23. fecha:
24. description: Fecha de la incidencia
25. type: datetime
26. latitud:
27. description: Latitud donde se ha enviado la
incidencia
28. type: number
29. longitud:
30. description: Longitud donde se ha enviado la
incidencia
31. type: number
32. estado:
33. description: Estado de la incidencia
34. type: string
35. tipo:
36. description: Tipo de incidencia
37. type: string
38. playa:
39. description: Nombre de la playa
40. type: string
41. TipoIncidencia_id:
42. description: Id del tipo de incidencia
43. type: string
62
44. Playa_id:
45. description: Id de la playa
46. type: integer
47. 401:
48. description: El usuario que realiza la
petición no esta autorizado
49. body:
50. application/json:
51. type: string
52. example: Unathorized
53. 404:
54. description: No se encuentra la incidencia
55. body:
56. application/json:
57. type: string
58. example: Not found
59. 500:
60. description: Error del servidor
61. body:
62. application/json:
63. type: string
64. example: Internal server error
o GET /incidencias/dameTipos: Dicho método nos devuelve un array
con todos los tipos de incidencia disponibles, para que el usuario
asigne un tipo u otro.
1. /incidencias/dameTipos: 2. get: 3. description: Obtenemos la lista de tipos de incidencia 4. responses: 5. 200: 6. description: Petición correcta 7. body: 8. application/json: 9. properties: 10. array:
11. properties:
12. id:
13. type: number
14. description: Id del tipo
15. nombre:
16. type: string
17. description: Nombre del tipo
18. descripcion:
19. type: string
20. description: Descripción del tipo
21. 401:
22. description: El usuario que realiza la
petición no esta autorizado
23. body:
24. application/json:
25. type: string
26. example: Unathorized
63
27. 500:
28. description: Error del servidor
29. body:
30. application/json:
31. type: string
32. example: Internal server error
o GET /incidencias/dameEstados: Cuando el gestor quiere cambiar el
estado de una incidencia, debe obtener primero una lista con los
estados disponibles a los que puede cambiar la incidencia, que
contendrá id y nombre del estado.
1. /incidencias/dameEstados: 2. get: 3. description: Obtenemos la lista de estados que se le pueden
asignar a una incidencia
4. responses: 5. 200: 6. description: Petición correcta 7. body: 8. application/json: 9. properties: 10. array:
11. properties:
12. id:
13. type: number
14. description: Id del tipo
15. nombre:
16. type: string
17. description: Nombre del tipo
18. 401:
19. description: El usuario que realiza la
petición no esta autorizado
20. body:
21. application/json:
22. type: string
23. example: Unathorized
24. 500:
25. description: Error del servidor
26. body:
27. application/json:
28. type: string
29. example: Internal server error
o GET /incidencias/damePorEstado/:id: En el mapa solo se ven las
incidencias que se encuentran con un estado determinado, puesto que
no será de utilidad para el usuario ver las incidencias que están
64
cerradas por ejemplo en el mapa. Dicho método nos devolverá, en
base a un id de estado, una lista con incidencias que tienen dicho
estado.
1. /incidencias/damePorEstado/{id}: 2. uriParameters: 3. id: 4. description: Id del estado 5. type: integer 6. get: 7. description: Obtenemos las incidencias con un estado
determinado
8. responses: 9. 200: 10. description: Lista de incidencias
11. body:
12. application/json:
13. properties:
14. array:
15. properties:
16. id:
17. description: Id de la incidencia
18. type: integer
19. titulo:
20. description: Titulo de la incidencia
21. type: string
22. descripcion:
23. description: Descripcion de la incidencia
24. type: string
25. fecha:
26. description: Fecha de la incidencia
27. type: datetime
28. latitud:
29. description: Latitud donde se ha enviado
la incidencia
30. type: number
31. longitud:
32. description: Longitud donde se ha enviado
la incidencia
33. type: number
34. estado:
35. description: Estado de la incidencia
36. type: string
37. tipo:
38. description: Tipo de incidencia
39. type: string
40. playa:
41. description: Nombre de la playa
42. type: string
43. TipoIncidencia_id:
44. description: Id del tipo de incidencia
45. type: string
46. Playa_id:
47. description: Id de la playa
48. type: integer
49. 401:
50. description: El usuario que realiza la
petición no esta autorizado
65
51. body:
52. application/json:
53. type: string
54. example: Unathorized
55. 404:
56. description: No se encuentra la incidencia
57. body:
58. application/json:
59. type: string
60. example: Not found
61. 500:
62. description: Error del servidor
63. body:
64. application/json:
65. type: string
66. example: Internal server error
o GET /incidencias/damePorPlaya/:id: Cuando un usuario filtra las
incidencias de una playa concreta, se utiliza este método, al cual se le
envía un id de una playa, y nos devuelve todas las incidencias que se
han producido en dicha playa.
1. /incidencias/damePorPlaya/{id}: 2. uriParameters: 3. id: 4. description: Id del estado 5. type: integer 6. get: 7. description: Obtenemos las incidencias publicadas para una
playa
8. responses: 9. 200: 10. description: Lista de incidencias
11. body:
12. application/json:
13. properties:
14. array:
15. properties:
16. id:
17. description: Id de la incidencia
18. type: integer
19. titulo:
20. description: Titulo de la incidencia
21. type: string
22. descripcion:
23. description: Descripcion de la incidencia
24. type: string
25. fecha:
26. description: Fecha de la incidencia
27. type: datetime
28. latitud:
29. description: Latitud donde se ha enviado
la incidencia
66
30. type: number
31. longitud:
32. description: Longitud donde se ha enviado
la incidencia
33. type: number
34. estado:
35. description: Estado de la incidencia
36. type: string
37. tipo:
38. description: Tipo de incidencia
39. type: string
40. playa:
41. description: Nombre de la playa
42. type: string
43. TipoIncidencia_id:
44. description: Id del tipo de incidencia
45. type: string
46. Playa_id:
47. description: Id de la playa
48. type: integer
49. 401:
50. description: El usuario que realiza la
petición no esta autorizado
51. body:
52. application/json:
53. type: string
54. example: Unathorized
55. 404:
56. description: No se encuentra la incidencia
57. body:
58. application/json:
59. type: string
60. example: Not found
61. 500:
62. description: Error del servidor
63. body:
64. application/json:
65. type: string
66. example: Internal server error
o POST /incidencias/:id/cambiarEstado: El gestor es el encargado de
cambiar el estado de las incidencias, y para dicho fin se utiliza este
método. Se envía el nuevo estado que tendrá la incidencia en el cuerpo
del mensaje, y en el parámetro de la URL se envía el id de la
incidencia.
1. /incidencias/{id}/cambiarEstado: 2. uriParameters: 3. id:
67
4. description: Id de la incidencia 5. type: integer 6. post: 7. description: Cambiar estado de la incidencia 8. body: 9. application/json: 10. properties:
11. idEstadoIncidencia:
12. description: Id del nuevo estado de la incidencia
13. type: integer
14. responses:
15. 200:
16. description: Estado cambiado correctamente
17. body:
18. application/json:
19. properties:
20. message:
21. description: Mensaje
22. type: string
23. 401:
24. description: El usuario que realiza la
petición no esta autorizado
25. body:
26. application/json:
27. type: string
28. example: Unathorized
29. 404:
30. description: No se encuentra la incidencia
31. body:
32. application/json:
33. type: string
34. example: Not found
35. 500:
36. description: Error del servidor
37. body:
38. application/json:
39. type: string
40. example: Internal server error
o GET /incidencias/todas: Para que el gestor sea capaz de ver una lista
con todas las incidencias, dicho método le devuelve un array con
todas las incidencias del sistema.
1. /incidencias/todas: 2. get: 3. description: Obtenemos una lista con todas las incidencias 4. responses: 5. 200: 6. description: Lista de incidencias 7. body: 8. application/json: 9. properties: 10. array:
11. properties:
68
12. id:
13. description: Id de la incidencia
14. type: integer
15. titulo:
16. description: Titulo de la incidencia
17. type: string
18. descripcion:
19. description: Descripcion de la incidencia
20. type: string
21. fecha:
22. description: Fecha de la incidencia
23. type: datetime
24. latitud:
25. description: Latitud donde se ha enviado
la incidencia
26. type: number
27. longitud:
28. description: Longitud donde se ha enviado
la incidencia
29. type: number
30. estado:
31. description: Estado de la incidencia
32. type: string
33. tipo:
34. description: Tipo de incidencia
35. type: string
36. playa:
37. description: Nombre de la playa
38. type: string
39. TipoIncidencia_id:
40. description: Id del tipo de incidencia
41. type: string
42. Playa_id:
43. description: Id de la playa
44. type: integer
45. 401:
46. description: El usuario que realiza la
petición no esta autorizado
47. body:
48. application/json:
49. type: string
50. example: Unathorized
51. 404:
52. description: No se encuentra la incidencia
53. body:
54. application/json:
55. type: string
56. example: Not found
57. 500:
58. description: Error del servidor
59. body:
60. application/json:
61. type: string
62. example: Internal server error
69
- indicadores.js: En este archivo, tenemos los métodos que están relacionados
con los indicadores de una playa.
o GET /indicadores/dameDePlaya/:id: Obtenemos una lista con todos
los indicadores de la playa que contiene su valor numérico actual, su
valor textual, nombre, descripción y fecha.
1. /indicadores/dameDePlaya/{idPlaya}: 2. uriParameters: 3. idPlaya: 4. description: Id de la playa 5. type: integer 6. get: 7. description: Obtenemos los indicadores de una playa 8. responses: 9. 200: 10. description: Indicadores obtenidos correctamente
11. body:
12. application/json:
13. properties:
14. array:
15. properties:
16. nombre:
17. description: Nombre del indicador
18. type: string
19. descripcion:
20. description: Descripcion del indicador
21. type: string
22. valorN:
23. description: Valor numérico
24. type: number
25. valorT:
26. description: Valor textual
27. type: string
28. fecha:
29. description: Última fecha de modificación
30. type: datetime
31. Playa_id:
32. description: Id de la playa
33. type: integer
34. 401:
35. description: El usuario que realiza la
petición no esta autorizado
36. body:
37. application/json:
38. type: string
39. example: Unathorized
40. 404:
41. description: No hay indicadores para dicha playa
42. body:
43. application/json:
44. type: string
45. example: Not found
46. 500:
47. description: Error del servidor
70
48. body:
49. application/json:
50. type: string
51. example: Internal server error
o GET /indicadores/damePorNombre/:nombre/:idPlaya: Nos devuelve
el indicador que le enviamos como parámetro para la playa que
solicitamos en detalle, con el valor de todas sus variables en el
momento actual.
1. /indicadores/damePorNombre/{nombre}/{idPlaya}: 2. uriParameters: 3. nombre: 4. description: Nombre del indicador 5. type: string 6. idPlaya: 7. description: Id de la playa 8. type: integer 9. get: 10. description: Obtenemos un indicador en una playa
11. responses:
12. 200:
13. description: Indicadores obtenidos correctamente
14. body:
15. application/json:
16. properties:
17. indicador:
18. properties:
19. nombre:
20. description: Nombre del indicador
21. type: string
22. descripcion:
23. description: Descripcion del indicador
24. type: string
25. valorN:
26. description: Valor numérico
27. type: number
28. valorT:
29. description: Valor textual
30. type: string
31. fecha:
32. description: Última fecha de modificación
33. type: datetime
34. Playa_id:
35. description: Id de la playa
36. type: integer
37. variables:
38. properties:
39. array:
40. properties:
41. nombre:
42. description: Nombre del indicador
71
43. type: string
44. descripcion:
45. description: Descripcion del
indicador
46. type: string
47. valorN:
48. description: Valor numérico
49. type: number
50. valorT:
51. description: Valor textual
52. type: string
53. fecha:
54. description: Última fecha de
modificación
55. type: datetime
56. indicador:
57. description: Indicador
58. type: string
59. Playa_id:
60. description: Id de la playa
61. type: integer
62. 401:
63. description: El usuario que realiza la
petición no esta autorizado
64. body:
65. application/json:
66. type: string
67. example: Unathorized
68. 404:
69. description: No hay indicadores para dicha playa
70. body:
71. application/json:
72. type: string
73. example: Not found
74. 500:
75. description: Error del servidor
76. body:
77. application/json:
78. type: string
79. example: Internal server error
- variables.js: En este archivo solamente contamos con un método, que es
POST /variables/cambiar, al cual se le envía en el body un JSON con el
nombre de la variable que queremos cambiar, el id de la playa y el nuevo
valor que le daremos a dicha variable.
1. /variables/cambiar: 2. post: 3. description: Cambiar variables 4. body: 5. application/json: 6. properties: 7. nombre:
72
8. description: Nombre de la variable 9. type: string 10. idPlaya:
11. description: Id de la playa
12. type: integer
13. valorN:
14. description: Valor numérico
15. type: integer
16. responses:
17. 200:
18. description: Cambio realizado correctamente
19. body:
20. application/json:
21. properties:
22. message:
23. description: Mensaje
24. type: string
25. 400:
26. description: Error
27. body:
28. application/json:
29. type: string
30. example: Error
31. 401:
32. description: El usuario que realiza la
petición no esta autorizado
33. body:
34. application/json:
35. type: string
36. example: Unathorized
37. 500:
38. description: Error del servidor
39. body:
40. application/json:
41. type: string
42. example: Internal server error
73
Implementación
La implementación es la fase en la que pasamos a implementar los requisitos
obtenidos previamente siguiendo el diseño que hemos planteado en la fase anterior.
Para validar la propuesta se ha implementado un prototipo que se va a detallar a
continuación, y posteriormente se han realizado una serie de pruebas sobre el
mismo.
Arquitectura implementada
En este apartado, procederemos a describir la arquitectura de la aplicación que
habíamos diseñado previamente, pero centrándonos en qué se ha empleado para
implementar dicha arquitectura.
Los sensores inteligentes que proporcionan información al sistema para el posterior
cálculo de KBQIs son cámaras. La cámara es el módulo de cámara de Raspberry, y
el dispositivo embebido sobre el cual se monta el sensor es una Raspberry Pi 3. Para
mantenerlo todo unido de una manera cómoda y práctica, y evitar tener cables, se
ha empleado una caja que tiene un agujero para la cámara, lo cual la hace un sistema
compacto y portable.
74
Figura 23: Caja de la Raspberry pi 3 con módulo de cámara.
La Raspberry tiene instalado el SO Raspbian, y la programación del contador de
personas se ha realizado mediante Python 2.7. Para disponer de métodos de visión
artificial se ha usado también la biblioteca OpenCV, que está disponible para usar
en Python, entre otros lenguajes.
La aplicación móvil se ha desarrollado mediante el framework de desarrollo de
aplicaciones híbridas Ionic, puesto que nos permite generar aplicaciones para varias
plataformas, y de esta manera habrá una mayor cantidad de usuarios que tendrán
acceso a la aplicación.
75
Aplicación móvil
Procederemos ahora a ver algunos puntos importantes en relación con la
implementación en Ionic de nuestra aplicación móvil.
Funcionamiento
Figura 24: Captura de la pantalla de carga de la aplicación.
Lo primero que vemos cuando iniciamos la app es una pantalla de carga
personalizada con el logotipo que se ha usado para la aplicación sobre un fondo con
los colores de la app y un círculo que indica que está cargando.
76
Figura 25: Captura de permisos requeridos para usar la aplicación.
Cuando se instala la aplicación y se accede a alguna página en la cual haga falta, nos
pedirá los permisos necesarios para poder realizar ciertas acciones, como obtener la
ubicación, realizar fotos o grabar audio. Deberemos aceptar dichos permisos si
queremos que la app funcione correctamente, puesto que, si no los aceptamos, la
aplicación cerrará dicha página y volverá a la anterior
77
Figura 26: Captura de la pantalla inicial de la aplicación.
La pantalla que nos aparece al iniciar la app es la de Login. Aquí tenemos varias
opciones.
- La opción de hacer Login nos dará acceso a nuestro perfil en la app, y
podremos acceder al resto de pantallas, puesto que es necesario estar
autenticado en la aplicación para poder realizar cualquier operación.
78
Figura 27: Captura de la pantalla de registro de nuevos usuarios.
- Otra opción es la de crear una cuenta, la cual nos llevará a la pantalla de
registro. En la pantalla de registro tendremos la opción de rellenar una serie
de datos y darnos de alta en el sistema.
79
Figura 28: Captura de la lista de incidencias.
Una vez hemos iniciado sesión en el sistema, nos lleva a la pantalla de la lista de
incidencias que hemos mandado sobre las playas. Además, tenemos el botón que
nos lleva a crear una nueva incidencia, y podemos ver los detalles de cada
incidencia publicada.
80
Figura 29: Captura de la creación de una nueva incidencia.
- Si le damos al botón de + para añadir una nueva incidencia, nos llevará a una
página en la que podremos crear una nueva incidencia. Deberemos añadir
una descripción, y seleccionar una playa.
81
Figura 30: Captura del Select Search empleado para seleccionar playas.
Podremos seleccionar la playa buscando de una manera muy cómoda. Cuando la
seleccionemos, nos aparecerá en el mapa, además de nuestra posición, que sale al
cargar la nueva incidencia, la posición de la playa que hemos seleccionado, para que
podamos comprobar que realmente es correcta la playa.
Podremos añadir imágenes también sobre la incidencia, por ejemplo, si hay una
ducha rota o un acceso en malas condiciones, para documentarlo y ayudar al gestor
a localizar el problema.
Además, podremos añadir audios también para brindar una mayor accesibilidad a
la aplicación y que sea más cómodo para ciertos grupos de personas.
82
Figura 31: Captura de la previsualización de imágenes.
Podemos realizar una vista previa de una foto seleccionando una, o eliminarla
mediante el botón de eliminar.
Con los audios también podemos comprobar que lo hemos grabado correctamente,
mediante el botón de reproducir o eliminarlos.
Una vez tenemos todos los detalles de la incidencia podemos enviarla haciendo
click en el botón de debajo.
83
Figura 32: Captura del mensaje de seguridad para no dejar incidencias a medias.
Si por lo contrario nos hemos dado cuenta que no queremos enviar la incidencia,
haremos click en la flecha superior izquierda, y cuando nos aparezca el modal
indicándonos que se perderá todo, haremos click en aceptar.
84
Figura 33: Captura de los detalles de la incidencia.
Si queremos revisar las incidencias que hemos mandado, tenemos la opción de ver
los detalles de nuestras incidencias, en cuya opción no podremos modificar nada,
únicamente ver detalles, la playa, imágenes y audios que hemos realizado. El gestor
tendrá la capacidad de cambiar el estado de la incidencia desde esta pantalla.
85
Figura 34: Captura del menú de la aplicación.
Si nos fijamos bien, arriba a la izquierda podemos ver que hay un botón para
mostrar el menú. Si hacemos click en él, se abrirá un desplegable a la izquierda con
el menú y las diferentes opciones que tiene, y podremos ir a ellas. Además
dispondremos de un avatar, nuestra información de perfil, y un botón para cerrar
sesión en la app.
86
Figura 35: Captura del mapa con las incidencias.
Tenemos una opción muy útil también, en la que podemos ver todas las incidencias
que hay. Veremos un mapa con las incidencias que no están solucionadas, y
haciendo zoom podremos buscar la playa que nos interese, seleccionar la incidencia
y verla en detalle.
87
Figura 36: Captura de la lista de indicadores de una playa.
En caso de estar autenticados como gestor, tendremos también la opción de
modificar los 4 indicadores de la playa, tras seleccionar sobre qué playa queremos
realizar la modificación de variables: IServicios, ITransporte, IAlrededores e
IAplaya. En caso de estar autenticados como ciudadanos, únicamente podremos ver
el valor de dichos indicadores, y no nos aparecerá el botón de editar
Si vamos a cualquiera de ellos, veremos que nos aparecen con los variables a partir
de las que se calculan, que podemos modificar para actualizar el indicador.
88
Figura 37: Captura del filtrado de incidencias por playa.
Además, tendremos la opción de filtrar las incidencias de una playa específica, para
de esta manera obtener una lista con las incidencias que se han producido en esa
playa.
89
Figura 38: Captura de edición de perfil del usuario.
Por último tenemos la opción de editar la información de nuestro perfil, como son
el nombre, los apellidos y el email.
LoadingController
Cuando nos autenticamos, hacemos una petición al servidor, y debemos esperar a
que éste nos responda con la información de autenticación correcta o incorrecta y
los datos de usuario. Igualmente, cuando creamos una nueva incidencia, se accede
a la geolocalización y se obtienen tanto las coordenadas actuales del usuario como
el lugar en el que está, y esto debe marcarse en el mapa.
Ambos son procesos que tardan unos instantes, y para dar una mayor sensación de
profesionalidad, además de no permitir al usuario interactuar con la app durante
ese tiempo, utilizaremos el LoadingController de ionic-angular para que se muestre
90
un indicador de carga durante el tiempo que se realizan las operaciones necesarias
en nuestra app [24].
Geolocalización
Para obtener las coordenadas del usuario, se ha hecho uso del plugin Geolocation,
que se encuentra en ionic-native.
Gracias a dicho plugin, podemos realizar una llamada al método
getCurrentPosition, al que le pasamos una serie de opciones como son el timeout
que queremos tener en milisegundos, o enableHighAccuracy, que siendo true,
provocará que la aplicación devuelva los mejores resultados de ubicación posibles,
con la contra de ser un método un poco más lento.
Google Maps
En algunas ocasiones, como cuando entramos a una incidencia, o abrimos el mapa
de incidencias, es necesario que se visualice un mapa de Google Maps por ejemplo
en nuestra aplicación.
Esto lo conseguimos gracias a la API de JavaScript, añadiendo el script que contiene
la librería de Google Maps en el index.html. Para ello debemos generar primero una
API key, que es la que nos identifica ante google en cada petición que realizamos, e
introducirla en el script.
Creamos en la página que nos interesa un objeto de tipo mapa, al que le ponemos
una serie de opciones como centro, zoom, tipo de mapa y la manera en la que se van
a gestionar los gestos. En nuestro caso, le hemos puesto una gestión de manera
cooperativa. Esto quiere decir que, si el usuario hace scroll apoyándose en el mapa,
no se moverá el mapa, sino que se hará scroll de manera normal. Si lo que
quisiéramos es desplazarnos por el mapa, deberemos hacerlo con dos dedos. Así, el
usuario no cometerá errores al momento de navegar en nuestra aplicación, ni se
91
atascará intentando bajar a la parte del final de las incidencias. En el caso del mapa
de incidencias no se ha empleado el cooperativo, sino el por defecto, ya que será
más cómodo dado que no hay que bajar a ningún sitio, sino que todo es un mapa.
Figura 39: Captura del gesture handling cooperative.
Una vez hemos creado el mapa, procederemos a añadir los marcadores. Para ello
crearemos un objeto de tipo marcador, y en sus opciones le diremos el mapa al que
pertenece, el tipo de animación y la posición en la que se encontrará (objeto tipo
LatLng). Crearemos después un objeto tipo InfoWindow con un contenido, y
después añadiremos un listener para que al hacer click en un marcador, se muestre
el InfoWindow con el contenido que se le ha asignado. En algunos casos, en el
InfoWindow escribiremos la dirección en la que se encuentra el usuario, creando un
objeto de tipo Geocoder, al que le pasaremos las coordenadas y hará reverse
geocoding, proporcionándonos la dirección.
92
Cabe destacar también que, en el caso del mapa con las incidencias, para que no
aparezcan todos los marcadores, lo cual proporcionaría una mala experiencia de
usuario, ya que se podría llegar a cubrir el mapa de incidencias si hubiera muchas,
y no quedaría nada bien. Por ello, la solución para que quede de una manera más
sencilla y bonita, hemos decidido hacer uso de Marker Clustering. De esta manera,
las incidencias que se encuentran próximas, se agrupan y muestran el número de
marcadores que hay agrupados en una zona.
Figura 40: Captura donde se aprecian los marcadores juntos.
93
Figura 41: Captura donde se muestran los marcadores separados al acercarnos.
Cámara
En las incidencias, hemos decidido que los usuarios puedan enviar además de la
descripción y la playa, fotos para que el gestor vea dónde hay un problema a través
de imágenes.
Para dicho fin, se ha empleado el plugin de Cordova Camera, que es el que nos
permite tomar fotos. Dicho plugin, además de realizar fotos con la cámara de
nuestro móvil, nos permite seleccionar una de la galería, con lo que cuando el
usuario hace click en el símbolo de la cámara, le aparecerá un ActionSheet para que
elija si quiere realizar la foto o seleccionarla de la galería.
Audio
En cuanto a los audios, en las incidencias también se le dará la posibilidad al usuario
de grabar audios, para que pueda explicar con mayor detalle la incidencia, además
de proporcionar una mayor accesibilidad a la app.
94
Para poder grabar audios y reproducirlos necesitaremos el plugin de Cordova
Media. Debemos tener en cuenta que se usarán diferentes funciones para iOS y para
Android, con lo cual debemos diferenciarlos tanto para grabar como para
reproducir nuestros audios.
Select Searchable
En el momento en el que usuario está redactando la incidencia, se le pedirá que
seleccione la playa con la que está relacionada la incidencia. Puesto que mostrar
todas las playas de la Comunidad Valencia sería bastante incómodo porque el
usuario tendría que localizar la playa entre muchas playas, hemos decidido que lo
más cómodo sería usar un plugin que permite al usuario buscar y filtrar mientras
escribe, con lo que se agiliza mucho el proceso de buscar y seleccionar la playa.
95
Contador de personas
Sustraer fondo con BackgroundSubstractorMog2
Figura 42: Ejemplo de sustracción de fondo.
La sustracción de fondo trata de eliminar el fondo y detectar los objetos que se están
moviendo [25]. Si tuviéramos una imagen inicial de la zona sin personas, podríamos
restar un fotograma con otro y obtendríamos dónde hay algo de movimiento, pues
sería en el punto en el que no había nada y ahora hay algo, pero como no podemos
asegurarnos de que en el primer fotograma no vaya a haber nadie, debemos crear
un sustractor de fondo.
Es interesante que no se detecten sombras, puesto que, si no, la altura de las
personas podría ser totalmente incorrecta.
En la imagen superior se ha aplicado una sustracción de fondo al video, y podemos
ver como las sombras en su mayor parte están en un color más grisáceo.
96
Threshold
Figura 43: Ejemplo del threshold.
Una vez se ha realizado la sustracción de fondo, como hemos comentado en el
punto anterior, las sombras quedan coloreadas en un color grisáceo, aunque no es
exacto ni perfecto, puesto que encontramos colores grisáceos incluso dentro de las
personas, o en algunas zonas que no deberían estar. Esto lo arreglaremos
posteriormente mediante otras operaciones.
Es el momento de clasificar píxeles mediante threshold, para que dejen de aparecer
dichas sombras en un color gris, y únicamente aparezcan los que son de un color
blanco, con lo cual le diremos que los que estén por debajo de un umbral se
clasifiquen a negro, y los que estén por encima, a blanco.
97
Opening
Figura 44: Ejemplo de opening.
Vista la foto anterior, vemos que hay zonas en las que aparecen zonas blancas muy
finas, y nosotros buscamos que la persona sea un completo, un todo, razón por la
cual es el momento de realizar un opening. El opening consiste en una erosion
seguida de una dilation. Es útil para eliminar objetos pequeños, y se rellenan de
negro partes pequeñas [26].
En nuestro caso, esto sirve por ejemplo para eliminar el ruido del fotograma, que
quedará mucho más limpia, y preparar el contorno de la persona con bloques más
grandes para realizar el closing posteriormente.
98
Closing
Figura 45: Ejemplo de closing.
Closing es lo contrario a opening, opening es erosion seguido de dilation, mientras
que closing es dilation seguido de erosion. Es un método muy útil para rellenar
huecos negros pequeños [27].
En nuestro caso, es útil para rellenar los huecos que pueden haber dentro de una
persona, provocados anteriormente al eliminar sombras, y de esta manera
conseguir una persona blanca mejor definida.
99
Contours
Figura 46: Ejemplo de findContours.
Una vez tenemos a las personas definidas, es el momento de obtener los contornos
de dichas figuras. Es por ello que usaremos el método findContours, al cual le
pasaremos el fotograma con el closing anterior y nos sacará los contronos de las
personas.
Para el ejemplo y que se vea cómodamente, realizaremos un drawContours, para
ver de qué manera OpenCV nos saca los contornos de cada figura. Podemos ver que
lo único que se ha hecho, es dibujar el contorno de cada figura que teníamos en la
dilation, pero utilizaremos el fotograma original para que se vea mejor.
De esta manera, tendremos en una variable, un array con los contornos que hemos
detectado, y podremos iterar posteriormente sobre ellos.
100
Moments
Figura 47: Ejemplo de moments para localizar el centroide.
Ahora que tenemos los contornos, querremos obtener más información sobre ellos.
Para este objetivo, encontramos la función Moments, que nos proporciona
información sobre el contorno, como por ejemplo el área, y puntos útiles para
calcular el centroide (cx y cy) [28]. De esta manera, podremos descartar contornos
que sean muy pequeños para ser una persona, y obtendremos el centro de cada
contorno, punto que servirá de referencia para cada contorno.
A partir de ahora, dejaremos de dibujar los contornos de las personas, puesto que
ya sabemos que funciona, y nos centraremos en mostrar el rectángulo que lo
encuadra obteniendo dichas coordenadas mediante la función boundingRect, y
dibujando un rectángulo, lo cual nos quedará mucho más limpio, y escribiremos las
posiciones inferior izquierda y superior derecha en un texto a su lado para que nos
sea más cómodo desarrollar.
101
Figura 48: Ejemplo del boundingRect que contiene a la persona.
Personas
Crearemos una clase Persona, que nos servirá para darle atributos a cada contorno,
que será una persona.
Iteraremos sobre dicho array, y para cada persona observaremos si se encuentra
dentro de la zona central que hemos definido, que constará de una línea superior y
una línea inferior, y será la zona que el usuario deberá cruzar para que se detecte
que sube o baja.
102
Figura 49: Ejemplo de las líneas superior, inferior y central.
Comprobaremos si dicho contorno es nuevo, para poder agregarlo al array en caso
de que así sea, y comprobaremos si su centroide está dentro de las zonas
delimitadas superior e inferior, añadimos el centroide al array de recorridos de
dicha persona, lo cual nos servirá posteriormente para saber si sube o baja.
Igualmente, calcularemos la altura en ese instante y la añadiremos al array de
alturas, sobre el que posteriormente realizaremos la media para obtener resultados
más exactos.
En caso de que el usuario haya salido de la zona delimitada, es el momento de
obtener la dirección que llevaba, para saber si sube o si baja. Para saber si un
contorno es el mismo que una persona, lo hemos definido como si el centroide del
contorno se encuentra dentro del boundingRect de una persona.
103
Realizaremos un timeout, en el cual, si una persona ha dejado de aparecer durante
10 fotogramas seguidos, se le sacará del array de personas, con el objetivo de que el
mismo se vaya limpiando y no se produzcan overflows.
Operaciones para calcular la altura de una persona
Cálculo del ángulo perpendicular
Figura 50: Representación del ángulo que forma el centro de la cámara con la perpendicular al suelo.
En primer lugar, debemos calcular el ángulo que formará la perpendicular con el
suelo con la perpendicular del centro de la cámara de nuestra Raspberry Pi, al cual
llamaremos I. Dicho ángulo está representado en la figura 49.
104
Figura 51: Representación del ángulo I y de la cámara en detalle
En la figura 50 podemos ver el mismo ángulo I representado anteriormente.
Además, tenemos l1, que es la distancia del pie de la caja de la Raspberry a la
ubicación de la cámara, y l2 que representa la distancia entre la cámara y la parte
superior de la caja. Los lados a y b representan las proyecciones de la cámara, y serán
introducidos por el usuario, dependiendo de cómo coloque dicha cámara con
respecto al suelo.
Primero calcularemos mediante proporcionalidad el valor de a1 mediante la
siguiente fórmula:
a1 = l1*a/(l1+l2)
Una vez calculado a1, procederemos a calcular el ángulo C, cuya fórmula será la
siguiente:
C=arcsen(a1/l1)
105
Posteriormente, y sabiendo que la suma de los ángulos I y C producirá un ángulo
rectángulo, calcularemos I:
I=90-C
Cálculo de la distancia a los pies
Figura 52: Representación de las variables necesarias para calcular la distancia a los pies
Buscando en las especificaciones del módulo de cámara de la Raspberry pi,
obtenemos que dicho sensor tiene un ángulo de visión de 62.2x48.8 grados.
Debemos tener en cuenta los grados de alto de tiene dicho sensor, pues será clave
para determinar la altura de una persona. También debemos tener en cuenta que el
módulo de la cámara generará un vídeo que tendrá 480 píxels, con lo cual
deberemos relacionar los píxels de la cámara en los que se ubican los pies p1 con los
grados del ángulo, y lo haremos mediante proporcionalidad. Es importante saber
que los píxels irán de arriba abajo, mientras que nuestros ángulos irán al revés, con
lo cual le deberemos dar la vuelta. Obtendremos entonces, el ángulo en el que se
encuentran los pies del usuario P:
106
P=(48.8-((48.8*p1)/480))
El problema es que lo anterior ahora debemos referenciarlo con el ángulo en el que
tenemos situada la cámara I, y con la apertura de ángulo de la cámara. La fórmula
resultante nos dará el ángulo que forma la perpendicular de la cámara con los pies
del usuario U.
U = I-(48.8/2)+P
Teniendo el ángulo y la altura del suelo a la cámara s, dato que necesitaremos que
el gestor introduzca cuando inicia el programa, podremos calcular h, que será la
distancia de la cámara a los pies:
h=s/sen(90-U)
Cálculo de la distancia desde el suelo hasta la persona
Figura 53: Representación de las variables necesarias para calcular la distancia a la cabeza
107
Teniendo la distancia de la cámara a la persona calculada anteriormente, ahora
procederemos mediante el Teorema de Pitágoras, a calcular la distancia entre la
proyección de la cámara al suelo y la persona d.
d=√ℎ2 − 𝑠2
Cálculo de la altura de la persona
Igual que hemos realizado antes, calcularemos ahora por proporcionalidad el
ángulo con respecto a los píxels que hay a la cabeza P2.
P2=(48.8-((48.8*p1)/480))
Del mismo modo que para el cálculo del ángulo a los pies, deberemos ahora
relacionarlo con el ángulo de la cámara, de manera que nos quede colocado en la
posición que se encuentra la cámara:
U2 = I-(48.8/2)+P
Por último, calcularemos mediante la fórmula de la tangente de un ángulo, la altura
x que tiene dicha persona.
x=d/tan(U2)
108
Pruebas y validación
Nos encontramos la fase final del desarrollo software. Aquí es donde nos
encargamos de verificar que el sistema que hemos desarrollado cumple con lo que
el “cliente” nos había pedido, y tratamos de evaluar en qué grado cumple las
expectativas del cliente. Además, se realizan numerosas pruebas para minimizar al
máximo las probabilidades de fallos.
API
La API se ha desplegado en un servidor proporcionado por la EPS, al cual se nos ha
concedido acceso mediante ssh. Empleando este mismo protocolo, hemos sido
capaces de enviar de la máquina local a la remota los archivos comprimidos que
componen la base de datos y la API.
Figura 54: Acceso mediante ssh al servidor
Primero se ha entrado en mysql, y desde ahí se ha accedido a la base de datos
gestionPlayas, que es donde se ha ubicado la base de datos de nuestra aplicación, y
se ha importado la misma.
109
Figura 55: Acceso a la base de datos en el servidor.
Una vez tenemos la base de datos en marcha, hemos pasado a hacer las pruebas con
el servidor, para lo que se ha utilizado node. Tras hacer las pruebas y ver que todo
funcionaba a la corrección, mediante el uso de la herramienta forever, se ha puesto
la aplicación a correr como un servicio para que no se termine al cerrar la ventana
de ssh y esté en funcionamiento continuo.
Figura 56: Proceso en funcionamiento
110
Cámara
Figura 57: Cámara colocada en un entorno cerrado para realizar las pruebas.
El despliegue y pruebas de la cámara se han realizado en un entorno controlado,
puesto que no se dispone todavía de los permisos del ayuntamiento necesarios para
hacer las pruebas en las playas. Se han realizado pruebas con diferente niveles de
luz, y sobre las que han pasado diferentes personas para verificar que el
funcionamiento es el correcto.
Se han obtenido unos resultados bastante buenos en cuanto al tracking de personas
y la comprobación de si entran o salen, con márgenes de error muy pequeños. En
cuanto a la altura, la aproximación obtenida gracias al algoritmo también ha servido
para determinar si la persona era adulta o niño de un modo bastante bueno.
111
Aplicación móvil
Inicialmente se han realizado las pruebas gracias al comando ionic serve, en el propio
navegador, pero cuando hemos llegado a aspectos más complejos de nuestro
proyecto que han requerido de Cordova, como puede ser capturar imágenes o
audios, hemos tenido que realizarlas en un dispositivo Android conectado al
ordenador, que gracias a la herramienta de dispositivos que nos proporciona
Chrome podemos debugguear cómodamente en nuestro ordenador.
Posteriormente, cuando ya estaba la aplicación finalizada, se han realizado una serie
de pruebas desde el teléfono móvil desde diferentes sitios y con cuentas tanto de
usuario como de gestor, y se ha comprobado que todo funcionaba a la perfección.
112
Conclusiones
Se ha conseguido desarrollar un sistema autónomo y automático para gestionar la
recopilación de las playas de manera continua para poder realizar posteriormente
el cálculo de los KBQIs de cada playa.
Es un proyecto muy amplio y ambicioso, pero se ha dejado abierta la puerta a
nuevos métodos de sensorización y automatización que se puedan desarrollar en el
futuro, debido a que los métodos de la API están preparados para admitir nuevos
elementos de adquisición de información.
Personalmente, éste proyecto ha sido todo un reto, en el que me he encontrado con
bastantes dificultades, puesto que no conocía las tecnologías que he usado. Era mi
primera vez trabajando con visión artificial, con lo que tuve que leer una gran
cantidad de artículos y documentaciones para comprender el funcionamiento de los
métodos proporcionados por OpenCV.
También era la primera vez que desarrollaba aplicaciones móviles, y finalmente
Ionic ha resultado ser una opción muy cómoda y completa para poder desarrollar
aplicaciones híbridas.
Finalmente, el sistema que se ha conseguido desarrollar ha resultado ser totalmente
funcional y efectivo, permitiendo así una mayor cantidad de obtención de
información sobre variables que finalmente incidirán en los indicaodres de las
playas.
113
Referencias
[1] Wikipedia. OpenCV. 2018. https://es.wikipedia.org/wiki/OpenCV
[2] LuisMi Gracia. ¿Qué es OpenCV?. 2013. https://unpocodejava.com/2013/10/09/que-
es-opencv/
[3] OpenCV team. About - OpenCV library. 2018. https://opencv.org/about.html
[4] Wikipedia. Ionic (mobile app framework). 2018.
https://en.wikipedia.org/wiki/Ionic_(mobile_app_framework)
[5] Ionic. Concepts. https://ionicframework.com/docs/intro/concepts/
[6] Tinashe Munyaka. Ionic From Scratch: What Is Ionic?. 2017.
https://code.tutsplus.com/tutorials/ionic-from-scratch-what-is-ionic--cms-29323
[7] Ionic. Ionic Native App Installation with Ionic Cli and Cordova.
https://ionicframework.com/docs/intro/installation/
[8] Ionic. Components. https://ionicframework.com/docs/components/#overview
[9] Jose Jesus Perez Rivas. Qué es y cómo empezar con Ionic Framework. 2015.
http://www.phonegapspain.com/que-es-y-como-empezar-con-ionic-framework/
[10] Git. https://git-scm.com/
[11] Kayla Ngan. What is Git?. 2018. https://docs.microsoft.com/en-
us/azure/devops/learn/git/what-is-git
[12] Korbin Brown. What is GitHub and what is it used for?. 2016.
https://en.wikipedia.org/wiki/GitHub
[13] Luciano Castillo. Conociendo Github. 2012.
https://conociendogithub.readthedocs.io/en/latest/data/introduccion/
114
[14] Pablo Domínguez. El ciclo de vida del software.
https://openclassrooms.com/en/courses/4309151-gestiona-tu-proyecto-de-
desarrollo/4552406-el-ciclo-de-vida-del-software
[15] Wikipedia. Proceso para el desarrollo de software. 2018.
https://es.wikipedia.org/wiki/Proceso_para_el_desarrollo_de_software#Modelos_
de_Desarrollo_de_Software
[16] Carlos-vialfa. Ciclo de vida del software. https://es.ccm.net/contents/223-ciclo-
de-vida-del-software
[17] Javire Garzás. Ciclos de vida para gestionar un proyecto software: cascada,
espiral, iterativo, incremental o ágil. 2013.
http://www.javiergarzas.com/2013/07/ciclos-de-vida-software.html
[18] Ciclo de vida adaptativo vs predictivo.
https://samuelcasanova.com/2016/06/ciclo-de-vida-adaptativo-vs-predictivo/
[19] Qué es SCRUM. https://proyectosagiles.org/que-es-scrum/
[20] Andrés Hevia. Análisis orientado a servicios.
https://andreshevia.com/2015/04/26/analisis-orientado-a-servicios/
[21] Humberto Cervantes. Arquitectura de Software.
https://sg.com.mx/revista/27/arquitectura-software
[22] Pedro Gutiérrez. Fundamento de las bases de datos: Modelo entidad-relación.
https://www.genbeta.com/desarrollo/fundamento-de-las-bases-de-datos-modelo-
entidad-relacion
[23] Adrián Alonso Vega. Diseñando y documentando tus APIs utilizando RAML.
https://adrianalonso.es/desarrollo-web/apis/disenando-y-documento-apis-
utilizando-raml/].
115
[24] Ionic. LoadingController – Ionic API Documentation.
https://ionicframework.com/docs/api/components/loading/LoadingController/
[25] OpenCV. Background substraction.
https://docs.opencv.org/3.3.0/db/d5c/tutorial_py_bg_subtraction.html
[26] OpenCV. Morphology Transformations.
https://docs.opencv.org/2.4/doc/tutorials/imgproc/opening_closing_hats/opening_
closing_hats.html
[27] OpenCV. Morphology Transformations.
https://docs.opencv.org/3.4/d3/dbe/tutorial_opening_closing_hats.html
[28] OpenCV. Contour Features.
https://docs.opencv.org/3.1.0/dd/d49/tutorial_py_contour_features.html