From e6f91be6b5bb4c119d9c20dcca95a07329b47a60 Mon Sep 17 00:00:00 2001 From: Yann Caumartin <yann.caumartin@insa-cvl.fr> Date: Sat, 3 Dec 2016 23:25:56 +0100 Subject: [PATCH] Fonction de reperage d'agglomerat + petits changements --- Modele/agglo.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++- Modele/agglo.h | 24 +++++++++---- 2 files changed, 115 insertions(+), 7 deletions(-) diff --git a/Modele/agglo.c b/Modele/agglo.c index ccb4528..768f872 100644 --- a/Modele/agglo.c +++ b/Modele/agglo.c @@ -16,6 +16,7 @@ ErrEnum initAgglo(Agglomerat* a,Point* pts, uint32_t taille) a->moy.lon=0; for (uint32_t i=0; i<taille;i++) { + pts[i].type=AGGLOMERAT; a->agglo[i]=&pts[i]; a->moy.lat+=pts[i].pos.lat; a->moy.lon+=pts[i].pos.lon; @@ -35,8 +36,9 @@ void libereAgglo(Agglomerat *const a) Agglomerat fusionAgglo(Agglomerat const* const a1, Agglomerat const* const a2) { + /*Pour que les agglomérats soient dans l'ordre chronologique*/ if (a1->agglo[0]->date > a2->agglo[0]->date) - return fusionAgglo(a2,a1); + return fusionAgglo(a2,a1); Agglomerat retour; @@ -49,10 +51,14 @@ Agglomerat fusionAgglo(Agglomerat const* const a1, Agglomerat const* const a2) return (Agglomerat){ {0, 0}, NULL, 0}; } + /*Définition des valeurs du nouvel agglomérat*/ + retour.nbPts=a1->nbPts+a2->nbPts; retour.moy.lat=(a1->moy.lat+a2->moy.lat)/2; retour.moy.lon=(a1->moy.lon+a2->moy.lon)/2; + /*Concaténation des points dans le nouvel agglomérat*/ + for(uint32_t i=0; i<a1->nbPts;i++) { retour.agglo[i]=a1->agglo[i]; @@ -72,3 +78,93 @@ uint32_t ecartTemps(Agglomerat const* const a1, Agglomerat const* const a2) return a2->agglo[0]->date - a1->agglo[a1->nbPts -1]->date; } + +ErrEnum repereAgglo(Point* points, uint32_t tailleP, Agglomerat** agglos, uint32_t* tailleA) +{ + uint32_t periode=points[1].date - points[0].date; + uint32_t debut,fin,t; + *tailleA=0; + Agglomerat** agglosTmp=calloc(tailleP/2, sizeof(Agglomerat*)); + if (agglosTmp==NULL) + { + fprintf(stderr, "%s\n", strerror(errno)); + return ALLOCATION_FAILURE; + } + Agglomerat* tmp=NULL; + + for(uint32_t i=1; i<tailleP; i++) + { + /*debut et fin représentent les index entre lesquels sont compris les + points du potentiel futur agglomérat*/ + debut=i-1; + fin=i; + + while(fin<tailleP && + distance(&(points[fin].pos),&(points[fin-1].pos)) / periode <= VMIN*MARGE) + /*Tant que la personne n'est pas en dessous d'une certaine vitesse + (et qu'on est pas à la fin du tableau) */ + { + fin++; + } + if ((fin-debut)*periode>=DUREEMINI) + /*Si les points couvrent plus que la durée minimum d'un agglomérat + on crée un agglomérat à partir de ces points*/ + { + t=*tailleA; + + if ((agglosTmp[t]=calloc(1, sizeof(Agglomerat)))==NULL) + { + fprintf(stderr, "%s\n", strerror(errno)); + return ALLOCATION_FAILURE; + } + + if(initAgglo(agglosTmp[t], points + debut,fin-debut)==ALLOCATION_FAILURE) + { + return ALLOCATION_FAILURE; + } + + if(t!=0 && (ecartTemps(agglosTmp[t-1],agglosTmp[t])<DIFTMINI + || distance(&agglosTmp[t]->moy, &agglosTmp[t-1]->moy)<DISTMINI)) + /*Si l'agglomérat construit est proche en distance ou en temps de l'agglomérat + précédent on les fusionne*/ + { + if ((tmp=calloc(1,sizeof(Agglomerat)))==NULL) + { + fprintf(stderr, "%s\n", strerror(errno)); + return ALLOCATION_FAILURE; + } + + *tmp=fusionAgglo(agglosTmp[t-1],agglosTmp[t]); + + libereAgglo(agglosTmp[t-1]); + libereAgglo(agglosTmp[t]); + free(agglosTmp[t-1]); + free(agglosTmp[t]); + + agglosTmp[t]=NULL; + agglosTmp[t-1]=tmp; + tmp=NULL; + } + else + { + (*tailleA)++; + } + + } + i=fin; + } + + if ((*agglos=calloc(*tailleA, sizeof(Agglomerat)))==NULL) + { + fprintf(stderr, "%s\n", strerror(errno)); + return ALLOCATION_FAILURE; + } + + for(uint32_t i=0; i<*tailleA; i++) + { + agglos[0][i]=*agglosTmp[i]; + free(agglosTmp[i]); + } + free(agglosTmp); + return SUCCESS; +} diff --git a/Modele/agglo.h b/Modele/agglo.h index 2c8c734..22c23d1 100644 --- a/Modele/agglo.h +++ b/Modele/agglo.h @@ -28,7 +28,7 @@ d'écarter les cas où la personne ralentit pour une raison quelconque*/ * * @return Retourne une valeur d'erreur définie dans 'strucutres.h' */ -ErrEnum initAgglo(Agglomerat*,Point* ,uint32_t); +ErrEnum initAgglo(Agglomerat* a,Point* pts, uint32_t taille); /** * @brief Libère la mémoire prise par le tableau de pointeurs sur points de @@ -36,9 +36,9 @@ ErrEnum initAgglo(Agglomerat*,Point* ,uint32_t); * * @param a L'agglomérat où on libère la mémoire * -* @return Procédure +* @return Valeur d'erreur ou de succes définies dans structures.h */ -void libereAgglo(Agglomerat *const); +void libereAgglo(Agglomerat *const a); /** * @brief Fusionne deux agglomérats @@ -52,7 +52,7 @@ void libereAgglo(Agglomerat *const); * @return Résultat de la fusion des deux agglomérat. La structure est remplie de 0 * en cas d'échec. */ -Agglomerat fusionAgglo(Agglomerat const* const, Agglomerat const* const); +Agglomerat fusionAgglo(Agglomerat const* const a1, Agglomerat const* const a2); /** * @brief Retourne l'écart de temps entre les deux agglomérats @@ -65,5 +65,17 @@ Agglomerat fusionAgglo(Agglomerat const* const, Agglomerat const* const); * * @return L'écart de temps entre les deux agglomérats */ -uint32_t ecartTemps(Agglomerat const* const, Agglomerat const* const); -ErrEnum repereAgglo(Point*, uint32_t, Agglomerat**, uint32_t*); \ No newline at end of file +uint32_t ecartTemps(Agglomerat const* const a1, Agglomerat const* const a2); + +/* + * @brief Repère les agglomérats à partir d'un tableau de points + * + * @param points Tableau de points servant au repérage des agglomérats + * @param tailleP Taille du tableau de points + * @param agglos Adresse du tableau qui contiendra les agglomérats repérés + * @param tailleA Adresse de la variable qui contiendra la taille du tableau d'agglomérats + * + * @return Valeur d'erreur ou de succes définies dans structures.h + */ +ErrEnum repereAgglo(Point* points, uint32_t tailleP, Agglomerat** agglos, uint32_t* tailleA); +