Specializarea Informatic a [618470]

Ministerul Educat ¸iei Nat ¸ionale¸
Universitatea ”OVIDIUS” Constant ¸a
Facultatea de Matematic ˘a s ¸i Informatic ˘a
Specializarea Informatic ˘a
Sistem mobil pentru servicii de
asistent ,a turistic ˘a cu localizarea rutelor
de transport urban
Lucrare de licent ¸ ˘a
Coordonatori s ¸tiint ¸ifici:
Lect. univ. dr. S ¸ erban Cristina
Conf. univ.dr. Puchianu Crengut ¸a
Absolvent: [anonimizat] ¸a
2018

Cuprins
Cuprins i
List˘a de figuri 1
1 Introducere 3
1.1 Context proiect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2 Motivat,ie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.3 Obiectivele sistemului software ”Tourist helper” . . . . . . . . . . . . . 4
1.4 Cerint,e sistem ”Tourist Helper” . . . . . . . . . . . . . . . . . . . . . . 5
1.4.1 Cerint,e funct,ionale . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.4.2 Cerint,e non-funct,ionale . . . . . . . . . . . . . . . . . . . . . . 6
1.5 Structura lucr ˘arii de licent,˘a . . . . . . . . . . . . . . . . . . . . . . . . 6
2 Tehnologii s,i elemente teoretice utilizate 7
2.1 Node JS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.2 JAVA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.3 Android . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.4 MYSQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.5 HTTP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
i

Cuprins Cuprins
2.6 JSON . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.7 Rutarea . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.8 GPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.9 WebSockets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.10 MVC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.11 Google Maps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.12 Algoritmul A* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
3 Proiectare s,i implementare 13
3.1 Arhitectura general ˘a a sistemului . . . . . . . . . . . . . . . . . . . . . 13
3.2 Diagrama Use-Case . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.3 Serverul . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.3.1 Implementarea serverului . . . . . . . . . . . . . . . . . . . . . 19
3.4 Aplicat,ia Android . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
3.4.1 Downloadarea s,i afis,area datelor . . . . . . . . . . . . . . . . . 40
3.4.2 Design-ul Interfet,ei . . . . . . . . . . . . . . . . . . . . . . . . . 43
3.4.3 Crearea fragmentelor . . . . . . . . . . . . . . . . . . . . . . . 45
3.5 Proiectarea bazei de date . . . . . . . . . . . . . . . . . . . . . . . . . 54
3.5.1 Diagrama Entit ˘at,i-Asociat,ii (DEA) . . . . . . . . . . . . . . . . . 55
3.5.2 Schema MMED (Modelul matematic elementar al datelor) . . 56
3.5.3 Algoritmul Cheilor . . . . . . . . . . . . . . . . . . . . . . . . . 58
3.5.4 MRD (Modelul Relational al Datelor) . . . . . . . . . . . . . . . 60
3.6 Algoritmul de rutare . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
3.6.1 Alegerea funct,iei euristice . . . . . . . . . . . . . . . . . . . . . 63
3.6.2 Implementarea algoritmului A* . . . . . . . . . . . . . . . . . . 65
4 Testarea sistemului 73
5 Concluzii 76
ii

Cuprins Cuprins
Bibliografie 78
iii

List˘a de figuri
2.1 Arhitectura android [1] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
3.1 Arhitectura de nivel ˆınalt a sistemului . . . . . . . . . . . . . . . . . . . . . 14
3.2 Diagrama Use-Case sistem . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.3 Model View Controller Pattern [2] . . . . . . . . . . . . . . . . . . . . . . . 19
3.4 Arhitectura node.[3] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.5 Dependente Server. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
3.6 Folder Structure API. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
3.7 Rute api. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
3.8 Comunicare websockets.[4] . . . . . . . . . . . . . . . . . . . . . . . . . . 32
3.9 Permisiuni Aplicatie. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
3.10 Flowchart turist . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
3.11 Flowchart sofer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
3.12 Exemplu interfat,˘a s,ofer. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
3.13 Componenta chat. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
3.14 Vizualizare liste. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
3.15 Creare lista. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
3.16 Diagrama de clase PathFinding . . . . . . . . . . . . . . . . . . . . . . . . 65
3.17 Raspuns JSON rute . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
3.18 Exemplu algoritm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
1

List˘a de figuri List ˘a de figuri
Abstract
This paper proposes an Android application for mobile phones that aims to gu-
ide tourists through visited cities. It calculates the optimal path with a pathfinding
algorithm that uses accessible public transport routes. The ”Tourist helper” applica-
tion provides information on bus routes and displays possible tourist attractions to
visit while also integrating a social component through which tourists can interact
with each other. The system uses GPS services and websockets to locate turists
and buses in real time. The bus tracking is done within the application through the
drivers who send their latitude and longitude to the server. At the same time, with
the same application, tourists can track the buses on any bus route, in real time.
The user gets flexibility in planning trips using this application to decide which bus
to take and when, the waiting time being reduced this way.
Rezumat
Aceast ˘a lucrare propune o aplicat,ie Android pentru telefoanele mobile care are
c˘a scop ghidarea turis,tilor prin oras,ele vizitate. Aceasta calculeaz ˘a drumul optim cu
un algoritm de pathfinding care se foloses,te de rutele de transport ˆın comun acce-
sibile. Aplicat,ia ”Tourist helper” furnizeaz ˘a informat,ii despre traseele autobuzelor s,i
afis,eaz˘a posibile obiective turistice de vizitat, integr ˆandˆın acelas,i timp s,i o compo-
nent˘a social ˘a prin care turis,tii pot interact,iona ˆıntre ei. Sistemul utilizeaz ˘a servicii
GPS s,i protocolul websockets ˆın vederea localiz ˘ariiˆın timp real a turis,tilor s,i a auto-
buzelor. Urm ˘arirea locat,iei autobuzelor se face ˆın cadrul aplicat,iei prin intermediul
s,oferilor care ˆıs,i trimit latitudinea s,i longitudinea spre server. Totodat ˘a, prin aceeas,i
aplicat,ie turis,tii pot urm ˘ari autobuzele de pe orice traseu, ˆın timp real. Utilizato-
rul obt,ine flexibilitate ˆın planificarea c ˘al˘atoriilor folosind aceast ˘a aplicat,ie, pentru a
decide ce autobuz s ˘a ia s,i cˆand, timpul de as,teptare al turistului fiind redus.
2

Capitolul 1
Introducere
1.1 Context proiect
Contextul realiz ˘arii aplicat,iei propuse este acela al circulat,iei cˆat mai intense a
oamenilor pe cuprinsul ˆıntregului glob p ˘amˆantesc s,i a dorint,ei lor de a ajunge c ˆat
mai rapid ˆın orice locat,ie, cu costuri minime de timp s,i de bani. Oameni ˆıs,i doresc
experient,e interesante s,i memorabile s,i prin c ˘al˘atorii le pot satisface. De la vizitarea
familiei s,i a prietenilor p ˆan˘a la descoperirea de peisaje s,i culturi noi, oameni r ˘amˆan
cu amintiri de durat ˘a din timpul c ˘al˘atoriilor.
Turismul a cunoscut o mare dezvoltare ˆın ultima vreme, iar o aplicat,ie us,or de
accesat, conectat ˘a la transportul ˆın comun dintr–o localitate, care poate ˆındruma
utilizatorii cum s ˘a circule ˆın interiorul acesteia, care s ˘a le prezinte obiectivele de
vizitat s,i care s ˘aˆıi poat ˘a pune ˆın leg ˘atura cu alte grupuri de turis,ti, realiz ˆand schim-
buri de idei s,i impresii, este c ˆat se poate de util ˘a s,i binevenit ˘a. Iar c ˆand aceast ˘a
aplicat,ie foloses,te un sistem de operare din ce ˆın ce mai r ˘aspˆandit s,i laˆındem ˆana
oricui prin intermediul smartphone-ului, cum este Android, poate deveni o solut,ie
rapid ˘a s,i convenabil ˘a la problema circulat,iei s,i orient ˘ariiˆıntr–un oras,.
Smartphone-urile au devenit din ce ˆın ce mai folosite ˆın viat,a omului modern,
acestea fiind foarte r ˘aspˆandite. Acest domeniu se afl ˘aˆıntr-o continu ˘a cres,tere care
nu da semn de oprire, majoritatea populat,iei planetei av ˆand acces la un smartphone
fie Android fie iphone care este folosit ˆın scopul realiz ˘arii a multiple servicii precum
socializarea, plata online, consumul de media.
Avˆandˆın vedere c ˘a aproape oricine det,ine un smartphone ˆın ziua de azi, lu-
crarea ˆıs,i propune implementarea unei aplicat,ii mobile care ˆıs,iˆındrum ˘a utilizatorii
printr-un oras,, oferindu-le calcularea de rute optime utiliz ˆand traseele firmelor de
transport din oras,ul respectiv s,i urm ˘arirea ˆın timp real a mijloacelor de transport.
Aplicat,iaˆıi permite fiec ˘arui utilizator s ˘a publice liste cu locat,ii turistice pe care le
consider ˘a interesante sau s ˘a vizualizeze listele create de alt,i turis,ti. De asemenea
un utilizator poate comunica cu grupuri de turis,ti, prin componenta social ˘a.
3

Introducere Motivat,ie
Astfel prin folosirea acestei solut,ii software turistul respectiv c ˆas,tiga timp ˆın plus
de vizitare, dorindu-se mics,orarea timpului petrecut pentru c ˘autarea locat,iilor de vizi-
tat s,i a traseelor c ˘atre acestea s,i folosirea acestui timp salvat ˆın explorarea oras,ului.
Aplicat,ia are o interfat,˘a intuitiv ˘a s,i ofer ˘a un mod rapid s,i laˆındemn ˘a pentru desco-
perirea punctelor de interes din zon ˘a s,i pentru orientarea printr-un oras,str˘ain. ˆIn
plus dac ˘a dores,te s˘a socializeze, turistul poate comunica cu alt,i utilizatori pentru a
face schimburi de p ˘areri s,i impresii.
Aceast ˘a aplicat,ie este un ghid turistic virtual s,i are c ˘a scop imbun ˘at˘at,irea experie-
nt,ei de vizitare a unui oras,str˘ain fiind mai ales folositoare acelor persoane care nu
s-au preg ˘atit dinainte de vizit ˘a.
1.2 Motivat ,ie
ˆIn ultimul timp se observ ˘a o cres,tere ˆın domeniul de dezvoltare a aplicat,ilor
android, la momentul actual mult,i utilizatori prefer ˆand s ˘a foloseasc ˘a o aplicat,ie pe
telefon dedicat ˘a dec ˆat un site web, multe site-uri web av ˆand s,i un echivalent ˆın form ˘a
de aplicat,ie mobil ˘a.
Am ales aceast ˘a tem ˘a pentru c ˘aˆımi place s ˘a c˘al˘atoresc. Un alt motiv a fost
dorint,a de ˆınv˘at,are s,i aprofundare a procesului de dezvoltare a aplicat,iilor pe An-
droid, deoarece acest sistem de operare este ˆın cres,tere s,i foarte r ˘aspˆandit. De
asemenea am vrut s ˘a integrez s,i un server pentru c ˘a din ce ˆın ce mai multe aplicat,ii
cont,in s,i o component ˘a de backend. Un dezvoltator trebuie s ˘a s,tie cum s ˘a interact,io-
neze cu un server s,i s˘aˆınt,eleag ˘a modul de funct,ionare al acestuia atunci c ˆand cre-
eaz˘a aplicat,ii.
Aplicat,ia a fost implementat ˘a pe Android pentru c ˘a acesta este unul din cele mai
populare sisteme de operare pe mobil. Acest lucru asigur ˘a desc ˘arcarea s,i instalarea
aplicat,iei de c ˆat mai mult,i utilizatori posibili. Smartphone-urile sunt des folosite ˆın
scopul localiz ˘arii vehiculelor pentru c ˘a au un dispozitiv GPS atas,at.
Motivat,ia implement ˘arii propriului algoritm de rutare a fost acea c ˘a api-ul google
maps impune limit ˘ari asupra num ˘arulului de cereri f ˘acute de c ˘atre o aplicat,ie spre
serverele lor (de exemplu 2500 de cereri pe zi maxim pentru directions api), iar prin
implementarea algoritmului A* se evit ˘a aceste restrict,ii.
1.3 Obiectivele sistemului software ”Tourist
helper”
Obiectivul principal realizat de c ˘atre sistemul software este ˆındrumarea utiliza-
torilor c ˘atre locat,iile turistice ale unui oras,, prin intermediul unei aplicat,ii Android.
Acest lucru se realizeaz ˘a cu ajutorul algoritmului de rutare A*.
4

Introducere Cerint,e sistem ”Tourist Helper”
Un alt obiectiv la fel de important este crearea unei solut,ii cu costuri mici de
instalare s,i mentenant,˘a pentru vizualizarea ˆın timp real a autobuzelor necesare ˆın
scopul atingerii destinat,iei dorite.
Pentru a sugera utilizatorului locat,ii de vizitat, aplicat,ia identific ˘a oras,ulˆın care
se afl ˘a acesta s,i ii afis,eaz˘a liste de obiective turistice din oras,ul respectiv, acest
lucru reprezent ˆand un alt obiectiv important.
De asemenea pe l ˆang˘a vizualizarea de liste un utilizator ˆıs,i poate crea propria
list˘a pentru a distribui locat,iile pe care le consider ˘a interesante sau mai put,in cunos-
cute.
Un alt obiectiv este oferirea suportului pentru comunicare ˆıntre turis,ti, struc-
turat ˘a pe grupuri, afis,ˆandu-se doar grupurile din oras,ulˆın care se afl ˘a utilizatorul
respectiv.
Realizarea sistemului a constat ˆın:
.crearea unui server care expune un API pentru desc ˘arcarea s,iˆınc˘arcarea de
resurse, folosind o baza de date MYSQL. Server-ul suport ˘a comunicarea din-
tre client,iˆın timp real.
.dezvoltarea aplicat,iei android care ofer ˘a utilizatorului o interfat,˘a intuitiva s,i
us,or de folosit ˆın scopul acces ˘arii tuturor funct ¸ionalit ˘at ¸ilor descrise ˆın cerint,ele
funct,ionale.
1.4 Cerint ,e sistem ”Tourist Helper”
1.4.1 Cerint ,e funct ,ionale
.Localizare mijloace transport : Sistemul trebuie s ˘aˆıi ofere posibilitatea uti-
lizatorului de a vizualiza pe o harta locat,iileˆın timp real a autobuzelor care
trebuie folosite pentru a atinge o destinat,ie. Pentru a realiza acest lucru tre-
buie s ˘a existe s,i o port,iune a aplicat,iei dedicat ˘a s,oferilor care se vor autentifica
cu un anumit autobuz s,iˆıs,i vor trimite locat,ia (prin intermediu unui server).
.Vizualizare s,i creare de liste : Utilizatorii au posibilitatea s ˘a vizualizeze s,i s˘a
selecteze o lista de locat,ii turistice ˆın scopul vizitei. De asemenea pot sa ˆıs,i
creeze s,i s˘aˆıs,i publice propria lista.
.Grupuri de chat : Pentru a socializa ˆıntre ei turis,tii pot comunica ˆın timp real
prin grupuri de chat, create anterior de c ˘atre alt,i utilizatori ˆın oras,ul respectiv.
Totodat ˘a fiecare turist ˆıs,i poate crea propriul grup.
.Calculare drum optim : Pentru a afla drumul optim c ˘atre o locat,ie, folosind
rutele de transport ˆın comun disponibile sistemul va utiliza algoritmul de rutare
A*
.Creare cont : un utilizator ˆıs,i poate crea un cont prin specificarea unui user-
name s,i a unei parole
5

Introducere Structura lucr ˘arii de licent,˘a
1.4.2 Cerint ,e non-funct ,ionale
.Utilizabilitate : Aplicat,ia trebuie sa fie us,or de folosit, oferindu-i utilizatorului o
interfat,˘a intuitiva s,i rapida. De asemenea prin faptul c ˘a serverul expune un api
acesta poate fi reutilizat de pe orice client fie smartphone,browser, program
desktop etc.
.Comunicarea : Transmiterea de date dintre server s,i client este f ˘acut˘a prin
intermediul protocolului HTTP . Serverul trebuie de asemenea sa suporte co-
municarea ˆın timp real dintre un num ˘ar mare de client,i.
.Performant,˘a: Aplicat,ia trebuie s ˘a r˘aspund ˘aˆıntr-un mod rapid la select,ia unei
funct,ionalit ˘at,i din interfat,a. R˘aspunsurile primite de la server vor avea o latent,˘a
mic˘a, mai ales ca acesta este implementat folosind tehnologia Node.js.
.Us,urint,a ad ˘augare cont,inut: Ad ˘augarea suportului pentru un nou oras,se
poate face us,or prin inserarea informat,iilor despre rutele de transport ˆın comun
ale oras,ului respectiv ˆın baza de date.
1.5 Structura lucr ˘arii de licent ,˘a
Primul capitol cont,ine contextul proiectului s,i descrie toate cerint,ele s,i obiecti-
vele pe care sistemul trebuie s ˘a leˆındeplineasc ˘a.
Al doilea capitol prezint ˘a o scurt ˘a descriere a tehnologiilor s,i a elementelor teo-
retice folosite.
Cel de al treilea capitol descrie ˆınˆıntregime procesul de modelare s,i implemen-
tare a sistemului. Aici este prezentat algoritmul de rutare s,i arhitectura sistemului,
ˆımpreun ˘a cu toate componentele care o alc ˘atuiesc.
ˆIn capitolul patru este prezentat modul ˆın care sistemul a fost testat, pentru a
m˘a asigura c ˘a acesta funct,ioneaz ˘a cum trebuie.
Ultimul capitol cont,ine concluziile formate ˆın urma realiz ˘ari acestei lucr ˘ariˆımpreu-
n˘a cu posibile dezvolt ˘ari ulterioare.
6

Capitolul 2
Tehnologii s ,i elemente teoretice
utilizate
2.1 Node JS
Node.js [5] este o platform ˘a care permite ca limbajul JavaScript s ˘a fie folosit ˆın
afara browserelor web, pentru crearea de aplicat,ii server-side robuste s,i scalabile.
Aceast ˘a tehnologie a ap ˘arutˆın anul 2009 s,i a fost scris ˘a de Ryan Dahl. Node.js este
cross-platform, lightweight,bazat pe evenimente s,i utilizeaz ˘a un model non-blocking
I/O care este potrivit pentru aplicat,ii real-time. Este scris ˆın C, C++,JavaScript s,i
utilizeaz ˘a motorul JavaScript V8(folosit de asemenea de chrome), construind un
ˆınvelis,ˆın jurul acestuia pentru a oferi aplicat,ii de ret,ea rapide. Node.js aduce pro-
gramarea bazat ˘a pe evenimente la serverele web, permit,ˆand dezvoltarea de servere
web rapide folosind JavaScript s,i o colect,ie de ”module” care manipuleaz ˘a diferite
funct,ionalit ˘at,i de baz ˘a. Modulele externe care nu vin cu instalarea node sunt pro-
curate prin intermediul npm(node package manager) care constituie cel mai mare
ecosistem de libr ˘arii open source din lume. Dezvoltatorii pot crea servere scalabile
f˘ar˘a a folosi threading, utiliz ˆand un model de programare bazat pe evenimente.
2.2 JAVA
Java [6] este un limbaj de programare de nivel ˆınalt s,i orientat pe obiecte.
Aplicat,iile java sunt compilate ˆın bytecode care poate rula pe orice arhitectur ˘a de
computer prin intermediul mas,inii virtuale java(JVM). Acest limbaj de programare a
fost lansat ˆın anul 1995 de c ˘atre compania Sun Microsystems.
7

Tehnologii s,i elemente teoretice utilizate Android
2.3 Android
Android [7] este un sistem de operare mobil ˆıntret,inut de Google. Acesta este
open-source s,i se bazeaz ˘a pe kernelul Linux, fiind proiectat pentru dispozitive to-
uchscreen precum smartphone-uri s,i tablete. Dezvoltatorii ˆıs,i pot crea propriile
aplicat,ii Android utiliz ˆand kitul de dezvoltare software(sdk) gratuit. Aplicat,iile An-
droid sunt scrise folosind limbajul Java (sau Kotlin) s,i ruleaz ˘a prin intermediul unei
mas,ini virtuale Java( JVM ) optimizat ˘a pentru dispozitivele mobile. Mas,ina virtual ˘a
”Dalvik” a fost utilizat ˘a pan ˘a la versiunea Android 4.4 iar de la versiunea 5.0 a fost
inlocuit ˘a de Android Runtime(ART). Platforma android este alc ˘atuit˘a din mai multe
componente principale, acestea sunt ilustrate mai jos.
Figura 2.1 : Arhitectura android [1]
Kernelul linux st ˘a la baza funct,ionalit ˘at,ii sistemului de operare Android, el se
ocup ˘a cu operat,ii de baz ˘a low-level cum ar fi threadingul s,i gestiunea RAM.
8

