View
213
Download
0
Category
Preview:
Citation preview
Encaminhamento de Pessoas e Veículos no Interior deEdifícios
Rui Filipe Sequeira Casimiro
Dissertação para obtenção do Grau de Mestre em
Engenharia Informática e de Computadores
Orientador: Prof. Renato Jorge Caleira Nunes
Júri
Presidente: Prof. Paolo RomanoOrientador: Prof. Renato Jorge Caleira NunesVogal: Prof. Alberto Manuel Ramos da Cunha
Outubro 2016
ii
Resumo
Dos sistemas de encaminhamento estudados, a maioria não partilha os mecanismos que permitem
adicionar novos mapas ao sistema nem são soluções suficientemente genéricas para poderem ser
usadas em qualquer espaço. De modo a preencher esta lacuna, neste trabalho é proposto um sistema
de encaminhamento para edifícios aberto e genérico, de modo a facilitar a introdução de novos mapas
e aumentar a divulgação do sistema.
O resultado é uma aplicação para smartphones, desenvolvida em Android, que permite gerar per-
cursos eficazes em contextos exigentes, o que foi testado e sujeito a uma avaliação criteriosa. Este
documento descreve a aplicação desenvolvida e detalha o seu funcionamento.
A funcionalidade principal da aplicação é calcular percursos entre dois pontos, tendo em conta
eventuais restrições impostas pelo utilizador (como evitar escadas ou elevadores) e devolver instruções
textuais. Estas instruções indicam todas as mudanças de direção e incluem sempre que possível pontos
de referência. Estas instruções são ainda enriquecidas com a presença de um mapa 2D. Para além do
cálculo de percursos a aplicação vai permitir listar pontos de interesse disponíveis no edifício, estacionar
o veículo próximo de um destino alvo e fornecer indicações para voltar ao mesmo.
Para o administrador de um edifício a aplicação vai permitir criar uma representação do espaço
através de um conjunto reduzido de conceitos, presentes na maioria dos edifícios. Esta representação
é feita através de uma especificação em XML que pode ser gerada através do JOSM.
Palavras-chave: encaminhamento, mapa XML, JOSM, smartphone, Android
iii
iv
Abstract
Most of the indoor routing systems found in our research lack the means to add new maps to the system
and are not generic enough to fit all types of indoor spaces. In order to fill this gap, we propose an open
and generic indoor routing system, in order to ease the addition of new maps and the disclosure of the
system. The result is an Android smartphone application capable of answering the most challenging
route searches. This work describes the application in great detail.The main application feature is ge-
nerating instructions for the route returned by the route search between a start point and an end point,
taking into account possible restrictions the user might choose to avoid such as stairs and elevators.
This instructions help the user take the turns and also include reference points witch further enrich the
instructions. A 2D map of the building is also shown. The application also includes other features like a
point of interest directory, park near a target destination and providing instructions to return to the vehi-
cle. For a building administrator the system will provide a mapping mechanism through the definition of
a small set of concepts common to all kinds of buildings. This representation is done through a XML
specification witch can be generated through JOSM.
Keywords: routing, XML map, JOSM, smartphone, Android
v
vi
Índice
Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iii
Abstract . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . v
Índice de Figuras . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ix
Glossário . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xi
1 Introdução 1
1.1 Contexto e Motivação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.2 Objetivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.3 Estrutura da dissertação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2 Trabalho relacionado 5
2.1 Sistemas de Localização . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.1.1 Conclusões . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.2 Sistemas de encaminhamento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.2.1 VeLoc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.2.2 PINwI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.2.3 RoughMaps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.2.4 Google Indoor Maps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.2.5 KAILOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.2.6 iNavigation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.2.7 OntoNav . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.2.8 Soluções para centros comerciais . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.2.9 Conclusões . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.3 OpenStreetMap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.4 Algoritmos de encaminhamento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3 Descrição da solução 17
3.1 Requisitos do sistema de encaminhamento . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.1.1 Requisitos não funcionais . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.1.2 Requisitos funcionais . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.2 Componentes do sistema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.3 Visão geral da solução . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
vii
3.4 Construção de um mapa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.4.1 Mapa em XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3.4.2 Gerar mapa XML com o JOSM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
3.5 Algoritmo para criar grafo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
3.6 Módulo para calcular percursos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
3.7 Módulo para gerar instruções . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
3.7.1 Mudança de direção . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
3.7.2 Divisão do percurso em segmentos . . . . . . . . . . . . . . . . . . . . . . . . . . 30
3.7.3 Algoritmo para identificar pontos de referência . . . . . . . . . . . . . . . . . . . . 31
4 Implementação 35
4.1 Alterações ao JOSM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
4.2 Estrutura do projeto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
4.3 Armazenamento e partilha de dados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
4.4 Gestão de mapas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
4.5 Inicialização das estruturas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
4.6 Definição de origem e destino . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
4.7 Procura de percursos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
4.8 Obter instruções . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
4.9 Restrições . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
4.10 Apoio ao estacionamento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
4.11 Alterar idioma . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
5 Avaliação 49
5.1 Correção dos algoritmos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
5.1.1 Cenários de teste . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
5.1.2 Análise dos testes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
5.2 Desempenho . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
6 Conclusões 59
Bibliografia 61
A Cenário de utilização 63
viii
Índice de Figuras
2.1 Exemplo XML de um objeto do tipo nó na base de dados do OpenStreetMap . . . . . . . 14
2.2 Exemplo XML de um objeto do tipo caminho na base de dados do OpenStreetMap . . . . 15
2.3 Algoritmo de Dijkstra adaptado de [18] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.1 Componentes do sistema e como são usados . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.2 Visão geral da solução . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.3 Captura de ecrã numa utilização do JOSM . . . . . . . . . . . . . . . . . . . . . . . . . . 26
3.4 Exemplo de grafo com o respetivo grafo linha a vermelho . . . . . . . . . . . . . . . . . . 27
3.5 Direções no plano horizontal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
3.6 Hierarquia de segmentos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
3.7 Mapa de parte de um percurso (destacado entre o nó 1 e 6) com 5 pontos de referência
(a vermelho) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
4.1 Ecrã lista de mapas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
4.2 Ecrã adicionar novo mapa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
4.3 Ecrã calcular rota . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
4.4 Mapa 2D da aplicação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
4.5 Ecrã de restrições . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
5.1 Piso -1 do edifício . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
5.2 Piso 0 do edifício . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
5.3 Piso 1 do edifício . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
5.4 Piso 2 do edifício . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
A.1 Ecrã descarregar mapa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
A.2 Ecrã de gestão de mapas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
A.3 Restrições . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
A.4 Diretório . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
A.5 Opções de um destino . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
A.6 Ecrã resultados para estacionar perto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
A.7 Ecrã estacionar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
A.8 Ecrã procurar rota . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
ix
A.9 Instruções 1/5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
A.10 Instruções 2/5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
A.11 Instruções 3/5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
A.12 Instruções 4/5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
A.13 Instruções 5/5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
A.14 Ecrã menu principal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
x
Glossário
ADB Android Debug Bridge.
DDMS Dalvik Debug Monitor Server.
DOM Domain Object Model.
DR Dead Reckoning.
GC Garbage Collection.
GPS Global Positioning System.
HTTP Hypertext Transfer Protocol.
JOSM Java OpenStreetMap Editor.
OSM OpenStreetMap.
QRC Quick Response Code.
SAX Simple API for XML.
XML eXtensible Markup Language.
XSLT EXtensible Stylesheet Language Transforma-
tion.
xi
xii
Capítulo 1
Introdução
1.1 Contexto e Motivação
Passamos grande parte do nosso tempo em espaços fechados como escolas e centros comerciais.
Chegar onde queremos é um dos problemas principais com que nos deparamos, principalmente quando
nos deslocamos pela primeira vez a um destes sítios. Podemos perguntar a outra pessoa, procurar num
diretório e até seguir placas indicativas mas obviamente nenhuma destas soluções é a ideal. Mesmo
que a informação encontrada esteja correta, a maior parte das soluções obriga à sua memorização.
Uma solução óbvia para este problema no contexto de um espaço exterior é usar um dispositivo
GPS (Global Positioning System). Através do GPS podemos ter o problema do encaminhamento re-
solvido em qualquer parte do globo (dependendo da cobertura dos seus mapas). No entanto, o GPS
não funciona bem em espaços fechados. Atualmente, aproveitando o acesso generalizado a tablets
e smartphones, seria de esperar que já existisse uma solução normalizada para encaminhamento em
edifícios mas tal não acontece.
Coloca-se então a seguinte questão: porque não temos uma solução idêntica ao GPS que funcione
dentro de edifícios? Para responder a esta questão vamos identificar as diferenças principais entre en-
caminhamento no interior e no exterior de edifícios. Estas diferenças são importantes porque permitem
responder à pergunta anterior e, servem ainda de linha orientadora para o trabalho a desenvolver nesta
dissertação ao ajudarem a identificar os principais desafios a ultrapassar no desenvolvimento de um
sistema de encaminhamento para espaços fechados.
Um processo de encaminhamento em geral consiste em 1) determinar a localização do utilizador, 2)
calcular o melhor percurso entre origem e destino, 3) devolver informação útil que permita ao utilizador
chegar ao destino. Determinar a localização do utilizador dentro de um edifício é uma das diferenças
cruciais. Como veremos no capítulo seguinte, e ao contrário do que acontece com o GPS, um sistema
de localização para espaços fechados exige a instalação de equipamentos específicos em cada edifício.
Esta situação não é diferente da que ocorre no caso do GPS que depende de uma infraestrutura de
satélites que circulam a terra. A diferença é que essa infraestrutura serve todo o planeta enquanto uma
instalação num edifício só serve esse mesmo edifício.
1
Alguns sistemas de encaminhamento focam-se principalmente em encontrar soluções para o pro-
blema da localização. Como resultado surgiram vários sistemas de encaminhamento, mas cada um lida
com o problema da localização de forma individual levando o utilizador a ter de cumprir os requisitos
da tecnologia específica para poder utilizar o sistema. Além disso os requisitos num edifício podem
ser completamente distintos dos requisitos noutro edifício. Muitos edifícios podem nem sequer dispor
de qualquer infraestrutura de apoio à localização dado que os custos de implementação podem ser
elevados.
Existem também soluções que optam por nem sequer incluir qualquer sistema de localização o
que acontece principalmente nas soluções para centros comerciais. Ainda assim, como cada centro
comercial dispõe da sua própria aplicação, o utilizador é forçado a instalar uma aplicação diferente para
cada um e tem de lidar com uma variedade de interfaces o que é pouco prático e confuso.
Outra grande diferença a ter em conta é a representação do espaço. De facto, para calcular o
melhor percurso e apresentá-lo ao utilizador é necessário criar uma representação do espaço, ou seja,
um modelo computacional que represente o edifício. Quando se pretende representar estradas, este
modelo é normalmente uma rede de nós ligados entre si. Apesar deste modelo também poder ser usado
em espaços fechados, é preciso ter em conta que no interior de um edifício o utilizador também se pode
deslocar na vertical entre pisos. Além disso, o acesso a imagens de satélite facilita bastante a criação
do modelo das estradas em qualquer ponto do globo enquanto num edifício a única possibilidade é
recorrer a plantas ou a vistorias ao local.
Por último convém ainda referir que a informação gerada para encaminhar o utilizador no exterior
tem de ser adaptada para o contexto de um espaço fechado. Para além do utilizador se pode deslocar
na vertical, alguns dos conceitos usados no exterior como ruas e cruzamentos não são tão óbvios em
espaços fechados dado que o utilizador tem mais liberdade de movimentos nestes espaços.
1.2 Objetivos
Neste trabalho será desenvolvido um sistema de encaminhamento para espaços fechados que ultra-
passa os problemas identificados anteriormente através duma solução genérica. O objetivo é que a
solução possa ser aplicada em qualquer espaço com pouco esforço e sem necessidade de alterar a
aplicação ou recorrer a programação. O produto final será uma aplicação Android para smartphones e
tablets desenvolvida em Java capaz de encaminhar o utilizador em espaços como centros de conferên-
cias, aeroportos, hospitais, escolas, centros comerciais, escritórios ou outros espaços similares.
Além de nos focarmos na aplicação do ponto de vista do utilizador, iremos preocupar-nos também
em facilitar ao máximo a tarefa de quem cria os mapas para a aplicação. Para isso iremos isolar a
representação do espaço da restante aplicação através de ficheiros XML que irão conter o mapa do
espaço com toda a informação necessária. Desta forma, a mesma aplicação que encaminha pessoas
num centro comercial em Lisboa pode ser usada num hospital em Braga, bastando para isso usar o
mapa (ficheiro XML) com a representação do espaço correspondente. A escolha desta representação,
ou seja, do conteúdo do ficheiro XML vai merecer uma atenção especial visto que vai influenciar di-
2
retamente a qualidade e generalidade da solução proposta. Por um lado, o uso duma representação
complexa irá dificultar a criação dos mapas e comprometer a generalidade da solução. Por outro lado,
uma representação demasiado simples pode diminuir a qualidade daquela que se considera a funcio-
nalidade mais importante da aplicação: gerar instruções com qualidade suficiente para que o utilizador
chegue ao seu destino.
Cada mapa de um edifício será representado no seu ficheiro XML. O conteúdo do ficheiro irá respei-
tar o modelo de dados do OpenStreetMap (OSM) que é um Sistema de Informação Geográfica (SIG)
com informação geográfica do mundo. Destacamos duas vantagens importantes ao usarmos este mo-
delo. A primeira vantagem é que este modelo de dados (baseado em redes de nós ligados entre si
formando caminhos) permite utilizar algoritmos de encaminhamento já bem conhecidos como o Dijks-
tra e A* na procura de uma rota para o destino. Outra vantagem de usar o modelo de dados do OSM
é que este dispõe do Java OpenStreetMap Editor (JOSM), uma ferramenta open source que permite
editar de forma gráfica o modelo de dados. Isto significa que podemos desenhar o mapa de um edifício
através da ferramenta (colocando objetos como pontos de interesse e definindo caminhos entre estes)
que depois de exportado para um ficheiro no formato XML poderá ser lido pela nossa aplicação. Esta
ferramenta irá facilitar muito a tarefa de quem cria os mapas. Note-se que apesar do formato XML
ser de fácil leitura e compreensão, as pessoas estão habituadas a visualizar plantas de edifícios como
desenhos em mapas a duas dimensões e o JOSM oferece essa possibilidade. Um bom exemplo da
utilidade desta ferramenta é a modificação de um mapa existente (imagine-se o caso de um centro
comercial que sofreu obras de remodelação e modificou a disposição de algumas das suas lojas) que
fica mais simples se a pessoa puder visualizar o mapa do espaço em duas dimensões.
Em termos de funcionalidades, pretende-se que o utilizador possa descarregar mapas remotamente.
Damos assim a possibilidade a qualquer pessoa ou entidade para disponibilizar os seus mapas publi-
camente bastando para isso que partilhe o endereço dos mesmos. Depois da aplicação carregar o
mapa de um espaço, o utilizador poderá listar todos os pontos de interesse disponíveis nesse espaço.
A funcionalidade mais importante será a devolução de instruções textuais que irão auxiliar o utilizador
a chegar ao seu destino. Tal como no processo de criação da representação do espaço, a presença
de um mapa 2D pode ser vantajosa para auxiliar o utilizador a chegar ao seu destino. Por este motivo
iremos adicionar um mapa 2D para auxiliar o utilizador a seguir as instruções destacando a zona do
mapa que cada instrução se refere. Este mapa será opcional visto que pode ter um impacto negativo
quando visualizado num dispositivo com o ecrã pequeno. Pretende-se também que a aplicação ajude
o utilizador a escolher o melhor local para estacionar o seu veículo e a voltar a este.
Quanto ao percurso calculado para o destino, este não será sempre o percurso mais curto. Iremos
desenvolver mecanismos para minimizar não só a distância, mas também o número de mudanças de
direção no percurso. Além disso, se o percurso incluir mudanças de piso, então deverá ser selecionado
o melhor meio de transporte vertical dado o número de pisos no percurso, as limitações do utilizador
(físicas ou outras) e as suas preferências. Alguns utilizadores têm dificuldade em usar escadas ou
podem simplesmente preferir não entrar em elevadores e por isso será criado um mecanismo que
permita aos utilizadores definir tais restrições.
3
A solução aqui proposta não irá resolver o problema da localização nem será usado um sistema
de localização existente. As soluções atuais para o problema da localização requerem que sejam
distribuídos no espaço objetos em localizações conhecidas (como beacons magnéticos ou pontos de
acesso Wi-Fi). Estes objetos comunicam depois com o dispositivo móvel do utilizador que recebe dos
objetos informação (através de sensores específicos) que lhe permitem determinar a sua localização
no espaço. Este processo iria tornar a nossa solução mais cara, devido à complexidade de instalação e
manutenção destes objetos e também menos genérica, devido à necessidade de sensores específicos
que iriam impor restrições ao nível dos equipamentos usados.
Para manter a generalidade do sistema iremos optar por deixar que seja o próprio utilizador a in-
dicar a sua localização com base em pontos de referência junto a si. Um ponto de referência poderá
ser qualquer elemento que se destaque e seja facilmente visível. Note-se que dentro de um edifício
será quase sempre possível orientar um utilizador com base em pontos de referência. Um edifício é
construído para ser utilizado por pessoas e em princípio terá sempre pontos de referência (como os
próprios pontos de interesse para onde as pessoas se pretendem deslocar, marcos, paredes pintadas
entre outros) e zonas com pouca liberdade de movimentos (como corredores).
1.3 Estrutura da dissertação
No capítulo 2 é apresentado o trabalho relacionado. Serão apresentadas diversas soluções para o
encaminhamento em espaços fechados, os principais algoritmos de encaminhamento e também os
tipos de dados do OSM no qual o nosso modelo de dados se baseia.
No capítulo 3 é descrita a arquitetura da solução proposta.
Segue-se o capítulo 4 com detalhes de utilização e implementação do sistema.
No capítulo 5 o sistema é avaliado.
Por fim, no capítulo 6, concluímos identificando possíveis melhorias ao sistema para trabalho futuro.
4
Capítulo 2
Trabalho relacionado
Neste capítulo vamos começar por analisar na Secção 2.1 o estado da arte relativo a tecnologias de
localização para espaços fechados. Segue-se a apresentação na Secção 2.2 dos sistemas de encami-
nhamento que se consideram mais relevantes face aos objetivos da presente dissertação. Depois, na
Secção 2.3 apresentamos o projeto OpenStreetMap (OSM). Será destacado o seu modelo de dados
baseado numa rede de nós ligados entre si, o qual será usado como base da solução apresentada
nesta dissertação. Os algoritmos de encaminhamento que permitem proceder ao cálculo do caminho
de menor custo numa rede deste género serão apresentados na Secção 2.4.
2.1 Sistemas de Localização
No contexto deste trabalho, um sistema de localização tem um papel fundamental porque permite de-
terminar a posição e fazer o seguimento em tempo real de um dispositivo. É normal encontrarmos um
sistema de localização como elemento principal na arquitetura de um sistema de encaminhamento.
Como exemplo mais conhecido temos o Global Positioning System (GPS), um sistema de cobertura
global, que conta com um conjunto de satélites que emitem um sinal que possibilita aos recetores
determinarem a sua posição. Apesar de ser um sistema utilizado em larga escala para localização
exterior, limitações tecnológicas impedem a utilização do GPS no interior de edifícios. De facto, um dos
requisitos para o bom funcionamento do GPS é que o sinal eletromagnético não sofra interferências
durante o percurso [1].
Na verdade, não existe um sistema equivalente ao GPS para o interior de edifícios, isto é, não existe
um sistema cuja instalação resolva o problema da localização em todos os espaços interiores como
acontece com o GPS onde os satélites atingem cobertura global resolvendo o problema da localização
em qualquer parte do mundo. O que existe são soluções específicas que podem variar tanto na tecnolo-
gia como na técnica de determinação da localização. As técnicas dizem respeito aos algoritmos usados
para determinar a localização com base na informação trocada entre os dispositivos móveis e as esta-
ções fixas. A informação pode ser trocada recorrendo a várias tecnologias. As técnicas mais relevantes
são: Dead Reckoning (DR), proximidade, triangulação, assinaturas e híbridas. Quanto às tecnologias,
5
as mais usadas são: Wi-Fi, redes celulares, Bluetooth, tags RFID e Quick Response Codes (QRC).
A desvantagem de existir um variado leque de soluções é que os dispositivos que se pretendam lo-
calizar nestes espaços são obrigados a dispor de sensores e de software específico dependendo das
tecnologias e técnicas utilizadas no espaço em questão.
A técnica de localização mais simples é baseada em proximidade. Nesta abordagem são distribuí-
dos pelo edifício um conjunto de objetos em localizações conhecidas. O dispositivo assume que a sua
localização é a mesma do objeto mais próximo de si. Em [2] é apresentado um sistema cuja infraes-
trutura é composta por um conjunto de emissores de campos magnéticos distribuídos pelo espaço em
localizações conhecidas. O dispositivo móvel dispõe de um mapa com as localizações de cada um
dos objetos e usa um algoritmo para determinar a sua própria localização com base neste mapa e na
identificação do objeto mais próximo de si. Cada um dos objetos emite uma assinatura que é lida pelo
dispositivo móvel através do magnetómetro de 3 eixos que lhe permite assim fazer a distinção entre
cada objeto e identificar o mais próximo. Apesar de simples, esta técnica pode ter um custo elevado
quando são usados objetos que emitem um sinal de forma ativa (desde logo porque necessitam de
acesso a uma fonte de energia para funcionarem). Outra solução de menor custo é usar como objetos
fixos marcas QRC que podem ser lidas através da câmara de um dispositivo móvel como proposto em
[3].
Na técnica de DR são utilizados os sensores instalados no próprio dispositivo (giroscópio, aceleró-
metro, bússola etc.) onde a informação da velocidade, da direção e da última posição do dispositivo é
usada para estimar a localização seguinte. A vantagem desta técnica é que não é necessária a ins-
talação de infraestruturas. No entanto é necessário um mecanismo diferente que forneça a posição
inicial do dispositivo. Além disso, o erro introduzido pelos sensores tem um efeito cumulativo; a localiza-
ção real começa a divergir com o aumento da distância. Por este motivo periodicamente é necessário
calibrar o sistema. Em [4] são apresentadas algumas técnicas para esse efeito.
As técnicas baseadas em triangulação permitem a um objeto móvel determinar a sua localização
sabendo as distâncias entre si e três ou mais pontos de referência cujas localizações são distintas e
conhecidas. É o que acontece no caso do GPS onde os satélites servem de pontos de referência.
Aproveitando o facto das redes Wi-Fi estarem disponíveis em grande parte dos edifícios, a investigação
debruçou-se sobre a possibilidade de aplicar aqui também a triangulação. Todavia, o sinal transmi-
tido pelos pontos de acesso (AP) nestes espaços sofre interferências causadas por obstáculos que
influenciam o resultado das medições [5].
Foi então que surgiu uma nova técnica baseada em assinaturas onde, em vez do cálculo da distân-
cia para cada AP, se guarda apenas a intensidade do sinal recebido de cada um. Com esta técnica é
necessário proceder a um passo extra, onde o espaço é dividido em células e é criado um mapa onde
são registadas leituras com a intensidade do sinal obtido de cada um dos APs. Depois, no processo de
localização, são usados algoritmos determinísticos para encontrar a célula cuja assinatura apresenta
maior semelhança com a da localização desconhecida. Um dos problemas desta abordagem é a incer-
teza gerada quando duas localizações distintas têm assinaturas semelhantes no mapa. Este problema
foi atenuado com a utilização de algoritmos probabilísticos que utilizam outro critério de desempate:
6
escolher a localização onde a probabilidade da assinatura se verifica ser maior.
Apesar dos algoritmos probabilísticos aumentarem a precisão do sistema, têm a desvantagem de
ser necessário proceder a várias leituras em cada célula durante a criação do mapa. Consequente-
mente, este aumento de precisão tem um custo elevado [6]. O sistema RADAR [7] foi um dos primeiros
sistemas a aplicar a técnica de assinaturas com algoritmos determinísticos. Importa salientar aqui a
morosidade do processo de criação do mapa onde é preciso percorrer o espaço ponto a ponto e re-
gistar a assinatura numa base de dados. O processo é agilizado em sistemas mais recentes onde é
possível criar o mapa percorrendo trajetos em velocidade constante como acontece em [8].
Por último temos os sistemas de localização híbridos que são os mais promissores. Como vimos, a
técnica anterior (baseada em assinaturas) é problemática quando localizações distintas têm assinaturas
semelhantes no mapa. Além disso, devido à complexidade do algoritmo, o tempo de execução pode
ser elevado, principalmente no caso dos algoritmos probabilísticos. Os sistemas híbridos combinam
uma ou mais das técnicas vistas anteriormente para aumentar a precisão do sistema. Por exemplo [9]
propõe um algoritmo que recorre a mapas de assinaturas (do campo magnético terrestre e Wi-Fi) que
combinado com a técnica de DR atingiu um erro máximo de 3.7m em 80% dos erros de localização
verificados em ambiente de testes. Os resultados anteriores são relevantes porque a precisão de cada
uma das técnicas isoladamente é muito inferior. Com o mapa de assinaturas Wi-Fi consegue-se um
erro máximo de 6.3m e com o mapa de assinaturas do campo magnético terrestre um erro máximo de
17.3 metros (ambos em 80% dos erros de localização). O mapa de assinaturas do campo magnético
terrestre é construído recorrendo ao magnetómetro para detetar a intensidade do campo magnético e
ao acelerómetro para decompor o campo magnético nas suas componentes horizontais e verticais. A
desvantagem destes sistemas híbridos é que dependem da utilização de vários sensores o que esgota
rapidamente a bateria do dispositivo.
Resta ainda apresentar o conceito de crowdsourcing que permite a colaboração dos próprios utili-
zadores durante o processo de criação dos mapas de assinaturas. O GROPING [10] e o KAILOS [11]
são dois dos sistemas que permitem passar o esforço da criação dos mapas de assinaturas para os
próprios utilizadores.
A diferença entre estes dois sistemas é que enquanto no KAILOS é sempre necessário fornecer
plantas do espaço, no GROPING o processo é totalmente automático. Neste processo, os utilizadores
são convidados a registar através dos seus smartphones trajetórias aleatórias enquanto se deslocam
pelo edifício. Durante o trajeto é pedido também aos utilizadores que marquem pontos de interesse as-
sim que passem por estes. O mapa do edifício é depois criado automaticamente através dum algoritmo
que encontra os pontos de sobreposição e faz a correspondência entre as várias trajetórias recebidas
dos utilizadores, construindo assim um modelo daquele espaço. Note-se que o crowdsourcing pode
ter um papel fundamental no desenvolvimento daquele que possa vir a ser um sistema global de lo-
calização em edifícios. Aliás, a esse respeito o KAILOS aparenta ser o sistema mais próximo de um
sistema global de posicionamento para edifícios porque oferece uma API pública onde qualquer pessoa
pode contribuir com a criação dos mapas. Além disso a API devolve as coordenadas geográficas com
a localização atual do dispositivo incluindo informação do piso onde este se encontra. A dificuldade é
7
que para já todas as aplicações se encontram em coreano o que impede o teste do sistema.
2.1.1 Conclusões
Neste momento os sistemas de localização ainda apresentam muitas desvantagens. Como vimos,
apesar da evolução dos sistemas de localização nos últimos anos, atualmente ainda não é possível
chegar a um edifício novo e usufruir de um sistema de localização de imediato. Antes disso é necessário
instalar algum tipo de infraestrutura no espaço ou usar uma infraestrutura já existente desde que se
proceda a um processo de treino do sistema. Este processo geralmente tem custos elevados. Depois
deste processo de treino, e ainda que o sistema apresente uma boa precisão num local, devido à
dinâmica destes espaços, nada garante que esta precisão se mantenha ao longo do tempo. Pelo
mesmo motivo também não se pode assumir que essa precisão seja idêntica noutros locais do mesmo
edifício.
Apesar de constituir um desafio interessante, por um lado desenvolver um sistema de localização de
raiz seria suficientemente complexo para ocupar por si toda esta dissertação. Por outro lado nenhum
dos sistemas de localização aqui analisados aparenta ser um bom candidato a incluir no nosso sistema
de encaminhamento. No geral os sistemas existentes requerem o uso de infraestruturas que podem
não estar disponíveis ou que têm um custo de instalação elevado e, mesmo as soluções que não
requerem o uso de infraestruturas, obrigam ainda assim a todo um processo de treino do sistema o que
também tem um custo significativo. Nenhuma das soluções de localização se encontra pronta a usar
assim que um utilizador entra pela primeira vez num novo espaço e isso vai contra um dos objetivos
principais da presente dissertação: generalizar o uso da tecnologia. Por tudo isto, bem como por não
haver espaço nem tempo disponível, o tema da localização foi aqui focado apenas para se perceber
as suas possibilidades, limitações e como funcionam no geral as soluções existentes atualmente. Não
vamos desenvolver mais este tema passando o foco da dissertação a ser apenas o encaminhamento.
2.2 Sistemas de encaminhamento
2.2.1 VeLoc
O VeLoc [12] é o único sistema encontrado que foi desenhado especificamente para veículos em par-
ques de estacionamento e não inclui encaminhamento de pessoas. O VeLoc permite localizar um
veículo no parque de estacionamento recorrendo ao smartphone e não é necessário que este disponha
de GPS ou Wi-Fi, mas sim de acelerómetro e giroscópio. Estes sensores são usados para determinar
a velocidade e a orientação do veículo, e ainda, a orientação do smartphone em relação ao veículo
durante a trajetória. Os sensores são ainda usados para identificar pontos de referência no espaço du-
rante a trajetória como lombas, rampas e curvas. Todos os dados inerciais anteriores juntamente com
a planta do espaço são fornecidos em tempo real a um algoritmo. O algoritmo recorre às trajetórias e
à planta do espaço para limitar a localização do veículo apenas aos caminhos da planta que possam
8
acomodar a trajetória. De seguida, os pontos de referência são usados para finalmente determinar uma
localização específica.
Nos testes os veículos foram localizados dentro dum raio de 10m 80% das vezes. Assim, este sis-
tema permite saber a localização do veículo mesmo sem o utilizador ter de especificar explicitamente o
lugar onde estacionou. Apesar disso é preciso imobilizar o veículo no momento em que se passa do ex-
terior para dentro do parque e marcar esse momento na aplicação. É ainda necessária a disponibilidade
dos sensores inerciais e o sistema não assiste o utilizador a retomar o veículo, apenas informa onde
este se encontra. Também é preciso ter em conta que a maioria das plantas não contém informação
das lombas, logo é necessário proceder a marcação manual. Finalmente, situações como pára-arranca
ou quando o utilizador mexe no dispositivo durante a trajetória podem destabilizar o sistema.
2.2.2 PINwI
O PINwI [13] apresenta um sistema de encaminhamento onde o utilizador necessita apenas de um
smartphone equipado com câmara fotográfica, acelerómetro e magnetómetro. Ao entrar no piso de um
edifício, é necessário fornecer ao sistema uma fotografia com uma planta do espaço que pode ser, por
exemplo, uma planta de emergência. Depois é necessário proceder à calibração do sistema recorrendo
a duas localizações conhecidas. Para isso, o utilizador marca no sistema a sua localização atual sobre
a fotografia e desloca-se para a outra localização conhecida onde procede da mesma maneira. A partir
daqui o sistema atualiza a marca com a localização atual sobre o mapa de forma automática recorrendo
à técnica de localização de Dead Reckoning.
Apesar de terem obtido feedback positivo nos testes de utilização, muitos equipamentos introduzi-
ram um erro considerável na localização estimada através de DR o que inviabiliza o uso da aplicação
em certos dispositivos. É importante notar que apesar da simplicidade do sistema, o utilizador tem de
encontrar toda a informação desejada através da fotografia da planta, o que é bastante difícil de encon-
trar. Outra desvantagem é que tem de ser o próprio utilizador a calcular a rota para um destino porque
o sistema não dispõe de qualquer informação topológica do espaço.
2.2.3 RoughMaps
No RoughMaps [14] é apresentada uma plataforma de suporte à localização em espaços interiores
para dispositivos móveis através de mapas simbólicos. Mapa simbólico significa que qualquer mapa
deve ser aceite desde que faça sentido para os utilizadores. Ou seja, a plataforma não impõe qualquer
restrição quanto ao mapa a ser utilizado, quer em termos de escala, no propósito ou na sua precisão.
Isto significa que até a fotografia de um rascunho em papel pode ser submetido como mapa na plata-
forma. Trata-se de uma plataforma porque corre em servidores próprios e permite que utilizadores não
treinados façam upload e administrem os seus próprios mapas.
As duas vertentes principais deste sistema são: administração e utilização. Na vertente de adminis-
tração, os servidores dispõem de uma interface web onde é possível fazer upload do mapa e definir um
sistema de localização específico como, por exemplo, códigos QR. Pode-se definir em cada ponto do
9
mapa um código QR correspondente.
Na vertente de utilização, a plataforma fornece uma API para as aplicações específicas acederem
aos dados nela guardados. Como forma de teste à plataforma, neste trabalho é também apresentada
uma aplicação Android que demonstra as capacidades da API. É possível escolher um servidor espe-
cífico, fazer uma ligação direta a este, selecionar um edifício e, dentro deste, o mapa de um dos pisos.
Depois, ao fazer a leitura dos códigos QR em cada localização, a localização é atualizada com uma
marca sobre o mapa simbólico.
Este sistema mostra-se extremamente flexível quanto ao suporte dos mapas, à semelhança do
sistema PINwI visto anteriormente. No entanto, esta flexibilidade é conseguida à custa da simplificação
do modelo de dados de tal forma que não é possível registar pontos de interesse ou efetuar o cálculo
de rotas através da plataforma.
2.2.4 Google Indoor Maps
Também a Google tem vindo a integrar desde 2011 mapas interiores na sua plataforma Google Maps.
Isto significa que nos locais onde já existem mapas definidos é possível navegar exatamente da mesma
forma como se faz no exterior. No mapa é desenhado todo o percurso para chegar ao destino e são
apresentadas instruções que incluem o número de metros a percorrer até ao destino ou até ao próximo
elevador ou escadas rolantes no caminho para o destino. A Google tem uma infraestrutura disponível
para que as pessoas procedam ao upload das plantas dos vários pisos de um edifício como imagens
digitais para a Google posteriormente validar. Após validação o edifício fica disponível no Google Maps
para qualquer utilizador. Só é possível carregar mapas de países que constem numa lista presente no
site da Google 1, a qual neste momento ainda não inclui Portugal.
2.2.5 KAILOS
KAILOS [11] apresenta-se como um sistema de localização global para espaços fechados porque inclui
o seu próprio sistema de localização baseado em mapas de assinaturas Wi-Fi e aposta em crowdsour-
cing na sua criação. É composto por três componentes: KAI-Navi, KAI-Map e KAI-Pos.
KAI-Pos é o sistema de localização do KAILOS e define uma API que permite que qualquer outra
aplicação recorra ao KAI-Pos para efeitos de localização em espaços fechados. KAI-Map é constituído
por várias aplicações que possibilitam a criação dos mapas de assinaturas em qualquer edifício através
de crowdsourcing. Finalmente o KAI-Navi é um sistema de navegação integrado: funciona dentro e fora
de edifícios. Para localização no exterior é usado o GPS enquanto que dentro de edifícios é usado o
KAI-Pos.
O KAI-Navi foi instalado no Campus KAIST em Daejeon, na Coreia do Sul com um total de 40
edifícios onde já é possível navegar com sucesso, mesmo quando se visita o Campus pela primeira
vez. É preciso notar que isto só é possível depois da contribuição de voluntários na criação do mapa de
assinaturas. É também muito prematuro atribuir ao sistema a denominação de global porque para isso
1https://support.google.com/maps/answer/1685827?hl=en
10
seria necessário cobrir grande parte dos edifícios no planeta. Finalmente também não ajuda o facto de
neste momento as ferramentas para criação dos mapas de assinaturas não terem tradução para inglês.
2.2.6 iNavigation
O iNavigation [15] é um sistema web e baseia-se no uso de fotografias do interior do edifício para
localizar e encaminhar os utilizadores. São selecionados vários pontos num piso que serão usados
como balizas. Uma baliza é normalmente uma intersecção, uma porta, uma saída ou o início/fim de um
corredor. São tiradas fotografias em cada uma das balizas em várias direções. Também são tiradas
fotografias a cada 5/10m entre cada baliza.
O método de localização é offline, ou seja, é o utilizador que define a sua localização. Existem duas
maneiras de o fazer: através de palavras chave ou através do upload de uma imagem da localização
desconhecida. Perante uma palavra chave, o sistema pesquisa fotografias com palavras chave idênticas
associadas; perante uma fotografia, através dum algoritmo de processamento de imagens, o sistema
procura as fotografias no sistema com maior semelhança à dada e o utilizador escolhe a sua localização
como uma delas. É também possível navegar entre localizações através das setas que aparecem sobre
a imagem principal (que representa a localização atual).
Para efeitos de encaminhamento é criado um grafo que mantém as ligações relativas entre cada ba-
liza segundo oito direções. É também apresentado um algoritmo que permite calcular automaticamente
a distância entre duas balizas através da análise das imagens. Com base no grafo é possível calcular
o melhor percurso entre origem e destino. A rota é devolvida como uma sequência de imagens das
balizas entre origem e destino. A ideia é o utilizador ir seguindo a direção certa através das fotografias
de cada uma das balizas apresentadas. Também é apresentado na interface um mapa 2D com o piso
completo e uma marca vermelha na localização da baliza atual.
Apesar de apresentar um conceito inovador, dada a complexidade dos algoritmos de processamento
de imagens este sistema é executado em servidores remotos e é acedido através de uma interface web.
Quanto ao processo de criação do mapa, este exige tirar muitas fotografias e em várias direções o que
o torna num processo moroso.
2.2.7 OntoNav
O OntoNav [16] é um sistema de encaminhamento híbrido porque utiliza não só um modelo geomé-
trico, mas também um modelo semântico para seleção e descrição do percurso ao utilizador. O modelo
semântico inclui a definição de objetos como o próprio utilizador, onde são definidas as suas limita-
ções físicas e as suas preferências. Inclui também a definição de objetos estruturais do edifício como
corredores, portas, saídas, elevadores, etc.
A grande vantagem deste modelo é que permite calcular um percurso cuja descrição é dada com
o cuidado de respeitar limitações físicas dos utilizadores bem como as suas preferências de enca-
minhamento (há pessoas que não gostam de andar de elevador). Isto significa que o modelo tem
expressividade suficiente para, por exemplo: evitar uma rota se esta incluir escadas e o utilizador tiver
11
dificuldades de mobilidade; incluir pontos de referência com descrições áudio se o utilizador for invisual;
usar imagens para descrever uma rota se o utilizador for uma criança.
A arquitetura do sistema é composta por dois componentes principais. O primeiro é o serviço de
computação geométrica que é responsável pelo cálculo de todos os percursos possíveis desde a lo-
calização do utilizador até um ponto de interesse recorrendo a uma base de dados com as plantas do
edifício. O segundo é o serviço de seleção semântica que filtra os percursos devolvidos pelo serviço
anterior com base nas características e preferências de encaminhamento do utilizador, selecionando
apenas o mais compatível. Este é um processo com um elevado custo computacional.
A desvantagem desta abordagem é que o utilizador necessita de proceder a um longo processo
de configuração quando executa a aplicação pela primeira vez. Também a administração do modelo
semântico requer mais esforço em termos de modelação, validação e manutenção dos dados o que
consequentemente dificulta o seu uso generalizado.
2.2.8 Soluções para centros comerciais
Fastmall2 é um sistema de encaminhamento desenvolvido pela MindSmack para dispositivos Android
e Apple. Funciona em centros comerciais e neste momento encontra-se em expansão para suportar
também hospitais, aeroportos, centros de convenções e outros. Ao abrir a aplicação temos um mapa do
mundo com marcações em todos os edifícios onde o sistema funciona. Escolhido um edifício é possível
depois navegar no mapa 2D alternando entre os vários pisos. Também se pode aceder ao diretório
de lojas e pesquisar por nome e categoria. Qualquer loja pode ser adicionada aos favoritos e como
se trata de um sistema comercial são apresentadas promoções e ofertas disponíveis no momento.
A localização atual é dada pelo próprio utilizador que escolhe junto a que loja se encontra. Depois
escolhe-se outra loja como destino e o sistema devolve uma rota que pode incluir escadas ou apenas
elevador conforme escolhido na interface. O percurso é devolvido como uma sequência de instruções
textuais com atualização no mapa 2D da localização. As instruções textuais incluem uma direção a
seguir até ao próximo ponto de referência. Os pontos de referência podem ser escadas, casas de
banho, outras lojas ou a loja de destino. Existe ainda uma opção que permite a gravação áudio do
lugar de estacionamento e que serve depois como auxiliar de memória no momento em que o utilizador
pretende voltar ao seu veículo.
Também as aplicações para smartphones dos centros comerciais Colombo3 em Portugal e West-
field4 em Londres já incluem funções de encaminhamento. Estas aplicações permitem navegar num
mapa 2D nos vários pisos disponíveis e encontrar as várias lojas e promoções disponíveis. Quanto
ao percurso, em ambos os casos este é devolvido como desenho no mapa 2D com destaque nas
mudanças de piso mas sem qualquer instrução textual a acompanhar.
2http://www.fastmall.com/3http://www.colombo.pt4https://uk.westfield.com/london
12
2.2.9 Conclusões
Da análise dos vários sistemas de encaminhamento vimos que um dos desafios é a escolha da informa-
ção a incluir nas instruções para guiar o utilizador no seu percurso. Em primeiro lugar estas instruções
oferecem mais valor quando o utilizador se encontra num ponto onde tem de tomar uma decisão quanto
à próxima direção a seguir e, após uma mudança de direção, para confirmar que o utilizador se encontra
no caminho certo. Em segundo lugar estas instruções são entregues de várias formas: textualmente,
através de imagens e recorrendo a áudio. Destas, as mais usadas são as instruções textuais apoiadas
normalmente por mapas 2D. Quanto à informação presente nas instruções, é dada preferência à inclu-
são, por esta ordem: de pontos de referência, de ruas e da distância a percorrer. Outro aspeto muito
importante é que as rotas devem ser calculadas em função das possíveis limitações físicas do utilizador
como acontece no OntoNav e no Fastmall.
Vimos também que nenhum dos sistemas permite representar o interior de um edifício com o ní-
vel de detalhe adequado. Em particular, como acontece no Google Indoor Maps e nos sistemas para
centros comerciais, a inexistência de um mecanismo livre que permita a qualquer pessoa criar a repre-
sentação de um espaço fechado impede uma maior divulgação dos mesmos. Para facilitar a divulgação
de um sistema, por um lado a representação do espaço não deve ser demasiado complexa como acon-
tece no KAILOS, OntoNav e Inavigation. Por outro lado, também não deve ser demasiado simples como
no PINwI e RoughMaps sob pena de limitar as funcionalidades do sistema. Em todos estes sistemas
falta também uma funcionalidade que permita ao utilizador regressar ao seu veículo. Apenas o VeLoc e
o Fastmall permitem ao utilizador consultar a localização do seu veículo. Apesar disso, nenhum destes
sistemas encaminha o utilizador para o parque onde o veículo se encontra estacionado. No caso do
VeLoc nem tão pouco é contemplado o encaminhamento de pessoas.
Em suma, as maiores limitações dos sistemas de encaminhamento aqui estudados são:
� Falta de mecanismos para que sejam adicionados novos mapas de forma simples
� Dependência de sistemas de localização o que impõe mais restrições aos dispositivos móveis que
correm as aplicações e aumenta os custos (devido à necessidade de infraestruturas de suporte
aos sistemas de localização)
� As rotas calculadas não têm em conta as limitações físicas ou outras do utilizador
� Não encaminham o utilizador de volta ao seu veículo
2.3 OpenStreetMap
Para obter mapas das estradas em qualquer parte do globo temos os serviços de mapas como o Google
Maps. No entanto, serviços como o Google Maps impõem várias restrições ao nível de utilização
do serviço. Os dados com a informação geográfica global nem sequer são acessíveis publicamente
porque fazem parte da propriedade comercial de outras empresas. Isto impede a criação livre de
outros serviços sobre este como, por exemplo, serviços de pesquisa de trajetos.
13
O OpenStreetMap5 (OSM) é um serviço alternativo que ultrapassa estas limitações oferecendo um
sistema livre e colaborativo. No OSM qualquer pessoa pode contribuir com dados geográficos e toda a
informação e mapas dai derivados são de utilização livre. Em Janeiro de 2016 este serviço já contava
com mais de 2.400.000 utilizadores registados6. Para suportar o modelo colaborativo, o OSM disponi-
biliza toda uma infraestrutura composta por ferramentas para aquisição de dados móveis, aplicações
de edição dos dados geográficos, serviços de armazenamento e um modelo de dados desenvolvido à
medida.
O modelo de dados do OSM é muito simples e assenta em apenas três tipos de objetos primitivos:
nós, caminhos e relações7. Qualquer dos objetos pode incluir um conjunto de tags compostas por um
par chave/valor que descrevem características do objeto. Os exemplos que veremos estão representa-
dos em XML que é um dos formatos disponíveis para visualizar a informação geográfica.
Um nó representa um ponto único na superfície terrestre e é representado pelas suas coordenadas
de latitude e longitude. Um nó é normalmente usado em conjunto com outros nós para representar
objetos em forma de linha como por exemplo estradas. Também é usado para representar um elemento
único como um ponto de interesse. A Figura 2.1 mostra um exemplo de um ponto de interesse, neste
caso um monumento.
<node id="1119839344" lat="38.7253190" lon="-9.1500036">
<tag k="historic" v="memorial"/>
<tag k="name" v="Sebastião José de Carvalho e Melo, Marquês de Pombal"/>
<tag k="wikipedia" v="pt:Sebastião José de Carvalho e Melo, Marquês de Pombal"/>
</node>
Figura 2.1: Exemplo XML de um objeto do tipo nó na base de dados do OpenStreetMap
Um caminho é uma coleção de nós ligados entre si em forma de linha. Permite representar vias de
trânsito, rios, linhas de comboio, etc. Caso a linha seja fechada então representa um polígono e neste
caso permite representar áreas como lagos, reservas naturais, edifícios, etc.
Finalmente as relações são um tipo de dados abstrato que permite definir ligações lógicas entre
outros objetos, incluindo outras relações. Como exemplos mais comuns temos restrições de circulação
e definição de percursos. Por exemplo, uma relação pode definir um percurso de autocarro composto
por vários objetos do tipo caminho. Outro exemplo: numa restrição de obrigatório virar à direita, é
necessário indicar um caminho de origem, um caminho de destino e ainda o nó onde se verifica a
restrição. Quanto às tags, apesar de não ser imposta qualquer restrição no seu uso existem listas com
chaves e valores recomendados8.
5http://www.openstreetmap.org/6http://wiki.openstreetmap.org/wiki/Stats7http://wiki.openstreetmap.org/wiki/Elements8http://wiki.openstreetmap.org/wiki/Map_Features
14
<way id="146666964">
<nd ref="1106337270"/>
<nd ref="580276697"/>
<nd ref="1106602967"/>
<nd ref="1135819007"/>
<nd ref="1135819062"/>
<nd ref="1135819018"/>
<tag k="destination" v="Avenida da Liberdade;Rua Joaquim António de Aguiar"/>
<tag k="foot" v="no"/>
<tag k="highway" v="primary"/>
<tag k="lanes" v="2"/>
<tag k="name" v="Avenida Fontes Pereira de Melo"/>
<tag k="oneway" v="yes"/>
</way>
Figura 2.2: Exemplo XML de um objeto do tipo caminho na base de dados do OpenStreetMap
2.4 Algoritmos de encaminhamento
Considerando uma rede de nós ligados entre si, o algoritmo de Dijkstra permite calcular o caminho de
menor custo desde um nó (a origem, que denominaremos por A) até cada um dos restantes nós da
rede. Vamos definir as seguintes variáveis deste algoritmo:
� c(i; j), como o custo da ligação entre dois nós i e j (com c(i; j) = 1 se não existir um caminho
direto entre i e j)
� D(v), como o custo do melhor caminho (caminho de menor custo) desde o nó de origem até v
� p(v), como o nó anterior a v no caminho de menor custo desde o nó de origem até v
� N , como o conjunto de todos os nós cujo caminho de menor custo desde a origem já está calcu-
lado definitivamente.
Em termos gerais, o algoritmo de Dijkstra na figura 2.3 atualiza os valores de D(v) e p(v) iterativa-
mente até estes se tornarem definitivos para todos os nós da rede. Quando estes valores se tornam
definitivos para um dado nó v, é possível saber qual o custo total do melhor caminho desde A, bem
como o nó que o antecede nesse caminho. O custo do caminho desde a origem até um dado nó fica
definitivamente calculado quando o nó é adicionado ao conjunto N . Uma prova deste facto é feita de
modo informal em [17]. Como a cada ciclo do algoritmo é adicionado um novo nó ao conjunto N , a
cada ciclo é encontrado um novo caminho de menor custo desde A até esse nó. Isto significa que caso
se pretenda procurar o melhor caminho para um nó específico, o algoritmo pode terminar no instante
em que esse nó é adicionado ao conjunto N , senão serão calculados os melhores caminhos desde A
até cada um dos restantes nós da rede.
Quando um nó é adicionado ao conjunto N , então já foram adicionados nas iterações anteriores
todos os nós com custo total inferior. Como consequência, o espaço de procura do algoritmo de Dijkstra
expande-se em todas as direções que rodeiam o nó de origem A.
15
1: for all nodes v do2: if v adjacent to A then3: D(v) = c(A; v)4: else5: D(v) =16: end if7: end for8: repeat9: find w not in N such that D(w) is a minimum
10: add w to N
11: for all v 2 neighbours(w) do12: if D(w) + c(w; v) < D(v) then13: D(v) = D(w) + c(w; v)14: p(v) = w
15: end if16: end for17: until all nodes in N
Figura 2.3: Algoritmo de Dijkstra adaptado de [18]
Este algoritmo pode ser alterado de forma a expandir mais diretamente em direção ao destino e
assim reduzir substancialmente o espaço de procura. Para isso é necessário recorrer a uma função
heurística capaz de estimar o custo do caminho entre cada nó v e o destino. O único requisito para esta
função h(v) é que o valor estimado nunca pode ser superior ao custo real do melhor caminho. Para o
caso de uma rede de estradas, um exemplo de uma heurística válida é a distância em linha reta que
separa dois nós.
Podemos agora ver o algoritmo A* como uma adaptação do Dijkstra para usar uma função heurística.
A diferença é apenas o critério de seleção do próximo nó a ser expandido. Em vez de selecionar o nó
com menor custo desde a origem, no A* seleciona-se o nó com menor estimativa do custo do melhor
caminho para o destino. Ou seja, no algoritmo da figura 2.3 (linha 9), o novo critério passa a ser o
valor mínimo de f(v), com f(v) = D(v) + h(v). Repare-se que neste caso, no momento em que o
nó de destino d é adicionado ao conjunto N , o valor da heurística h(v) é zero, ou seja, ficamos com
f(d) = D(d). Em f é assim guardado o custo do melhor caminho para o destino. Como o custo real de
um caminho não pode ser inferior ao valor estimado, é desnecessário expandir mais nós depois do nó d
ser adicionado ao conjunto N . Pode-se concluir que quanto maior for a precisão da heurística utilizada,
menos nós serão expandidos e mais eficiente será o algoritmo A* em relação ao algoritmo de Dijkstra.
Quando os algoritmos terminam, para além do custo total do melhor caminho para o destino, tam-
bém se pode obter o caminho exato. Para isso, começa-se por obter o nó anterior ao nó de destino
d, guardado em p(d), e repete-se o processo até ao nó de origem. Em termos de eficiência temos o
algoritmo de Dijkstra com tempo de execução O(jV jlogjV j + jEj), sendo jV j o número de nós e jEj o
número de ligações na rede. Como vimos, o A* será tanto melhor quanto a heurística utilizada, sendo
que no pior caso é igual ao Dijkstra.
16
Capítulo 3
Descrição da solução
Depois da apresentação do problema e da análise de várias soluções existentes, vamos agora propor a
nossa solução para o problema. Vamos começar por listar os vários requisitos da aplicação numa ten-
tativa de oferecer não só as melhores funcionalidades das soluções existentes, mas também algumas
funcionalidades que as soluções atuais não oferecem e que consideramos a sua existência uma mais
valia para o utilizador. Será também incluído neste capítulo o funcionamento dos algoritmos propostos
na resolução do problema.
3.1 Requisitos do sistema de encaminhamento
Da análise do trabalho relacionado identificaram-se várias necessidades que o sistema de encaminha-
mento aqui proposto deve colmatar para ser útil no interior de edifícios. Os requisitos que se seguem
são o resultado dessa análise:
3.1.1 Requisitos não funcionais
1. Oferecer uma solução aberta;
2. Permitir criar mapas de forma simples;
3. Minimizar os requisitos de hardware;
4. Devolver resultados em tempo razoável;
5. Ter em conta possíveis dificuldades de mobilidade dos utilizadores;
3.1.2 Requisitos funcionais
1. Suportar vários mapas na mesma aplicação;
2. Permitir que seja obtido facilmente o mapa de um novo espaço;
3. Permitir listar os pontos de interesse disponíveis num espaço;
4. Permitir organizar pontos de interesse em categorias;
5. Encaminhar o utilizador para os pontos de interesse;
17
6. Ajudar o utilizador a estacionar no melhor sítio possível;
7. Ajudar o utilizador a voltar ao seu veículo;
3.2 Componentes do sistema
Figura 3.1: Componentes do sistema e como são usados
O componente principal é o dispositivo móvel que executa o sistema de encaminhamento que será
usado pelo utilizador. A melhor forma encontrada para cumprir os requisitos funcionais 1 e 2 é introduzir
mais dois componentes para além do dispositivo móvel: o desktop e o servidor de mapas. O desktop
representa a máquina onde o administrador de um espaço vai criar os mapas. No contexto deste
trabalho interessa apenas o mecanismo através do qual um administrador pode criar esses mapas
cumprindo-se o requisito funcional 1. Os mapas serão adicionados ao servidor de mapas também pelo
administrador do espaço para serem depois descarregados pelo dispositivo móvel. O servidor de mapas
pode ser um simples servidor de ficheiros. Esta é a melhor forma de fazer chegar os mapas ao maior
número possível de dispositivos móveis cumprindo-se assim o requisito funcional 2. Interessa por isso
criar também os mecanismos no dispositivo móvel para que seja possível obter mapas remotamente.
De um modo geral a garantia dos requisitos funcionais 1 e 2 é conseguida pela divisão em compo-
nentes aqui proposta. Os restantes requisitos funcionais serão cumpridos através da implementação
apresentada no capítulo 4. Quanto aos requisitos não funcionais:
1. A nossa solução será aberta;
2. Na secção 3.4 vamos apresentar duas formas de construir um mapa;
3. Vamos minimizar os requisitos de hardware não dependendo de sistemas de localização nem de
bibliotecas externas e desenvolvendo algoritmos eficientes;
4. Vamos testar a nossa aplicação apresentando testes de desempenho;
5. Vamos ter em conta possíveis dificuldades de mobilidade dos utilizadores recorrendo a um meca-
nismo de restrições extremamente flexível;
18
3.3 Visão geral da solução
A solução aqui proposta pretende resolver o problema do encaminhamento em edifícios em 2 passos. O
primeiro passo é encontrar uma solução que permita representar o edifício num modelo computacional.
A solução para este passo é apresentada na secção 3.4. O segundo passo consiste em analisar o
mapa XML e oferecer as funcionalidades de encaminhamento ao utilizador. Para isso podemos ver
na figura 3.2 que a solução foi decomposta em três partes no dispositivo móvel. A primeira parte é
criar mais uma representação do espaço, desta vez compatível com a procura de percursos. Essa
representação será o grafo proposto na secção 3.5. A segunda parte da solução é, a partir desse grafo
calcular o percurso que o utilizador deve seguir. O módulo apresentado na secção 3.6 irá oferecer essa
solução. A última parte é gerar instruções para apresentar ao utilizador, isto é, comunicar o percurso
ao utilizador numa linguagem amigável. A solução será recorrer a algoritmos para dividir um percurso
em segmentos, detetar mudanças de direção e identificar pontos de referência que serão apresentados
na secção 3.7.
Figura 3.2: Visão geral da solução
3.4 Construção de um mapa
Um mapa dum edifício será sempre representado num único ficheiro XML. A escolha deste formato tem
várias vantagens. Primeiro porque é um formato normalmente usado para armazenamento e transporte
de dados que é o que se pretende. Depois porque pode ser lido facilmente por pessoas graças à
sua estrutura simples e flexível. Esta é composta por um único elemento raiz e dentro deste podem
existir outros elementos desde que corretamente aninhados, ou seja, o próximo elemento a ser fechado
tem de ser o último aberto. Um exemplo é <map></map>, onde <map> abre o elemento e de seguida
</map> fecha-o. Não há restrições quanto ao nome do elemento desde que sejam usados carateres
Unicode. Adicionalmente podem ser incluídos atributos no elemento como em <map name="casa das
artes"></map>, onde “name” é nome do atributo e “casa das artes” o seu valor.
Como o mapa de um espaço se trata de um simples ficheiro de texto, para o construir basta um
editor de texto e as plantas dos vários pisos do edifício. Não há nenhum requisito especial para estas
19
plantas; podem até ser rascunhos em papel feitos à mão. O objetivo é que seja possível identificar
todos os objetos presentes (pontos de interesse, elevadores, etc.) e as zonas onde as pessoas podem
circular.
Cada mapa representa um edifício. No contexto deste trabalho vamos construir mapas para edi-
fícios. Um edifício é composto por um ou mais pisos. Para o deslocamento entre pisos são usadas
escadas, escadas rolantes e elevadores. Destes pisos alguns podem ser parques de estacionamento.
As pessoas estacionam os seus veículos nos parques e acedem aos pisos onde se encontram os pon-
tos de interesse para finalmente voltarem ao seu veículo que se encontra num lugar de estacionamento.
Estes são os principais conceitos da aplicação sendo que outros conceitos são adicionados para orga-
nização lógica da aplicação como as restrições, as categorias e a escala. Note-se que estes conceitos
foram escolhidos para manter a melhor relação qualidade/esforço, ou seja, para que sejam suficien-
temente expressivos para representar um edifício e as suas particularidades, tornando o sistema de
encaminhamento útil e, ao mesmo tempo simples, para minimizar o esforço de construção do mapa.
Antes de começarmos a definir a estrutura exata de um mapa em XML convém fazer a seguinte
observação. Apesar do formato XML ser de fácil compreensão, não nos podemos esquecer que para o
propósito que este é usado (definir a planta de um espaço), a perceção geométrica que existe na planta
2D perde-se depois no ficheiro XML. Isto dificulta tanto a criação como a modificação de um mapa em
XML. Por este motivo, depois de detalharmos a estrutura de um mapa em XML vamos mostrar como é
que o JOSM pode ser usado para gerar o XML do mapa evitando-se a manipulação direta do XML.
3.4.1 Mapa em XML
O primeiro elemento (a raiz) de um mapa é sempre o elemento map. O elemento map tem como filhos
os elementos nó (node), caminho (way) e relação (relation), em qualquer número de elementos mas
obrigatoriamente por esta ordem. Os três elementos anteriores formam os tipos de dados do OSM (ver
Capítulo 2.3) e cada elemento tem um identificador único. Um caminho contém sempre uma sequência
ordenada de nós enquanto uma relação contém apenas nós, apenas caminhos ou uma combinação de
nós e caminhos. Todos os conceitos da aplicação são definidos através destes tipos de dados primários
e de tags filhas (do tipo <tag k="chave" v="valor">).
Cada nó tem associada uma coordenada geográfica composta por um par de valores inteiros não
negativos x (abcissa) e y (ordenada) sendo que a origem (x = 0, y = 0) corresponde ao canto superior
esquerdo da planta. Assim, cada nó é definido explicitamente apenas num plano 2D (tem apenas duas
coordenadas). A sua posição no plano 3D é inferida seguindo as referências para os restantes objetos,
ou seja, obtendo os caminhos a que este nó pertence e, finalmente, a que piso pertence a relação
que inclui esses caminhos. Todos os objetos que pertencem a um piso são representados através de
tags filhas do nó que define a sua posição, garantindo-se assim que todos os objetos têm uma posição
geográfica atribuída. O nó é um elemento primário importante porque vai servir de base para a definição
dos conceitos que se seguem:
� � �
20
Conceito: Edifício
Elemento: map
Atributos: name (texto)
Notas: O atributo name será o nome sugerido ao utilizador quando este descarregar o mapa para o
seu dispositivo. Se o atributo name não estiver definido, será sempre sugerido NovoMapa como nome.
O utilizador pode sempre modificar para um nome mais descritivo.
Exemplo:
<map name="hotel">
<!-- Sequência de nós -->
<!-- Sequência de caminhos -->
<!-- Sequência de relações -->
</map>
� � �
Conceito: Caminho
Elemento: way
Atributos: id (número inteiro único)
Tags: <tag k=“oneway” v=“yes”/>
Notas: Um caminho é composto por uma sequência de nós. A tag oneway é opcional e a ser usada só
permite movimento num sentido. O sentido é dado pela ordem com que os nós aparecem no caminho,
isto é, do primeiro para o último. Todos os nós são declarados no elemento map antes dos caminhos.
Nos caminhos os nós são referenciados através do seu identificador recorrendo ao elemento <nd
ref="[id do nó]"/>. É importante que a definição de caminhos seja corretamente realizada. Qualquer
erro pode comprometer a capacidade da aplicação em calcular percursos. Por exemplo, é sempre
possível encontrar um percurso entre dois nós que pertencem ao mesmo caminho (possíveis restrições
à parte). Já no caso de dois nós que pertencem a caminhos distintos, só será possível encontrar
um percurso entre estes se ambos os caminhos tiverem um nó em comum (com o mesmo id) ou se
estiverem indiretamente ligados através de outros caminhos.
Exemplo:
<way id="2810">
<nd ref="114"/>
<nd ref="115"/>
<tag k="oneway" v="yes"/>
</way>
� � �
Conceito: Ponto de interesse
Elemento: node
21
Atributos: id (número inteiro único) | x, y (número inteiro não negativo)
Tags: <tag k=“pi” v=“yes”/> <tag k=“name” v=“[nome]”/>
Notas: Um ponto de interesse tem sempre uma posição fixa no piso dada pelo nó no qual este é
definido. [nome] é o nome atribuído a este ponto de interesse. O nome escolhido será apresentado
na aplicação tal como está definido. Se existe mais do que um ponto de interesse relacionado, isto
é, que sirva o utilizador da mesma forma em vários locais como acontece com as casas de banho e
multibanco, o nome dos vários pontos de interesse deve ser exatamente igual; o sistema vai assumir
que se trata do mesmo ponto de interesse.
Exemplo:
<node id="3112" x="86" y="94">
<tag k="pi" v="yes"/>
<tag k="name" v="Entrada Principal"/>
</node>
� � �
Conceito: Acesso vertical
Elemento: node
Atributos: id (número inteiro único) | x, y (número inteiro não negativo)
Tags: <tag k=“vtype” v=“stairs|lift|escalator”/> <tag k=“vgroup” v=“[grupo]”/>
Tag de restrição: <tag k=“forbid” v=“up|down”/>
Notas: Um acesso vertical tem sempre uma posição fixa no piso dada pelo nó no qual este é definido.
vtype é o tipo de acesso e pode ter os valores lift (elevador), stairs (escadas) e escalator (escadas
rolantes). [grupo] é o nome do grupo a que pertence o meio de acesso. Este nome tem de ser igual
ao dos meios de acesso nos outros pisos aos quais o utilizador chega se seguir por este acesso. A tag
de restrição permite definir, por exemplo, escadas rolantes que só permitem ir para cima (proibindo a
direção contrária). Para proibir para cima usa-se o valor up e para baixo o valor down. Ao definir um
acesso vertical é automaticamente adicionada uma restrição ao sistema que vai permitir ao utilizador
evitar este meio de acesso se assim desejar.
Exemplo:
<node id="3112" x="86" y="94">
<tag k="vtype" v="lift"/>
<tag k="vgroup" v="elevador norte"/>
</node>
� � �
Conceito: Lugar de estacionamento
Elemento: node
Atributos: id (número inteiro único) | x, y (número inteiro não negativo)
22
Tags: <tag k=“park” v=“yes”/> <tag k=“zone” v=“[zona]”/> <tag k=“code” v=“[código]”/>
Notas: Um lugar de estacionamento tem sempre uma posição fixa no piso dada pelo nó no qual este
é definido. [zona] e [código] são o nome da zona e código do lugar de estacionamento respetivamente.
No mesmo nó também pode ser definido um meio de acesso vertical.
Exemplo:
<node id="3112" x="86" y="94">
<tag k="park" v="yes"/>
<tag k="zone" v="vermelha"/>
<tag k="code" v="3Z"/>
</node>
� � �
Conceito: Piso
Elemento: relation
Atributos: id (inteiro não negativo único)
Tags: <tag k=“type” v=“level”/> <tag k=“level” v=“[piso]”/>
Notas: [piso] é um valor inteiro com o piso correspondente. Além das tags são incluídos todos os
caminhos que pertencem ao piso. No exemplo encontra-se a definição do segundo piso de um edifício.
Este piso só tem definidos dois caminhos.
Exemplo:
<relation id="2810">
<member type="way" ref="2970"/>
<member type="way" ref="2945"/>
<tag k="type" v="level"/>
<tag k="level" v="2"/>
</relation>
� � �
Conceito: Piso de estacionamento
Notas: O piso de estacionamento é em tudo igual ao piso normal com a tag adicional: <tag k=“park”
v=“yes”/>. Quanto aos outros elementos da relação, apesar de se poderem definir caminhos neste tipo
de piso, o mais usual é termos apenas nós. Isto porque o essencial para a aplicação dos parques de
estacionamento são os seus lugares de estacionamento que estão normalmente junto dos meios de
acesso verticais. Os meios de acesso verticais podem e devem ser definidos no mesmo nó dos lugares
de estacionamento. Por sua vez os nós com acessos verticais já definem as suas ligações aos outros
pisos sem ser necessário definir caminhos explicitamente.
Exemplo:
23
<relation id="2810">
<member type="node" ref="1356"/>
<member type="node" ref="1707"/>
<tag k="type" v="level"/>
<tag k="level" v="-1"/>
<tag k="park" v="yes"/>
</relation>
� � �
Conceito: Piso com escala
Tag de escala: <tag k=“distance” v=“[distância em metros]”/>
Notas: Opcionalmente pode ser definido um fator escala a qualquer tipo de piso (normal ou de estacio-
namento). Para usar a escala marcam-se duas localizações no piso e atribui-se uma distância real em
metros entre elas. As duas localizações são definidas através de dois membros da relação do tipo nó
com o atributo role="distance-mark". A distância entre as duas marcas é definida em metros pela tag
de escala. No exemplo encontra-se um piso cuja distância real entre as localizações do nó 1 e do nó 2
é de 30 metros.
Exemplo:
<relation id="2810">
<member type="node" ref="1" role="distance-mark"/>
<member type="node" ref="2" role="distance-mark"/>
<tag k="type" v="level"/>
<tag k="level" v="2"/>
<tag k="distance" v="30"/>
</relation>
� � �
Conceito: Categoria
Elemento: node
Atributos: id (número inteiro único) | x, y (número inteiro não negativo)
Tags: <tag k=“categories” v=“[categorias]”/>
Notas: [categorias] tem o nome de uma ou mais categorias separadas por vírgulas. O ponto de in-
teresse definido num nó com categorias passará a pertencer a essas categorias. É possível assim
agrupar os pontos de interesse por categorias. O ponto de interesse do exemplo pertence às catego-
rias entradas e saídas.
Exemplo:
<node id="3112" x="86" y="94">
<tag k="pi" v="yes"/>
24
<tag k="name" v="Entrada Principal"/>
<tag k="categories" v="entradas,saídas"/>
</node>
� � �
Conceito: Restrição
Elemento: node
Atributos: id (número inteiro único) | x, y (número inteiro não negativo)
Tags: <tag k=“restriction” v=“[nome]”/>
Notas: [nome] tem o nome atribuído à restrição. Este nome será apresentado ao utilizador num painel
de restrições. O utilizador pode escolher evitar ou não a restrição. Caso escolha evitar o sistema vai
procurar sempre percursos que não passem por este nó.
Exemplo:
<node id="3112" x="86" y="94">
<tag k="restriction" v="obras de remodelação"/>
</node>
3.4.2 Gerar mapa XML com o JOSM
Para o dispositivo móvel um mapa é sempre um ficheiro XML. Já vimos na secção anterior todos os
elementos XML necessários para definir os conceitos suportados pelo sistema. O JOSM oferece a
possibilidade de criar o mapa XML através duma interface gráfica em 5 passos:
1. Obter as plantas dos vários pisos do edifício (podem ser rascunhos em papel digitalizados);
2. Guardar as plantas no diretório /josm/plantas;
3. Adicionar uma nova camada no JOSM para cada piso (com o mesmo nome da planta correspon-
dente);
4. Definir os conceitos (pontos de interesse, elevadores, etc.) presentes nos vários pisos através da
caixa de ferramentas do JOSM e guardar cada um dos ficheiros;
5. Executar a ferramenta josm-to-xml.sh numa linha de comandos passando a localização dos vários
ficheiros anteriores como argumentos;
Na figura 3.3 podemos ver o exemplo de uma utilização do JOSM onde já se encontra a planta
do piso como fundo (definindo a área de desenho válida). Na caixa de ferramentas vertical do lado
esquerdo temos as ferramentas que permitem colocar nós na área de desenho e definir ligações entre
estes (caminhos). O valor exato das coordenadas de cada nó não tem importância desde que se defina
um fator de escala para cada piso. Na barra vertical do lado direito podemos ver uma secção para as
“Tags”. Ao carregar em “Add” abre uma caixa de edição que permite definir uma chave e um valor para
a tag. No exemplo podemos ver que já foram adicionadas as tags pi=yes e name=Livraria, definindo-se
assim um ponto de interesse. Para definir os restantes conceitos da aplicação, procede-se de forma
25
Figura 3.3: Captura de ecrã numa utilização do JOSM
idêntica usando as tags apropriadas. No final, e estando todos os conceitos definidos, procede-se à
criação da relação que define o piso através da mesma barra vertical na secção “Relations”. As caixas
de edição do JOSM permitem adicionar todos os conceitos à relação do piso. O processo de criação
de um mapa é assim mais confortável através do JOSM do que diretamente através do XML.
3.5 Algoritmo para criar grafo
O grafo criado pelo algoritmo tem dar suporte ao cálculo de percursos e à geração de instruções pelos
restantes módulos. Como já vimos anteriormente, para representar as vias onde os utilizadores podem
circular no edifício é usado um modelo de dados composto por nós e caminhos. Na presença duma
estrutura de dados deste género o mais natural seria criar um grafo cujos nós e ligações seriam os
mesmos definidos na construção do mapa do edifício em que as ligações teriam um custo associado
igual à distância entre os nós que ligam.
No entanto, e dado que o criador do mapa pode definir estes caminhos com o número de nós e de
ligações que desejar, um percurso gerado num grafo deste género pode conter várias mudanças de
direção, muitas delas desnecessárias (provocadas por um possível excesso de ligações). Este facto
ia causar dificuldades ao utilizador visto que cada mudança de direção adicional representa esforço
26
acrescido por parte do utilizador em seguir as indicações. De modo a evitar esta situação é importante
oferecer ao módulo de procura de percursos a possibilidade de penalizar as mudanças de direção.
Deste modo a nossa solução usa um grafo denominado grafo linha (proposto em [19]) capaz de lidar
com custos de mudanças de direção. Neste grafo cada nó representa uma ligação da rede original e
cada ligação representa uma transição entre duas ligações consecutivas da rede original.
Na Figura 3.4 encontra-se um exemplo simples de um grafo linha com duas ligações. A preto temos
a rede original e a vermelho o seu grafo linha. Como se pode verificar, na rede original as ligações
guardam o custo de atravessar cada um dos segmentos a e b restando apenas a possibilidade de
adicionar o custo da mudança de direção ao nó 2. Mas adicionar o custo da mudança de direção ao
nó 2 não é uma solução porque se este nó tiver outra ligação, como a marcada a tracejado na figura
onde não se verifica nenhuma mudança de direção, fica impossível diferenciar ambos os casos. Já no
grafo linha podemos verificar que uma ligação representa o movimento entre dois segmentos da rede
original e portanto o custo da mudança de direção pode ser associado a esta ligação. Com esta solução
o algoritmo original de Dijkstra pode ser aplicado neste tipo grafo sem qualquer alteração passando a
suportar o custo de mudanças de direção.
Figura 3.4: Exemplo de grafo com o respetivo grafo linha a vermelho
3.6 Módulo para calcular percursos
Calcular um percurso consiste em obter um caminho válido entre a origem e o destino no grafo gerado
pelo algoritmo anterior. Entre o algoritmo de Dijkstra e o A* (vistos anteriormente na Secção 2.4)
escolhemos usar o algoritmo de Dijkstra visto que é o único que pode ser usado quando a localização
exata do destino não é conhecida à partida. Esta situação verifica-se, por exemplo, quando o destino
é uma casa de banho (não interessa qual) ou se pretende calcular o parque de estacionamento mais
próximo de um dado ponto de interesse (novamente, não é importante qual o parque escolhido). Além
disso, o algoritmo A* requer o uso de uma função heurística que não seria fácil desenvolver nos casos
em que a origem e o destino se encontram em pisos distintos.
Escolhido o algoritmo, falta ainda analisar de que forma é que os custos serão atribuídos a cada
ligação do grafo. Importa notar que neste algoritmo não é suficiente definir os custos de cada ligação
27
como a distância física que separa os dois nós e aplicar o Dijkstra. Como já foi explicado anteriormente,
convém reduzir tanto quanto possível, o número de mudanças de direção. Solucionar este problema
no grafo linha é simples. Sempre que uma ligação represente uma mudança de direção, o seu custo
será dado pelo somatório da distância a percorrer com um valor que penaliza o custo total do troço
comparativamente a um troço com o mesmo comprimento mas em linha reta.
Mas há outro aspeto importante a ter em conta: a escolha do meio de acesso a usar entre pisos. A
ligação entre pisos geralmente é feita através de um meio de acesso vertical como escadas, escadas
rolantes e elevadores. Apesar de terem a mesma função, é óbvio que o custo de cada um não é o
mesmo. Como exemplo, se um utilizador se encontra junto a umas escadas e o destino é no piso
imediatamente acima, pode não fazer sentido devolver um percurso que encaminhe o utilizador para
um elevador mais distante do que as escadas. No entanto, se o destino se encontra a dois ou mais
pisos de distância, já pode fazer sentido devolver o percurso que usa o elevador. Para resolver esta
situação, sempre que uma ligação é vertical são aplicados dois custos extra distintos: um de entrada e
um de transporte. O custo de entrada é motivado pelo facto dos elevadores terem um custo de entrada
relativamente alto mas depois do utilizador entrar têm um custo muito baixo, ou seja, compensam para
distâncias mais longas. Já umas escadas, apesar de nem sequer terem um custo específico associado
à entrada, apresentam um custo alto durante o movimento entre pisos (custo de transporte).
Resta ainda analisarmos o suporte às restrições. Sempre que o utilizador escolhe evitar uma res-
trição, o percurso devolvido deve oferecer uma alternativa. Para isso é necessário recorrer mais uma
vez à atribuição de custos nas ligações do grafo. Sempre que uma ligação represente a passagem por
um dos nós que inclui uma restrição, então é atribuído um custo muito elevado a essa ligação. Existem
duas grandes vantagens desta abordagem. A primeira é que as restrições podem ser evitadas ou não
em tempo de execução sem que seja necessário alterar a estrutura do grafo (basta alterar o custo das
ligações correspondentes). A outra é que é sempre possível obter um resultado mesmo que todos os
caminhos estejam restritos, o problema é que o seu custo será muito elevado.
3.7 Módulo para gerar instruções
A geração de instruções é a funcionalidade mais importante do sistema de encaminhamento porque
são as instruções que vão auxiliar o utilizador a chegar ao seu destino. Os três modos mais usados
para apresentar instruções ao utilizador são: instruções textuais, instruções de voz, e apresentação de
um mapa 2D. A nossa opção é gerar instruções textuais e apresentar um mapa 2D com o trajeto. As
instruções de voz ficam de fora porque são mais apropriadas para sistemas de encaminhamento com
localização em tempo real. O mapa 2D é opcional dado que a sua utilidade depende muito do tamanho
do ecrã disponível no dispositivo móvel.
O caso mais simples é gerar instruções quando o utilizador consegue chegar ao destino seguindo
sempre em linha reta; ai basta orientar o utilizador na direção do destino e indicar o número de metros
que este deve percorrer. O caso mais geral é o percurso incluir mudanças de direção e até mudanças
de piso. O funcionamento geral deste algoritmo passa por dividir um percurso em segmentos até
28
cada um destes segmentos incluir apenas movimentos em linha reta. O utilizador acaba assim por ser
encaminhado por objetivos.
Se um percurso inclui deslocamento em dois pisos, então este é dividido em três segmentos. O
primeiro segmento encaminha o utilizador desde o início até ao ponto onde a mudança de piso ocorre
(entrada para um meio de acesso vertical) através de uma ou mais instruções. O segundo segmento
indica ao utilizador para que piso se deve deslocar como, por exemplo, “Suba para o piso 3”. Finalmente,
o terceiro segmento que será idêntico ao primeiro encaminha o utilizador no piso final até este chegar
ao seu destino final.
Resta então analisarmos como é que o encaminhamento é feito dentro de cada piso. Como já
vimos, o segmento dum piso pode incluir várias mudanças de direção sendo que o essencial é auxiliar
o utilizador a identificar o local onde ocorre cada uma das mudanças de direção. O segmento do piso é
então também ele decomposto em segmentos que representam cada troço em linha reta. No primeiro
troço em linha reta de cada piso é necessário orientar inicialmente o utilizador na direção certa. Para
isso será sempre dado como ponto de referência o ponto de interesse de origem ou o meio de acesso
vertical usado imediatamente antes para chegar ao piso. Assim, a primeira instrução gerada em cada
piso define a orientação inicial do utilizador e será do tipo: “De costas para xpto continue 5 metros”.
Quando os pontos de referência e as vias de circulação são geometricamente perpendiculares (que é
o caso mais usual), o utilizador não terá dificuldade em orientar-se na direção certa. Mesmo quando a
geometria não é perpendicular, a inclusão de um ponto de interesse na instrução seguinte ajuda a tirar
as dúvidas como, por exemplo, na instrução “Vire à esquerda (direção a sala 4)”.
Depois de inicialmente orientado resta indicar ao utilizador as próximas mudanças de direção até
este chegar finalmente ao seu destino. É nas mudanças de direção que o utilizador pode ficar na dú-
vida se executou a instrução devidamente. Por este motivo, sempre que possível, o módulo gerador de
instruções vai incluir nas instruções textuais dois pontos de referência, um que se encontre antes da
mudança de direção e um que se encontre depois. Para identificar os pontos de referência a incluir nas
instruções será usado um algoritmo apresentado mais à frente. Ambos os pontos de interesse encon-
trados por este algoritmo vão enriquecer as instruções geradas e aumentar a confiança do utilizador
que este se encontra no caminho certo. Repare-se nos exemplos: “Continue 25 metros (passe sala 1)”
e “Vire à direita (direção a sala 6)”. Nas instruções anteriores “sala 1” foi o ponto de referência obtido
pelo algoritmo no troço imediatamente antes da mudança de direção enquanto “sala 6” foi obtido no
troço imediatamente depois.
De seguida é apresentado o modo como uma mudança de direção é identificada, como é que
o percurso é dividido em segmentos e ainda será explicado o algoritmo para identificar pontos de
referência.
3.7.1 Mudança de direção
Vamos considerar as seguintes mudanças de direção: para cima, para baixo, para a esquerda e para
a direita. Deixamos de fora movimentos para trás porque seriam úteis apenas em sistemas com posi-
29
cionamento em tempo real. Identificar movimentos verticais (para cima ou para baixo) é relativamente
simples visto que o movimento ocorre entre pisos distintos. Dentro do mesmo piso vamos usar o ângulo
de cada movimento para detetar mudanças de direção para a esquerda ou direita.
O ângulo de um movimento é definido pelo ângulo formado pelos dois vetores envolvidos no mo-
vimento. Verifica-se uma mudança de direção sempre que dois vetores formem um ângulo superior a
20�. Para detetar para qual dos lados (esquerda ou direita) é efetuado o movimento usamos o seguinte
algoritmo. Em primeiro lugar definem-se dois vetores auxiliares, o primeiro que forma um ângulo de
90� com o vetor de origem (referência para o lado direito) e o segundo que forma um ângulo de -90�
(referência para o lado esquerdo). O lado é depois dado conforme o declive do vetor de destino se
aproxime mais da referência esquerda ou direita. Na Figura 3.5 primeiro são representadas as várias
direções possíveis conforme a variação do ângulo e depois é dado um exemplo de um movimento para
a direita do segmento a para o segmento b. Neste exemplo ~ve e ~vd são os vetores de referência para o
lado esquerdo e para o lado direito respetivamente, com movimento confirmado pelo algoritmo para o
lado direito porque o ângulo entre ~v1 e ~v2 é superior a 20� e �1 é menor que �2.
(a) Direções em função do ângulo (b) Movimento para a direita
Figura 3.5: Direções no plano horizontal
3.7.2 Divisão do percurso em segmentos
O percurso obtido pelo módulo de procura de percursos é dividido numa estrutura em árvore conforme
representado na Figura 3.6. A raiz da árvore é um BuildingSegment que representa o percurso com-
pleto do utilizador. Este segmento tem como filhos um ou mais LevelSegment conforme o movimento
se verifique em mais do que um piso do edifício. Entre cada LevelSegment existe sempre um Change-
LevelSegment que representa o movimento entre pisos. Cada LevelSegment tem sempre como último
filho um FinishSegment que representa o fim do percurso quando o utilizador já chegou ao destino. Um
movimento em linha reta no LevelSegment para o destino final ou para um meio de acesso vertical é
representado pelo filho StraightUntilObjectSegment. Já um movimento em linha reta no LevelSegment
seguido de uma mudança de direção é representado por um StraightUntilTurnSegment. Finalmente,
30
o segmento StraightUntilTurnSegment é decomposto num StraightSegment seguido de um TurnSeg-
ment que representam o segmento até à mudança de direção e a mudança de direção respetivamente.
Como se pode ver na figura, só os elementos nas folhas das árvores é que vão produzir mensagens
com instruções textuais.
Figura 3.6: Hierarquia de segmentos
3.7.3 Algoritmo para identificar pontos de referência
O objetivo deste algoritmo é identificar os melhores pontos de referência a incluir nas instruções textuais
para auxiliar o utilizador nas mudanças de direção, ou seja, nos pontos de decisão. Pretende-se que
este algoritmo identifique um ponto de referência imediatamente antes e um imediatamente depois
de cada ponto de decisão. O utilizador sabe que pode avançar à vontade até encontrar o ponto de
referência (imediatamente antes) e só depois é que precisa de se preocupar em efetuar a mudança
de direção para o lado indicado (calculado através do algoritmo apresentado na secção 3.7.1). Caso o
utilizador possa seguir mais do que um caminho para o lado indicado na instrução, o ponto de referência
depois da mudança de direção vai ajudar o utilizador a optar pelo caminho correto desde que este
seja visível do ponto de decisão. Mesmo que o ponto de referência não seja logo visível, assim que
seja visível dará confiança ao utilizador que segue no caminho certo. Com isto podemos observar
que os pontos de referência acrescentam qualidade às instruções geradas mesmo quando não se
encontram junto do ponto de decisão. Tendo isto em conta, o algoritmo aqui apresentado é baseado
em pontuações. Dependendo de vários critérios, o algoritmo atribui uma pontuação a cada ponto de
referência e aquele que pontue menos é o escolhido para ser incluído nas instruções textuais.
O algoritmo aqui proposto aceita como entrada um segmento em linha reta (com dois pontos de
decisão, o primeiro no início e o segundo no fim do segmento) e devolve dois pontos de referência, um
junto ao primeiro ponto de decisão e o o outro junto ao segundo ponto de decisão. O primeiro é usado
como ponto de referência imediatamente depois da primeira mudança de direção (para ser usado nas
31
instruções do tipo “Vire à direita (direção a p1)”) enquanto o segundo é usado como ponto de referência
imediatamente antes da segunda mudança de direção (para ser usado nas instruções do tipo “Continue
25 metros (passe p1)”).
No primeiro passo deste algoritmo são selecionados como candidatos a pontos de referência os
pontos de referência junto dos pontos de decisão. Para isso, o algoritmo de Dijkstra é usado para
procurar todos os pontos de referência cuja distância (desde o nó de início do troço) é inferior ao
comprimento total do troço. No segundo passo são excluídos todos os pontos de interesse obtidos no
passo anterior cujo percurso inclua mais do que uma mudança de direção. O objetivo é excluir todos os
pontos de interesse que não se encontrem na linha de visão do utilizador. No último passo é atribuída
uma pontuação (dada pela fórmula 3.1 com valor real entre 0 e 1) a cada um dos candidatos restantes
em que os melhores candidatos vão pontuar menos.
Pi =1
2�
di;pddMax
+1
2�
lilMax
� (1� i 2 rota) : (3.1)
Esta fórmula é usada para determinar a pontuação Pi de cada candidato i e tem em conta dois
critérios. Um é a distância em linha reta di;pd que separa cada candidato i do ponto de decisão pd.
O outro é o número total de nós li ligados diretamente ao candidato i (definidos durante a construção
do mapa). O critério anterior só conta para a fórmula se o candidato não pertencer ao percurso que o
utilizador vai seguir (devolvido pelo algoritmo de cálculo de percursos). Cada um dos critérios anteriores
tem o mesmo peso na fórmula e são ambos normalizados (divididos pelo respetivo valor máximo dMax
e lMax) para obtermos sempre um valor no intervalo [0,1].
Com o primeiro critério damos pontuação mais baixa aos candidatos mais próximos do ponto de
decisão. Se o candidato pertence ao percurso que o utilizador vai seguir, o segundo critério é sempre
zero. Desta forma o segundo critério favorece os candidatos que estão no percurso do utilizador (o que
é desejável visto que o utilizador irá ver com facilidade um ponto de referência à sua frente) e penaliza
(com um aumento da pontuação) os candidatos que não pertencem ao percurso do utilizador. Dos
candidatos que não pertencem ao percurso do utilizador, são mais penalizados aqueles que tiverem
mais nós ligados diretamente a si (maior li). Os candidatos com mais do que uma ligação estão na
passagem para outra zona do edifício, possivelmente desviada da direção que o utilizador deve seguir.
Como resultado, a sua inclusão nas instruções textuais pode confundir o utilizador levando-o a crer que
deve seguir por esse caminho. Por outro lado, os candidatos que só tenham uma ligação são como
caminhos sem saída e assim o utilizador não terá outro caminho em vista que o confunda.
Para melhor compreendermos o algoritmo vamos explicar passo a passo a sua aplicação ao exemplo
da Figura 3.7 que mostra parte de um percurso que o utilizador vai seguir em linha reta entre dois pontos
de decisão (mudança de direção nos nós 1 e 6). Repare-se que os pontos de interesse P1, P2, P3 e
P5 têm apenas uma ligação enquanto P4 tem duas ligações. Neste exemplo, o primeiro passo do
algoritmo é aplicar o algoritmo de Dijkstra definindo o nó 1 como origem e devolvendo todos os pontos
de referência encontrados cuja distância total é inferior à distância total do troço que liga os nós (1, 2,
3, 4, 5, 6). Como resultado são devolvidos os pontos de referência P1, P2, P3 e P4 sendo que P5 é
32
Figura 3.7: Mapa de parte de um percurso (destacado entre o nó 1 e 6) com 5 pontos de referência (avermelho)
excluído porque é o único que se encontra a uma distância superior à permitida.
No segundo passo é excluído P2 porque a rota para este inclui duas mudanças de direção nos
pontos de decisão que ocorrem nos nós 3 e 8.
No terceiro e último passo do algoritmo é calculada a pontuação de cada um dos candidatos res-
tantes (P1, P3 e P4) em relação a cada um dos pontos de decisão (nós 1 e 6). Aplicando a fórmula
a P1 em relação ao nó 1 temos 12� 3
10+ 1
2� 1
2� 1 o que dá uma pontuação final de 0.4. Aplicando
novamente a fórmula a P1 mas desta vez em relação ao nó 6 temos 12� 11
11+ 1
2� 1
2� 1 o que dá uma
pontuação final de 0.75. Repetindo os cálculos para os pontos de referência restantes ficamos com as
pontuações dos pontos de interesse P1, P3 e P4 em relação ao nó 1 de 0.4, 0.75 e 1 respetivamente.
Em relação ao nó 6 ficamos com as pontuações dos pontos de interesse P1, P3 e P4 de 0.75, 0.43 e
0.67 respetivamente.
O algoritmo permite-nos então concluir que o melhor ponto de referência em relação ao primeiro
ponto de decisão é o P1 com a pontuação de 0.4 (que é menor que a dos restantes candidatos). Já
o melhor ponto de referência em relação ao nó 6 é o P3 com uma pontuação de 0.43. Note-se que
apesar de P4 se encontrar mais perto do nó 6 do que P3, o facto de P4 ter duas ligações ao contrário
de P3 que só tem uma faz com que P3 seja o melhor ponto de referência no segundo ponto de decisão
apesar de estar mais longe deste.
33
34
Capítulo 4
Implementação
Neste capítulo serão apresentadas as decisões chave que foram tomadas na implementação das fun-
cionalidade e algoritmos propostos no capítulo anterior.
4.1 Alterações ao JOSM
Como já foi referido, o JOSM é um editor de mapas para o projeto OpenStreetMap desenvolvido em
Java e de código aberto. A grande vantagem deste editor é permitir definir mapas OSM através de uma
interface gráfica. Aproveitando que o modelo de dados proposto neste trabalho é baseado no OSM,
foram feitas algumas alterações ao código fonte do JOSM para adaptá-lo às nossas necessidades.
É de referir que, dada a elevada complexidade do código fonte do JOSM, a versão que resultou das
nossas alterações não é ainda um produto acabado mas já permite lidar com a criação dos mapas mais
facilmente do que através da manipulação direta do XML.
A primeira modificação foi em termos de coordenadas. Como se sabe o JOSM é próprio para
espaços exteriores e portanto no ecrã de desenho podemos contar com toda a superfície terrestre e
um sistema de coordenadas (latitude, longitude). O nosso objetivo é definir um sistema de coordenadas
x (ordenada), y (abcissa) para cada planta de um edifício. Para efetuar esta adaptação seria necessária
uma funcionalidade para carregar imagens para o ecrã. Como esta opção não foi encontrada no JOSM,
decidimos colocar imagens num diretório próprio e alterar o JOSM para que desenhasse no ecrã uma
imagem com o mesmo nome do mapa sempre que uma exista no diretório. Esta imagem passa a ser a
nova área de desenho e ao seu canto superior esquerdo é atribuída a coordenada (0, 0) e ao seu canto
inferior direito a coordenada (largura da imagem em pixeis, altura da imagem em pixeis).
A partir deste momento podemos então definir o mapa do edifício desenhando por cima da imagem.
Depois, no momento em que cada nó é escrito para o ficheiro XML, são adicionados os atributos x e y
ao elemento nó cujos valores são calculados usando como referência a coordenada (latitude, longitude)
correspondente ao ponto (x=0, y=0).
Apesar de não estar preparado para suportar a definição de vários pisos, existe no OSM o conceito
de camadas. As camadas permitem ter na mesma interface vários contextos de desenho. Apesar de
35
podermos aproveitar as camadas para desenhar os vários pisos de um edifício, cada piso é guardado
no seu ficheiro XML mas a aplicação aqui desenvolvida requer um ficheiro por edifício. Foi por isso ne-
cessário criar um pequeno programa (denominado josm-to-xml.sh) capaz de receber como argumentos
as localizações dos vários ficheiros XML de cada piso e gerar apenas um ficheiro com todos os pisos
incluídos. Este utilitário está escrito em shell script (para distribuições GNU/Linux) e, depois de transfor-
mar os argumentos passados na linha de comandos, executa internamente um script XSLT (EXtensible
Stylesheet Language Transformation) responsável pela criação do ficheiro XML final.
Novamente, é importante lembrar que o ideal seria evitar o uso deste utilitário (josm-to-xml.sh) mas,
para isso seria necessário alterar com mais cuidado o código fonte do JOSM.
4.2 Estrutura do projeto
A aplicação aqui proposta foi desenvolvida para a plataforma Android. Dada a quantidade e complexi-
dade dos algoritmos necessários para o seu funcionamento, justificava-se a criação de testes automá-
ticos que garantissem o correto funcionamento do código desenvolvido até então. Para isso, além do
projeto Android denominado prototype, foi também criado o projeto Java denominado core. Ao projeto
core foi adicionada a framework JUnit1 que suporta a criação de testes automáticos na linguagem Java.
Assim, na plataforma Android foi apenas desenvolvido o código que diz respeito à interação com o uti-
lizador e os algoritmos em core foram acedidos através de chamadas à biblioteca externa gerada por
core (core.jar). Note-se que com esta separação, core não tem conhecimento algum sobre a existência
de prototype, apenas o inverso se verifica. Esta opção facilitou bastante o desenvolvimento do projeto
dado que, no que diz respeito ao código incluído em core, não é necessário nenhum dispositivo Android
ou simulador para a sua execução ou teste.
O ambiente de desenvolvimento foi o Eclipse, executado num portátil com o sistema operativo Fe-
dora 19. O dispositivo Android usado foi um Samsung Galaxy Tab 4.
Quanto à estrutura de diretórios do prototype, esta é composta pela estrutura pré-definida de qual-
quer projeto em Android. O código desenvolvido foi incluído em src/ e é composto basicamente pelas
várias atividades de interação com o utilizador. Para além do código fonte foram ainda incluídos alguns
recursos em res/, tais como, as strings em res/values e res/values-pt, os ícones em res/drawable-ldpi e
ainda, os layouts em res/layout.
No caso do core já temos uma estrutura de diretórios mais complexa. No entanto, esta segue o
padrão já apresentado no capítulo 3:
� core.data contém todos os tipos de dados usados para representar o mapa de um edifício em
memória;
� core.map contém o parser que vai processar o ficheiro XML com o mapa de um edifício;
� core.routing contém todo o código necessário para criar o grafo linha e calcular percursos através
do algoritmo de Dijkstra;
1http://junit.org
36
� core.instructions contém o código para divisão da rota em segmentos, detetar mudanças de dire-
ção e identificar pontos de referência;
� core.util contém algumas classes utilitárias para efetuar cálculos geométricos como a distância no
plano cartesiano;
� core.paint contém algumas classes de suporte ao desenho do mapa 2D;
4.3 Armazenamento e partilha de dados
Além das estruturas de dados mantidas em memória, é necessário também recorrer ao armazena-
mento de dados de forma persistente, desde logo para guardar os mapas dos edifícios. Além disso,
é importante guardar o estado da aplicação para que se mantenham as preferências do utilizador em
futuras execuções da mesma. O Android permite várias formas de armazenamento persistente sendo a
mais óbvia o uso de ficheiros. Outra forma de armazenamento de dados é a utilização de preferências
partilhadas através da classe SharedPreferences. Nas preferências partilhadas é possível armazenar
dados primitivos em pares chave/valor. Na nossa implementação escolhemos usar ambas as formas
de armazenamento referidas atrás, sendo que existem ainda outras opções como as bases de dados.
Os dados armazenados pelo prototype de forma persistente são:
1. Lugar em que o utilizador estacionou o seu veículo;
2. Restrições definidas e o seu estado (evitar/não evitar);
3. Tamanho do mapa 2D (em percentagem do máximo disponível);
4. Conteúdo dos mapas em XML;
5. Nome dos vários mapas adicionados à aplicação (e localização dos respetivos ficheiros com o
conteúdo XML);
Os dados em 1, 2 e 3 são armazenados diretamente como texto (tipo String) nas preferências parti-
lhadas. O conteúdo dos mapas (4) é guardado diretamente em ficheiros. Por último temos a estrutura
de dados em 5 que também é armazenada nas preferências partilhadas mas, como é mais complexa
(formada por um conjunto de objetos), não pode ser guardada diretamente como tipo primitivo. Primeiro
transforma-se a estrutura numa sequência de dados binários implementando a interface Serializable
em todos os objetos que fazem parte da estrutura. Depois, transformam-se os dados binários em texto
através da codificação base64 (através da classe Base64); desta forma a estrutura é guardada nas
preferências partilhadas como se de um tipo primitivo se tratasse (neste caso o tipo String).
Acerca da partilha de dados, este é um assunto importante no que diz respeito a aplicações para a
plataforma Android. Uma aplicação em Android está organizada em atividades. Cada atividade deve ter
um contexto muito específico e pode definir o seu próprio layout para interagir com o utilizador. Estas
atividades, fazendo parte da mesma aplicação, necessitam de partilhar dados entre elas. No entanto,
os mecanismos recomendados para partilhar dados no Android implicam copiar os dados do espaço
de memória de uma atividade para outra. No caso da nossa aplicação este mecanismo pode ter um
impacto negativo no desempenho dado que as estruturas de dados criadas no início da execução da
37
aplicação (quando o utilizador escolhe o mapa onde pretende interagir) têm alguma complexidade e são
necessárias em todas as outras atividades. A solução encontrada foi definir uma variável estática (de-
claração static) cujo objeto atribuído (classe Main definida em core) nunca é eliminado pelo mecanismo
de GC (Garbage Collection) do Java. O motivo pelo qual este objeto nunca é eliminado enquanto se
encontra atribuído a uma variável estática (desde que o processo associado à aplicação não termine)
prende-se com o facto da máquina virtual Java o colocar na sua GC root. Todos os objetos na GC root,
bem como todos os objetos referenciados por estes, não são eliminados.
4.4 Gestão de mapas
Assim que o prototype é iniciado, a atividade HomeActivity é responsável por dar ao utilizador a pos-
sibilidade de gerir os mapas. É apresentada uma lista com todos os mapas disponíveis localmente
(descarregados para a memória do dispositivo previamente) com várias opções. Qualquer mapa pode
ser usado pela aplicação desde que tenha sido transferido para o dispositivo móvel pelo gestor. O ges-
tor permite adicionar, editar e eliminar mapas da sua lista. Esta lista é mantida na classe HomeMapList
composta por entradas do tipo HomeMapEntry que guardam o nome do mapa e a sua localização no
sistema de ficheiros do dispositivo. Esta lista é guardada de forma permanente através das SharedPre-
ferences do Android.
A atividade DownloadMapActivity é responsável por adicionar um novo mapa na lista e transferir o
respetivo ficheiro, sendo que o ficheiro pode ter origem em dois tipos de localizações distintas. Uma é
uma localização remota em que o ficheiro é transferido através do protocolo HTTP (Hypertext Transfer
Protocol). A outra é um ficheiro local que possa ser acedido diretamente pelo sistema de ficheiros do
dispositivo. Em ambos os casos é criada uma AsyncTask para lidar com a transferência do ficheiro. Uma
AsyncTask foi desenhada para executar operações em background e depois apresentar os resultados
na interface. O progresso da transferência é mostrado no ecrã recorrendo à classe ProgressDialog
do Android. Para facilitar a introdução do endereço com a localização do mapa, este endereço pode
ser copiado e colado na caixa de texto correspondente graças à utilização do ClipboardManager do
Android.
Durante a transferência de um mapa, este é temporariamente guardado num ficheiro com nome
aleatório (são evitadas colisões nos nomes) e extensão tmp. Só quando a transferência do ficheiro é
concluída com sucesso é que a extensão do ficheiro é modificada para xml. Com isto garantimos que
não ficam ficheiros perdidos a ocupar memória desnecessariamente (os ficheiros com a extensão tmp
são eliminados quando a aplicação inicia). Assim que o ficheiro é transferido na totalidade, é pedido ao
utilizador para definir um nome para o novo mapa. No entanto, e como não são permitidos dois mapas
com o mesmo nome, é sugerido um nome para o mapa isento de colisões. A primeira tentativa é usar
o nome definido pelo criador do mapa quando escreveu o XML do mesmo (através do atributo name do
elemento map). Se já existir outro mapa com o mesmo nome, então é sugerido o nome concatenado
com a string “_0” tantas vezes quantas as necessárias até que os nomes não colidam.
A opção para editar um mapa modifica apenas o nome com que este é apresentado na lista ao utili-
38
zador; internamente é sempre o mesmo ficheiro e tem sempre o mesmo nome. Quando é selecionada a
opção para eliminar um mapa, e após o utilizador confirmar que tem a certeza que pretende continuar,
então a entrada na lista dos mapas correspondente é eliminada, bem como o ficheiro correspondente
guardado localmente.
Figura 4.1: Ecrã lista de mapas Figura 4.2: Ecrã adicionar novo mapa
4.5 Inicialização das estruturas
Para suportar todas as funcionalidades da aplicação é necessário inicializar várias estruturas de dados.
Este processo tem início com a análise do mapa do espaço em XML. Para analisar um ficheiro XML
pode ser usada a API DOM (Document Object Model), mas esta carrega para memória todo o ficheiro
XML e tal não é necessário nem recomendado em dispositivos com memória limitada. Recorremos
antes à API SAX (Simple API for XML) baseada em eventos. O SAXParser esconde os detalhes de
se ter de lidar com a análise de um ficheiro de texto. Um cliente do SAXParser fica à espera de uma
notificação sempre que um elemento XML é encontrado no ficheiro. Esta notificação é feita através
de callbacks que incluem nos seus argumentos o nome e os possíveis atributos do elemento XML. As
callbacks implementam a interface ContentHandler.
A nossa implementação do ContentHandler encontra-se na classe core.map.MapParser. A estraté-
gia usada para criar as estruturas de dados aproveita o facto dos elementos em XML serem aninhados
uns nos outros (sendo que todos os elementos se encontram aninhados na raiz). Para criar os objetos
do tipo core.Data.Node, por exemplo, assim que o elemento nó tem início é criado um objeto do tipo
Node que é guardado numa variável temporária e são inicializados os atributos correspondentes aos
atributos do elemento XML (como as suas coordenadas). Paralelamente, é inicializada uma lista para
guardar possíveis tags aninhadas neste elemento. Depois, sempre que uma tag é encontrada basta
adicioná-la à lista. Assim que é chamada a callback de notificação de fim do elemento nó, todas as tags
são processadas sendo o nó modificado de acordo com as mesmas e este é finalmente adicionado de
forma permanente a uma estrutura que guarda todos os nós. A variável temporária é então inicializada
a null, bem como a lista de tags, ficando as variáveis temporárias disponíveis para processar o próximo
elemento. O processamento dos restantes elementos é feita de forma semelhante.
Depois da análise de todo o ficheiro XML, o resultado são objetos de vários tipos, inicializados
39
de acordo com os dados no ficheiro. Destes, vamos destacar dois tipos que são essenciais para se
perceber as restantes secções. Um são os objetos do tipo nó. Cada elemento XML do tipo nó é
representado por um objeto da classe core.data.Node. Como se sabe, este objeto terá uma localização
no piso (classe core.data.Level), cujas coordenadas (x, y) serão atributos seus, enquanto o piso a que
pertence será inferido a partir do piso a que pertencem os caminhos (classe core.data.Way) que incluem
este nó.
O outro, é o grafo linha que permite efetuar procuras de percursos. A sua implementação é muito
simples. Como no mapa não são definidos explicitamente Ways verticais (através de elementos way),
estes são criados pelo algoritmo conforme indicado pelas tags vgroup e vtype. Depois, cada Way pre-
viamente criado é dividido em segmentos, ou seja, é adicionado um WaySegment entre cada par de
nós. A cada WaySegment são associados dois nós do grafo linha (classe core.routing.LineNode), um
em cada direção. Quanto à definição das ligações entre cada LineNode, por cada conjunto de Way-
Segments que partilhem um nó em comum, os respetivos LineNode são ligados respeitando sempre
as vias de sentido único (não criando essas ligações). É importante referir ainda que, por questões de
eficiência, as distâncias e a direção entre cada par de LineNodes é calculada durante a construção do
grafo para ser consultada sempre que necessário mais tarde.
4.6 Definição de origem e destino
Já vimos como se constrói um mapa de um espaço, como é que este é analisado e quais os objetos de
maior importância que dai resultam. Falta explicar como é que a aplicação escolhe quais as localizações
que podem servir de origem e de destino. Como sabemos, o utilizador terá de escolher não só a
localização de destino, mas também a sua própria localização de origem. As localizações que podem
ser usadas como origem e destino são selecionadas segundo alguns critérios. Este mecanismo de
seleção é automático para simplificar ao máximo a construção do mapa. Na interface da aplicação
estas localizações são depois sugeridas ao utilizador através da apresentação de uma lista com todas
elas, sendo que é possível filtrar os resultados desta lista através da introdução de caracteres.
Primeiro, vamos definir uma localização de forma genérica. Todos os nós são possíveis candidatos
a localizações, no entanto, para o utilizador uma localização terá de ter uma descrição textual que
o ajude a identificar a mesma. Assim, todos os nós que tenham um objeto definido são possíveis
localizações. Se se trata de um nó com um lugar de estacionamento ou um ponto de interesse ou um
meio de acesso vertical definido, então a sua localização é dada pelo nome do mesmo (“Parque [piso,
zona, código lugar]”, “nome do ponto de interesse”, “elevador”, “escadas rolantes” e “escadas”). Foi
criada uma classe para representar este conceito, ou seja, para representar a associação entre um nó
e a sua descrição textual (core.data.HumanLocation).
Desta forma, se duas HumanLocation têm nós distintos mas as suas descrições textuais são iguais
então, para o utilizador trata-se da mesma localização. Por este motivo estas HumanLocations são
excluídas da lista de origens; uma origem tem de ter uma localização única. No entanto, note-se o caso
excecional em que duas HumanLocation têm localizações distintas mas estas não coincidem no mesmo
40
piso. Neste caso, mesmo com descrições textuais iguais, ambas são consideradas origens dado que o
utilizador pode distingui-las sabendo o piso onde se encontra.
Quanto à lista de destinos, esta é criada da seguinte forma. Um destino é representado na classe
core.data.Destination e ao contrário de uma origem, não necessita de ter uma localização única, nem
mesmo dentro do mesmo piso. Um destino, para que se distinga de outro, basta que tenha uma
descrição textual única. Assim um Destination pode estar associado a vários nós. O método chave
implementado em Destination é o getNodeRecognizers(). Este método devolve uma lista de objetos do
tipo routing.NodeRecognizer que são capazes de identificar se um dado nó é uma das localizações do
Destination. Este método é muito importante dado que permite ao utilizador que escolha, por exemplo,
como destino um multibanco. Existindo vários espalhados num edifício, a aplicação vai devolver o
percurso para o primeiro encontrado graças aos NodeRecognizers que vão saber identificar as suas
localizações.
4.7 Procura de percursos
Quando o utilizador pretende obter um percurso para um destino escolhe a opção “Calcular rota”. A
atividade responsável por esta opção RouteSearchActivity é iniciada e é dada a possibilidade ao uti-
lizador para escolher uma origem e um destino (ver figura 4.3). Para facilitar esta escolha é apre-
sentada uma lista com todas as localizações possíveis tal como foi explicado na secção 4.6. Para
preencher esta lista recorre-se a objetos que implementam a interface android.widget.Adapter. Estes
objetos servem de acesso aos dados que serão apresentados na lista. Também são responsáveis por
gerar o layout de cada elemento da lista. Na nossa implementação o layout de cada elemento da
lista mostra a descrição textual da localização bem como o piso a que pertence (se for único). As-
sim que o utilizador confirma que deseja efetuar a procura, a atividade cria um pedido de procura e
passa-o para a classe core.routing.PathFinder responsável por servir o pedido. Neste pedido (do tipo
core.routing.RouteRequest) é incluída uma origem (do tipo HumanLocation), um destino (do tipo Desti-
nation), as restrições (core.routing.Restrictions) e uma função de custo (core.routing.CostFunction). Isto
é tudo o que se sabe sobre uma procura no prototype. Todos os restantes detalhes da implementação
da procura são conhecidos apenas no core.
Quando chega um pedido de procura ao PathFinder, este devolve um percurso (core.routing.Path)
para cada NodeRecognizer da lista de NodeRecognizer obtida do Destination. Sempre que o cami-
nho de menor custo para um nó é encontrado, é feita uma verificação para se perceber se algum dos
NodeRecognizer reconhece o nó. Se tal se verificar então é encontrado um resultado para o Node-
Recognizer em questão e a procura continua até todos os NodeRecognizer terem reconhecido um nó.
Note-se que neste tipo de procura, apesar de se poderem obter vários resultados, o grafo é percorrido
na sua totalidade no máximo uma vez. Esta procura até pode terminar antes: no momento em que já
foi encontrado um resultado para cada NodeRecognizer. No caso geral, um destino devolve apenas
um NodeRecognizer como resultado da chamada a getNodeRecognizers(). São usados vários Node-
Recognizer apenas para a funcionalidade de estacionar junto a um ponto de interesse. Neste caso é
41
necessário mostrar um resultado por cada piso de estacionamento.
Finalmente resta detalhar como é que o algoritmo de Dijkstra está implementado de modo a permitir
o máximo de flexibilidade e eficiência. Para aproveitar o facto de ser mais eficiente terminar o algoritmo
de Dijkstra assim que as necessidades de procura estejam satisfeitas, usamos um padrão semelhante
ao usado pelo SAXParser visto anteriormente na secção 4.5. No método que dá início à execução do
algoritmo de Dijkstra é passado como argumento um objeto que contém callbacks que serão usadas
para notificar o chamador do algoritmo sempre que seja encontrado um caminho de menor custo para
um dado nó. As callbacks também servem para o algoritmo de Dijkstra perguntar ao chamador se já
pode dar por terminada a procura. Desta forma o chamador pode terminar o algoritmo na melhor altura,
colecionando tantos resultados quantos deseje na mesma execução do algoritmo melhorando-se a
eficiência do mesmo.
Uma nota ainda quanto à função de custo que também é passada como argumento ao algoritmo
de Dijkstra. Apesar das distâncias entre nós do grafo já terem sido calculadas previamente (durante a
construção do mesmo), o cálculo do custo é deixado para o momento em que o algoritmo percorre o
grafo. Existe uma função de custo responsável por efetuar este cálculo. Desta forma é possível usar o
mesmo grafo e a mesma implementação do algoritmo para objetivos distintos. Por exemplo, quando é
necessário encontrar pontos de referência, é usado este mesmo algoritmo de Dijkstra mas a função de
custo tem em conta apenas o fator distância. Pelo contrário, quando é necessário procurar o percurso
que o utilizador vai seguir, então são tidos em conta os fatores distância e as mudanças de direção (são
também consideradas as restrições, como se explicará adiante). Na nossa implementação, a distinção
entre os vários casos é feita alterando apenas a função de custo usada; o restante código mantém-se
inalterado.
Figura 4.3: Ecrã calcular rota
42
4.8 Obter instruções
Depois do utilizador escolher uma origem e um destino, e caso a atividade RouteSearchActivity encon-
tre um percurso válido, a atividade ShowInstructionsActivity é iniciada com o percurso passado como
argumento. Esta atividade é então responsável pela apresentação de uma sequência de instruções
textuais. Estas instruções são acompanhadas por um mapa 2D para auxiliar o utilizador a chegar ao
destino. Mais uma vez esta atividade não tem de lidar com os detalhes de implementação desta funcio-
nalidade. É a classe core.instructions.InstructionsGenerator a responsável por transformar um percurso
num conjunto de instruções conforme apresentado na secção 3.7. Quando esta classe recebe o per-
curso como argumento, cria um RootSegment (raiz da árvore) e invoca o seu método buildTree(). O
resultado é uma árvore de segmentos construída de forma recursiva (RootSegment adiciona os seus
filhos à árvore e invoca também os seus métodos buildTree()). Finalmente, cada segmento é respon-
sável por adicionar a instrução textual gerada por si a um objeto do tipo core.routing.Instructions, que
mantém todos os dados que a atividade necessita para apresentar instruções ao utilizador. Estes da-
dos incluem, para além do texto de cada instrução, a posição no mapa em que cada instrução deve ser
mostrada ao utilizador, a distância que falta percorrer e ainda, a origem e o destino do percurso.
Estando na posse de um objeto do tipo Instructions, a atividade procede então à apresentação dos
dados na interface gráfica, aguardando por possíveis eventos gerados por ações do utilizador. O ecrã
do dispositivo é dividido verticalmente em 3 partes iguais. Na primeira parte é apresentado o contexto
do percurso, ou seja, é mostrada a origem da rota, o destino, a distância total a percorrer e a distância
que ainda falta percorrer. Além disso, existe um botão que permite alterar com facilidade a origem
do percurso. Este botão é útil quando o utilizador se perde no espaço e precisa de atualizar a sua
localização atual mantendo o mesmo destino final. Na segunda parte do ecrã temos a visualização do
texto com a instrução atual e dois botões que permitem ir para a instrução seguinte ou voltar para a
anterior.
Finalmente, na terceira e última parte do ecrã é apresentado um mapa 2D com o percurso. A altura
máxima deste mapa pode ser reduzida nas definições da aplicação sendo que o espaço restante é
acrescentado de forma igual às primeiras duas partes. Esta opção pode ser útil em dispositivos de
pequena dimensão ou para pessoas que não gostam de se orientar em mapas. Para cada instrução, só
é apresentada a parte do piso atual a que esta diz respeito. Por exemplo, numa instrução do tipo “vire à
direita” só é mostrado o cruzamento atual, o possível ponto de referência referido na instrução e, uma
pequena margem à volta para maior visibilidade da área circundante. Isto é tudo conseguido através
da classe core.paint.Viewport, usada pela atividade ShowInstructions para obter as coordenadas de
cada nó. A Viewport transforma assim as coordenadas de cada nó com base no tamanho do ecrã e do
percurso a visualizar. A Viewport suporta ainda as funções de panorâmica (deslizando no mapa) e de
zoom (clicando nos botões “+” e “-” no canto superior direito) que são úteis caso o utilizador deseje ter
outra vista do mapa. Quando alguma destas funções tem início, a Viewport é informada e de imediato
recalcula as coordenadas dos nós. A Viewport é assim a responsável por posicionar corretamente os
elementos do mapa. Quanto à atividade ShowInstructions, esta é responsável por colocar os elementos
43
ordenadamente no ecrã conforme se segue:
� desenhar a azul todos os caminhos definidos no mapa;
� de todos os caminhos, marcar a cinzento apenas os que o utilizador tenha de percorrer para
chegar ao destino;
� destacar a verde a parte do caminho que diz respeito à instrução atual;
� escrever o texto das descrições textuais de todos os pontos de referência referidos na instrução
atual, bem como da origem e do destino do percurso;
� se a instrução inclui pontos de referência, destacar a sua localização com uma bola amarela para
fácil identificação;
� escrever o texto com a descrição textual de todas as restantes localizações no mapa, omitindo as
localizações cujo texto fique sobreposto com o de outra localização previamente escrita;
� desenhar uma seta a branco que identifica a direção em que é assumido que o utilizador se
encontra (oferecendo assim uma referência que permite ao utilizador distinguir a esquerda da
direita);
Figura 4.4: Mapa 2D da aplicação
4.9 Restrições
Para descrever com expressividade suficiente o movimento de pessoas é necessário recorrer a res-
trições. Basta olhar para o que acontece nas caixas de um supermercado (onde só é possível sair),
ou num centro comercial com escadas rolantes que só permitem subir. As restrições anteriores são
permanentes, ou seja, são características físicas do edifício que podem ser definidas no XML do mapa
através das tags apresentadas na secção 3.4.1. A implementação destas restrições é oferecida pelo
algoritmo de construção do grafo que simplesmente não cria as ligações correspondentes às vias de
sentido único.
44
Há ainda que considerar as pessoas que, por exemplo, não podem ou não querem deslocar-se em
elevadores. Este caso dá origem a um desafio adicional comparativamente às restrições anteriores:
o utilizador pode querer evitá-las ou não, necessitando por isso de um mecanismo de escolha. Ainda
assim estas restrições são de algum modo previsíveis, isto é, podemos esperar que existam em todos os
edifícios com mais de um piso. Não há por isso necessidade de definir estas restrições explicitamente;
assume-se a sua presença nos locais onde existe um meio de acesso vertical. Para implementar estas
restrições foi adicionado um painel de restrições que mostra ao utilizador todas as restrições presentes
numa estrutura de dados própria para o efeito. Automaticamente o sistema adiciona nesta estrutura
uma restrição com o nome de cada meio de acesso vertical presente no mapa (“elevador”, “escadas”
e “escadas rolantes”). Depois, durante a procura de um percurso é usado o mesmo mecanismo que
permite evitar mudanças de direção, tal como foi explicado na secção 4.7: usando uma função de
custo que define um custo elevado para as ligações do grafo correspondentes ao movimento vertical a
evitar. Desta forma o algoritmo só devolve o percurso que passa pela restrição caso não encontre uma
alternativa de menor custo; nesse caso o utilizador é avisado que uma restrição é violada pelo percurso
devolvido.
Mas existem ainda outras restrições a considerar mais imprevisíveis. Estas são as restrições que
quem constrói o mapa quer dar a possibilidade ao utilizador de evitar mas que não podem ser inferi-
das automaticamente como no caso das anteriores. Estas restrições podem ir desde uma passagem
estreita, à presença de um degrau, ou, podem até nem ser obrigatoriamente características físicas do
espaço como, por exemplo, dar a possibilidade ao utilizador de evitar passar por zonas de fumadores.
Estas restrições são extremamente flexíveis e podem ser definidas pelo criador do mapa através da
colocação da tag restriction num nó XML. Todos os nomes destas restrições serão também incluídos
na estrutura de dados com as restrições do painel e por isso serão mostradas ao utilizador que po-
derá escolher evitá-las ou não. Tal como no caso dos meios de acesso verticais, durante uma procura,
sempre que seja encontrado um nó do grafo que inclua um restrição a evitar, os custos das ligações
correspondentes serão elevados. Na figura 4.5 é apresentado o exemplo de um painel gerado para
um mapa que inclui uma restrição com o nome “passagem estreita” (definida com o elemento <tag
k=“restriction” v=“passagem estreita”/>).
Figura 4.5: Ecrã de restrições
45
4.10 Apoio ao estacionamento
Nesta secção pretende-se explicar como é que a aplicação desenvolvida apoia o utilizador durante o
estacionamento. Apesar do objetivo inicial do trabalho ser o encaminhamento de pessoas e veículos, o
que implica que em ambos os casos se guie o utilizador durante todo o percurso, optou-se por apenas
encaminhar pessoas e apoiar o estacionamento. Esta decisão deve-se a vários motivos.
Em primeiro lugar pretende-se que a aplicação seja facilmente utilizável em qualquer espaço, dai a
decisão de não se recorrer a sistemas de localização. A verdade é que é difícil manter esta decisão e
encaminhar veículos. Só é razoável deixar que seja o utilizador a passar manualmente para a instrução
textual seguinte (simulando a atualização da localização) caso este tenha as mãos livres, o que não
acontece durante a condução de veículos. Em segundo lugar, a interface a usar tem de ser diferente
dado que não se pode esperar que o utilizador leia instruções enquanto conduz. Por último, é bom
lembrar que dentro de um edifício, o lugar em que o veículo fica estacionado é de menor importância,
o principal é chegar ao destino final na zona pedestre.
O apoio ao estacionamento é então oferecido através de duas opções. Na primeira é sugerido ao
utilizador onde é que este deve estacionar o seu veículo. Na segunda é guardado o lugar de estaci-
onamento para que mais tarde o utilizador possa voltar ao seu veículo. Na primeira opção é dada a
possibilidade ao utilizador que escolha, por exemplo, uma certa loja dum centro comercial como des-
tino final e como resultado é devolvida uma lista com várias opções onde este pode estacionar. Note-se
que geralmente os parques de estacionamento contêm marcações com o nome das ruas e números a
marcar cada lugar de estacionamento. Se estes identificadores seguirem uma ordem lógica (o que se
geralmente se verifica), é de esperar que o utilizador consiga chegar com facilidade ao lugar sugerido.
Mesmo que o utilizador se engane no percurso, provavelmente não há problema em conduzir mais uns
metros extra; normalmente é mais importante minimizar a distância de caminhada. Esta função será de
grande utilidade para uma pessoa com limitações físicas que a impeçam de se deslocar com facilidade.
Quando o utilizador escolhe um destino final é usado o algoritmo de Dijkstra para encontrar o cami-
nho de menor custo desse destino até ao primeiro nó que contenha um lugar de estacionamento. No
entanto, a procura não termina de imediato; esta continua até ser encontrado um lugar de estaciona-
mento em todos os pisos do parque. Com isto pretende-se evitar a situação que se segue. Imagine-se
que o utilizador já se encontra no piso 1 e a sugestão devolvida é que estacione no piso 2. Para levar o
seu veículo até ao piso 2, o utilizador tem de dar uma volta considerável, subir uma rampa e estacionar
para depois acabar por entrar no mesmo elevador que podia ter apanhado quando se encontrava no
piso 1. Para evitar situações como esta, todos os resultados apresentados indicam também a distância
total a percorrer. Caso o utilizador escolha, por exemplo, um WC como destino final, então o algoritmo
efetua uma procura destas para cada um dos WC e só devolve o melhor dos resultados.
A outra opção de apoio ao estacionamento é dada pela funcionalidade de estacionar, onde o utiliza-
dor pode indicar o lugar onde estaciona. Também é possível preencher esta opção com os resultados
devolvidos pela funcionalidade anterior, bastando para isso clicar num dos resultados. Depois, e quando
o utilizador pretender voltar ao seu veículo, basta que carregue na opção para tal; de imediato o destino
46
é preenchido com o lugar de estacionamento ficando a faltar somente a introdução da localização atual.
4.11 Alterar idioma
A funcionalidade para alterar o idioma não se encontra nas definições da aplicação, no entanto são
suportadas as línguas portuguesa e inglesa. Para se poder alterar entre ambas é necessário alterar o
idioma do próprio dispositivo Android através das definições. O idioma da aplicação irá coincidir com
o do Android sendo que, caso não exista tradução para o idioma escolhido, então é escolhida a língua
inglesa. Esta funcionalidade é conseguida graças a um mecanismo próprio do Android. No Android é
recomendado que se mantenham todas as strings cujo conteúdo seja apresentado ao utilizador num
ficheiro próprio, agrupadas por idioma. Desta forma o Android irá obter a string ao ficheiro correspon-
dente ao idioma selecionado. Para agrupar as strings por idioma estas são incluídas num ficheiro de
nome strings.xml guardado num diretório cujo nome inclui o sufixo correspondente ao idioma (pt para
Portugal, es para Espanha, etc.). Podemos então encontrar as strings em inglês em /res/values/s-
trings.xml e as strings em português em /res/values-pt/strings.xml.
47
48
Capítulo 5
Avaliação
Neste capítulo pretende-se avaliar o trabalho proposto nos capítulos anteriores. Para isso vamos co-
meçar por explicar a metodologia usada e depois apresentarmos os resultados obtidos. Pretendemos
demonstrar, em primeiro lugar, que a aplicação executa corretamente as funcionalidades propostas e,
em segundo lugar, pretendemos medir o seu desempenho durante a execução das mesmas.
Um dos aspetos mais relevantes desta aplicação é a forma inteligente como calcula percursos tendo
em conta as características do espaço físico. Durante a avaliação vamos, numa primeira fase, criar uma
série de cenários nos quais será comparado o resultado devolvido pela aplicação com o resultado espe-
rado em cada um destes cenários específicos. Com isto garantimos a correção de todos os algoritmos
desenvolvidos. Numa segunda fase iremos testar o desempenho destes mesmos algoritmos medindo
valores como o uso de CPU, a quantidade total de memória RAM utilizada e o tempo de execução. O
que se pretende é verificar se o tempo de execução é razoável numa situação real porque, por melhores
que sejam os resultados apresentados pela aplicação, estes deixam de ser interessantes a partir do
momento em que o utilizador tenha de esperar demasiado tempo para os obter.
Todos os testes aqui realizados foram executados num tablet Samsung Galaxy Tab 4 de 7 polegadas
com um processador Quad-Core de 1.2GHz e memória RAM de 1.5GB. Este foi o dispositivo disponível
durante o desenvolvimento do trabalho e apesar de não ser o dispositivo típico que será usado para
correr a aplicação, as suas características são bastante comuns. Atualmente já existem smartphones
com 8 cores e mais memória RAM que o dispositivo usado. A grande diferença está no tamanho do
ecrã mais reduzido nos smatphones mas isso influencia apenas a legibilidade do mapa 2D.
5.1 Correção dos algoritmos
Para testar a correção dos algoritmos é necessário colocar a aplicação perante um conjunto de si-
tuações distintas. Para isso, criámos um mapa de um espaço fictício que pode ser considerado um
pequeno centro comercial com 4 pisos representado nas figuras 5.1 a 5.4. O piso -1 é apenas um
parque de estacionamento e os pisos 0, 1 e 2 estão destinados à circulação de pessoas e incluem uma
variedade de pontos de interesse.
49
Figura 5.1: Piso -1 do edifício
Figura 5.2: Piso 0 do edifício
Figura 5.3: Piso 1 do edifício
Figura 5.4: Piso 2 do edifício
50
Seguem algumas observações importantes sobre este espaço.
Para termos ideia da escala do edifício, a largura total do espaço em cada piso é de aproximada-
mente 43 metros. Quanto aos custos de utilização dos acessos verticais, apresentados como um par
(custo de entrada, custo de transporte), estes são de: (10, 1), (1, 3), (1, 10) para o elevador, escadas
rolantes e escadas respetivamente. Como já foi explicado, estes custos são importantes durante a
execução do algoritmo para determinar qual o melhor acesso a ser usado em cada situação.
Note-se que as escadas (nas figuras do lado direito) são divididas em 2 grupos (A e B) dado que
estas ligam o piso -1 ao 0 (grupo B) e o piso 1 ao 2 (grupo A) mas são interrompidas entre o piso 0 e 1,
tratando-se por isso de escadas diferentes.
Foram ainda definidas três restrições neste mapa. A restrição r1 (marcada na figura 5.3 com o
sinal de proibido) é uma restrição definida recorrendo à tag <tag k="restriction" v="passagem
estreita"/> e por isso pode ser evitada ou não pelo utilizador através da interface da aplicação. Alguns
dos cenários de teste que se seguem vão evitar esta restrição. As outras duas restrições definidas são
características físicas imutáveis do espaço, ou seja, foram definidas de forma permanente no mapa e
não podem ser alteradas na interface. Uma é o caminho em frente à Saída da Exposição no piso 2
que só permite circular no sentido das setas (marcadas a vermelho na figura 5.4). A outra restrição foi
definida no piso 1 através da tag <tag k="forbid" v="up"/> marcada com o sinal de proibido na figura
5.3 (junto das escadas rolantes). Esta restrição foi definida nas escadas rolantes e impede que sejam
usadas para subir para o piso 2, ou seja, só é possível usá-las do piso 2 para o piso 1. Resta ainda
lembrar que, para além destas restrições específicas, temos ainda a possibilidade de evitar, através da
interface da aplicação, o uso de qualquer dos acessos verticais na sua totalidade.
Segue então um conjunto de cenários de teste que se consideram o mais abrangentes possível e
cuja descrição deve ser suficiente para se perceber que os algoritmos funcionam como pretendido em
todos os cenários.
5.1.1 Cenários de teste
� � �
Cenário de teste 1
Objetivo: Verificar que na presença de dois percursos distintos cuja distância total a percorrer é pró-
xima, então o percurso com menor número de mudanças de direção é o escolhido
Dados de entrada: Origem = Entrada/Saída Sul (piso 0), Destino = Livraria (piso 0)
Resultado esperado: O percurso devolvido deve ser o que passa pelo Quiosque central com uma
distância total de 31 metros e que só inclui duas mudanças de direção. Outra solução possível é o
percurso que passa por Maestro que, apesar de ter menos 1 metro de distância (30 metros no total),
deve ser evitado dado que tem maior número de mudanças de direção
Resultado obtido: “Distância total: 31 metros” |“De costas para Entrada/Saída Sul siga 20 metros
até encontrar Quiosque central” |“Vire à esquerda” |“Siga 6 metros” |“Vire à direita (direção a Livraria)”
51
|“Siga 5 metros e chegou ao destino” |“Chegou ao destino”
� � �
Cenário de teste 2
Objetivo: Verificar que o meio de acesso vertical escolhido é feito de forma inteligente
Dados de entrada1: Origem = Gelados (piso 0), Destino = Flores (piso 1)
Resultado esperado1: O percurso devolvido deve seguir pelas escadas rolantes e não pelo elevador.
O percurso pelo elevador tem a menor distância (25 metros) comparado com o percurso pelas escadas
rolantes (31 metros), no entanto, usar o elevador para subir apenas um piso tem um custo mais elevado
dado o possível tempo de espera pelo mesmo
Resultado obtido1: “Distância total: 31 metros” |“De costas para Gelados siga 4 metros” |“Vire à
direita (direção a Quiosque central)” |“Siga 11 metros até encontrar escadas rolantes” |“Suba para o
piso 1” |“De costas para escadas rolantes siga 9 metros (passe Roupa)” |“Vire à direita” |“Siga 3 metros”
|“Vire à direita (direção a Flores)” |“Siga 3 metros e chegou ao destino” |“Chegou ao destino”
Dados de entrada2: Origem = Gelados (piso 0), Destino = Praça Central (piso 2)
Resultado esperado2: Este cenário é idêntico ao anterior mas neste caso o deslocamento vertical é
de 2 pisos em vez de 1. Assim, o meio de acesso escolhido já deve ser o elevador
Resultado obtido2: “Distância total: 20 metros” |“De costas para Gelados siga 4 metros” |“Vire à
esquerda (direção a elevador)” |“Siga 6 metros até encontrar elevador” |“Suba para o piso 2” |“De costas
para elevador siga 8 metros e chegou ao destino” |“Chegou ao destino”
� � �
Cenário de teste 3
Objetivo: O percurso devolvido respeita os acessos verticais de sentido único
Dados de entrada1: Origem = Roupa (piso 1), Destino = Animais (piso 2)
Resultado esperado1: O percurso devolvido não deve seguir pelas escadas rolantes dado que a
restrição neste acesso vertical não permite subir para o piso 2
Resultado obtido1: “Distância total: 39 metros” |“De costas para Roupa siga 5 metros” |“Vire à
esquerda (direção a elevador)” |“Siga 14 metros até encontrar elevador” |“Suba para o piso 2” |“De
costas para elevador siga 14 metros (passe Praça Central)” |“Vire à direita (direção a Animais)” |“Siga 5
metros e chegou ao destino” |“Chegou ao destino”
Dados de entrada2: Origem = Animais (piso 2), Destino = Roupa (piso 1)
Resultado esperado2: O percurso devolvido deve seguir pelas escadas rolantes dado que a restrição
neste acesso vertical é no sentido inverso
52
Resultado obtido2: “Distância total: 17 metros” |“De costas para Animais siga 5 metros” |“Vire à direita
(direção a escadas rolantes)” |“Siga 3 metros até encontrar escadas rolantes” |“Desça para o piso 1”
|“De costas para escadas rolantes siga 3 metros” |“Vire à esquerda (direção a Roupa)” |“Siga 5 metros
e chegou ao destino” |“Chegou ao destino”
� � �
Cenário de teste 4
Objetivo: O percurso devolvido respeita as vias de sentido único
Dados de entrada1: Origem = Praça central (piso 2), Destino = Saída Exposição (piso 2)
Resultado esperado1: Não deve ser encontrado um caminho válido dado que o caminho em frente ao
destino é de sentido único na direção contrária
Resultado obtido1: “Erro: Não foi encontrado um caminho para o destino: Saída da Exposição”
Dados de entrada2: Origem = Saída Exposição (piso 2), Destino = Cinemas (piso 2)
Resultado esperado2: Como a restrição não influencia o sentido deste movimento, deve ser devolvido
o percurso para o destino sem qualquer problema
Resultado obtido2: “Distância total: 28 metros” |“De costas para Saída Exposição siga 4 metros”
|“Vire à esquerda (direção a Praça Central)” |“Siga 21 metros (passe Praça Central)” |“Vire à direita
(direção a Cinemas)” |“Siga 3 metros e chegou ao destino” |“Chegou ao destino”
� � �
Cenário de teste 5
Objetivo: Quando existe mais do que uma localização para o destino então deve ser devolvido o
percurso para a localização mais próxima
Dados de entrada: Origem = Flores (piso 1), Destino = WC (piso 1 em 2 locais possíveis)
Resultado esperado: O percurso devolvido deve ser na direção de Pesca dado que o outro WC se
encontra mais afastado (junto a Jogos)
Resultado obtido: “Distância total: 15 metros” |“De costas para Flores siga 3 metros” |“Vire à direita
(direção a Pesca)” |“Siga 8 metros (passe Pesca)” |“Vire à esquerda (direção a WC)” |“Siga 4 metros e
chegou ao destino” |“Chegou ao destino”
� � �
Cenário de teste 6
Objetivo: O percurso devolvido evita as restrições ativas sempre que possível
Dados de entrada: Origem = Flores (piso 1), Destino = WC (em 2 locais possíveis no piso 1), Evitar r1
53
Resultado esperado: Como o percurso para a WC mais próxima se encontra restrito (pela restrição
em frente a Pesca), o percurso deve seguir para a outra WC disponível no mesmo piso (junto a jogos)
Resultado obtido: “Distância total: 23 metros” |“De costas para Flores siga 3 metros” |“Vire à esquerda
(direção a elevador)” |“Siga 16 metros (passe Jogos)” |“Vire à direita (direção a WC)” |“Siga 4 metros e
chegou ao destino” |“Chegou ao destino”
� � �
Cenário de teste 7
Objetivo: Se o percurso devolvido obriga à passagem por uma restrição ativa, então o utilizador é
avisado que o resultado apresentado viola uma restrição
Dados de entrada: Origem = Costura (piso 1), Destino = Flores (piso 1), Evitar r1
Resultado esperado: Como o único percurso possível tem de passar obrigatoriamente pelo local
restrito (em frente a Pesca), o percurso devolvido deve ser o mesmo tal como se não existisse restrição,
a diferença é que o utilizador deve ser avisado que uma restrição não é respeitada
Resultado obtido: “Atenção! O caminho encontrado viola as restrições impostas!” |“Distância total:
15 metros” |“De costas para Costura siga 12 metros (passe Pesca)” |“Vire à esquerda (direção a Flores)”
|“Siga 3 metros e chegou ao destino” |“Chegou ao destino”
� � �
Cenário de teste 8
Objetivo: Verificar que são encontrados percursos mesmo quando é necessário recorrer a vários aces-
sos verticais para chegar ao piso de destino
Dados de entrada: Origem = Farmácia (piso 0), Destino = Cinemas (piso 2), Evitar elevador
Resultado esperado: A única forma de chegar ao destino é usar as escadas rolantes até ao piso 1 e
depois as escadas para o piso 2
Resultado obtido: “Distância total: 100 metros” |“De costas para Farmácia siga 4 metros” |“Vire à
esquerda (direção a Quiosque central)” |“Siga 13 metros até encontrar Quiosque central” |“Vire à direita
(direção a escadas rolantes)” |“Siga 9 metros até encontrar escadas rolantes” |“Suba para o piso 1” |“De
costas para escadas rolantes siga 9 metros (passe Roupa)” |“Vire à esquerda (direção a Desporto)”
|“Siga 22 metros (passe WC)” |“Vire à esquerda (direção a escadas)” |“Siga 4 metros até encontrar
escadas” |“Suba para o piso 2” |“De costas para escadas siga 4 metros” |“Vire à direita (direção a Praça
Central)” |“Siga 30 metros (passe Praça Central)” |“Vire à direita (direção a Cinemas)” |“Siga 3 metros e
chegou ao destino” |“Chegou ao destino”
� � �
54
Cenário de teste 9
Objetivo: São sugeridos os melhores lugares para o utilizador estacionar o seu veículo conforme o seu
destino final
Dados de entrada1: Estacionar junto a Farmácia
Resultado esperado1: Para ficar perto da farmácia deve ser sugerido ao utilizador que estacione na
zona azul junto do lugar com código 15B
Resultado obtido1: Parque [Piso -1, azul, 15B] a 18 metros
Dados de entrada2: Estacionar junto a Maestro
Resultado esperado2: Para ficar perto de Maestro deve ser sugerido ao utilizador que estacione na
zona vermelha junto do lugar com código 6Z
Resultado obtido2: Parque [Piso -1, vermelha, 6Z] a 20 metros
5.1.2 Análise dos testes
Como se pode constatar a aplicação desenvolvida obteve o resultado desejado em todos os testes. Os
cenários de teste anteriores permitem-nos ainda tirar várias conclusões sobre a aplicação desenvolvida.
Em primeiro lugar podemos contar com resultados que respeitam sempre as restrições impostas, quer
tenham sido definidas ao criar o mapa, como no caso das vias de sentido único horizontais (cenário
4) ou verticais (cenário 3), quer tenham sido definidas de forma dinâmica pelo utilizador através da
interface da aplicação (cenário 6). Mesmo quando não é possível obter resultados que respeitem todas
as restrições, a aplicação assume a responsabilidade de fornecer uma alternativa razoável (cenário 7).
Podemos notar também que a aplicação é capaz de procurar percursos complexos quando a disposição
do espaço físico assim o exige, tal como pode ser verificado no cenário 8 onde não existem ligações
diretas entre pisos para o percurso em questão.
É de destacar ainda a capacidade de tomar decisões inteligentes como nos casos em que são
evitadas mudanças de direção desnecessárias (cenário 1), a escolha do meio de acesso vertical é feita
de forma informada (cenário 2), a casa de banho mais próxima é encontrada sempre primeiro (cenário
5) e é sugerido o lugar de estacionamento mais próximo do destino final (cenário 9).
5.2 Desempenho
Apesar do mapa usado na secção anterior ser o ideal para testar a correção dos algoritmos, um mapa
de maiores dimensões é mais indicado para testar o desempenho dos algoritmos. Tendo isto em conta,
para esta secção foi criado um novo mapa, desta vez inspirado num espaço real: o centro comercial
Colombo. De facto, o centro comercial Colombo é um bom teste para o desempenho da aplicação dado
que é constituído por 3 pisos e cerca de 340 lojas 1.
1https://en.wikipedia.org/wiki/Colombo_Centre
55
Com a ajuda do JOSM foram necessárias pouco mais de 3 horas para desenhar o mapa de todo o
centro comercial. Só não foram marcados os lugares de estacionamento dado que não constam nos
diretórios online. O resultado foi um mapa em XML com a representação de 3 pisos e 285 pontos de
interesse. No total o ficheiro XML conta com 592 nós, necessários para representar não só os pontos
de interesse, mas também as vias de circulação.
Para efetuar as medições do uso de CPU e de memória RAM, o primeiro passo foi ligar o dispositivo
por USB a um computador portátil capaz de executar as ferramentas ADB (Android Debug Bridge) e
DDMS (Dalvik Debug Monitor Server). Depois, para medir a utilização de CPU executámos o comando
“adb shell top” num terminal no computador portátil. O comando anterior permite executar o comando
“top” no dispositivo móvel e este permite visualizar a utilização de CPU (e outros dados) de todos os
processos a serem executados no dispositivo. De seguida, durante 3 minutos procedemos ao uso inten-
sivo da aplicação para calcular vários percursos, descarregar mapas, visualizar o diretório, entre outros.
Durante este processo, no terminal foram registados os valores de utilização de CPU e verificámos que
o valor máximo atingido foi de 12% (que coincide com os instantes de carregamento do ficheiro com o
mapa do espaço e com os instantes de procura de percursos), sendo que na maioria das vezes o valor
registado foi de 5% ou até de 0% em idle state. É de destacar que a aplicação em nenhum momento
sobrecarregou o dispositivo em termos de CPU.
Para medir a utilização de memória RAM foi usado o DDMS. Esta ferramenta apresenta a quantidade
total de memória atribuída à aplicação bem como a quantidade em uso a cada instante. Como durante a
execução de uma aplicação a quantidade de memória atribuída é sempre crescente, a qualquer instante
podemos consultar a quantidade máxima de memória que foi utilizada. Assim, tal como nas medições
de CPU, após alguns minutos de utilização verificámos que a quantidade total de memória utilizada
atingiu um máximo de 14,660MB sendo que destes, 5,966MB se encontravam livres (cerca de 40%).
Estes valores de utilização de memória RAM podem-se considerar muito razoáveis (15MB) tendo em
conta a capacidade dos dispositivos usados hoje em dia e o facto de terem sido incluídos alguns ícones
no menu principal da aplicação.
Quanto aos tempos de execução, importa essencialmente ter em conta dois momentos chave du-
rante a execução da aplicação. Um é o momento em que o ficheiro com o mapa do espaço é inici-
almente carregado e as respetivas estruturas de dados são inicializadas (o que inclui a execução do
algoritmo para criar o grafo), o outro é o momento em que o utilizador obtém instruções (o que inclui
procura de percursos e geração de instruções). Por este motivo, procedemos ao registo dos tempos
de execução em milissegundos dos blocos de código correspondentes a estes momentos recorrendo à
função Java System.currentTimeMillis() que devolve a hora atual em milissegundos. Com a diferença
dos valores devolvidos pela função antes e depois da execução do bloco de código correspondente
sabemos o tempo de execução de cada um.
Depois da utilização da aplicação durante alguns minutos verificámos que: o tempo de carrega-
mento inicial do mapa manteve-se quase sempre próximo dos 500ms; quanto à obtenção de instruções,
verificou-se uma grande variação nos tempos registados dependendo da origem e destino escolhidos.
No entanto, o tempo máximo de execução nunca ultrapassou os 160ms dado que a procura de percur-
56
sos nunca ultrapassou os 80ms tal como aconteceu com a geração de instruções que também nunca
ultrapassou os 80ms. É importante assinalar que estes tempos de execução se podem considerar
desprezáveis dado que o utilizador comum os perceciona como instantâneos.
Ao contrário do que se pensava, a procura de percursos (baseada no algoritmo de Dijkstra) acabou
por registar valores muito bons (abaixo dos 60ms em todas as pesquisas). O motivo pelo qual a geração
de instruções atinge algumas vezes o mesmo tempo de execução da procura de percursos é devido ao
algoritmo de procura de pontos de referência a incluir nas instruções (que também recorre ao algoritmo
de Dijkstra). Relembramos que para encontrar os pontos de referência é necessário efetuar procuras
através do algoritmo de Dijkstra em cada segmento em linha reta em que o percurso original foi dividido.
Conclui-se que a soma dos tempos de execução das procuras em cada um destes segmentos pode
atingir o mesmo valor do tempo de execução do percurso original e portanto seria possível melhorar
mais os tempos de execução se não fossem incluídos pontos de referência nas instruções.
O bom desempenho da aplicação é comprovado pela boa fluidez com que se consegue fazer a
transição entre os vários ecrãs, mesmo durante a visualização das instruções em que é desenhado um
mapa 2D. O único instante mais crítico em termos de desempenho é o carregamento do ficheiro com o
mapa (operação que demora cerca de 500ms), que confirma que foi uma boa decisão de implementa-
ção proceder ao carregamento do mesmo apenas uma vez durante a execução da aplicação.
57
58
Capítulo 6
Conclusões
Este trabalho foi motivado pela lacuna que existe atualmente em termos de sistemas de encaminha-
mento para o interior de edifícios. Hoje em dia a maioria dos dispositivos móveis já traz incluído um
sistema GPS; isso equivale a dizer que o problema do encaminhamento ao ar livre está resolvido com
um só dispositivo e uma aplicação, para todo o planeta. Já em edifícios o mesmo não se verifica. Da
análise do trabalho relacionado concluímos que a maioria das soluções existentes requerem que o dis-
positivo do utilizador cumpra vários requisitos de hardware. A escolha de uma destas soluções não
é óbvia e quase sempre implica custos elevados para um administrador de um espaço que vê ainda
serem excluídos os utilizadores que não cumpram os requisitos.
O que se pretendia com o nosso trabalho era resolver este problema oferecendo uma solução que
beneficiasse quer o utilizador, quer o administrador de um espaço. O caminho para essa solução re-
queria então uma abordagem alternativa à dos sistemas anteriores. Deste modo, a utilização de um
sistema de localização foi substituído por um mecanismo de localização assistido onde o utilizador iden-
tifica um elemento que se distingue dentro do edifício e, através desse elemento, o sistema determina
a localização do utilizador. A desvantagem desta opção é a impossibilidade de detetar a localização do
utilizador de forma automática; no entanto, tem a vantagem de reduzir os custos para o administrador
do espaço e ainda de aumentar a generalidade da solução que abrange assim um maior número de
utilizadores. Apesar disso, consideramos que esta opção pode ser problemática no contexto do enca-
minhamento de veículos dado que o utilizador tem as mãos ocupadas enquanto conduz, não podendo
interagir com a aplicação. Por este motivo o sistema aqui proposto não encaminha veículos passo a
passo apesar de contar com funcionalidades de apoio ao estacionamento.
Em termos de encaminhamento foi tido o cuidado de não devolver um percurso qualquer mas antes
um que tem em atenção as limitações do espaço e eventuais restrições impostas pelo utilizador. Este
percurso é desenhado num mapa 2D que por si só já orienta o utilizador. Mas são também apresentadas
instruções textuais que são simples e só aparecerem nos momentos chave, ou seja, nos pontos de
decisão. Estas instruções textuais tiveram de ser bem pensadas; em nenhum ponto podíamos depender
de conceitos demasiado complexos pois isso iria trazer dificuldades ao administrador do espaço que
seria obrigado a defini-los. Na verdade existem apenas três conceitos essenciais para o funcionamento
59
do sistema que são: pisos, pontos de interesse e meios de acesso verticais.
Consegue-se assim simplificar significativamente o processo de construção de um mapa benefici-
ando também o administrador do espaço que mesmo sem ter definido conceitos como cruzamentos
ou pontos de referência os vê incluídos nas instruções textuais. Acabamos assim por permitir que o
administrado defina mapas através dum processo simples. Uma prova deste facto é termos conseguido
construir para os nossos testes um mapa de um centro comercial de grandes dimensões em poucas
horas. Mesmo depois da construção do mapa tivemos o cuidado de não exigir meios de armazena-
mento e distribuição complexos; basta um simples servidor de ficheiros. Por último, não deixámos de
pensar nos utilizadores que se deslocam de veículo para estes espaços. Estes podem voltar facilmente
ao seu veículo indicando apenas onde este foi estacionado. Até no momento da chegada ao parque de
estacionamento, desde que o utilizador tenha um destino alvo bem definido na zona pedestre, a aplica-
ção consegue indicar ao utilizador qual o melhor lugar em que deve estacionar. Estas funcionalidades
não requerem que o administrador do espaço construa todo o mapa do seu parque de estacionamento;
basta que indique os seus lugares de estacionamento junto dos meios de acessos a outros pisos.
Neste trabalho foram ainda realizados testes que provaram a correção dos algoritmos e ainda que
estes não são exigentes em termos de recursos. O protótipo desenvolvido provou assim decidir cor-
retamente, mesmo quando posto à prova em cenários desafiantes. Se possível, devem também ser
feitos testes com utilizadores reais em vários tipos de edifícios. O feedback obtido deve ser usado para
melhorar a aplicação sempre que possível.
A aplicação tem ainda bastantes aspetos a melhorar. Entre eles convém lembrar que os espaços
não se mantêm estáticos. Deve por isso ser criado um mecanismo que permita ao utilizador atualizar um
mapa para a versão mais recente de forma simples. Podemos também pensar em incluir sistemas de
localização desde que se tenha o cuidado de manter a aplicação funcional independentemente destes.
Por exemplo, um sistema de localização, mesmo que tenha baixa precisão pode sempre contribuir para
filtrar a lista de localizações, ficando esta apenas com as localizações que se encontrem num raio
inferior ao erro máximo desse sistema.
A aplicação deve também poder ser portada para outras plataformas de modo a chegar ao maior
número possível de utilizadores. Isso é facilitado dado que o sistema aqui apresentado é totalmente
livre e não depende de nenhuma biblioteca externa. Todo o código fonte inclui ainda testes de unidade
que podem ser usados como ponto de partida para o desenvolvimento na nova plataforma.
Finalmente, fica o desejo que este trabalho seja continuado e mantenha a mesma linha orientadora,
onde as decisões são tomadas, primeiro a pensar nos seus utilizadores, e só depois na tecnologia
usada.
60
Bibliografia
[1] M. May and C. LaPierre. Assistive Technology for Visually Impaired and Blind People, chapter
Accessible Global Positioning System (GPS) and Related Orientation Technologies, pages 261–
288. Springer London, 2008.
[2] A. Sheinker, B. Ginzburg, N. Salomonski, L. Frumkis, B.-Z. Kaplan, and M. B. Moldwin. A method
for indoor navigation based on magnetic beacons using smartphones and tablets. Measurement,
81:197 – 209, 2016.
[3] A. Mulloni, D. Wagner, I. Barakonyi, and D. Schmalstieg. Indoor positioning and navigation with
camera phones. IEEE Pervasive Computing, 8:22–31, 2009.
[4] H. Wang, S. Sen, A. Elgohary, M. Farid, M. Youssef, and R. R. Choudhury. No need to war-drive:
Unsupervised indoor localization. In Proceedings of the 10th International Conference on Mobile
Systems, Applications, and Services, pages 197–210. ACM, 2012.
[5] V. Honkavirta, T. Perala, S. Ali-Loytty, and R. Piche. A comparative survey of wlan location finger-
printing methods. In Positioning, Navigation and Communication, 2009. WPNC 2009. 6th Workshop
on, pages 243–251, 2009.
[6] Z. Turgut, G. Z. G. Aydin, and A. Sertbas. Indoor localization techniques for smart building environ-
ment. Procedia Computer Science, 83:1176 – 1181, 2016.
[7] P. Bahl and V. N. Padmanabhan. Radar: an in-building rf-based user location and tracking system.
pages 775–784. Institute of Electrical and Electronics Engineers, Inc., 2000.
[8] S. hoon Jung, S. Lee, and D. Han. A crowdsourcing-based global indoor positioning and navigation
system. Pervasive and Mobile Computing, 31:94 – 106, 2016.
[9] Y. Li, P. Zhang, H. Lan, Y. Zhuang, X. Niu, and N. El-Sheimy. A modularized real-time indoor
navigation algorithm on smartphones. In Indoor Positioning and Indoor Navigation (IPIN), 2015
International Conference on, pages 1–7, 2015.
[10] C. Zhang, K. P. Subbu, J. Luo, and J. Wu. Groping: Geomagnetism and crowdsensing powered
indoor navigation. IEEE Transactions on Mobile Computing, 14:387–400, 2015.
[11] D. Han, S. Lee, and S. Kim. Kailos: Kaist indoor locating system. In Indoor Positioning and Indoor
Navigation (IPIN), 2014 International Conference on, pages 615–619, 2014.
61
[12] M. Zhao, R. Gao, J. Zhu, T. Ye, F. Ye, Y. Wang, K. Bian, G. Luo, and M. Zhang. Veloc: Finding your
car in the parking lot. In Proceedings of the 12th ACM Conference on Embedded Network Sensor
Systems, pages 346–347. ACM, 2014.
[13] M. Löchtefeld, S. Gehring, J. Schöning, and A. Krüger. Pinwi: Pedestrian indoor navigation without
infrastructure. In Proceedings of the 6th Nordic Conference on Human-Computer Interaction: Ex-
tending Boundaries, pages 731–734. ACM, 2010.
[14] R. Wasinger, K. Gubi, J. Kay, B. Kummerfeld, M. Fry, and T. Kuflik. Roughmaps a generic platform
to support symbolic map use in indoor environments. In Indoor Positioning and Indoor Navigation
(IPIN), 2012 International Conference on, pages 1–10, 2012.
[15] E. Wang and W. Yan. inavigation: an image based indoor navigation system. Multimedia Tools and
Applications, 73:1597–1615, 2014.
[16] C. Anagnostopoulos, V. Tsetsos, P. Kikiras, and S. Hadjiefthymiades. Ontonav: a semantic indoor
navigation system, 2005.
[17] S. M. LaValle. Planning Algorithms. Cambridge University Press, 1st edition, 2006.
ISBN:0521862051.
[18] J. F. Kurose and K. W. Ross. Computer networking : a top-down approach featuring the Internet.
Addison-Wesley, 1st edition, 2001. ISBN:0-201-47711-4.
[19] S. Winter. Modeling costs of turns in route planning. GeoInformatica, 6:345–361, 2002.
62
Anexo A
Cenário de utilização
O utilizador antes de sair de casa usa a sua ligação à rede para obter o mapa do centro comercial
onde pretende comprar a comida para a sua tartaruga. O utilizador abre a aplicação e descarrega o
mapa introduzindo o endereço (figura A.1) do mesmo que encontrou online. Quando chega ao parque
de estacionamento do centro comercial, antes de estacionar, o utilizador abre a aplicação e escolhe o
mapa descarregado anteriormente (figura A.2), definindo que quer apenas usar o elevador (figura A.3)
visto que leva o bebé no carrinho. De seguida abre o diretório (figura A.4) e seleciona “Animais”. No
ecrã seguinte o utilizador escolhe a opção “Estacionar aqui perto” (figura A.5). Como resultado obtém
a lista da figura A.6 que lhe indica que deve estacionar no piso -1, zona vermelha, lugar 6Z. O utilizador
conduz até ao lugar sugerido e estaciona o veículo guardando a informação do lugar (figura A.7). De
seguida o utilizador procura um percurso desde o lugar de estacionamento até à loja “Animais” (figura
A.8). Nas figuras A.9 a A.13 são mostradas as instruções apresentadas ao utilizador enquanto este se
desloca até à loja “Animais”. Finalmente, depois de se servir na loja “Animais” o utilizador seleciona a
opção “Voltar ao veículo” do menu principal cujo ecrã pode ser visto na figura A.14.
63
Figura A.1: Ecrã descarregar mapa
64
Figura A.2: Ecrã de gestão de mapas
65
Figura A.3: Restrições
66
Figura A.4: Diretório
67
Figura A.5: Opções de um destino
68
Figura A.6: Ecrã resultados para estacionar perto
69
Figura A.7: Ecrã estacionar
70
Figura A.8: Ecrã procurar rota
71
Figura A.9: Instruções 1/5
72
Figura A.10: Instruções 2/5
73
Figura A.11: Instruções 3/5
74
Figura A.12: Instruções 4/5
75
Figura A.13: Instruções 5/5
76
Figura A.14: Ecrã menu principal
77
78
Recommended