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);
+