Tehnologii s,i elemente teoretice utilizate MYSQL
Prin HAL(Hardware Abstraction Layer) sunt expuse capabilit ˘at,i hardware ale
dispozitivului c ˘atre Java Api Framework. Acest strat este alc ˘atuit din mai multe
libr˘arii, fiecare distribuind o interfat,˘a de comunicare cu o anumit ˘a component ˘a har-
dware cum ar fi camera sau bluetooth.
Android Runtine(ART) este un mediu de rulare a aplicat,iilor folosit de sistemul
de operare android, execut,ia codului av ˆand loc ˆıntr-o mas,in˘a virtual ˘a.
Multe componente s,i servicii de baz ˘a ale sistemului android cum ar fi ART s,i
HAL, sunt construite folosindu-se libr ˘arii scrise ˆın C s,i C++. Platforma android ofer ˘a
api-uri java pentru a le accesa. De exemplu un dezvoltator poate utiliza OpenGL ES
prin api-ul OpenGL din cadrul framework-ului java android.
Java API Framework cont,ine un set de interfet,e de programare(APIs) prin care li
se permite programatorilor s ˘a scrie rapid s,i us,or aplicat,ii pentru telefoanele Android.
ˆIntregul set de caracteristici ale sistemului de operare Android este f ˘acut disponibil
prin aceste API-uri scrise ˆın java.
System apps, reprezint ˘a aplicat,iile de baz ˘a pe care le cont,ine orice smartphone
Android. Acestea sunt aplicat,ii precum camera, email, calendar, sms etc.
Android studio este mediul de dezvoltare integrat(IDE) oficial pentru aplicat,iile
android, fiind construit peste IntelliJ IDEA de la JetBrains s,i proiectat special pentru
dezvoltarea Android. Acesta ofer ˘a un emulator performant care poate fi folosit ˆın
testarea aplicat,iilor.
2.4 MYSQL
Este cel mai popular sistem de gestionare a bazelor de date relat,ionale(RDBMS)
open source. MySQL este dezvoltat de c ˘atre Oracle Corporation s,i a ap ˘arut pen-
tru prima dat ˘aˆın anul 1995. Aceasta tehnologie este folosit ˘a pentru a stoca da-
tele necesare sistemului. Gestionarea datelor se face prin comenzi din limbajul
SQL(Structured Querry Language).
9

Tehnologii s,i elemente teoretice utilizate HTTP
2.5 HTTP
Este protocolul care st ˘a la baza internetului.Hypertext transfer protocol [8] defi-
nes,te un set de reguli folosit ˆın trimiterea datelor(text,imagini,video) s,iˆın formatarea
acestora pe internet. HTTP este un protocol stateless, deoarece fiecare comand ˘a
este executat ˘a independent, f ˘ar˘a a cunoas,te comenzile care au avut loc ˆınainte.
Acest protocol utilizeaz ˘a modelul server-client, clientul trimite cereri iar serverul
r˘aspunde. Un r ˘aspuns HTTP cont,ine s,i un status code. Prin intermediul acestui
cod aplicat,ia client ˆıs,i poate da seama care este eroarea. Cele mai folosite coduri
sunt urm ˘atoarele:
.200-cerere reus,it˘a
.401-cerere respins ˘a din cauza autentific ˘ari es,uate
.403-acces interzis pe aceast ˘a pagin ˘a
.500-eroare intern ˘a de pe server
De asemenea HTTP defines,te comenzi precum GET s,i POST, care sunt utili-
zate ˆın afis,area s,i crearea de resurse. ˆIn decursul acestei lucr ˘ari se va folosi proto-
colul HTTP pentru transferul datelor dintre server s,i client.
2.6 JSON
JSON(JavaScript Object Notation) este un format text, minimal, us,or de citit
pentru structurarea datelor. Este folosit ˆın principal pentru a transmite date ˆıntre un
client s,i o aplicat,ie web, ca o alternativ ˘a la XML. Datele sunt structurate sub form ˘a
de perechi cheie-valoare. Acest format a devenit din ce ˆın ce mai popular ˆın ultima
vreme, mai ales ˆın dezvoltarea aplicat,iilor web. R ˘aspunsurile returnate de c ˘atre
serverul aplicat,iei vor urma acest format deoarece reprezint ˘a un standard ˆın ziua de
azi s,i este us,or de parsat pe partea de client. Mai jos este ilustrat un exemplu de
date stocate ˆın format JSON.
f
”name” : ”Radu ” ,
” age ” : 21 ,
” address ” :f
” streetAddress ” : ”123 Street ” ,
” c i t y ” : ” Constanta ”
g,
” phoneNumbers ” : [
f
” number ” : ”212 555 1234”
g,
f
” number ” : ”646 555 4567”
g]
g
10

Tehnologii s,i elemente teoretice utilizate Rutarea
2.7 Rutarea
Reprezint ˘a procedeul de calculare a unui drum optim de la un nod A pan ˘a la un
nod B dintr-un graf care cont,ine o mult,ime de noduri, fiecare reprezent ˆand o locat,ie.
Acest termen mai este folosit s,iˆın rutarea pachetelor pe internet, care se realizeaz ˘a
prin intermediul unor rutere care folosesc diferite protocoale de rutare precum RIP
s,i OSPF . Pentru dezvoltarea aplicat,iei am studiat acest concept deoarece este ne-
cesar ˆın implementarea algoritmului care determin ˘a drumul cel mai bun dintre un
turist s,i o locat,ie de vizitat, folosind traseele autobuzelor din oras,ul respectiv.
2.8 GPS
GPS(Global Positioning System) [9] este un sistem de navigare prin intermediul
c˘aruia se poate afl ˘a pozit,ia oric ˘arui obiect pe glob. Pozit,ia este descris ˘a prin latitu-
dine s,i longitudine, iar GPS-ul se bazeaz ˘a pe unde radio s,i se foloses,te de satelit,i
pentru a funct,iona. Navigarea GPS este conceput ˘a pentru a fi utilizat ˘aˆın zone des-
chise, pe drumuri sau pentru a naviga ˆın oras,.ˆIn aceast ˘a lucrare se foloses,te acesta
tehnologie pentru a afla pozit,ia autobuzelor, turis,tilor s,i a obiectivelor de vizitat.
2.9 WebSockets
Websockets este [10] un protocol de comunicare care permite deschiderea unei
sesiuni de comunicare dintre un client s,i un server. Cu acest api clientul poate tri-
mite mesaje serverului s,i primes,te r˘aspunsuri bazate pe evenimente f ˘ar˘a a fi nevoie
s˘a interogheze serverul de fiecare dat ˘a pentru un r ˘aspuns. Protocolul websockets
este complet diferit fat ˘a de HTTP , permit,ˆand fluxul de date bidirect,ional. Aceast ˘a
tehnologie este folositoare mai ales ˆın aplicat,iile care trebuie s ˘a comunice ˆın timp
real. Modulul Socket.io folosit ˆın implementarea serverului utilizeaz ˘a websockets.
2.10 MVC
MVC(Model View Controller) [11] este un stil arhitectural care are ca scop or-
ganizarea codului s,i imbun ˘at˘at,irea mentenant,ei. Acest lucru este realizat prin se-
pararea logicii aplicat,iei de interfat,a afis,at˘a utilizatorului. Astfel aplicat,ia este sepa-
rat˘aˆın trei p ˘art,i principale: modelul,view-ul s,i controlerul. Modelul este responsabil
de gestiunea datelor folosite de aplicat,ie, aici av ˆand loc interogarea bazei de date.
View ofer ˘a utilizatorului o interfat,˘a prin care acesta poate interact,iona, iar controlerul
cont,ine codul care se execut ˘aˆın funct,ie de act,iunile utilizatorului.
11

Tehnologii s,i elemente teoretice utilizate Google Maps
2.11 Google Maps
Este un serviciu web creat de Google, care ofer ˘a informat,ii detaliate despre
regiuni s,i locat,ii geografice de pe tot globul. Google maps ofer ˘a un API care per-
mite afis,area de h ˘art,iˆın alte aplicat,ii. Prin intermediul acestui API am putut afis,a
informat,iile necesare pentru informarea turis,tilor.
2.12 Algoritmul A*
Este un algoritm [12][13] des folosit ˆın probleme de calculare a drumului cel mai
scurt s,i de traversare a grafurilor. ˆIn aceast ˘a lucrare A* este folosit pentru a g ˘asi
calea cea mai scurt ˘a dintre un nod de pornire (locat,ie start) s,i un nod destinat,ie,
folosindu-se de o metod ˘a euristic ˘a. Acest algoritm este similar cu algoritmul lui Di-
jkstra, diferent,a fiind ˆın alegerea urm ˘atorului nod. Nodurile sunt selectate pe baza
unei funct,ii f care reprezint ˘a costul acumulat pan ˘aˆın nodul curent s,i estimarea
distant,ei de la acesta pan ˘a la destinat,ie. Euristicile sunt folosite pentru a calcula
acesta estimare deoarece distant,a real ˘a dintre oricare nod s,i nodul destinat,ie este
cunoscut ˘a numai dup ˘a ce drumul cel mai scurt a fost g ˘asit. Implementarea s,i modul
de funct,ionare al acestui algoritm este descris ˆın sect,iunea 3.6.
12

Capitolul 3
Proiectare s ,i implementare
Aplicat,ia ”Turist helper” ˆıi permite unui utilizator s ˘a creeze sau s ˘a selecteze liste
de locat,ii turistice create de c ˘atre alt,i utilizatori s,iˆılˆındrum ˘a pe acesta, calcul ˆand
o cale optim ˘a cu algoritmul A*, c ˘atre locat,iile respective folosindu-se de rutele de
transport urban din oras,ul respectiv. Totodat ˘a,ˆıi ofer ˘a posibilitatea s ˘a urm ˘areasc ˘a
ˆın timp real autobuzele care circul ˘a pe traseele care fac parte din drumul calculat
de c˘atre algoritmul de rutare. De asemenea utilizatorul poate s ˘a caute s,i s˘aˆıntre
ˆıntr-un grup de chat pentru a comunica cu alt,i turis,ti.
ˆIn capitolul acesta se va face o prezentare general ˘a a arhitecturii sistemului.
Prima sect,iune cont,ine o prezentare pe scurt a ˆıntregii arhitecturi de sistem, dup ˘a
care se prezint ˘aˆın detaliu fiecare pas din implementare s,i este descris ˘a fiecare
component ˘aˆın parte.
3.1 Arhitectura general ˘a a sistemului
Determinarea arhitecturii folosite este un pas important ˆın dezvoltarea oric ˘arui
sistem software. Pentru a realiza toate cerint,ele funct,ionale ale aplicat,iei, sunt ne-
cesare servicii precum stocarea datelor pe un server central s,i comunicarea dintre
client,iˆın timp real. Astfel de servicii trebuie s ˘a fie gestionate de o component ˘a
software extern ˘a cunoscut ˘a sub numele de backend. Backend-ul va rula pe unul
sau mai multe servere, ascult ˆand solicit ˘arile dispozitivelor care ruleaz ˘a aplicat,ia cli-
ent s,i r˘aspunz ˆand cererilor acestora.
As,adar, sistemul prezint ˘a o arhitectur ˘a de tip Client/Server cu un client Android
s,i un server central care are acces la o baz ˘a de date s,i care gestioneaz ˘a comuni-
carea ˆın timp real dintre client,i. Aplicat,ia Android(clientul) va comunica cu serve-
rul central(backend) prin internet. Clientul a fost implementat ˆın limbajul Java, iar
server-ul foloses,te tehnologia Node.js.
13

Proiectare s,i implementare Arhitectura general ˘a a sistemului
ˆIn figura de mai jos se poate vedea structura sistemului ˆımpreun ˘a cu toate com-
ponentele sale.
Figura 3.1 : Arhitectura de nivel ˆınalt a sistemului
Dup˘a cum se vede ˆın figura de mai sus, sistemul este alc ˘atuit din trei compo-
nente principale acestea fiind serverul, baza de date s,i aplicat,ia Android.
1.Serverul pune resursele la dispozit,ia tuturor client,ilor prin diferite adrese url,
f˘acˆand astfel leg ˘atura dintre client,i si baza de date. Pe server este implementat
un RESTfull API care r ˘aspunde prin resurse json. De asemenea serverul este
responsabil s,i de comunicarea ˆın timp real dintre client,i, lucru necesar pentru
urm˘arirea autobuzelor s,i pentru modulul de chatting.
2.Clientul este aplicat,ia Android care prezint ˘a o interfat,˘a utilizatorului, oferindu-i
un mod de a vizualiza datele preluate de la server prin interogarea acestuia
pentru resurse, sau de a trimite date. Prin interfat,˘a userul poate beneficia de
funct,ionalit ˘at,ile descrise ˆın cerint,ele funct,ionale. Un utilizator al aplicat,iei client
este un turist sau un s,ofer de autobuz.
3.Baza de date este folosit ˘a de c ˘atre server pentru stocarea permanent ˘a a da-
telor (rute, locat,ii turistice, conturi utilizator, etc).
Funct,ionalitatea sistemului se bazeaz ˘a pe comunicarea corect ˘a dintre aceste
componente.
14

Proiectare s,i implementare Diagrama Use-Case
3.2 Diagrama Use-Case
O diagram ˘a a cazurilor de utilizare [14] este ˆın forma cea mai simpl ˘a o descriere
sau o reprezentare a comportamentului sistemului software s,i a interact,iunii actorilor
software cu acesta. Diagrama cazurilor de utilizare arat ˘a diferite tipuri de utilizatori
ai unui sistem ˆımpreun ˘a cu cazurile de utilizare s,i va fi deseori ˆınsot,it˘a de alte tipuri
de diagrame cum ar fi diagrame de activit ˘at,i, de secvent,e de sistem etc.
Figura 3.2 : Diagrama Use-Case sistem
Aceast ˘a diagram ˘a prezint ˘a cazurile de utilizare software cu relatile dintr ele s,i
relat,iile dintre cazuri s,i actorii software.
ˆIn continuare voi exemplifica c ˆateva dintre cele mai importante cazuri de utili-
zare ale aplicat,iei.
15

Proiectare s,i implementare Diagrama Use-Case
Caz de utilizare: Creare lista de locat,ii turistice
Nume: Creare lista de locat,ii turistice
Actor software: Turist
Precondit,ii:Autentificare cu succes utilizator s,i acces la internet.
Postcondit,ii:A fost ˆınc˘arcat ˘a o list ˘a de locat,ii turistice pe server.
Flux principal:
Turist Sistem
1.Cere ad ˘augare locat,ie 2.Afis,are fereastra dialog
3.Introducere date 4.Verificare date [A1]
5.Introducere locat,ieˆıntr-o list ˘a tempo-
rar˘a
6.Repetare de la pas 1 p ˆan˘a cˆand nu
mai dores,te ad ˘augarea de locat,ii noi
7.Cere ˆınc˘arcare list ˘a 8.Afis,are formular denumire list ˘a
9.Introducere nume s,i descriere 10.Verific ˘a date[A1]
11.Apas ˘a buton upload 12.Construies,te s,i trimite cererea c ˘atre
server
13. Verifica dac ˘a lista cont,ine 3 locat,ii
unice [A2]
14.Memoreaz ˘aˆın baza de date
Flux alternativ:
[A1]: Datele necesare nu au fost introduse, sau au fost introduse gres,it
.Sistemul afis,eaz˘a un mesaj care descrie eroarea, fluxul continu ˘a de la pasul 2
[A2]:Lista trimis ˘a cont,ine mai put,in de 3 locat,ii unice
.Sistemul ˆıi afis,eaz˘a utilizatorului acest lucru printr-un pop-up, acesta put ˆand
s˘a s,tearg ˘a locat,iile care nu sunt unice.
16

Proiectare s,i implementare Diagrama Use-Case
Caz de utilizare: Localizare autobuz
Nume: Localizare autobuz
Descriere: Descrie comportamentul sistemului s,i modul de interact,iune cu un s,ofer
atunci c ˆand se dores,te pornirea serviciului de localizare a unui autobuz
Actor software: S,ofer
Precondit,ii:Autentificare autobuz cu succes, acces la internet s,i la servicii gps
Postconditii: Autobuzul respectiv a fost localizat in timp real
Flux principal:
S,ofer Sistem
1.Selecteaz ˘a traseul de pornire(dus
sauˆıntors)2.Ret,ine id-ul traseului selectat
3.Pornes,te localizarea 4.Se conecteaz ˘a la server ˆın camera
traseului respectiv
5.Trimite locat,ia autobuzului c ˘atre ser-
ver [A1]
6.Opres,te localizarea 7.Se deconecteaz ˘a de la server
Flux alternativ:
[A1]: Autobuzul se afl ˘aˆın ultima stat,ie din traseul curent.
.Sistemul se deconecteaz ˘a de la server.
.Este schimbat traseul.
.Sistemul se conecteaz ˘a la server ˆın camera noului traseu s,i continua execut,ia
de la pasul 5.
Caz de utilizare: Inregistrare cont
Nume: Inregistrare cont
Actor software: Turist
Precondit,ii:Acces la internet s,i serverul sa fie funct,ional.
Postcondit,ii:Sistemul a memorat datele unui cont nou.
Flux principal:
Turist Sistem
1.Cere creare cont 2.Afis,are fereastr ˘a introducere date
3.Introduce date cont 4.Verific ˘a date [A1]
5.Memoreaz ˘aˆın baza de date [A2]
17

Proiectare s,i implementare Diagrama Use-Case
Flux alternativ:
[A1]: Date necompletate
.Sistemul ˆıi spune utilizatorului ce c ˆampuri nu au fost completate, iar fluxul se
reia de la pasul 2
[A2]:Exist ˘a un utilizator deja cu acelas,i nume
.Sistemul afis,eaz˘a un mesaj de eroare, iar fluxul se reia de la pasul 2.
Caz de utilizare: Urm ˘arire autobuze
Nume: Urm˘arire autobuze
Actor software: Turist
Precondit,ii:A fost calculat drumul c ˘atre o locat,ie turistic ˘a s,i are acces la internet s,i
servicii gps.
Postcondit,ii:Au fost urm ˘arite ˆın timp real autobuzele.
Flux principal:
Turist Sistem
1.Cere afis,are autobuze 2.Conectare la server s,i plasarea
socket-ului ˆın camerele traseelor nece-
sare[A1]
3.Primire locat,ii autobuze de la server
s,i afis,area acestora pe hart ˘a
4.Cere oprire localizare 5.Deconectare de la server
Flux alternativ:
[A1]: Conectare es,uat˘a
.Fluxul principal este intrerupt.
.Sistemul ˆıncearc ˘a s˘a se reconecteze.
18

Proiectare s,i implementare Serverul
3.3 Serverul
Serverul ofer ˘a un REST API care este accesibil de c ˘atre dispozitive mobile sau
de c ˘atre orice alt ˘a platform ˘a, cum ar fi un browser. Serverul este responsabil cu
distribut,ia datelor c ˘atre client,i s,i cu comunicare ˆın timp real.
Pe lˆang˘a faptul c ˘a acesta trebuie s ˘a prelucreze cererile venite de la client,iˆın
funct,ie de metoda HTTP s,i url, el mai trebuie s ˘a suporte s,i comunicarea prin web-
sockets ne ˆıntrerupt ˘a.
Protocolul websockets permite interact,iunea dintre un client s,i un server web,
facilit ˆand transferul de date ˆın timp real de la client c ˘atre server sau invers, comuni-
carea fiind full-duplex.
Pentru a realiza acest lucru serverul trebuie s ˘a fie s,i un websocket server, adic ˘a
o aplicat,ie TCP care ascult ˘a pe un port s,i urmeaz ˘a protocolul websockets(RFC6645).
O modalitate de a crea un websocket server este prin folosirea libr ˘ariei populare
open-source, Socket.IO.
3.3.1 Implementarea serverului
Tehnologiile folosite ˆın faza de implementare au fost Node.JS ˆımpreun ˘a cu fra-
meworkul Express.js s,i modulul Socket.io. Dezvoltarea s-a realizat cu ajutorul lim-
bajului Javascript.
Visual studio code a fost IDE-ul folosit pentru implementarea modulelor serve-
rului s,i structurarea acestora sub form ˘a unui RESTfull API.
Un alt stil arhitectural folosit ˆın implementare a fost MVC(Model-view-controller)
care separ ˘a codul ˆın p˘art,i interconectate, av ˆand fis,iere model pentru preluarea s,i
introducerea informat,iilorˆın baza de date s,i fis,iere controller care se ocup ˘a de logica
dintre cerere s,i r˘aspuns. ˆIn cazul meu pe server nu exist ˘a view-uri, clientul fiind un
smarthphone android.
Figura 3.3 : Model View Controller Pattern [2]
19

Proiectare s,i implementare Serverul
Am ales s ˘a folosesc Node.js deoarece este foarte performant pentru aplicat,ii
real time pe web(Data Intensive Real-time Applications) s,i foarte rapid, fiind construit
peste Google Chrome v8 Javascript engine. Codul serverului ruleaz ˘a pe un singur
thread ˆın mod asincron s,i este bazat pe evenimente.
Un server tradit,ional creat f ˘ar˘a Node.js urmeaz ˘a modelul ”Multi Threaded Requ-
est Response” [15]. Client,ii trimit cereri la server care apoi proceseaz ˘a cererea s,i
trimite un r ˘aspuns.
Acest model foloses,te protocolul HTTP s,i utilizeaz ˘a threaduri multiple pentru a
trata cereri concurente. Serverul as,teapt ˘aˆıntr-o bucl ˘a infinit ˘a s,i ment,ine un pool
limitat de threaduri pentru a furniza servicii client,ilor, distribuind pentru fiecare ce-
rere c ˆate un thread. Acest thread se va ocup ˘a cu citirea unei cereri de la client,
procesarea acesteia s,i executarea, dac ˘a este nevoie, a operat,iilor de tipul ”Blocking
I/O” ce implic ˘a blocarea threadului p ˆan˘a cˆand aceast ˘a operat,ie se termin ˘a, adic ˘a
exist ˘a date de citit sau au fost scrise date complet. P ˆan˘a cˆand operat,ia respectiv ˘a
nu e completat ˘a threadul st ˘a s,i as,teapt ˘a. Din acest motiv pentru a prelucra cereri
concurente sunt necesare threaduri multiple, fiind acordat c ˆate un thread nou pen-
tru fiecare conexiune a unui client. Dac ˘a mai multe requesturi ale client,ilor cont,in
operat,ii de tipul ”Blocking I/O” atunci aproape toate threadurile sunt ocupate iar res-
tul cererilor vor avea de as,teptat mai mult. Aceast ˘a metod ˘a nu este recomandat ˘aˆın
cazul ˆın care serverul este ˆıns˘arcinat spre a servi un num ˘ar mare de client,i.
Pentru a trata un num ˘ar mare de conexiuni simultane exist ˘a o alternativ ˘a, Non-
Blocking I/O care foloses,te un singur thread ˆın scopul servirii conexiunilor multiple
concurente. Platforma Node.js urmeaz ˘a un model single threaded cu un event loop
care se bazeaz ˘a pe mecanisme de callback s,i nuˆıntrerupe threadul principal.
Node.js este conceput pentru a fi excelent ˆın aplicat,ii cu multe operat,ii de I/O,
folosind o arhitectur ˘a non-blocking s,i bazat ˘a pe evenimente. ˆIn loc s ˘a creeze un
thread pentru fiecare cerere, este folosit doar un singur thread principal pentru toate.
De exemplu c ˆand se face o interogare pe baza de date ˆın loc s ˘a se blocheze threadul
pan˘a cˆand operat,ia s-a terminat, se va folosi o funct,ie callback care se execut ˘a la
completarea interog ˘arii.
Node poate executa codul s,iˆıntr-un mod sincron dar de cele mai multe ori
acesta este executat asincron. Asta ˆınseamn ˘a c˘aˆın timpul implement ˘arii serve-
rului voi utiliza metode care au atas,ate o funct,ia callback pentru tratarea finaliz ˘arii
execut,iei acestora. ˆIn timp ce se as,teapt ˘a rezultatul unei operat,ii, urm ˘atoarea operat,ie
poate fi extras ˘a din coad ˘a (queue) pentru a fi executat ˘a. Imediat ce o operat,ieˆıs,i
termin ˘a execut,ia, evenimentul callback asociat acestea se declans,eaz˘a s,i este tratat
de c˘atre funct,ia callback dat ˘a c˘a parametru.
20

Proiectare s,i implementare Serverul
Figura 3.4 : Arhitectura node.[3]
Aceasta tehnologie este o alegere bun ˘a pentru serverele care trebuie s ˘a prelu-
creze un volum mare de mesaje scurte cu o latent,˘a redus ˘a precum:
.Real Time Location Tracking
.Instant Messaging
.Video Streaming
Asemenea sisteme se numesc real-time-applications s,i pot fi dezvoltate cu
us,urint,a.
Abilitatea lui Node de a procesa multe cereri cu timpi scurt,i de r ˘aspuns ˆıl fac
perfect pentru aplicat,ii web moderne. Din aceste motive Node.js este o alegere
popular ˘a pentru single page applications unde randarea e f ˘acut˘a pe partea de client
s,i serverul ofer ˘a un JSON API.
Nu este recomandat de folosit Node JS pentru aplicat,iile care sunt CPU inten-
sive, din acest motiv am ales s ˘a execut algoritmul de rutare pe client s,i nu direct pe
server.
Pentru a asigura funct,ionalitatea necesar ˘a serverului implementarea a cont,inut
urm˘atorii pas,i:
.crearea unui API RESTfull care r ˘aspunde la cereri HTTP
.ad˘augarea unui modul de comunicare ˆın timp real prin socketuri
Pe lˆang˘a funct,ionalitatea de web service care r ˘aspunde cererilor HTTP serverul are
rolul de a sust,ine transferul de date ˆın timp real full duplex cu client,ii.
Node.js este modular s,i a fost creat de la ˆınceput ca s ˘a poat ˘a fi us,or de extins
prin pluginuri s,i pachete. Node.js vine cu propriul sistem de management al pa-
chetelor, Node Package Manager(NPM), prin care se pot instala, s,terge sau updata
pachetele folosite ˆın proiect. Pe parcursul procedeului de implementare al serverului
voi folosi mai multe module, acestea vor fi instalate cu NPM.
21

Proiectare s,i implementare Serverul
Figura 3.5 : Dependente Server.
NPM este managerul de pachete utilizat de node s,i constituie cel mai mare
depozit de libr ˘arii open-source.
3.3.1.1 NPM:Node Package Manager
Npm [16] este un manager de pachete pentru Node.js. Un pachet este un
director care cont,ine unul sau mai multe fis,iere(module). O aplicat,ie web depinde de
multe pachete. Acestea sunt ˆın general c ˘ar˘amizile care fac posibil ˘a crearea solut,iilor
mari s,i complexe. Folosind Npm, programatorii pot s ˘aˆıs,iˆımpart ˘a codul scris ˆıntr-un
mod us,or, acesta put ˆand fi folosit ˆın aplicat,iile altora. Odat ˘a ce pachetele au fost
instalate prin Npm, este foarte us,or de verificat dac ˘a au fost f ˘acute modific ˘ari sau
update-uri unui anumit pachet.
Registry este o baz ˘a de date public ˘a foarte mare de software javascript care
cont,ine informat,ii despre pachetele pe care dezvoltatorii le distribuie. Aceast ˘a baz ˘a
de date cont,ine peste 600.000 de pachete. Pentru a instala un pachet se foloses,teˆın
consol ˘a comanda npm install s,i numele acestuia. De exemplu ”npm install express”.
Unele dintre cele mai folosite pachete npm sunt: express, socket.io, mongodb, jade,
redis, mysql.
22

Proiectare s,i implementare Serverul
3.3.1.2 Express JS
Serverul este implementat folosind Express.js [17] care este un framework rapid
s,i minimalist utilizat ˆın crearea aplicat,iilor web. Express.js poate fi folosit pentru a
construi aplicat,ii robuste s,i complete prin intermediul tehnologiei Node.js.
Express ofer ˘a toate facilit ˘at,ile necesare pentru crearea unui server web:
.Intelegere HTTP : Acceptarea conexiunilor TCP , procesarea cererilor HTTP s,i
trimiterea de r ˘aspunsuri HTTP .
.Rutare : Mapeaza url-uri la funct,ii scrise pe server.
.Suport pentru Middleware : Permite ad ˘augarea mai multor straturi de pro-
cesare unui cereri. Acest lucru simplifica implementarea de sesiuni, cookies,
securitate.
Funct,iile middleware sunt funct,ii care se execut ˘aˆıntre request s,i response (ce-
rere si raspuns). Acestea au acces la obiectul request, la obiectul response (res)
s,i la urm ˘atoarea funct,ie middleware. Middleware-ul poate urm ˘atoarele: s ˘a exe-
cute orice cod, s ˘a fac ˘a modific ˘ari la obiectele request s,i response, s ˘a termine ciclul
request-response, s ˘aˆınceap ˘a execut,ia urm ˘atoarei funct,ii middleware.
Acest framework cont,ine un router avansat s,i se axeaz ˘a pe simplificarea cre ˘arii
unui web API, motiv pentru care l-am ales pentru a implementa serverul.
var express = require(’express’);
var app = express();
app.get(’/’, function (req, res){
res.send("Hello world!");
});
app.listen(3000);
Aceasta secvent ˘a de cod creeaz ˘a o aplicat,ie express pe portul 3000 s,i r˘aspunde
cu stringul ”Hello World” pentru toate cererile f ˘acute la url-ul ”localhost:3000/”/
Express ofer ˘a o modalitate robust ˘a de a mapa diferite cereri la anumite funct,ii
de tratare a acestora. Acest procedeu se numes,te Routing s,i se refer ˘a la modul ˆın
care serverul r ˘aspunde solicit ˘arilor clientului de pe diferite ”endpoints”(URI). Rutarea
de pe server este definit ˘a utiliz ˆand obiectul express app care corespunde unei me-
tode HTTP , de exemplu app.get() sau app.post(). Aceste metode necesit ˘a o funct,ie
callback care este invocat ˘a cˆand atunci c ˆand serverul primes,te o cerere pe ruta
specificat ˘a (endpoint) s,i metoda HTTP . De asemenea express ˆımi permite s ˘a tratez
rutele care cont,in parametri ˆın URL, oferind un mod us,or de a extrage aceste valori.
Un exemplu de url care cont,ine date arat ˘aˆın felul urm ˘ator ’/users/:userId/’.
Fiecare funct,ie de tratare a unei cereri trebuie s ˘a primeasc ˘a ca parametri un
obiect request s,i un obiect response. Obiectul request cont,ine toate informat,iile
legate de cererea respectiv ˘a, iar prin obiectul response se poate trimite un r ˘aspuns
c˘atre client.
23

Proiectare s,i implementare Serverul
3.3.1.3 Crearea Api
Serverul este de tip RESTful [18, pg. 39–53], care r ˘aspunde cu resurse ˆın
funct,ie de url s,i metoda HTTP . Indiferent de c ˆat de sofisticat este backend-ul acesta
nu va fi de folos p ˆan˘a cˆand serviciile sale nu sunt accesibile de c ˘atre client,iˆıntr-un
fel. Cel mai comun mod de a realiza acest lucru este printr-un Application Program-
ming Interface(API), un set de metode bine definite pe backend. Prin acest api li
se permite client,ilor s ˘a acceseze s,i s˘a uploadeteze date. Acesta sect,iune cont,ine
modul ˆın care am implementat api-ul, urm ˆand principiile arhitecturii REST.
Pentru a cres,te nivelul de abstractizare s,i pentru a construi o interfat,˘a care
permite comunicare intuitiv ˘a cu backend-ul a trebui s ˘a structurez serverul sub forma
unui REST API.
REST este un model arhitectural ˆın care dou ˘a sau mai multe aplicat,ii schimb ˘a
resurse ˆıntre ele printr-un set de operat,ii pe acestea. Resursele sunt unic reprezen-
tate prin URL-uri. API-ul va r ˘aspunde diferit ˆın funct,ie de metoda HTTP a cererii s,i
de url-ul acesteia. R ˘aspunsurile sunt structurate sub form ˘a unui JSON. Un r ˘aspuns
cont,ine: datele json, un cod HTTP s,i un mesaj care descrie potent,iale erori. Fiecare
cerere f ˘acut˘a unui REST API este stateless, adic ˘a serverul care se ocup ˘a de proce-
sare nu ment,ine nici un context ˆıntre cereri (sunt tratate independent). Orice valori
necesare pentru a procesa cererea trebuie trimise odat ˘a cu aceasta, de exemplu un
token de autentificare. Un api bun trebuie s ˘a ment,in˘a o interfat,˘a uniform ˘a. Pentru
oricare resursa, modul ˆın care o cerere este f ˘acut˘a trebuie s ˘a fie similar. De exem-
plu o cerere de modificare a numelui pentru un utilizator este similar cu o cerere de
modificare a numelui pentru o locat,ie. Transferul de date se face folosind standardul
HTTP(Hypertext Transfer Protocol).
Scopul principal al serverului este acela de a permite unei aplicat,ii client s ˘a
acceseze datele ˆın format JSON indiferent de sistemul de operare folosit.
La baza comunic ˘arii RESTful stau verbele HTTP: GET, POST, PUT, DELETE
care mai sunt referite des prin acronimul CRUD(Create-Read-Update-Delete). Aceste
verbe reprezint ˘a diferite tipuri de cereri trimise ˆıntre dou ˘a aplicat,ii capabile s ˘a ”vor-
beasc ˘a” HTTP . Fiecare metoda HTTP corespunde cu o act,iune asupra unei resurse.
.GET: O cerere de acest tip ˆıntotdeauna indic ˘a o operat,ie de preluare a unor
date. Ideal un API implementeaz ˘a posibilitatea de a prelua o resursa particu-
lar˘a identificat ˘a printr-un id sau de a prelua un array (o lista) care cont,ine toate
resursele de acel tip. ˆIn cazul ˆın care se dores,te precizarea id-ului resursei,
sau a oric ˘arei altei informat,ii relevante, acesta poate fi precizat ˘aˆın url ca un
parametru querry sau ca un parametru de path.
.POST: Cererile de tip post sunt folosite pentru crearea de noi instant,e a unei
resurse. ˆIn cazul meu acest tip de cerere este folosit la crearea unei liste de
locat,ii turistice, la logarea unui utilizator/s,ofer, la ˆınregistrarea unui cont s,i la
crearea unui grup de chat.
24

Proiectare s,i implementare Serverul
.PUT: este folosit pentru a crea sau a updata o resurs ˘a. Funct,ioneaz ˘a aproape
la fel ca s,i POST doar c ˘aˆın cazul preciz ˘arii id-ului resursei ˆın cerere serverul
va g˘asi mai ˆıntˆai acea resursa specific ˘a s,i o va updata.
.DELETE: este folosit pentru s,tergerea unei resurse de pe server. Este nece-
sar˘a precizarea id-ului ˆın cerere.
Pentru a crea un schelet de baz ˘a al serverului am folosit pachetul express-
generator care genereaz ˘a urm ˘atoarea structur ˘a de foldere.
Figura 3.6 : Folder Structure API.
ˆIn fis,ierul www are loc init,ializarea serverului HTTP creat cu frameworkul ex-
press, care este setat s ˘a asculte pe portul 3000. Pentru a hosta serverul s,i aˆıl face
accesibil prin internet pe acest port am f ˘acut port-forwarding. De asemenea tot ˆın
acest fis,ier are loc s,i init,ializarea socket.io, acesta av ˆand nevoie de o referint,˘a la
serverul HTTP . Acest fis,ier este primul care se execut ˘a la init,ializarea serverului.
"scripts": {
"start": "node ./bin/www",
"devstart": "nodemon ./bin/www"
}
App.js cont,ine logica serverului, api-ul este init,ializat aici. Astfel, sunt setate
rutele, se face conexiunea la baza de date s,i se stabilesc modulele utilizate de c ˘atre
aplicat,ie.
25

Proiectare s,i implementare Serverul
Un modul foarte importat pentru funct,ionarea aplicat,iei este body-parser, acesta
se ocup ˘a de cererile de tip post, ad ˘augˆandˆın obiectul req cont,inutul cererii care
poate fi accesat prin req.body.
ˆIn folderul routes se afl ˘a rutele api-ului care cont,in logica de rezolvare a unei
cereri HTTP de la o anumit ˘a adres ˘a. Pentru a realiza acest lucru se folosesc clase
de tip controller s,i model, serverul urm ˆand stilul arhitectural MVC.
Fis,ierul package.json cont,ine dependent,ele proiectului preciz ˆandu-se versiu-
nea fiec ˘areia s,i alte informat,ii legate de proiect precum punctul de start, numele
proiectului etc.
ˆIn folderul public sunt stocate fis,ierele statice care pot fi trimise utilizatorilor.
Imaginile locat,iilor turistice uploadate de c ˘atre utilizatori sunt stocate ˆın acest folder.
View-urile nu sunt folosite ˆın cazul meu deoarece aplicat,ia nu are s,i o versiune
pentru browser, singurul client momentan fiind un smarphone android.
Primul s,i cel mai important pas din implementarea API-ului a constituit definirea
rutelor ˆımpreun ˘a cu clasele model s,i controller cu ajutorul c ˘arora se construies,te
r˘aspunsul.
3.3.1.4 Construirea rutelor
Conceptul de route (rut ˘a) este folosit ˆın express pentru a defini act,iunile care s ˘a
ruleze la sosirea unei cereri, ˆın funct,ie de URL s,i verbul HTTP .
O rut ˘a este alc ˘atuit˘a din trei componente principale:
.Metoda HTTP asociat ˘a cu cererea app.get();
.URL-ul/locat,ia cereri app.get(’/lists’)
.O funct,ie de tratare care primes,te dou ˘a argumente: un obiect request s,i un
obiect response app.get(’/lists’,function(req,res){ );
Pentru crearea rutelor s-a folosit un obiect de tip express router. Router-ul pricipal
al aplicat,iei se afl ˘a pe adresa ”/api”. Acesta a fost setat ˆın fis,ierul app.js s,i cont,ine
ˆın interiorul s ˘auˆınc˘a alte patru routere pentru adrese diferite.
ˆIn imaginea de mai jos se pot vedea toate obiectele de tip router pentru rutele
care ˆıncep cu ”/api”.
26

Proiectare s,i implementare Serverul
Figura 3.7 : Rute api.
ˆIn interiorul acestor routere se afl ˘a metodele principale ale api-ului, care r ˘aspund
la cereri. ˆIn mod normal api-urile rest vor servi date ˆın diferite formate precum JSON
sau XML. Pentru simplitate api-ul va returna doar JSON. Returnarea unui obiect
JSON se face prin setarea atributului ’Content-type’ al r ˘aspunsului ˆın ’application/j-
son’ s,i prin transformarea obiectului javascript ˆın string prin metoda JSON.stringify().
Funct,iile de tratare a unei anumite cereri sunt responsabile de trimiterea r ˘aspun-
sului c ˘atre client s,i se folosesc de metode din fis,ierele controller. ˆIn controllere sunt
utilizate fis,ierele de tip model care interact,ioneaz ˘a cu baza de date. Un controller
este folosit pentru toate requesturile de pe o anumit ˘a resursa.
Pentru a stabili o conexiune cu baza de date, serverul se foloses,te de pache-
tul mysql care cont,ine driverul necesar. Datele conexiunii sunt precizate ˆın fis,ierul
database.js iar conexiunea este init,ializat ˘aˆın app.js. De asemenea tot aici se afl ˘a o
funct,ie care va rula atunci c ˆand se pierde conexiunea, ˆın scopul cre ˘arii unei cone-
xiuni noi.
const dbConnection=require(’./configdb’);
dbConnection.connect((err)=>{
if(err){
console.log(’Unable to connect to MySQL.’);
}
console.log(’Succesfully connected to mysql’);
console.log(’connected as id ’ + dbConnection.threadId);
console.log(’Config:’+JSON.stringify(dbConnection.config));
});
27

Proiectare s,i implementare Serverul
Fiecare metod ˘a de pe o rut ˘a are dou ˘a argumente, req s,i res care se refer ˘a la
cererea HTTP s,i r˘aspunsul asociat. Parametrul req va cont,ine toate datele aso-
ciate cu cererea HTTP , precum originea, headers, cookies s,i datele transmise, iar
parametrul res este r ˘aspunsul HTTP care va fi emis ˆınapoi la client.
Cele patru obiecte pentru rutare folosite de c ˘atre api sunt: busTracking ,users ,
liste,chat.ˆIn continuare voi descrie rolul fiec ˘aruia s,i voi explica metodele cele mai
importante cont,inute de acestea.
Obiectul de rutare bustracking se ocupa de: login autobuze, afis,area trase-
elor dintr-un oras,, determinarea oras,uluiˆın care se afla utilizatorul. Mai jos sunt
prezentate rutele cont,inute de acest obiect.
Loginul are loc ˆın funct,ia check login din controller. Aceast ˘a funct,ie primes,te
c˘a parametru num ˘arul de ˆınmatriculare al unui autobuz s,i parola acestuia care sunt
stocate ˆın corpul cererii(body-ul requestului) trimis prin metoda POST. Pentru a ve-
rifica dac ˘a autobuzul exist ˘aˆın baza de date, se execut ˘a o instruct,iune select. Dac ˘a
interogarea a returnat un autobuz, parola acestuia este apoi comparat ˘a cu parola
trimis ˘a de c ˘atre client s,i se returneaz ˘a dac ˘a autentificarea a avut loc cu succes sau
nu.
busTrackingModel.getBus(req.body.registration_number, function (err,result)
{
if(err){
res.status(401).json({message:"Error"});
}
else {
console.log(result);
if(result.length>0){//login bun bus exist
if(result[0].password==req.body.password){
//password correct
console.log("Succes login");
res.status(200).json({message:"Succes Login",bus_route_id
:result[0].bus_route_id});
}
else {
res.status(401).json({message:"Bus number and password do
not match"});
}
}
else {
res.status(401).json({message:"Bus number does not exist"});
}
}
});
28

Proiectare s,i implementare Serverul
Pentru a afis,a traseele autobuzelor dintr-un anumit oras,trebuie precizat id-ul
acestuia ˆın url dup ˘a care se execut ˘a o instruct,iune select pe baza de date. Rezul-
tatele sunt structurate de c ˘atre server ˆıntr-un format JSON us,or de citit s,i returnate
utilizatorului. ˆIn scopul determin ˘arii id-ului oras,uluiˆın care se afl ˘a un turist, se face
un select dup ˘a numele oras,ului trimis de c ˘atre acesta(aflat prin google maps api pe
client) s,i se returneaz ˘a id-ul g ˘asit.
Users cont,ine logica pentru login s,iˆınregistrarea de conturi, datele fiind trimise
prin metode POST. La ˆınregistrare parola este hashed prin modulul bcrypt pentru
a proteja datele utilizatorilor ˆın cazul compromiterii bazei de date. La fiecare login
reus,it i se returneaz ˘a clientului un token care poate fi folosit ulterior pentru a proteja
anumite rute. Prin acest token, fiecare utilizator poate fi identificat ˆın mod unic de
c˘atre server. Aplicat,ia client trebuie s ˘a trimit ˘a tokenul ˆımpreun ˘a cu toate cererile
care necesit ˘a autentificare, iar serverul o s ˘a valideze tokenul pentru a determina
dac˘a accesul ˆıi este interzis. Tokenurile sunt generate prin modulul jsonwebtoken.
Este folosit ˘a acesta solut,ie pentru protejarea rutelor deoarece un api restfull este
stateless(nu ment,ine context ˆıntre cereri).
Router-ul listeste responsabil de afis,area listelor de locat,ii turistice dintr-un
anumit oras,s,i a cont,inutului acestora. De asemenea tot aici are loc s,i crearea unei
liste turistice de c ˘atre un utilizator.
exports.getListsPaginationTest= function (limit,offset,city_id,callback){
var sql="SELECT *FROM list WHERE id IN (SELECT DISTINCT id_list FROM
(list_details ld INNER JOIN location l ON ld.id_location=l.id )
INNER JOIN city c ON c.id=l.city_id WHERE c.id=?) LIMIT ? OFFSET
?;";
connection.query(sql,[city_id,limit,offset], function (err,results){
if(err){
callback( true );
return ;
}
callback( false ,results);
});
};
Pentru afis,area listelor am implementat pe server paginare. Atunci c ˆand ser-
verul se ocup ˘a cu cantit ˘at,i mari de date este important acest lucru. Paginarea este
util˘a dintr-o perspectiva a performant,ei prin faptul c ˘a reduce num ˘arul de interog ˘ari
mari asupra bazei de date, dar este de asemenea util ˘a s,i din perspectiva clientului,
deoarece acesta poate solicita numai datele de care are nevoie.
Astfel la fiecare GET de preluare a datelor pe aceast ˘a resursa trebuia precizat,i
2 parametri: page s,i limit. Prin page se specific ˘a ce pagin ˘a se dores,te, iar prin
limit c ˆate elemente s ˘a fie afis,ateˆıntr-o pagin ˘a. Paginarea se face ˆın interog ˘arile
de pe baza de date prin utilizarea conceptelor de OFFSET s,i LIMIT. Calcularea
valorii offset folosit ˘aˆın query se face ˆın felul urm ˘ator: ”var offset = (page-1) * limit;”.
Pentru a downloada cont,inutul unei liste se realizeaz ˘a o cerere de tip GET la
adresa ’/api/liste/:id’ ˆın care se precizeaz ˘a id-ul listei dorite.
29

Proiectare s,i implementare Serverul
ˆInc˘arcarea unei liste de c ˘atre utilizatori se face prin folosirea formularelor multi-
part. Un formular de acest tip este o metod ˘a de trimitere a datelor de la client c ˘atre
un server printr-o cerere POST. O cerere de creare a unei liste cont,ine numele, des-
crierea, oras,ul, id-ul utilizatorului s,i fiecare locat,ieˆımpreun ˘a cu imaginile acestora.
Pentru a parsa acesta cerere se foloses,te modulul ’multer’, care se ocup ˘a de uploa-
dul imaginilor, atribuind fiec ˘areia un nume unic s,i atas,eaz˘a toate datele necesare la
obiectul req(request).
Inserarea listelor de locat,ii turistice ˆın baz ˘a de date se face prin intermediul
tranzact,iilor, ceea ce asigur ˘a integritatea datelor sistemului. Tranzact,iile cont,in o
succesiune de instruct,iuni SQL s,i sunt completate prin folosirea comenzilor COM-
MIT s,i ROLLBACK.
exports.uploadList = function (listItems, listData, callback) {
//bulk insert (’a’, ’b’), (’c’, ’d’) etc.
var sql = "INSERT IGNORE INTO LOCATION(name,description,lat,lng,
thumbnail,city_id) VALUES ? ;"
connection.beginTransaction( function (err) {
if(err) {
console.log(err);
callback( true , "Transaction Error");
}
connection.query(sql, [listItems], function (err, result) {
if(err) //eroare inafara de duplicate key
{
console.log(err);
return connection.rollback( function () {
callback( true , "Error Creating Locations");
});
}
var rowIds = [];
for ( var i = result.insertId; i < result.insertId + result.
affectedRows; i++) {
rowIds.push(i);
}
…………………………………………….
connection.commit( function (err) {
if(err) {
return connection.rollback( function () {
callback( true , "Error Commiting Changes!");
});
}
console.log("SUCCES ADDED LIST COMPLETELY!");
var r = new Object();
r.keptImages = keptImages;
r.insertedLocations = insertedLocations;
callback( false ,r);
});
});
Maiˆıntˆai se insereaz ˘a locat,iileˆın tabelul Location. Dac ˘a nu s-au introdus cel
put,in 3 locat,ii unice se face un rollback, iar ˆın caz contrar se creeaz ˘a lista s,i dup ˘a
acea se face leg ˘atura dintre cele 2 tabele(list s,i location). La finalul acestei operat,ii
se s,terg imaginile locat,iilor care nu au fost inserate, pentru a elibera spat,iu pe server.
30

Proiectare s,i implementare Serverul
Chat se ocup ˘a de afis,area tuturor grupurilor de chat dintr-un anumit oras,s,i de
creare de noi grupuri. Pentru afis,are s-a implementat paginare similar ca s,i la liste,
iar pentru crearea unui grup se foloses,te metoda POST s,i se impune o restrict,ie s,i
anume c ˘a un utilizator poate avea un singur grup ˆıntr-un oras,.
exports.create_group= function (req,res){
console.log(req.JWTdecodedUserData);
var groupData=req.body;
console.log(req.body);
groupData.creator=req.JWTdecodedUserData.id;
chatModel.addGroup(groupData, function (err,result){
if(err){
res.json({message:"Error, Ai creat deja o camera in orasul
acesta"});
}
else {
console.log("1 record inserted, ID: " + result.insertId);
res.json({message:"Succes"});
}
});
}
3.3.1.5 Integrare Socket.io
Pentru funct,ia de localizare a autobuzelor s,i funct,ia de chat a aplicat,iei, serverul
trebuie s ˘a suporte comunicarea ˆın timp real dintre el s,i client,ii s˘ai.
ˆIn scopul de a oferi serverului aceste capabilit ˘at,i am utilizat modulul socket.io
care foloses,te tehnologia websockets pentru transmiterea datelor ˆın mod full-duplex
pe o singur ˘a conexiune de tip TCP . Socket.io este o libr ˘arie javascript creat ˘a pentru
aplicat,iile real time de pe web. Aceast ˘a libr ˘arie permite comunicarea bidirect,ional ˘a
bazat ˘a pe evenimente dintre client s,i server, folosind ˆın principal protocolul webso-
ckets s,i polling ca o opt,iune alternativ ˘a. Integrarea socket.io ˆıntr-o aplicat,ie implic ˘a
dou˘a p˘art,i: partea de server s,i partea de client, ambele componente av ˆand un api
identic. Modulul se instaleaz ˘a pe server prin npm, iar pe client se foloses,te libr ˘aria
socket.io-client-java.
Polling [18, pg. 69–70] ˆIn ziua de azi comunicarea ˆın timp real este o parte
important ˘a a internetului. Totus,i implementarea acesteia nu a fost ˆıntotdeauna op-
tim˘a. Mai ales ˆın stadiile init,iale ale internetului, transmiterea datelor ˆın timp real era
ˆıntotdeauna implementat ˘a folosind polling, un procedeu ˆın care clientul contacteaz ˘a
ˆın mod regulat serverul pentru a verifica dac ˘a starea acestuia s-a schimbat. Dac ˘a
da(de exemplu un nou mesaj a fost primit), serverul r ˘aspunde trimit,ˆand un update
ˆınapoi.
WebSockets Pentru a evita interogarea repetat ˘a a serverului, este necesar ˘a
o solut,ie full-duplex ˆın care serverul poate comunica direct cu clientul, nefiind ne-
cesar ˘a init,iativa clientului de fiecare data. Cea mai avansat ˘a s,i folosit ˘a solut,ie la
aceast ˘a problem ˘a este protocolul websockets.
31

Proiectare s,i implementare Serverul
Acesta implic ˘a o conexiune direct ˘a, bidirect,ional ˘a dintre client s,i server, folo-
sind o singur ˘a conexiune TCP . Websockets este structurat ˆıntr-un mod care permite
ambelor p ˘art,i ale conexiunii s ˘a init,ieze transferul de date pe cont propriu.[19]
Figura 3.8 : Comunicare websockets.[4]
Maiˆıntˆai am creat un fis,ier separat care cont,ine toat ˘a logica legat ˘a de transferul
de date prin websockets, care se numes,te ”sockets.js”. Pentru init,ializarea modului
socket.io este necesar un server HTTP care este dat ca parametru ˆın fis,ierul ’www’.
Modulul socket.io este bazat pe evenimente iar integrarea acestuia ˆın sistem
const ˘aˆın definirea evenimentelor s,i a funct,iilor callback care vor rula la declans,area
acestora. Socket.IO cont,ine deja c ˆateva evenimente predefinite precum ”connec-
tion” s,i ”disconnection” acestea fiind evenimentele de baz ˘a unde se creeaz ˘a socke-
tul pentru prima dat ˘a s,i unde este distrus, ˆıncheindu-se astfel conexiunea.
La stabilirea conexiunii init,iale serverul s,i clientul trec prin procedeul de TCP
3-way handshake. Acest procedeu este folosit de protocolul TCP pentru a stabilii
o conexiune de tipul TCP/IP pe internet. Aceast ˘a tehnic ˘a implic ˘a transmiterea de
mesaje ”SYN,SYN-ACK,ACK” ˆıntre server s,i client.
var io = require( ’socket.io’ )( server );
io.on( ’connection’, function ( socket ) {
console.log( ’New user connected:’+socket.id );
});
Codul de mai sus ilustreaz ˘a realizarea unei conexiuni prin socket.io . Odat ˘a
ce procedeul de handshaking dintre server s,i client s-a terminat cu succes, se va
declans,a un eveniment de tip ”connection”. Pe l ˆang˘a numele evenimentului se mai
precizeaz ˘a s,i o funct,ie callback care primes,te ca parametru socket-ul tocmai creat
s,i descrie act,iunile care vor avea loc pentru evenimentul respectiv. De fiecare dat ˘a
cˆand un client se conecteaz ˘a la server funct,ia de tratare a evenimentului va fi invo-
cat˘a cu un sid(session ID) atribuit conexiunii. Prin acest id se poate identifica fiecare
socket ˆın mod unic. C ˆand un client trimite un eveniment c ˘atre server, metoda call-
back corespunz ˘atoare lui este invocat ˘a cu un sid s,i cu datele trimise.
32

Proiectare s,i implementare Serverul
Dup˘a ce conexiunea a fost stabilit ˘a, transferul de date dintre server s,i client se
realizeaz ˘a prin transmiterea de mesaje pe socket. Mesajele trebuie s ˘a fie codificate
ˆın formatul specificat de socket.io. Acest format ˆıi permite modulului s ˘a determine
tipul mesajului s,i datele trimise ˆımpreun ˘a cu metadate necesare pentru efectuarea
operat,iei.
Formatul unui mesaj este urmatorul ”[type] : [id ] : [endpoint] (: [data]).” [20,
pg.93]
.type este un integer care descrie tipul mesajului.
.id este id-ul mesajului, un integer care se incrementeaz ˘a s,i este opt,ional.
.endpoint este locat,ia la care trebuie transmis mesajul. Dac ˘a socketul face
parte dintr-un namespace, acesta va fi precizat aici.
.data cont,ine informat,iile transmise c ˘atre socket.
Pe lˆang˘a evenimentele deja incluse ˆın modul, un dezvoltator ˆıs,i poate crea pro-
priile evenimente la care s ˘a asculte serverul. Un eveniment propriu este creat prin
folosirea metodei socket.on(nume,function(data)) ce implic ˘a precizarea unui nume
unic s,i a unei funct,ii de callback.
Serverul poate de asemenea s ˘a s,i trimit ˘a evenimente c ˘atre client,i. Un client
trateaz ˘a un eveniment ˆıntr-un mod similar ca s,i pe server. Trimiterea evenimentelor
c˘atre un socket se face prin metoda socket.emit. Aceast ˘a metod ˘a primes,te ca para-
metri numele evenimentului, datele s,i eventual o funct,ie de acknowledgement care
ruleaz ˘a dup ˘a confirmarea trat ˘arii evenimentului trimis c ˘atre client.
ˆIn implementarea acestei componente am folosit camere de socketuri. Came-
rele de socketuri au fost necesare pentru localizarea autobuzelor de pe traseele
lor. Fiecare traseu are o camer ˘a asociat ˘aˆın care s,oferii ˆıs,i transmit locat,iaˆın mod
constant. Aceast ˘a transmitere duce la declans,area unui eveniment pe server numit
”busMoved”, lucru care implic ˘a executarea unui broadcast c ˘atre toate socketurile
din camera respectiv ˘a. Turis,tii primesc astfel locat,ia unui autobuz care s-a deplasat
pe traseul urm ˘arit de aces,tia. De asemenea conceptul de socket rooms este folosit
s,iˆın comunicarea dintre turis,ti prin grupuri de chat, fiecare grup av ˆand un nume
de camer ˘a unic. La transmiterea unui mesaj se realizeaz ˘a un broadcast ˆın grupul
respectiv.
Rooms: [20, pg. 66-75] Deoarece socket.io este un protocol bidirect,ional, ser-
verul poate transmite mesaje oric ˘arui client, oric ˆand. Pentru a face us,oar˘a trimiterea
de mesaje unor grupuri de client,i serverul va pune socketurile asociate acestora ˆın
camere diferite. La trimiterea unui mesaj se poate preciza s,i camera destinat,ie a
acestuia.
Camerele socket.io permit gruparea socket-urilor dintr-un anumit namespace ˆın
grupuri. Astfel un socket poate transmite mesaje direct,ionate numai unor anumite
grupuri, serverul f ˘acˆand un broadcast. Un socket poate intra/ies,i dintr-o camer ˘a prin
metodele join sau leave (executate numai de c ˘atre server). Dup ˘a ce un client se
conecteaz ˘a, acesta va preciza s,i camera ˆın care dores,te s˘a intre.
33

Proiectare s,i implementare Serverul
La deconectarea clientului de la server, automat acesta este scos s,i din toate
camerele din care f ˘acea parte.
io.on( ’connection’, function ( socket ) {
socket.join( ’some room’ );
});
io.to( ’some room’ ).emit( ’some event’ );
socket.leave( ’some room’ );
ˆIn scopul separ ˘arii serverului de websockets s,i dup ˘a tipul mesajelor (de locali-
zare sau de chat) s-au folosit namespaces pentru a crea dou ˘a canale de comunicare
diferite.
Namespaces: Api-ul ofer ˘a suport pentru namespaces, care permit creare de
canale diferite de socketuri pe aceeas,i conexiune. Acest lucru este folositor pentru a
minimiza num ˘arul total de resurse (conexiuni TCP) s,iˆın acelas,i timp pentru a separa
p˘art,i ale aplicat,iei, introduc ˆand diferent,iereˆıntre canalele de comunicat,ie.
Socket.IO accept ˘a mai multe conexiuni logice, toate multiplexate pe aceeas,i
conexiune fizic ˘a. Client,ii pot deschide mai multe conexiuni prin specificarea unui
spat,iu de nume (namespace) diferit pentru fiecare dintre acestea. ˆInainte de a se co-
necta, aplicat,ia client precizeaz ˘a namespace-ul dorit ˆımpreun ˘a cu numele de gazd ˘a
(pathname) s,i portul. De exemplu, conectarea la http://example.com:8000/chat va
deschide o conexiune la spat,iul de nume ”chat”.
Fiecare namespace este gestionat independent de celelalte, cu ID-uri de se-
siune separate (sids), funct,ii de tratare a evenimentelor s,i camere diferite. Este im-
portant ca aplicat,iile care folosesc mai multe spat,ii de nume s ˘a specifice namespace-
ul corect atunci c ˆand sunt setate funct,iile event-handler s,i camerele acestora. Se va
folosi argumentul opt,ional namespace disponibil ˆın toate metodele din clasa socke-
tio.server. Atunci c ˆand argumentul namespace este omis, setat la none sau la ’/’,
este utilizat un spat,iu de nume default. Pentru a crea un namespace se foloses,te
metoda io.of(’..’) pe partea de server.
Fiecare namespace cont,ine propriile sale camere, ad ˘augˆandu-se astfel ˆınc˘a un
nivel de separare a socketurilor. Client,ii pot trimite dou ˘a tipuri de mesaje. Acestea
sunt mesaje pentru localizarea autobuzelor s,i mesaje de comunicare ˆıntre turis,ti.
Astfel implementarea socket.io cont,ine dou ˘a namespace-uri numite ”bus-tracking”
s,i ”chat-groups”.
Namespace-ul folosit ˆın localizarea autobuzelor cont,ine un num ˘ar dinamic de
camere. Aceste camere sunt unice s,i reprezint ˘a traseele de autobuze (de exemplu
traseul dus de pe ruta 100). Astfel un client poate urm ˘ari doar autobuzele de pe
traseele care ˆıl intereseaz ˘a.
ˆIn acest namespace serverul se ocup ˘a cu evenimente de tip intrare/ies,ire ca-
mer˘a s,i evenimente de mis,care a unui autobuz.
34

Proiectare s,i implementare Serverul
var io = require(’socket.io’)(server, {
wsEngine: ’ws’
});
var buses= new Buses();
var trackingNsp=io.of("/bus-tracking");
trackingNsp.on(’connection’, function (socket){
socket.on(’joinBusTrackingRoom’, function (params){
if(params.type===’bus’){
socket.join(params.room);
buses.removeBus(socket.id);//sa nu fie in alt room deja
buses.addBus(socket.id,params.busName,params.room);
}
if(params.type===’user’){
for(room inparams.rooms){//poate urmari trasee multiple
console.log(params.rooms[room]);
socket.join(params.rooms[room]);
}
}
});
socket.on(’leaveBusTrackingRoom’, function (params){
socket.leave(params.room);
var bus=buses.getBus(socket.id);
if(bus){
buses.removeBus(socket.id);
}
});
socket.on("busMoved", function (locationData){
var bus=buses.getBus(socket.id);
if(bus)
{
socket.broadcast.to(bus.room).emit(’busMoved’,
generateLocationMessage(bus.busName,locationData.latitude,
locationData.longitude));
}
});
socket.on(’disconnect’, function (){
var bus=buses.removeBus(socket.id);
});
});
Un socket conectat la acest namespace poate fi un s,ofer (autobuz) sau un
turist. Aces,tia pot preciza camerele de localizare ˆın care doresc s ˘a intre, trimit,ˆand
de pe client spre server evenimentul ’joinBusTrackingRoom’ ˆımpreun ˘a cu numele
camerelor sub form ˘a de stringuri. ˆIn cazul ˆın care clientul este un autobuz, acesta
poate fi la un moment dat doar ˆıntr-o camer ˘a spre deosebire de un turist care poate
urm˘ari cˆate trasee dores,te. Pentru a stoca temporar informat,ii despre autobuze s,i
socketuri-le acestora s-a folosit o list ˘a de obiecte de tip Bus, nefiind necesar ˘aˆın
acest caz persistent,a datelor.
Evenimentul ’leaveBusTrackingRoom’ este folosit ˆın cazul ˆın care un autobuz
ˆıs,i schimb ˘a traseul, lucru care implic ˘a p˘ar˘asirea vechii camere s,i intrarea ˆıntr-una
nou˘a. Prin evenimentul ”busMoved” serverul trimite locat,ia unui autobuz tocmai
mis,cat spre restul socketurilor din aceeas,i camer ˘a.
35

Proiectare s,i implementare Serverul
Namespace-ul folosit pentru componenta de comunicare ˆıntre turis,ti are o abor-
dare similar ˘a cu cel folosit pentru localizarea autobuzelor, diferent,a principal ˘a fiind
c˘a mesajele trimise nu sunt locat,ii iar tot,i client,i pot s ˘a emit ˘a mesaje. ˆIn cazul pre-
cedent numai s,oferii puteau s ˘aˆıs,i updateze pozit,ia iar turis,tii doar s ˘a primeasc ˘a
evenimente de deplasare a autobuzelor.
var users= new Users();
var chatGroups=io.of("/chat-groups");
chatGroups.on("connection", function (socket){
socket.on(’join’, function (params,callback){
if(!isRealString(params.name) || !isRealString(params.room))
{
return callback({error:’Numele tau sau al camerei nu este ok’
});
}
socket.join(params.room);
users.removeUser(socket.id);
users.addUser(socket.id, params.name,params.room);
socket.emit(’newMessage’, generateMessage(’Server’, ‘Welcome to
the chat app room : ${params.room}‘));
socket.emit(’newMessage’, generateMessage(’Server’,‘There are: ${
users.getNrUsers(params.room)} users in this room ‘));
socket.broadcast.to(params.room).emit(’newMessage’,
generateMessage(’Server’, ‘${params.name} has joined the room
‘));
callback();
});
socket.on(’createMessage’, function (messageData ) {
var user=users.getUser(socket.id);
if(user && isRealString(messageData.text))
{
socket.broadcast.to(user.room).emit(’newMessage’,
generateMessage(user.name,messageData.text));
}
});
socket.on(’disconnect’, function () {
var user=users.removeUser(socket.id);
if(user){
socket.broadcast.to(user.room).emit(’updateUserList’, users.
getUserList(user.room));
socket.broadcast.to(user.room).emit(’newMessage’,
generateMessage(’Server’,‘${user.name} has left the room
!‘));
}
});
});
Un utilizator poate preciza numele grupului de chat ˆın care dores,te sa intre, iar
pentru a comunica cu restul grupului trimite evenimente de tip ”createMessage”.
Datele utilizatorilor (socket.id,camera,numele) care vorbesc la un moment dat
sunt stocate ˆın memoria serverului. La deconectare socketul este scos din grup.
36

Proiectare s,i implementare Aplicat,ia Android
3.4 Aplicat ,ia Android
Aplicat,ia reprezint ˘a clientul din arhitectura sistemului. Acesta este instalat ˘a pe
telefonul android al unui s,ofer sau al unui turist s,i este responsabil ˘a cu afis,area unei
interfet,e grafice intuitive prin care utilizatorii pot accesa toate serviciile sistemului.
ˆIn crearea aplicat,iei am folosit IDE-ul Android Studio ˆımpreun ˘a cu limbajul de
programare java.
Stilul arhitectural folosit ˆın proiectarea aplicat,iei este MVC, componentele sale
principale fiind activit ˘at,i, fragmente s,i clase de tip model. Aplicat,ia cont,ine activit ˘at,i
pentru autentificare/ ˆınregistrare turis,ti s,i s,oferi ˆımpreun ˘a cu o activitate principal ˘aˆın
care sunt afis,ate funct,iile aplicat,iei. Aceast ˘a activitate principal ˘a se numes,te ”Mai-
nActivity” s,i cont,ine mai multe fragmente care se interschimb ˘aˆıntre ele ˆın funct,ie de
select,ia utilizatorului din meniul de navigare. Astfel activitatea joac ˘a rolul unui con-
troller de navigare, iar fragmentele cont,in logica s,i cont,inutul principal al aplicat,iei.
Datele necesare sunt stocate ˆın clase de tip model iar view-urile sunt reprezentate
prin fis,iere layout xml.
Activitatea principal ˘a reprezint ˘a punctul de start al aplicat,iei. Este o compo-
nent˘a care are posibilitatea de a afis,a o interfat,˘a utilizatorului cu care acesta poate
interact,iona. O aplicat,ie este alc ˘atuit˘a din activit ˘at,i multiple. Fiecare activitate poate
ˆıncepe alt ˘a activitate prin obiecte ”Intent”. De fiecare dat ˘a cˆand o activitate nou ˘a
ˆıncepe, activitatea precedent ˘a este oprit ˘a s,i pus ˘aˆıntr-o stiv ˘a numit ˘a ”back stack”
care este folosit ˘aˆın navigare atunci c ˆand utilizatorul apas ˘a butonul de back. Codul
de mai jos ilustreaz ˘a modul ˆın care se ajunge ˆın activitatea principal ˘a dup ˘a un login
reus,it al turistului.
Intent i = new Intent(UserLoginActivity. this , MainActivity. class );
i.putExtra("id", integer);
i.putExtra("name",txtNume.getText().toString());
startActivity(i);
Pentru a accesa diferite p ˘art,i ale aplicat,iei se foloses,te un meniu de navigare
numit Navigation Drawer. Sect,iunile accesate prin acest meniu se numesc ”tabs”.
Aceste taburi sunt implementate prin intermediul fragmentelor.
Unfragment [21] este o reprezentare a unui proces s,i a unei interfet,e. El este
incorporat ˆın interiorul unei activit ˘at,i fiind str ˆans legat de ciclul de viat,˘a al acesteia.
O activitate poate ad ˘auga sau elimina fragmente din interiorul ei ˆın orice moment.
Aplicat,ia foloses,te fragmente ˆın toate activit ˘at,ile, fiecare fragment av ˆand propriul
fis,ier xml pentru layout s,i o clas ˘a java.
Fragmentele cont,in logica principala a programului, fiecare fragment fiind res-
ponsabil de un aspect al aplicat,iei. Ele gestioneaz ˘a operat,iile de baza ale acestui
proiect cum ar fi: urm ˘arirea autobuzelor, stabilirea conexiunii la server, downloada-
rea datelor, afis,area h ˘art,ii, etc.
37

Proiectare s,i implementare Aplicat,ia Android
ˆIn cadrul unei arhitecturi orientate pe fragmente, activit ˘at,ile devin controllere de
navigat,ie responsabile de pornirea altor activit ˘at,i, de prezentarea fragmentelor s,i de
transmiterea datelor. Fragmentele vor cont,ine logica s,i view-urile.
Ad˘augarea unui fragment ˆıntr-o activitate se poate face ˆın dou ˘a moduri:
.Static : ce implic ˘a specificarea fragmentului ˆın fis,ierul layout al activit ˘at,ii.
.Dinamic : fragmentul este ad ˘augat direct din cod prin clasele FragmentMana-
ger s,i FragmentTransaction. Layoutul activit ˘at,ii trebuie sa cont,in˘a un place-
holder( de obicei un FrameLayout) ˆın care fragmentul va fi inserat. Aceast ˘a
metoda dinamic ˘a este folosit ˘aˆın aplicat,ie.
fragment =HomeMapFragment.newInstance( mSelectedList ,cityId );
FragmentTransaction trns = getSupportFragmentManager().
beginTransaction();
trns.replace(R. id.main_content_frame ,fragment , "HomeMap");
trns.addToBackStack("HomeMap");
trns.commit();
ˆIn anumite cazuri, un fragmentul poate accepta mai multe argumente. Un model
comun este implementarea unei metode statice newInstance pentru crearea unui
fragment cu argumente. Acest lucru se datoreaz ˘a faptului c ˘a fragmentele trebuie s ˘a
aib˘a un constructor f ˘ar˘a parametri ˆın mod obligatoriu.
public class HomeMapFragment extends Fragment {
public static HomeMapFragment newInstance( ArrayList <ListItem> list,
int city) {
Bundle args = new Bundle();
args.putParcelableArrayList("list",list);// poate sa fie null
args.putInt("cityid",city);
HomeMapFragment f = new HomeMapFragment();
f.setArguments(args);
return f;
}
}
Fragmentele comunic ˘a intre ele prin activitatea p ˘arinte care coordoneaz ˘a navi-
garea s,i le seteaz ˘a argumentele acestora. Numai prin aceasta activitate fragmentele
pot transmite date intre ele.
Este foarte important s ˘a nu comunice direct intre ele s,iˆın general ar trebui
sa comunice doar prin activitatea p ˘arinte. Fragmentele trebuie s ˘a fie componente
modulare, independente s,i reutilizabile.
Astfel pentru comunicarea dintre fragmente s,i activitate se foloses,te o interfat,a
java.
public interface IMainActivity {
public void onListItemLongClicked( int listId,String listName);
public void onListSelected( ArrayList <ListItem> list);
public void onChatGroupSelected( int groupid,String groupName);
}
38

Proiectare s,i implementare Aplicat,ia Android
Activitatea care cont,ine fragmentele trebuie s ˘a implementeze aceast ˘a interfat,˘a
s,i s˘a suprascrie funct,iile necesare. La crearea fiec ˘arui fragment se preia o referint,˘a
a acestei interfet,e, implementat ˘aˆın activitatea p ˘arinte. C ˆand un fragment dores,te
s˘a fie ˆınlocuit sau s ˘a trimit ˘a date activit ˘at,ii sau unui alt fragment, acesta va apela
metoda corespunz ˘atoare din interfat,˘a, declans ˆandu-se un eveniment ˆın MainActi-
vity(activitatea p ˘arinte) care se ocup ˘a de afis,area/scoaterea fragmentelor din interfat,˘a
s,i setarea argumentelor acestora.
Pentru funct,ionarea aplicat,iei sunt necesare mai multe permisiuni, ele fiind
ment,ionate ˆın fis,ierul manifest al aplicat,iei. Aceste permisiuni sunt solicitate la prima
execut,ie a aplicat,iei.
Figura 3.9 : Permisiuni Aplicatie.
Implementarea aplicat,iei a cuprins mai multi pas,i, aces,tia fiind:
.crearea interfet,ei
.downloadarea s,i uploadarea datelor
.stabilirea comunic ˘ariiˆın timp real cu serverul
.implementarea algoritmului de rutare
.crearea fragmentelor care cont,in logica fiec ˘arei componente.
39

Proiectare s,i implementare Aplicat,ia Android
3.4.1 Downloadarea s ,i afis ,area datelor
Aplicat,ia este proiectat ˘a cu capacitatea de a comunica cu serverul central. Ser-
verul expune un API prin care client,ii pot downloada s,i uploada date.
Una dintre problemele principale ale dezvolt ˘arii aplicat,iilor mobile este ment,inerea
timpului de r ˘aspuns c ˆat mai mic al interfet,ei grafice la interact,iunile cu utilizato-
rul. Android randeaz ˘a interfat,a grafic ˘a pe threadul principal. Execut,ia operat,iilor
de lung ˘a durat ˘a pe acest thread va face interfat,a s˘a nu r ˘aspund ˘a.
Downloadarea datelor de la o surs ˘a extern ˘a precum un server necesit ˘a mult
timp s,i nu trebuie s ˘a ruleze pe theadul principal al aplicat,iei. Sistemul Android nu
permite executarea operat,iilor de networking pe acest thread, arunc ˆand except,ii
de tipulNetworkOnMainThreadException . Abordarea threadingului ˆıntr-un mod
corect este esent,ial˘a pentru performant,˘a general ˘a a aplicat,iei.
Astfel, downloadarea de date se face prin intermediul clasei AsyncTask. Async-
Task este un mecanism pentru executarea operat,iilorˆıntr-un background thread( ˆın
fundal) f ˘ar˘a a fi nevoie s ˘a se realizeze manual crearea s,i executarea threadului.
Acesta clas ˘a a fost proiectat ˘a pentru procese de scurt ˘a durat ˘a(cˆateva secunde
cel mult), downloadarea imaginilor f ˘acˆandu-se ˆıntr-un alt mod s,i anume folosind
libr˘aria Glide.
AsyncTask [22] este folosit ˘aˆınˆındeplinirea operat,iilor care nu pot fi executate
pe threadul de UI, precum downladarea datelor de la API. Execut,ia unei AsyncTask
const ˘aˆın trecerea prin patru pas,i, fiecare pas av ˆand o metod ˘a de callback. Metodele
care se ocup ˘a de execut,ia codului ˆın fiecare pas sunt urm ˘atoarele.
.doInBackGround() – Acest pas ruleaz ˘aˆıntr-un thread separat fat ˘a de UI s,i con-
staˆın codul procesului respectiv. ˆInainte de aceasta metoda se va apela on-
PreExecute() iar dup ˘a execut,ie onPostExecute().
.onPreExecute() – Este executat ˆınainte de ˆınceperea firului de execut,ie. Este
folosit pentru a configura o sarcin ˘a care trebuie f ˘acuta ˆın avans.
.onProgressUpdate() – Permite metodei doInBackground() s ˘a transmit ˘a date
c˘atre threadul de UI.
.onPostExecute() – Ruleaz ˘a dup ˘a execut,ia background threadului s,i preia re-
zultatele returnate de c ˘atre doInBackground()
Executarea unei AsyncTask se face invoc ˆand metoda execute prin care de ase-
menea se pot seta argumente.
Conexiunea s,i transferul datelor este realizat ˘a de c ˘atre clasa statica ApiHelper
prin urm ˘atoarea metoda:
40

Proiectare s,i implementare Aplicat,ia Android
public static byte [] getUrlBytes(RequestPackage requestPackage) throws
IOException{
String adress=requestPackage.getEndpoint();
String encodedParams=requestPackage.getEncodedParams();
if(requestPackage.getMethod().equals("GET")&&
encodedParams.length()>0){
adress=String.format("%s?%s",adress,encodedParams);
}
URL url= new URL(adress);
final int READ_TIMEOUT = 30000;
final int CONNECTION_TIMEOUT = 30000;
HttpURLConnection connection=(HttpURLConnection)url.openConnection();
if(requestPackage.getToken()!= null ){
//add token
String basicAuth = "Bearer " +requestPackage.getToken();
connection.setRequestProperty("Authorization",basicAuth);
Log.d( TAG, "getUrlBytes: using token:"+basicAuth);
}
connection.setRequestMethod(requestPackage.getMethod());
connection.setReadTimeout(READ_TIMEOUT);
connection.setConnectTimeout(CONNECTION_TIMEOUT);
connection.setDoInput( true );
if(requestPackage.getMethod().equals("POST")&& encodedParams.length()
>0){
connection.setDoOutput( true );
OutputStreamWriter writer= new OutputStreamWriter(connection.
getOutputStream(), "UTF-8");
writer.write(requestPackage.getEncodedParams());
writer.flush();
writer.close();
}
try {
ByteArrayOutputStream out =new ByteArrayOutputStream();
if(connection.getResponseCode() != HttpURLConnection. HTTP_OK ) {
//200
throw new IOException(connection.getResponseMessage() + ":
with " + adress);
}
InputStream in = connection.getInputStream();
int bytesRead = 0;
byte [] buffer = new byte [1024];
while ((bytesRead = in.read(buffer)) > 0) {
out.write(buffer, 0, bytesRead);
}
out.close();
return out .toByteArray();
}
finally{
connection.disconnect();
}
}
Listing 3.1 : Downloadarea datelor
41

Proiectare s,i implementare Aplicat,ia Android
Acesta metod ˘a creeaz ˘a un obiect URL dintr-un string s,i ulterior apeleaz ˘a me-
toda openConnection() pentru a init,ializa conexiunea care este transformat ˘aˆın obiec-
tul java HTTPUrlConnection. Conectarea la server va avea loc atunci c ˆand se ape-
leaz˘a metoda getInputStream() (sau getOutputStream() pentru cereri POST). Odat ˘a
ce s-a realizat conexiunea se apeleaz ˘a metoda read() a input streamului p ˆan˘a cˆand
datele au fost preluate ˆınˆıntregime, rezultatul fiind un array de bit,i.
Dup˘a downloadarea datelor ˆın format de bit,i aceste sunt transformate ˆıntr-un
string pentru a fi ulterior analizate (parsate). JSON(JavaScript Object Notation) este
un format de transfer al datelor care a devenit din ce ˆın ce mai popular ˆın ultimii ani,
ˆın special pentru serviciile web. Android include pachetul standard org.json care
cont,ine clase ce ofer ˘a acces simplu la crearea s,i parsarea textului JSON. Un obiect
JSON este un set de perechi nume-valoare scrise ˆıntre acolade. Un array JSON
este o list ˘a de obiecte JSON separate prin virgul ˘aˆıntre paranteze p ˘atrate. Obiectele
pot fi cuprinse unul ˆın cel ˘alalt, rezult ˆand o ierarhie. Api-ul org.json furnizeaz ˘a obiecte
Java corespunz ˘atoare textului JSON, cum ar fi JSONObject s,i JSONArray. Aceste
obiecte sunt folosite ˆın popularea claselor model.
Datele precum grupurile de chat s,i listele turistice ˆımpreun ˘a cu locat,iile acestora
sunt afis,ateˆın componenta layout RecyclerView. Aceasta reprezint ˘a un mod eficient
de a afis,a o cantitate mare de date, ment,inˆandˆın memorie un num ˘ar limitat de view-
uri. Implementarea acestei componente necesit ˘a crearea unui adapter care atribuie
valori view-urile ˆın funct,ie de pozit,ia acestora.
42

Proiectare s,i implementare Aplicat,ia Android
3.4.2 Design-ul Interfet ,ei
Interfat,a reprezint ˘a modul prin care un utilizator poate interact,iona cu aplicat,ia.
ˆIn Android un fis,ier care descrie interfat,a este sub forma unui XML. Crearea GUI-ului
s-a f˘acut prin constructorul de interfet,e integrat ˆın android studio.
<?xml version ="1.0" encoding ="utf-8"?>
<LinearLayout xmlns :android ="http://schemas.android.com/apk/res/android"
xmlns :app="http://schemas.android.com/apk/res-auto"
xmlns :tools ="http://schemas.android.com/tools"
android :layout_width ="match_parent"
android :layout_height ="match_parent"
android :background ="@drawable/gradient_background2"
android :gravity ="top"
android :orientation ="vertical"
android :padding ="40dp"
<ImageView
android :id="@+id/imageView"
android :layout_width ="wrap_content"
android :layout_height ="wrap_content"
android :src="@drawable/rttlogo"
android :layout_marginTop ="10dp"/>
<android .support .design .widget .TextInputLayout
android :layout_width ="match_parent"
android :layout_height ="wrap_content"
android :layout_marginTop ="80dp">
<EditText
android :id="@+id/txtNrInmatriculare"
android :layout_width ="match_parent"
android :layout_height ="wrap_content"
android :backgroundTint ="@color/colorPrimaryDark"
android :drawableLeft ="@drawable/ic_bus1"
android :inputType ="textPersonName"
android :textColor ="#cccccc"
android :textSize ="20sp"
android :hint ="@string/NR.Inmatriculare" />
</android .support .design .widget .TextInputLayout >
<android .support .design .widget .TextInputLayout
android :layout_width ="match_parent"
android :layout_height ="wrap_content"
android :layout_marginTop ="25dp">
<EditText
android :id="@+id/txtPassword"
android :layout_width ="match_parent"
android :layout_height ="wrap_content"
android :backgroundTint ="@color/colorPrimaryDark"
android :drawableLeft ="@drawable/ic_pass"
android :inputType ="textVisiblePassword"
android :textColor ="#cccccc"
android :textSize ="16sp"
android :hint ="@string/parola" />
</android .support .design .widget .TextInputLayout >
43

Proiectare s,i implementare Aplicat,ia Android
<Button
android :id="@+id/btnLogIn"
style ="@style/Widget.AppCompat.Button.Colored"
android :layout_width ="match_parent"
android :layout_height ="wrap_content"
android :layout_marginTop ="60dp"
android :textColor ="#cccccc"
android :background ="?android:attr/statusBarColor"
android :text ="Log In" />
</LinearLayout >
ˆIn codul de mai sus este ilustrat un exemplu de interfat,˘a creat ˘a prin limbajul
XML iar rezultatul se poate vedea mai jos.
44

Proiectare s,i implementare Aplicat,ia Android
3.4.3 Crearea fragmentelor
Principala logic ˘a a aplicat,iei se afla ˆın obiecte de tip fragment. Crearea unui
fragment implic ˘a designul interfet,ei f˘acut prin fis,iere xml s,i o clas ˘a java care cont,ine
codul de executat.
Astfel fiecare fragment are un rol important iar principalele fragmente folosite ˆın
aplicat,ie sunt urm ˘atoarele:
.HomeMapFragment
.GroupChatFragment
.BusTrackingFragment
.ChatGroupsListFragment
.ListsFragment
.ListDetailFragment
HomeMapFragment este fragmentul principal al aplicat,iei care este afis,at unui
turist. Interfat,a acestui fragment cont,ine o hart ˘a, o lista de locat,ii turistice, informat,iile
despre trasee s,i autobuze ˆımpreun ˘a cu un buton pentru urm ˘arirea acestora. ˆIn
evenimentul onCreate are loc init,ializarea h ˘art,ii, downloadarea informat,iilor despre
rutele din oras,ul respectiv(care se calculeaz ˘a imediat dup ˘a login) s,i setarea listei
selectate ˆın interfat,˘a.
Pentru a afis,a harta ˆın interfat,˘a se foloses,te api-ul de la google maps pentru
android. Integrarea acestui api const ˘aˆın procurarea unei chei din google developer
console s,i precizarea acesteia ˆın fis,ierul manifest. Acest fis,ier cont,ine informat,ii
despre aplicat,ie necesare la execut,ie.
Fiecare locat,ie are atas,at cˆate un buton ”Visit Location”. La ap ˘asarea acestuia
se foloses,te algoritmul de rutare descris ˆın sect,iunea 3.6 pentru a calcula un drum
optim. Dup ˘a execut,ia algoritmului se ret,in traseele care fac parte din drumul returnat
s,i se genereaz ˘a numele camerelor de sockeuri ale acestora. Camerele au formatul
urm˘ator: ”TrackingRoom”+id traseu s,i sunt unice.
La ap ˘asarea butonului ”Start Tracking” ˆıncepe procesul de urm ˘arire ˆın timp real
al autobuzelor de pe traseele returnate, din perspectiva unui turist. Fluxul acestui
proces este ilustrat ˆın flowchart-ul urm ˘ator.
45

Proiectare s,i implementare Aplicat,ia Android
Figura 3.10 : Flowchart turist
Pentru a comunica cu serverul ˆın timp real se foloses,te obiectul socket din
libr˘aria socket.io-client-java [23]. Socket-ul de pe aplicat,ia client ˆın acest caz doar
primes,te evenimente de tip ”update location” trimise de c ˘atre s,oferii autobuzelor.
Imediat dup ˘a ap ˘asarea butonului de localizare a mijloacelor de transport se
creeaz ˘a o conexiune ˆın felul urm ˘ator.
public void connectSocket(){
try{
Manager manager= new Manager( new URI("http://raduhdd.asuscomm.com
:3000"));
mSocket = manager.socket("/bus-tracking");
mSocket .connect();
configSocketEvents();
}catch (Exception e){
System. out.println(e.getMessage());
}
Dac˘a conexiunea s-a realizat cu succes se configureaz ˘a funct,iile de tratare a
evenimentelor trimise de c ˘atre server.
46

Proiectare s,i implementare Aplicat,ia Android
public void configSocketEvents(){
mSocket .on(Socket. EVENT_CONNECT ,onConnect );
mSocket .on(Socket. EVENT_DISCONNECT ,onDisconnect );
mSocket .on(Socket. EVENT_CONNECT_ERROR ,onConnectError );
mSocket .on(Socket. EVENT_CONNECT_TIMEOUT ,onConnectError );
mSocket .on("socketID", onSocketId );
mSocket .on("serverMessage", onServerMessage );
mSocket .on("busMoved", onUpdateLocation );
mSocket .on("busLeftRoom", busLeftRoom );
}
Astfel primul eveniment declans,at pe clientul android este ’EVENT CONNECT’.
Acest eveniment are loc dup ˘a ce este primit ˘a confirmarea de la server c ˘a a fost
init,iata conexiunea. ˆIn funct,ia de tratare a acestui eveniment are loc introducerea
socketului ˆın camerele traseelor necesare prin emiterea unui eveniment c ˘atre server.
private Emitter.Listener onConnect =new Emitter.Listener() {
@Override
public void call(Object… args) {
Log.d( TAG, "onConnect: Client connected to server");
JSONArray arr= new JSONArray();
JSONObject obj= new JSONObject();
try {
if(roomNames.size()>0){
obj.put("type","user");
for(String i:roomNames){
arr.put(i);
}
obj.put("rooms",arr);
mSocket .emit("joinBusTrackingRoom", obj);//Join multiple
rooms
}
}catch (Exception e) {
e.printStackTrace();
}
}
};
ˆIn metoda de tratare a evenimentului ”busMoved” are loc updatarea pozit,iilor
autobuzelor de pe hart ˘a. Toate markerele autobuzelor sunt stocate ˆıntr-un hashmap,
cheia fiind num ˘arul de ˆınmatriculare.
Astfel la fiecare declans,are a acestui eveniment se verific ˘a dac ˘a autobuzul res-
pectiv exist ˘aˆın hashmap. Dac ˘a nu exist ˘a, markerul acestuia este introdus pentru
prima dat ˘a s,i afis,at pe hart ˘a.
ˆIn cazul ˆın care acesta se reg ˘ases,teˆın hashmap, markerul asociat acestuia
este s,ters s,i reafis,at la noile coordonate. Deconectarea socketului are loc atunci
cˆand fereastra nu mai este ˆın view.
47

Proiectare s,i implementare Aplicat,ia Android
ˆInBusTrackingFragment are loc localizarea unui autobuz din perspectiva s,oferului.
Fragmentul acesta va fi afis,at numai dup ˘a ce logarea unui autobuzului a avut loc cu
succes, return ˆandu-se id-ul rutei din care face parte.
Mai jos este ilustrat ˘a ordinea de execut,ie a act,iunilor unui s,ofer de autobuz
pentru localizarea mas,inii.
Figura 3.11 : Flowchart sofer
La crearea acestui fragment se init,ializeaz ˘a harta s,i se downloadeaz ˘a informat,iile
despre cele 2 trasee (dus/ ˆıntors) din ruta pe care circul ˘a autobuzul, folosindu-se c ˘a
parametru ˆın url id-ul rutei obt,inut dup ˘a autentificare. Toate aceste date sunt prelu-
crate s,i ulterior stocate ˆın clase model.
Init,ial este prezentat ˘a o interfat,˘a prin care s,oferul poate alege traseul de ˆınceput
s,i s˘a porneasc ˘a localizarea autobuzului.
48

Proiectare s,i implementare Aplicat,ia Android
Figura 3.12 : Exemplu interfat ,˘a s,ofer.
La pornirea localiz ˘arii se init,ializeaz ˘a conexiunea s,i sunt configurate evenimen-
tele, similar ca s,iˆın HomeMapFragment. De data aceasta clientul poate intra doar
ˆıntr-o camer ˘a de socketuri, un autobuz nu ˆıs,i poate trimite locat,ia pe mai multe tra-
seeˆın acelas,i timp.
Spre deosebire de fragmentul afis,at utilizatorilor, conexiunea c ˘atre server nu se
ˆıncheie atunci c ˆand interfat,a nu mai este ˆın view. Acest lucru le permite s,oferilor s ˘a
trimit ˘a locat,ia autobuzului s,i cˆand aplicat,ia este ˆın background. Prin ap ˘asarea buto-
nului ”Stop Tracking” autobuzul este scos din camera ˆın care se afl ˘a s,i conexiunea
seˆıncheie.
Preluarea pozit,iei autobuzului de c ˘atre aplicat,ie se face prin FusedLocationApi
de la google. A fost setat update-ul locat,iei din 2 ˆın 2 secunde. La fiecare update al
locat,iei se trimite latitudinea s,i longitudinea c ˘atre server printr-un eveniment numit
”busMoved”.
49

Proiectare s,i implementare Aplicat,ia Android
JSONObject msg= new JSONObject();
try {
msg.put("latitude",latLng.latitude);
msg.put("longitude",latLng.longitude);
mSocket .emit("busMoved", msg);
}catch (JSONException e) {
e.printStackTrace();
}
Nu mai trebuie precizat ˘a s,i camera din care face parte socketul deoarece pe
server sunt stocate informat,ii despre fiecare autobuz conectat.
De fiecare data c ˆand locat,ia este updatata programul verific ˘a dac ˘a autobuzul
se afl ˘a la o distant,˘a mai mic ˘a de 100 metri fat,˘a de stat,ia final ˘a din traseul curent
(cap˘at de linie). ˆIn cazul ˆın care este adev ˘arat, dup ˘a 5 secunde se va executa o
operat,ie de schimbare a camerei de localizare, trec ˆandu-se astfel pe cel ˘alalt sens
al traseului (dus sau ˆıntors).
String oldRoom= roomName ;
roomName ="TrackingRoom"+((BusTrip) spinnerTrip .getSelectedItem()).
getTripId();//traseu schimbat
currentTripId =((BusTrip) spinnerTrip .getSelectedItem()).getTripId();
JSONObject obj= new JSONObject();
try {
obj.put("room",oldRoom);
mSocket .emit("leaveBusTrackingRoom", obj, new Ack() {
@Override
public void call(Object… args) {
String a=String.valueOf(args[0]);
Log.d( TAG, "leaveBusTrackingRoom: "+a);
JSONObject obj= new JSONObject();
try {
obj.put("busName", busName );
obj.put("room", roomName );
obj.put("type","bus");
mSocket .emit("joinBusTrackingRoom", obj);
}catch (Exception e) {
e.printStackTrace();
}
}
});
}catch (Exception e) {
e.printStackTrace();
}
Fragmentele care alc ˘atuiesc componenta de comunicare intre turis,ti sunt Cha-
tGroupsListFragment s,iGroupChatFragment . Primul dintre acestea este respon-
sabil cu afis,area grupurilor de chat din oras,ul respectiv s,i cu crearea unui nou grup
de c˘atre un utilizator. Crearea de grupuri se face prin trimiterea unei cereri POST
care cont,ine numele grupului, limba vorbit ˘a, id-ul utilizatorului s,i id-ul oras,ului.
50

Proiectare s,i implementare Aplicat,ia Android
Dup˘a selectarea unui grup este afis,atGroupChatFragment s,i se realizeaz ˘a
conexiunea cu serverul la namespace-ul ”chat-groups”. Se configureaz ˘a evenimen-
tele s,i se intr ˘aˆıntr-o camer ˘a al c ˘arei nume are formatul urm ˘ator:”room”+roomId.
Emiterea mesajelor se face prin evenimentul ”createMessage” iar pentru a primi
mesaje de la alt,i turis,ti din acelas,i grup clientul asculta dup ˘a evenimentul ”newMes-
sage”. La declans,area acestuia se adaug ˘a un nou mesaj ˆın view.
private void addMessage(String username, String message) {
mMessages .add( new Message(username,message));
mAdapter .notifyItemInserted( mMessages .size() – 1);
mRecyclerView .smoothScrollToPosition( mMessages .size() – 1);
}
Mai sus este ilustrat ˘a secvent,a de cod care adaug ˘a mesajele ˆın interfat,˘a, folosindu-
se component,a RecyclerView ˆın scopul afis,˘arii acestora. Deconectarea are loc
atunci c ˆand utilizatorul ap ˘asa butonul de back sau c ˆand navigheaz ˘a la alt ˘a fereastr ˘a.
Figura 3.13 : Componenta chat.
ListsFragment se ocup ˘a de afis,area listelor turistice din oras,ul curent. Aceste
liste sunt afis,ate pe mai multe pagini, o pagin ˘a cont,inˆand c ˆate 10 elemente. Astfel
url-ul de downloadare are nevoie de 2 parametri: num ˘arul de liste dorite s,i pagina.
Fiecare r ˘aspuns cont,ine datele sub format JSON s,i num ˘arul maxim de pagini. Un
utilizator poate oric ˆand s ˘a execute un refresh pentru a vedea dac ˘a s-au ad ˘augat
liste noi.
51

Proiectare s,i implementare Aplicat,ia Android
Dup˘a selectarea unei liste prin ap ˘asarea ˆındelungat ˘a asupra acesteia, este
afis,atListDetailFragment . Acest fragment va cont,ine fiecare locat,ie din lista res-
pectiv ˘a. Pentru a downloada datele corecte id-ul listei selectate este setat ca argu-
ment al fragmentului atunci c ˆand acesta este creat.
Dac˘a utilizatorul apas ˘a butonul de selectare a listei aceasta va fi transmis ˘aˆın
ˆıntregime activit ˘at,ii principale printr-o interfat,˘a java. La crearea fragmentului Home-
MapFragment aceast ˘a list ˘a selectat ˘a este precizat ˘a ca argument.
Figura 3.14 : Vizualizare liste.
52

Proiectare s,i implementare Aplicat,ia Android
Crearea unei liste are loc ˆınListUploadFragment . Interfat,a acestui fragment
cont,ine un buton de ad ˘augare a unei locat,ii s,i unul de uploadare a listei ˆınˆıntregime.
Figura 3.15 : Creare lista.
La ap ˘asarea butonului de ad ˘augare locat,ie este afis,ata o fereastra dialog prin
care utilizatorul poate introduce numele, descrierea, locat,ia s,i o poza reprezentativa.
Informat,iile despre locat,ii sunt stocate ˆıntr-o lista temporara.
Dup˘a ap˘asarea butonul de upload ii se cere utilizatorului un nume s,i o descriere
a listei dup ˘a care ˆıncepe procesul de uploadare la server. Toate datele sunt trimise
prin metoda POST folosind o cerere de tip multi-part. Uploadarea se face printr-o
singur ˘a cerere, toate datele fiind stocate ˆın aceasta.
53

Proiectare s,i implementare Proiectarea bazei de date
3.5 Proiectarea bazei de date
ˆIn scopul stoc ˘arii datelor de c ˘atre server, s-a folosit o baz ˘a de date implemen-
tat˘a cu MySQL. Acest SGBD (sistem de gestiune a bazelor de date) este cea mai
popular ˘a solut,ie open source folosit ˘aˆın crearea s,i managementul bazelor de date
relat,ionale [24].
ˆIn aceast ˘a baz ˘a de date se vor stoca informat,ii despre: oras,e, rute de autobuz,
conturi utilizatori, grupuri de chat s,i liste de locat,ii turistice.
Pentru interogarea bazei de date am utilizat limbajul SQL(Structured Query
Language).
Restrict,ii
.R(1): nu pot exista 2 utilizatori cu acelas,i username.
.R(2): nu pot exista 2 stat,ii cu aceeas,i latitudine s,i longitudine.
.R(3): nu pot exista 2 rute de autobuz cu acelas,i nume ˆıntr-un oras,.
.R(4): o rut ˘a de autobuze cont,ine 2 trasee (dus, ˆıntors).
.R(5): cele 2 trasee ale unei rute nu pot avea acelas,i nume.
.R(6): nu pot exista 2 autobuze cu acelas,i num ˘ar de ˆınmatriculare.
.R(7): o locat,ie turistic ˘a este identificat ˘a unic prin latitudine s,i longitudine
.R(8): o stat,ie poate face parte din mai multe trasee.
.R(9): un utilizator poate crea multiple liste turistice.
.R(10): un utilizator poate crea un singur grup de chat ˆıntr-un oras,.
.R(11): un oras,are asociate multiple locat,ii turistice.
.R(12): un oras,trebuie s ˘a fac ˘a parte dintr-o t,ara s,i are un nume unic ˆın aceasta.
.R(13): nu pot exista 2 locat,ii turistice cu acelas,i nume ˆın acelas,i oras,.
.R(14): o list ˘a turistic ˘a cont,ine minim 3 locat,ii unice din oras,ul acesteia.
.R(15): o locat,ie turistic ˘a se poate reg ˘asiˆın mai multe liste.
.R(16): nu pot exista 2 t,˘ari cu acelas,i nume.
.R(17): o list ˘a are un singur creator.
.R(18): un traseu nu poate cont,ine 2 stat,ii cu acelas,i num ˘ar de ordine.
54

Proiectare s,i implementare Proiectarea bazei de date
3.5.1 Diagrama Entit ˘at,i-Asociat ,ii (DEA)
Aceasta diagram ˘a arata entit ˘at,iile s,i asocierile dintre ele impreun ˘a cu atributele
acestora.
Atributele entit ˘at,ilor prezentate mai sus sunt ar ˘atate ˆın cele ce urmeaz ˘a:
55

Proiectare s,i implementare Proiectarea bazei de date
3.5.2 Schema MMED (Modelul matematic elementar
al datelor)
Aplic ˘am algoritmul de traducere din DEA ˆın MMED [25] s,i obt,inem urm ˘atoarea
schema MMED.
USER (Mult,imea utilizatorilor, turistii, care folosesc aplicat,ia)
id$int(11)
username$varchar(50) (unic,conform R1).
pass!varchar(255)
LOCATION (Mult,imea locat,iilor care vor alc ˘atui listele turistice)
id$int(11)
name!varchar(50)
description!TEXT
lat!decimal(10,8)
lng!decimal(10,8)
56

Proiectare s,i implementare Proiectarea bazei de date
thumbnail!varchar(255)
City: LOCATION !CITY (R11)
LIST (Mult,imea listelor de locat,ii turistice dintr-un anumit oras,)
id$int(11)
title!varchar(50)
description!TEXT
thumbnail!varchar(255)
created at!DATETIME
Creator: LIST!USER (R17)
LIST DETAILS (LIST,LOCATION) (Mult,imea perechilor de forma < list;location > .
Descrie cont,inutul unei liste. R14R15)
id$int(11)
CHAT ROOM (USER,CITY) (Mult,imea perechilor de forma <u;c> .)
id$int(11)
name!varchar(50) DEFAULT ’no name’
language!varchar(5) (”ro”,”eng”) DEFAULT ’eng’
created at!DATETIME
COUNTRY (Mult,imea tuturor t,˘arilor suportate de aplicat,ie)
id$int(11)
name$varchar(30) (unic conform R16)
CITY (Mult,imea oras,elor dintr-o t,ar˘a)
id$int(11)
cityname!varchar(30)
Country: CITY!COUNTRY
BUS (Autobuzele care apart,in unei rute)
busid$int(11)
registration number$varchar(30) (unic conform R6)
password!varchar(30)
Route: BUS!BUS ROUTE
BUS ROUTE (Mult,imea rutelor de transport in comun dintr-un oras,)
busroute id$int(11)
busroute name!varchar(30)
City: BUS ROUTE!CITY
57

Proiectare s,i implementare Proiectarea bazei de date
BUS ROUTE TRIP (Mult,imea traseelor care alc ˘atuiesc o ruta, acestea sunt de 2
feluri, dus si intors cf. R4)
tripid$int(11)
tripname!varchar(30)
direction!tinyint(1) default ’0’ (poate avea valorile ’0’,’1’)
Route: BUS ROUTE TRIP!BUS ROUTE
BUS ROUTE TRIP DETAILS (BUS ROUTE TRIP , BUS STOP)(Mult,imea perechi-
lor de forma <t;s> . Descrie stat,iile care alc ˘atuiesc un traseu.)
id$int(11)
stop order!int(11) (numarul statiei intr-un traseu R19)
BUS STOP (Mult,imea stat,iilor de autobuz.)
id$int(11)
lat!decimal(10,8)
lng!decimal(10,8)
stop name!varchar(20)
3.5.3 Algoritmul Cheilor
Algoritmul cheilor [25] a fost aplicat pe tabelele bazei de date, ˆın scopul pro-
iect˘arii cheilor. ˆIn continuare voi prezenta execut,ia acestuia pe c ˆateva tabele.
BUS ROUTE TRIP:
k= 2;K= (routeiddirection;routeid tripname );n= 3(routeid;direction;tripname )
kmax=C2
3= 3
i= 1(j=C1
3= 3)
1:1routeid cheie ?NU
Potexistamaimultetraseepeaceeasiruta
1:2direction cheie ?NU
(Potexistamaimultetraseecuaceasidirectie )
1:3tripname cheie ?NU
(Potexistamaimultetraseecuacelasinume )
i= 2(j=C2
3= 3)
2:1routeid;direction cheie ?DA
(Orutacon t,ineunsingurtraseudetipdussauintors (restrictiaR 4))
2:2routeid;tripname cheie ?DA
(Numeleunuitraseudepeorutaesteunic (restrictiaR 5))
2:3direction;tripname cheie ?NU
(Traseelecuaceasidirec t,iedardepealterutepotaveanumeidentice )
Algoritmulseopresteaicideoarecetoateperechileurmatoareconstituieosupercheie
Concluzie :k= 2;K= (tripnamerouteid;routeiddirection )
58

Proiectare s,i implementare Proiectarea bazei de date
CHAT ROOM:
k= 2;K= (creatorcity;creatorcreatedat );n= 5(name;language;createdat;creator;city )
kmax=C2
5= 10
i= 1(j=C1
5= 5)
1:1nume cheie ?NU
(Potexistamaimultegrupuricuacelasinume )
1:2limba cheie ?NU
(Potexistamaimultegrupuricuacelasilimba )
1:3createdat cheie ?NU
(Potexistamaimultegrupuricreateinacelasimoment )
1:4city cheie ?NU
(Potexistamaimultegrupuriinacelasioras )
1:5creator cheie ?NU
(Potexistamaimultegrupuricuacelasicreator )
i= 2(j=C2
5= 10)
2:1cityidcreator cheie ?DA
(Unutilizatorestelimitatlaunsingurgrupperoras (restrictiaR 10))
2:2cityidcreatedat cheie ?NU
(Ungrupdintrunoraspoateaveaaceeasidatadecrearecuoricealtgrup )
2:3cityidnume cheie ?NU
(Intrunoraspotexistagrupuricuacelasinume )
2:4cityidlimba cheie ?NU
(Intrunoraspotexistagrupuricarevorbescaceeasilimba )
2:5numelimba cheie ?NU
(Sepoateregasiungrupcareareacelasinumedarlimbavorbitaestediferita )
2:6numecreatedat cheie ?NU
(Douagrupuricuacelasinumepotficreateinacelasimoment )
2:7numecreator cheie ?NU
(Unutilizatorpoatecreagrupuricuacelasinumedarsafieinorasediferite )
2:8limbacreatedat cheie ?NU
(Potexistagrupuricarevorbescaceeasilimbasiaufostcreateinacelasimoment )
2:9limbacreator cheie ?NU
(Unutilizatorpoateaveacreagrupuricarevorbesclimbidiferite )
2:10creatorcreatedat cheie ?DA
(Unutilizatornupoatecreadouagrupuriinacelasimoment )
i= 3(j=C3
5= 10)
3:1namelanguagecreatedat cheie ?NU
(Potexistamaimultegrupuricuaceeasilimba; numesidatacreare )
Algoritmulcontinuainmodasemanatorpentrucelelaltecombinatiideatribute
Seiau ^ nconsiderarecombinatiicarenucuprinddejaocheie:
(identificatalapasiianteriori )
……………………………
Concluzie :k= 2;K= (cityidcreator;creatorcreatedat )
59

Proiectare s,i implementare Proiectarea bazei de date
3.5.4 MRD (Modelul Relational al Datelor)
1.USER( id,username) `username `pass
2.COUNTRY( idcountry ,name) `name
3.CITY( idcity,city nameidcountry) `cityname, id countryidcountry
4.BUS ROUTE( bus route id,bus route namecityid)`busroute name, `
cityididcity
5.BUS ROUTE TRIP( tripid,bus route iddirection,bus route idtripname) `
busroute id,`direction, `tripname, bus route idbusroute id, direc-
tion2f0;1g
6.BUS ROUTE TRIP DETAILS( id,tripidstop id, trip idstop order) `tripid,
`stop id,`stop order, trip idtripid, stop idstop id, stop order1,
stop order100
7.BUS( bus id,registration number) `registration number, `busroute id,
`password, bus route idbusroute id
8.BUS STOP( stop id,latlng)`lat,`lng,`stop name
9.LIST( listid,creatortitle,creatorcreated at)`title, `thumbnail, `crea-
tedat,`creator, `creatoruser id
10.LOCATION( location id,latlng,namecityid)`name, `thumbnail, `
lat,`lng,`cityididcity
11.LIST DETAILS( id,idlistidlocation) id listlistid, id locationlocation id
12.CHAT ROOM( id,creatorcity, creatorcreated at)`name, `creator, `
language, `city, creatoruser id, citycityid, language2f"ro";"eng"g
60

Proiectare s,i implementare Algoritmul de rutare
3.6 Algoritmul de rutare
Acest capitol prezint ˘a detaliat proiectarea s,i implementarea algoritmului de ru-
tare printr-un oras,folosind rutele de transport urban disponibile.
Am ales s ˘a folosesc algoritmul A* deoarece necesit ˘a un timp de execut,ie scurt
folosind o funct,ie euristic ˘a potrivit ˘a.ˆIn cel mai r ˘au caz are aceeas,i complexitate ca
s,i algoritmul Djikstra.
Algoritmul A* integreaz ˘a o euristic ˘aˆın procedeul de c ˘autare. ˆIn loc s ˘a aleag ˘a
urm˘atorul nod cu cel mai mic cost(m ˘asurat de la nodul de start), alegerea se face
luˆandˆın considerare costul de de la nodul de start plus o estimare p ˆan˘a la destinat,ie
(estimare euristic ˘a). Este o c ˘autare informat ˘a, la fiecare iterat,ie se alege nodul cel
mai promit,˘ator, care se apropie c ˆat mai mult de destinat,ie.
Algoritmul are aceeas,i abordare ca s,i Djikstra doar c ˘a foloses,te costul acumulat
plus costul de la nodul curent p ˆan˘a la destinat,ie ca funct,ie de evaluare a celui mai
promit,˘ator nod. Aceast ˘a valoare determin ˘a pozit,ia nodului ˆın priority queue, nodul
cel mai promit,˘ator fiind ˆıntotdeauna primul nod extras. Nodul cu valoarea cea mai
mic˘a va fi selectat din queue s,i extras, dup ˘a care este verificat dac ˘a reprezint ˘a
solut,ia dorit ˘a.
1Put node_start in the OPEN list with f( node_start ) = h( node_start )
2while the OPEN list is not empty {
3 Take from the open list the node node_current with the lowest f
4 f(node_current ) = g( node_current ) + h( node_current )
5 if node_current isnode_goal we have found the solution;
6 break
7 Generate each state node_successor that come after node_current
8 for each node_successor ofnode_current {
9 Set successor_current_cost = g( node_current ) + w( node_current ,
node_successor )
10 if node_successor is in the OPEN list {
11 ifg(node_successor ) <= successor_current_cost
12 continue
13 }else if node_successor is in the CLOSED list {
14 ifg(node_successor ) <= successor_current_cost
15 continue
16 Move node_successor from the CLOSED list to the OPEN list
17 }else {
18 Add node_successor to the OPEN list
19 Set h( node_successor ) to be the heuristic distance to node_goal
20 }
21 Set g( node_successor ) = successor_current_cost
22 Set the parent of node_successor tonode_current
23 }
24 Add node_current to the CLOSED list
25}
26if(node_current !=node_goal ) exit with error(the OPEN list is empty)
Listing 3.2 : Pseudocod A* [26]
61

Proiectare s,i implementare Algoritmul de rutare
OPEN este lista care cont,ine nodurile vizitate dar inc ˘a neexpandate(adica succesorii
nu au fost generat,iˆınc˘a).
CLOSED cont,ine nodurile care au fost vizitate s,i expandante.
Pe scurt A* este o modificare a algoritmului lui Djikstra optimizat pentru o sin-
gur˘a destinat,ie, Djikstra g ˘ases,te toate drumurile spre toate locat,iile iar A* g ˘ases,te
drumuri spre o singur ˘a locat,ie, prioritiz ˆand drumurile care se apropie cel mai mult
de aceasta. Acest lucru rezult ˘aˆıntr-un num ˘ar mai mic de noduri explorate s,i un timp
de executare mai bun.
Algoritmul creeaz ˘a un set de noduri explorate s,i o frontier ˘a s,i se foloses,te de
acestea pentru a g ˘asi solut,ia. La fiecare iterat,ie extrage un nod din frontier ˘a(lista
OPEN) s,iˆıl pune ˆın lista de noduri explorate (lista CLOSED). Fiecare stare (nod) are
variabilele f,g s,i h. Nodul extras este acela cu cea mai mic ˘a valoare f calculat ˘a prin
formula:
f=g+h (3.1)
.g: costul de la nodul de start p ˆan˘a la nodul curent
.h: o estimare a drumului cel mai scurt p ˆan˘a la nodul final
Valoarea F este relevant ˘a numai pentru nodurile din lista OPEN deoarece este
folosit ˘a pentru a selecta care nod s ˘a fie extras, acesta fiind cel mai probabil s ˘a ne
duc˘a spre destinat,ie.
Pentru nodul tocmai selectat se genereaz ˘a posibilile tranzit,ii din acesta s,i se
adaug ˘a in frontier ˘a. Toate acestea se repeta p ˆan˘a cˆand nodul extras este egal cu
nodul destinat,ie sau p ˆan˘a cˆand frontiera este goal ˘a.
ˆInainte de toate, pentru funct,ionarea eficient ˘a s,i garantarea unei solut,ii optime,
euristica aleas ˘a trebuie s ˘aˆındeplineasc ˘a urm ˘atoarele propriet ˘ati:
.Admisibilitate : O euristic ˘a admisibil ˘a nu supraestimeaz ˘a niciodat ˘a distant,a
pˆan˘a la destinat,ie. C ˘autarea A* cu o euristic ˘a admisibil ˘a este garant,ia g˘asirii
drumului optim. Vrem s ˘a select ˘am o funct,ie h(n) care este mai mic ˘a dec ˆat
costul real de atingere a destinat,iei, acest lucru conduce la rezultate corecte.
Dac˘a valoarea h este mai mare dec ˆat costul atunci algoritmul va fi mai rapid
deoarece exploreaz ˘a un num ˘ar mai mic de st ˘ari dar cu o acuratet,e a rezulta-
tului mai sc ˘azut˘a.
.Consistent,˘a: O euristic ˘a consistent ˘a ment,ine proprietatea h(x)<=d(x;y) +
h(y)pentru toate locat,iile x,y. ˆIn cazul ˆın care euristica este consistent ˘a A*
poate fi implementat ˆıntr-un mod mai eficient, nu se mai reevalueaz ˘a nodurile
deja vizitate s,i expandate. Proprietatea aceast ˘a garanteaz ˘a c˘a dac ˘a un nod a
fost evaluat deja, costul de a ajunge ˆın el nu poate fi mai mic. Imediat ce un
nod este pus ˆın lista CLOSED distant,a cea mai scurt ˘a pˆan˘a la acel nod este
cunoscut ˘a.
Performant,a algoritmului A* este strict dependent ˘a de alegerea unei funct,ii eu-
ristice ideale, av ˆandˆın vedere spat,iul de c ˘autare s,i natura problemei, euristica fi-
ind creierul algoritmului. Valoarea h ar fi ideal egal ˘a cu costul exact de a atinge
destinat,ia. Acest lucru nu este posibil ˆıns˘a, deoarece nu s,tim exact care va fi dru-
mul final, dar se poate g ˘asi o estimare c ˆat mai apropiat ˘a de adev ˘ar.
62

Proiectare s,i implementare Algoritmul de rutare
3.6.1 Alegerea funct ,iei euristice
Pentru a estima costul de la un nod la nodul final am ales s ˘a folosesc ca eu-
ristic ˘a timpul de deplasare dintre dou ˘a locat,ii geografice care se identific ˘a unic prin
latitudine s,i longitudine. Calculul timpul se realizeaz ˘a cu formula t=d=v.
public static double calcEuristica(PathFinderNode a,PathFinderNode b){
return PathFindingUtils.havesineDistance(a.getLat(), a.getLng(), b.
getLat(), b.getLng())/40;
}
ˆIn calculul euristicii m ˘a folosesc de formula distant,ei haversine [27]. Formula ha-
versine este o ecuat,ie important ˘aˆın navigat,ie care returneaz ˘a distant,a dintre dou ˘a
puncte av ˆandˆın vedere coordonatele lor geografice. Urm ˘atoarea ecuat,ie unde
este latitudinea, este longitudinea s,i R este raza p ˘amˆantului (raza= 6,371km) este
formula folosit ˘a pentru acest calcul.
a=sin2(
2) +cos 1cos 2sin2(
2)
c= 2atan2(pa;p
(1a))
d=Rc
Pentru calcularea acestei distant,e am creat o metod ˘a static ˘a public ˘aˆın clasa
PathFindingUtils.
public class PathFindingUtils
{
public static double havesineDistance( double lat1, double lng1, double
lat2, double lng2)
{
final int R=6371;//Earth radius in KM
double dlat=Math.toRadians((lat2-lat1));
double dlng=Math.toRadians((lng2-lng1));
lat1=Math.toRadians(lat1);
lat2=Math.toRadians(lat2);
double a= haversin(dlat) + Math.cos(lat1) *Math.cos(lat2) *
haversin(dlng);
double c = 2 *Math.atan2(Math.sqrt(a), Math.sqrt(1 – a));
return R*c;
//distance in killometers
}
public static double haversin( double val) {
return Math.pow(Math.sin(val / 2), 2);
}
}
63

Proiectare s,i implementare Algoritmul de rutare
ˆIn formula de calcul a funct,iei euristice viteza este setat ˘a c˘a fiind 40 de kilometri
pe or ˘a adic ˘a viteza unui autobuz. De asemenea ˆın algoritm mai este folosit ˘a viteza
de 5 kilometri pe or ˘a pentru calculul costului g de atingere a unei stat,ii merg ˆand
pe jos. ˆIn implementarea algoritmului costul de a ajunge ˆıntr-o stare/stat,ie este
influent,at de as,teptarea ˆın stat,ie s,i de modul ajungerii ˆın aceasta, adic ˘a pe jos sau
cu autobuzul. As,teptarea ˆın stat,ie a fost introdus ˘a pentru a rezolva o problem ˘aˆın
care se schimbau prea mult autobuzele. Astfel la schimbarea autobuzului curent se
adaug ˘a penalit ˘at,i de as,teptare.
Euristica este calculat ˘aˆın cazul cel mai bun, adic ˘a atunci c ˆand drumul de la
nodul curent la nodul final se realizeaz ˘a numai cu autobuzul, pentru a ment,ine pro-
priet˘at,ile de admisibilitate s,i consistent,˘a. Reprezent ˆand timpul minim posibil de a
ajunge ˆın starea final ˘a euristica este admisibil ˘a deoarece nu are cum s ˘a supra-
estimeze costul real p ˆan˘a la destinat,ie, iar proprietatea de consistent,˘a este s,i ea
respectat ˘a. De exemplu, dac ˘a calculam euristica cu viteza de mers pe jos era foarte
probabil s ˘a existe un drum mai rapid, ceea ce ˆınseamn ˘a c˘a estimarea supraesti-
meaz ˘a costul p ˆan˘a destinat,ie, deci admisibilitatea este ˆınc˘alcat ˘a iar programul nu
mai garanteaz ˘a solut,ia optim ˘a.
64

Proiectare s,i implementare Algoritmul de rutare
3.6.2 Implementarea algoritmului A*
Acest subcapitol cont,ine pas,ii urmat,iˆın implementarea algoritmului s,i explica-
rea modului de funct,ionare a acestuia. Scopul algoritmului este de a g ˘asi drumul cel
mai scurt c ˘atre o locat,ie turistic ˘a pornind de la pozit,ia turistului, costul fiind repre-
zentat de timpul de deplasare. Se ia ˆın considerare faptul c ˘a un turist poate merge
pe jos ˆıntre stat,ii s,i trebuie s ˘a as,tepte o perioad ˘a de timp c ˆand schimb ˘a autobuzul.
Datele de intrare ale algoritmului vor fi: punctul de plecare, destinat,ia s,i traseele
autobuzelor din oras,ul respectiv. Dup ˘a execut,ia algoritmului se va obt,ine o lista
de st ˘ari care descrie drumul spre locat,ia dorit ˘a, preciz ˆand stat,iile de urcare s,i de
cobor ˆare.
Figura 3.16 : Diagrama de clase PathFinding
BusRoute : este o clas ˘aˆın care sunt t,inute informat,ii despre o rut ˘a de transport
ˆın comun care cont,ine dou ˘a trasee, dus s,iˆıntors.
BusTrip : este o clas ˘a care cont,ine detalii despre un traseu al unei rute de
autobuz. Cont,ine toate stat,iileˆın ordinea ˆın care apar ˆın traseu.
65

Proiectare s,i implementare Algoritmul de rutare
BusStop : este o clas ˘a care cont,ine informat,iile despre stat,iile de autobuz.
PathFindingNode : este clasa folosit ˘a pentru a reprezenta st ˘arile (nodurile) din
algoritmul A*. Un astfel de nod cont,ine informat,ii despre locat,ia sa, adic ˘a latitudinea
s,i longitudinea.
Variabila name poate avea valorile ”Start”,”Goal” sau ”Numele Stat,iei Actuale”.
Pe lˆang˘a numele st ˘arii am avut nevoie s,i de variabila reached, care descrie modul
ˆın care s-a ajuns ˆın starea curent ˘a. Este nevoie de o astfel de variabil ˘a deoarece
exist ˘a cazuri ˆın care traseele nu sunt conectate ˆıntre ele, adic ˘a nu au cel put,in o
stat,ie comun ˘a.
Pentru a lua ˆın calcul toate posibilit ˘at,ile, se pot conecta oricare dou ˘a trasee prin
tranzit,ii de mers pe jos. Evident, costul g de deplasare din stat,ia precedent ˘aˆın stat,ia
curent ˘a se va calcula ˆın funct,ie de variabila reached. Dac ˘a aceasta are valoarea ”pe
jos”, ˆın formula de calculare a costului viteza va fi egal ˘a cu 5 kilometri pe or ˘a, iar
dac˘a este egal ˘a cu ”bus”, viteza va fi 40 de kilometri pe or ˘a.
Prin obiectul prev am acces la p ˘arintele st ˘arii actuale, acest lucru fiind folositor
ˆın parcurgerea recursiv ˘a pentru a afis,a solut,ia dup ˘a ce a fost g ˘asit˘a starea c ˘autat ˘a.
Variabila tripid este folosit ˘aˆın identificarea unic ˘a a unei st ˘ari. Nu este suficient
s˘a identific unic o stare doar dup ˘a latitudine s,i longitudine deoarece pot ap ˘area
probleme ˆın care se schimb ˘a traseul mult prea des, ˆın cazul ˆın care stat,ia urm ˘atoare
face parte din mai multe trasee. Pentru a rezolva aceast ˘a problem ˘a, a trebuit s ˘a m˘a
folosesc de tripid s,i s˘a adaug ˆın openset aceeas,i stat,ie pentru fiecare traseu din
care face parte.
public boolean equals(Object o) {
if(this == o) return true ;
if(o == null || getClass() != o.getClass()) return false ;
PathFinderNode node = (PathFinderNode) o;
if(Double .compare(node. lat,lat) != 0) return false ;
if(Double .compare(node. lng,lng) != 0) return false ;
return Integer.compare(node.getTripId(),getTripId())==0 ;
}
Cˆand se schimb ˘a traseul, algoritmul adaug ˘a la costul g s,i un timp de as,teptare,
prioritiz ˆandu-se astfel p ˘astrarea traseului curent c ˆat mai mult.
PathFindingUtils : este o clas ˘a static ˘a ajut ˘atoare care cont,ine formula de calcul
a distant,ei dintre dou ˘a locat,ii.
MyPathFinder : este o clas ˘a static ˘a public ˘a. Aceasta clas ˘a cont,ine metoda aS-
tarSearch care returneaz ˘a drumul optim sub forma unei liste de PathFinderNodes.
Aceast ˘a metod ˘a este apelat ˘a ori de c ˆate ori utilizatorul selecteaz ˘a o locat,ie
de vizitat din HomeMapFragment. Odat ˘a ap ˘asat butonul de vizitare, este apelat ˘a
aceast ˘a metod ˘a care returneaz ˘a drumul optim, iar fragmentul se ocup ˘a cu afis,area
acestuia ˆın harta de la google maps.
66

Proiectare s,i implementare Algoritmul de rutare
Port,iunile de mers pe jos sau cu autobuzul sunt afis,ateˆın modalit ˘at,i diferite.
Stat,iile afis,ate sunt doar cele ˆın care se schimb ˘a traseul, pentru a-i fi c ˆat mai clar
utilizatorului unde s ˘a coboare s,iˆın ce autobuz s ˘a urce ˆın continuare.
Maiˆıntˆai, pentru funct,ionarea metodei trebuie ca informat,iile despre rutele de
trasport s ˘a fie accesibile.
Astfel, ˆın callbackul onCreate() al fragmentului HomeMapFragment se descarc ˘a
datele de pe server, algoritmul put ˆand fi executat doar dup ˘a desc ˘arcarea acestor
date.
Desc ˘arcarea datelor necesare execut,iei se realizeaz ˘a printr-un request de tip
GET la url-ul ”http://raduhdd.asuscomm.com:3000/api/bus-tracking/routes/city/:cityId”.
Funct,ia care se ocup ˘a de transferul de bit,i dintre server si client se afla in clasa
statica ApiHelper.Toate aceste informat,ii despre rutele unui oras sunt st ˆanse de ca-
tre server folosind interog ˘ari sql.
exports.getCityRoutesInfo= function (city_id,callback){
var sql="SELECT city.id, city.city_name, bus_route.bus_route_id,
bus_route_name, bus_route_trip.trip_id, trip_name, direction,
stop_order, stop_id,stop2.stop_name, lat, lng FROM bus_route INNER
JOIN city ON city.id=bus_route.city_id INNER JOIN bus_route_trip
ON bus_route.bus_route_id = bus_route_trip.bus_route_id INNER JOIN
bus_route_trip_details brtd ON bus_route_trip.trip_id = brtd.
trip_id INNER JOIN bus_stop stop2 ON brtd.stop_id = stop2.id WHERE
bus_route.city_id=? ORDER BY bus_route_id, direction, stop_order;
"
connection.query(sql,[city_id], function (err,results){
if(err){
callback( true );
return ;
}
callback( false ,results);
});
}
Aceast ˘a interogare returneaz ˘a informat,iile necesare pentru a construi un r ˘aspuns
adecvat. Datele despre rutele oras,ului cerut vor fi afis,ateˆıntr-un format JSON us,or
de interpretat de c ˘atre un client.
Serverul parcurge rezultatele extrase din baza de date s,i construies,te un json
array (un vector) care cont,ine rutele de autobuz s,i traseele fiec ˘arei rute. Un traseu
va cont,ine o list ˘a de stat,ii ordonate.
67

Proiectare s,i implementare Algoritmul de rutare
Figura 3.17 : Raspuns JSON rute
Pe client, r ˘aspunsul primit trece prin procedeul de JSON parsing. Acest pro-
cedeu implic ˘a transformarea r ˘aspunsului de la server primit ca s,ir de caractere ˆın
obiecte java de tip BusRoute, care cont,in BusTrips ˆımpreun ˘a cu stat,iile acestora.
Desc ˘arcarea datelor de la server se face folosind un thread (fir de execut,ie) care
ruleaz ˘aˆın background (fundal) deoarece sistemul de operare Android nu permite
operat,ii legate de ret,ea pe thread-ul principal. Numai acum, dup ˘a ce aceste date au
fost downloadate cu succes, algoritmul de rutare se poate executa.
Metoda pentru calculul drumului optimim primes,te ca parametri latitudinea s,i
longitudinea locat,iei curente a utilizatorului (care este preluat ˘a folosind Fused Loca-
tion API) s,i a destinat,iei,ˆımpreun ˘a cu rutele de autobuze desc ˘arcate.
Laˆınceputul algoritmului, se init,ializeaz ˘a nodul de start s,i nodul destinat,ie.
Aceste dou ˘a noduri nu fac parte din niciun traseu, iar nodul de start este primul
element din lista OPEN.
Pentru implementarea listei OPEN se foloses,te o structur ˘a de date priority qu-
eue (coad ˘a de priorit ˘at,i). Aceast ˘a structur ˘a de date us,ureaz ˘a procedeul de extra-
gere a celui mai promit,˘ator nod.
68

Proiectare s,i implementare Algoritmul de rutare
Pentru a s,ti care element are prioritatea cea mai mare, se atribuie structurii prio-
rity queue un obiect de tip comparator ˆın constructor, cu ajutorul c ˘aruia se evalueaz ˘a
elementele ˆın funct,ie de valoarea lui f ( vezi 3.1).
Bucla principal ˘a a algoritmului ruleaz ˘a atˆat timp c ˆat frontiera nu este goal ˘a,
adic˘a pˆan˘a cˆand nu mai sunt posibilit ˘at,i neexplorate.
La fiecare iterat,ie este extras s,i eliminat din queue nodul cu cea mai mic ˘a va-
loare f(cel mai promit,˘ator) s,i marcat ca fiind explorat, prin ˆınserarea acestuia ˆın lista
closed.
Se verific ˘a mai ˆıntˆai dac ˘a starea tocmai extras ˘a este cea c ˘autat ˘a (destinat,ia do-
rit˘a). Dac ˘a da, se construies,te solut,ia parcurg ˆand recursiv p ˘arint,ii fiec ˘arei st ˘ari pˆan˘a
la starea de ˆınceput, iar solut,ia este returnat ˘a, algoritmul termin ˆandu-s,i execut,ia.
public void printPath1(PathFinderNode root, ArrayList <PathFinderNode> a)
{
if(root.getPrev() == null )
{
a.add(root);
return ;
}
printPath1(root.getPrev(),a);
a.add(root);
}
ˆIn caz contrar se genereaz ˘a toate tranzit,iile (posibilit ˘at,ile) din nodul tocmai ex-
tras. Pentru fiecare nod se adaug ˘a automat o tranzit,ie de mers pe jos p ˆan˘aˆın
starea final ˘a. Dac ˘a nodul se afl ˘a la o distant,˘a mai mare de 1 kilometru, i se seteaz ˘a
valoarea f ca fiind foarte mare, pentru ca aceast ˘a solut,ie s˘a fie o ultim ˘a opt,iune.
Dup˘a aceea se parcurg toate posibilit ˘at,ile g˘asite. Dac ˘a o stare se afl ˘a deja
ˆın lista de vizitate (closed set) aceasta poate fi ignorat ˘a, conform propriet ˘at,ii de
consistent,˘a a funct,iei euristice.
Costul g este calculat pentru fiecare stare ca fiind timpul de mers de la p ˘arinte
pˆan˘aˆın nodul curent plus costul de deplasare de la ˆınceput p ˆan˘a la p ˘arinte.
Acest cost se calculeaz ˘a diferit ˆın funct,ie de modul ˆın care s-a ajuns ˆın nod.
Dac˘a stat,ia a fost atins ˘a merg ˆand pe jos atunci ˆın formula de calculare a costului,
viteza va fi egal ˘a cu 5 km/h (viteza medie a unui om). Dac ˘a deplasarea a fost
realizat ˘a folosind un autobuz, viteza este 40/km/h (viteza medie a unui autobuz).
Port,iunile de mers cu autobuzul au astfel prioritate mai mare ˆın algoritm (nu poate
exista o solut,ie mai bun ˘a dec ˆat deplasarea cu autobuzul din nodul curent p ˆan˘a la
destinat,ie).
69

Proiectare s,i implementare Algoritmul de rutare
De asemenea, costul g cres,te cu 5 minute dac ˘a tripid-ul p ˘arintelui s,i a st ˘arii
curente nu sunt egale, adic ˘a dac ˘a s-a schimbat traseul. Acest lucru previne schim-
barea f ˘ar˘a de rost a autobuzelelor, ment,inˆand num ˘arul final de trasee folosite c ˆat mai
mic. Valoarea f din formula 3.1 este calculat ˘aˆın acelas,i mod pentru toate st ˘arile.
O stare este ad ˘augat ˘aˆın lista open (openset) dac ˘a aceasta nu exist ˘a deja, iar
ˆın cazul ˆın care exist ˘a, se verific ˘a dac ˘a valoarea f a acesteia este mai mic ˘a dec ˆat
valoarea f a echivalentului din openset. ˆIn caz afirmativ nodul din openset este
ˆınlocuit de nodul curent care este mai promit,˘ator. Dup ˘a ce au fost introduse toate
posibilit ˘at,ile, algoritmul se repet ˘a pˆan˘a cˆand a fost g ˘asit˘a starea c ˘autat ˘a sau p ˆan˘a
cˆand au fost explorate toate st ˘arile.
Figura 3.18 : Exemplu algoritm
70

Proiectare s,i implementare Algoritmul de rutare
3.6.2.1 Generarea posibilit ˘at,iilor de tranzit,ie
Dintr-un nod se pot genera mai multe feluri de tranzit,ii. Acestea sunt tranzit,ii de
tip mers pe jos sau cu autobuzul.
Pentru a lua ˆın considerare toate posibilit ˘at,ile s,i de a lega toate traseele de
autobuz ˆıntre ele a trebuit s ˘a se genereze s,i tranzit,ii de mers pe jos. ˆIn unele cazuri
este mai avantajos ca utilizatorul s ˘a coboare din autobuz, s ˘a mearg ˘a o distant,˘a
scurt ˘a pe jos, apoi s ˘a ia un alt autobuz din alt traseu.
Generarea nodurilor care pot fi atinse deplas ˆandu-se cu autobuzul, plec ˆand din
starea curent ˘a se face ˆın felul urm ˘ator:
-pentru fiecare traseu din oras,ul respectiv se caut ˘a stat,ia care are aceeas,i lati-
tudine s,i longitudine cu nodul curent.
-dup ˘a ce a fost g ˘asit˘a, dac ˘a stat,ia nu este cap de linie se adaug ˘a urm ˘atoarea
stat,ieˆın lista de posibile tranzit,ii.
ArrayList <PathFinderNode> posibilitatiiTranzitie= new ArrayList <>();
ArrayList <Integer> traseeCareContinStatia= new ArrayList <>();
//1.Statiile in care se poate ajunge cu autobuzul
for(BusTrip i:busTrips){
int pos=i.getStatii().indexOf( new BusStop("temp",cur.getLat(),cur.
getLng()));//pos statie in trip
if(pos!=-1 && pos!=i.getStatii().size()-1){
BusStop s=i.getStatii().get(pos+1);
PathFinderNode temp= new PathFinderNode("Bus",s.getStopName());
temp.setStopId(s.getStopId());
temp.setLat(s.getLat());
temp.setLng(s.getLng());
temp.setTripId(i.getTripId());
temp.setRouteName(i.getTripName());
posibilitatiiTranzitie.add(temp);
traseeCareContinStatia.add(i.getTripId());
}
}
Nodurile (stat,iile) care pot fi atinse merg ˆand pe jos din stat,ia curent ˘a sunt ge-
nerate ˆın felul urm ˘ator:
-Se parcurg toate traseele care nu cont,in stat,ia cu aceleas,i coordonate cu nodul
curent, deoarece nu are rost mersul pe jos dintre dou ˘a stat,ii care fac parte din
acelas,i traseu.
-La fiecare iterat,ie se caut ˘a cea mai apropiat ˘a stat,ie de stat,ia curent ˘a. Dac ˘a
distant,a dintre aceste stat,ii este mai mare de un kilometru, aceast ˘a posibilitate este
ignorat ˘a (am ales s ˘a existe o limit ˘a maxim ˘a de 1km de mers pe jos ˆıntre 2 stat,ii).
Faptul c ˘a se ia ˆın considerare doar cea mai apropiat ˘a stat,ie dintr-un traseu
mics,oreaz ˘a num ˘arul total de posibilit ˘at,i, folosindu-se astfel mai put,in˘a memorie.
71

Proiectare s,i implementare Algoritmul de rutare
Secvent,a de cod de mai jos prezint ˘a generarea tranzit,iilor de tipul ”mers pe jos”.
for(BusTrip i:busTrips){
if(!traseeCareContinStatia.contains(i.getTripId())){
BusStop closestStatie=i.getStatii().get(0);
for(BusStop j:i.getStatii()){
if(PathFindingUtils.havesineDistance(closestStatie.getLat(),
closestStatie.getLng(), cur.getLat(), cur.getLng())>
PathFindingUtils.havesineDistance(j.getLat(), j.getLng(),
cur.getLat(),cur.getLng())){
closestStatie=j;
}
}
if(PathFindingUtils.havesineDistance(closestStatie.getLat(),
closestStatie.getLng(), cur.getLat(), cur.getLng())>1){
continue ;
}
PathFinderNode temp= new PathFinderNode("Walking",closestStatie.
getStopName());
temp.setStopId(closestStatie.getStopId());
temp.setLat(closestStatie.getLat());
temp.setRouteName(i.getTripName());
temp.setLng(closestStatie.getLng());
temp.setTripId(i.getTripId());
posibilitatiiTranzitie.add(temp);
}
}
72

Capitolul 4
Testarea sistemului
Un pas important ˆın crearea sistemului a fost testarea acestuia pentru a vedea
dac˘a funct,ioneaz ˘a corespunz ˘ator cerint,elor software identificate ˆın faza de analiz ˘a.
Cele mai importante module testate au fost API-ul, componenta de urm ˘arire a auto-
buzelor s,i algoritmul de rutare.
Pentru testarea API-ului de pe server am utilizat programul postman. Post-
man este un program specializat ˆın testarea API-urilor prin protocolul HTTP , acesta
prezint ˘a o interfat,˘a us,or de utilizat s,i permite trimiterea cererilor c ˘atre server c ˆat s,i
interpretarea r ˘aspunsurilor acestuia.
73

Testarea sistemului Testarea sistemului
Testarea funct,ionalit ˘at,ii componentei de localizare ˆın timp real a autobuzelor a
fost realizat ˘a folosind emulatoarele de telefoane android din Android Studio. Fiecare
emulator reprezent ˆand un autobuz care se afl ˘aˆın mis,care pe un anumit traseu.
Un emulator android permite modificarea locat,iei acestuia reprezentat ˘a prin lati-
tudine s,i longitudine. Simularea mis,c˘arii autobuzelor a fost realizat ˘a prin ˆınc˘arcarea
fis,ierelor gpx ˆın emulator.
GPX(GPS exchange Format) este un format de date bazat pe standardul XML
folosit ˆın schimbul de coordonate GPS ˆıntre aplicat,ii. Spre deosebire de alte tipuri
de fis,iere care pot fi ˆınt,elese doar de programele care le-au creat, fis,ierele GPX
cont,in o descriere a cont,inutului acestora, permit,ˆand oricui s ˘a creeze un program
care s ˘a poat ˘a citi datele din ˘auntru.
74

Testarea sistemului Testarea sistemului
Fis,ierele GPX au fost folosite pentru a simula deplasarea autobuzelor pe tra-
seele acestora. Aceste fis,iere au fost generate prin intermediul sitului [28] , care
primes,te ca parametru un link c ˘atre o hart ˘a google maps pe care am mapat tra-
seul respectiv s,i returneaz ˘a un fis,ier care cont,ine datele necesare pentru simularea
mis,c˘arii unui autobuz.
ˆIn imaginea de mai jos se poate vedea console log-ul serverului ˆın timpul loca-
liz˘arii autobuzelor.
Pentru testarea execut,iei corecte a algoritmului de rutare A*, a fost necesar ˘a
colectarea datelor despre rutele de transport ˆın comun din oras,ele suportate. Mo-
mentan aplicat,ia ofer ˘a suport numai pentru oras,ul Constant,a, dar pot fi ad ˘augate pe
viitor cu us,urint,˘a mai multe oras,e, aplicat,ia continu ˆand s ˘a funct,ioneze.
Datele necesare au fost procurate de pe situl RATC Constant,a, dup ˘a care au
fost introduse ˆın baza de date s,i algoritmul a fost testat folosind aceste informat,ii.
75

Capitolul 5
Concluzii
ˆIn aceast ˘a lucrare a fost prezentat procesul de creare a unui sistem care are ca
scop ghidarea turis,tilorˆıntr-un oras,str˘ain, acesta fiind testat pentru oras,ul Constant,a.
Lucrarea descrie tot,i pas,ii urmat,i pentru realizarea acestui sistem care este alc ˘atuit
din client,i android s,i un server central care coordoneaz ˘a transferul de date.
Acest ghid turistic virtual este materializarea visurilor de vacant,˘a, indiferent c ˆat
de tradit,ionale, ˆındr˘aznet,e sau excentrice ar fi. Proiectul este un portal de turism
care pune accentul pe funct,ionalit ˘at,i multiple, astfel ˆıncˆat s˘a transforme experient,a
utilizatorului ˆıntr- o pl ˘acut˘a incursiune ˆın lumea tehnicii s,i a vacant,elor.
Toate funct,ionalit ˘at,ile s,i obiectivele aplicat,iei au fost implementate s,i testate cu
succes. Aplicat,ia calculeaz ˘a drumul optim de la un utilizator c ˘atre un obiectiv turistic.
Totodat ˘aˆıi ofer ˘a utilizatorului posibilitatea de a vizualiza ˆın timp real autobuzele
care circul ˘a pe traseele care fac parte din drumul returnat de algoritm. Sistemul
este low-cost s,i us,or de ˆıntret,inut, fiind foarte probabil ca un s,ofer s ˘a det,in˘a un
smartphone android. De asemenea aplicat,ia cont,ine s,i o component ˘a social ˘a prin
care utilizatorii pot crea s,i vizualiza liste de locat,ii turistice s,i prin care pot comunica
ˆın scopul schimb ˘arii de opinii s,i idei.
Contribut,ia mea la dezvoltarea aplicat,iei a constat ˆın studierea unor diferite sti-
luri arhitecturale s,i tehnologii s,iˆınˆınsus,irea cunos,tint,elor necesare. De asemenea
m-am documentat despre algoritmi de pathfinding precum A* s,i Djikstra s,i despre
multiple protocoale de transmitere a datelor pe internet precum websockets s,i HTTP .
Rolul meu a fost acela de integrare a tuturor acestor tehnologii s,i elemente teoretice
ˆıntr-o aplicat,ie rapid ˘a s,i us,or de folosit.
Acest proiect m-a ajutat s ˘aˆınt,eleg procesul de dezvoltare a unei aplicat,ii mobile
android care cont,ine multiple componente s,i funct,ionalit ˘at,i. Am fost nevoit s ˘a creez
un server care expune un API REST s,i care de asemenea suport ˘a comunicare ˆın
timp real prin websockets s,i s˘a fac conexiunea dintre acest server s,i aplicat,ie.ˆIn
crearea at ˆat a serverului c ˆat s,i a aplicat,iei am c ˘ap˘atat o ˆınt,elegere mai bun ˘a despre
MVC s,i despre important,a acestuia ˆıntr-un program.
76

Concluzii Concluzii
O dezvoltare ulterioar ˘a va fi extinderea componentei de chat. Aceast ˘a com-
ponent ˘a poate fi ˆımbun ˘at˘at,it˘a prin: ad ˘augarea de criptare a mesajelor end to end,
memorarea mesajelor ˆın scopul vizualiz ˘arii istoriei convorbirilor, ad ˘augarea a mai
multor tipuri de mesaje: mesaje imagine, masaje locat,ie etc, s,tergerea automat ˘a a
grupurilor de chat care au o vechime mai mare de c ˆateva zile. De asemenea o alt ˘a
funct,ionalitate interesant ˘a ar fi urm ˘arirea ˆın timp real a utilizatorilor dintr-un grup, ˆın
scopul ˆıntˆalnirii acestora.
Pe viitor se vor ad ˘auga informat,ii despre mai multe oras,e, momentan oferindu-
se suport numai pentru oras,ul Constant,a. O alt ˘a dezvoltare ulterioar ˘a ar putea fi
ad˘augarea de suport pentru alte tipuri de mijloace de transport ˆın comun precum
metrou, microbuze, ˆın funct,ie de dot ˘arile existente ˆın fiecare oras,.
77

Bibliografie
[1] Image. https://developer.android.com/guide/platform/
images/android-stack_2x.png .
[2] Image. https://koenig-media.raywenderlich.com/uploads/
2016/04/diagram-mvc-480×241.png .
[3] Image. https://jsao.io/wp-content/uploads/2017/05/
async-processing-nodejs.png .
[4] Image. https://www.pubnub.com/wp-content/uploads/2014/09/
WebSockets-Diagram.png .
[5] Despre nodejs. https://en.wikipedia.org/wiki/Node.js .
[6] Despre java. https://https:
//www.java.com/en/download/faq/whatis_java.xml .
[7] Arhitectura android.
https://developer.android.com/guide/platform/ .
[8] Despre http.
https://developer.mozilla.org/en-US/docs/Web/HTTP .
[9] Despre gps.
https://en.wikipedia.org/wiki/Global_Positioning_System .
[10] Despre websockets. https:
//developer.mozilla.org/en-US/docs/Web/API/WebSockets_API .
[11] Lector dr. Ciuc ˘a Marian-George. Curs dezvoltarea aplicat ¸iilor web.
[12] Lector dr. B ˘autu Elena. Curs inteligent ¸ ˘a artificial ˘a.
[13] Algoritmul astar descriere. https://algorithmsinsight.wordpress.
com/graph-theory-2/a-star-in-general/ .
78

Bibliografie Bibliografie
[14] Conf. dr. Puchianu Crengut ¸a. Curs ingineria sistemelor soft.
[15] Node arhitecture. http://www.havlena.net/en/programming/
node-js-how-it-differs-from-traditional-web-servers/ .
[16] Npm. https://docs.npmjs.com/getting-started/what-is-npm .
[17] Despre express. https://expressjs.com/ .
[18] Stefan Buttigieg and Milorad Jevdjenic. Learning Node.js for Mobile
Application Development . Packt Publishing Ltd, 2015.
[19] Websockets. https://www.pubnub.com/blog/
2015-01-05-websockets-vs-rest-api-understanding-the-difference/ .
[20] Rohit Rai. Socket.IO Real-time Web Application Development . Packt
Publishing Ltd, 2013.
[21] Fragmente android. https://guides.codepath.com/android/
Creating-and-Using-Fragments .
[22] Clasa asynctask. https:
//developer.android.com/reference/android/os/AsyncTask .
[23] Socket.io client.
https://github.com/socketio/socket.io-client-java .
[24] Sgbd-ul mysql. https://www.mysql.com/about/ .
[25] Conf. dr. Christian Mancas ¸. Curs sisteme de gestiune a bazelor de date.
[26] Pseudocod astar.
http://mat.uab.cat/ ˜alseda/MasterOpt/AStar-Algorithm.pdf/ .
[27] Distanta haversine.
https://www.movable-type.co.uk/scripts/latlong.html .
[28] Fisiere gpx. https://mapstogpx.com/mobiledev.php .
79

Similar Posts