Changements:

* Nouveaux types pour le présent (Carte), et le futur !
* Rajoute une libération de mémoire oubliée
* Crée un module de gestion de Carte
This commit is contained in:
HorlogeSkynet 2016-12-25 01:20:22 +01:00
parent c47295fe0e
commit aa0d4e0b9c
11 changed files with 141 additions and 71 deletions

@ -14,7 +14,7 @@ endif
.SILENT:
all: $(OBJ)/controleur.o $(OBJ)/conversion.o $(OBJ)/destruction.o $(OBJ)/miscellaneous.o $(OBJ)/controleAffichage.o $(OBJ)/waiting.o
all: $(OBJ)/controleur.o $(OBJ)/conversion.o $(OBJ)/destruction.o $(OBJ)/miscellaneous.o $(OBJ)/controleAffichage.o $(OBJ)/waiting.o $(OBJ)/carte.o
$(OBJ)/%.o: %.c
$(CC) -c -o $@ $< $(CFLAGS) $(GFLAGS) $(DEPFLAGS) $(DEP)/$(basename $<).d

46
Controleur/carte.c Normal file

@ -0,0 +1,46 @@
#include "carte.h"
void initialiserCarte(Carte *const carte)
{
if(carte != NULL)
{
carte->zoom = -1;
carte->type = FIRSTYPE + 1;
carte->echelle = -1.0;
carte->mapSprite = NULL;
carte->mapTexture = NULL;
carte->pointHautGauche = (Coordonnees){-1.0, -1.0};
carte->pointBasDroite = (Coordonnees){-1.0, -1.0};
carte->pointCentral = (Coordonnees){-1.0, -1.0};
}
else
{
fprintf(stderr, "Erreur lors de l\'initialisation d\'une carte qui n\'existe pas.\n");
exit(EXIT_FAILURE);
}
}
void calculPointCentral(Carte *const carte)
{
if(carte != NULL && (carte->pointHautGauche.lat != -1.0 && carte->pointBasDroite.lon != -1.0))
{
// Coordonnées du point central du rectangle fictif
carte->pointCentral = (Coordonnees){(carte->pointHautGauche.lat + carte->pointBasDroite.lat) / 2.0, (carte->pointHautGauche.lon + carte->pointBasDroite.lon) / 2.0};
}
else
{
fprintf(stderr, "Erreur lors du calcul du point central d\'une carte qui n\'existe pas (ou qui n'est pas initialisée).\n");
exit(EXIT_FAILURE);
}
}
void detruireCarte(Carte *const carte)
{
sfTexture_destroy(carte->mapTexture);
sfSprite_destroy(carte->mapSprite);
}

28
Controleur/carte.h Normal file

@ -0,0 +1,28 @@
#pragma once
#include "controleur.h"
/**
* @brief Initialise une instance de structure Carte.
*
* @param carte Pointeur sur la carte à initialiser !
* @return Procédure.
*/
void initialiserCarte(Carte *const carte);
/**
* @brief Calcul les coordonnées centrales d'une carte à partir de ses deux extrema.
*
* @param carte Pointeur sur la carte dans laquelle on va calculer le point central.
* @return Procédure.
*/
void calculPointCentral(Carte *const carte);
/**
* @brief Supprime une carte en libérant les pointeurs la contenant.
*
* @param carte Pointeur sur la carte à libérer !
* @return Procédure.
*/
void detruireCarte(Carte *const carte);

@ -9,8 +9,6 @@ ErrEnum controlePoints(sfRenderWindow *window, const char *cheminFichier, Mode m
/* Image de chargement et création des principales variables */
sfRenderTexture *renderTexture = initialisationRenderTexture(sfRenderWindow_getSize(window).x, sfRenderWindow_getSize(window).y);
sfTexture *mapTexture = NULL;
sfSprite *mapSprite = NULL;
sfSprite *renderSprite = NULL;
afficherLoading(window, renderTexture, &renderSprite);
@ -43,32 +41,31 @@ ErrEnum controlePoints(sfRenderWindow *window, const char *cheminFichier, Mode m
PointConverti *tabPointsConvertis = NULL;
// Des variables en vrac pour les différents futurs calculs / opérations
Coordonnees pointCentral, pointHautGauche, pointBasDroite;
uint32_t nbPointsAffiches, nbPointsSouhaiter = nbElements;
uint8_t zoom;
double echelle;
sfEvent event;
uint32_t nbPointsAffiches, nbPointsSouhaiter = nbElements;
Carte carte;
initialiserCarte(&carte);
// Lors de la première itération, on récupère les positions extrêmes des points
getExtrema(tabPoints, nbElements, &pointHautGauche, &pointBasDroite);
getExtrema(tabPoints, nbElements, &carte.pointHautGauche, &carte.pointBasDroite);
do
{
afficherLoading(window, renderTexture, &renderSprite);
getZoomEchelle(&pointHautGauche, &pointBasDroite, &zoom, &echelle);
getZoomEchelle(&carte);
// Coordonnées du point au centre du rectangle fictif
pointCentral = (Coordonnees){(pointHautGauche.lat + pointBasDroite.lat) / 2.0, (pointHautGauche.lon + pointBasDroite.lon) / 2.0};
calculPointCentral(&carte);
if(!getBackgroundMap(&pointCentral, zoom))
if(!getBackgroundMap(&carte))
{
flag = REQUEST_FAILURE;
break;
}
// On convertit les points en coordonnées cartésiennes !
tabPointsConvertis = conversionPoints(tabPoints, nbElements, &pointCentral, echelle);
tabPointsConvertis = conversionPoints(tabPoints, nbElements, &carte.pointCentral, carte.echelle);
if(tabPointsConvertis == NULL)
{
flag = ALLOCATION_FAILURE;
@ -76,7 +73,7 @@ ErrEnum controlePoints(sfRenderWindow *window, const char *cheminFichier, Mode m
}
// On affiche la carte !
afficherCarte(renderTexture, &mapTexture, &mapSprite, MAPFILE);
afficherCarte(renderTexture, &carte.mapTexture, &carte.mapSprite, MAPFILE);
nbPointsAffiches = 0;
@ -106,19 +103,19 @@ ErrEnum controlePoints(sfRenderWindow *window, const char *cheminFichier, Mode m
else
{
// L'utilisateur ne peut zoomer que si le zoom est inférieur à sa valeur maximal !
if(zoom < ZOOMAX)
if(carte.zoom < ZOOMAX)
{
// L'utilisateur a effectué un zoom sur la carte (et il est autorisé à le faire)
// --> 0n libère la mémoire des éléments actuellement affichés, et on re-boucle !
libererMemoireElementsAffiches(mapTexture, mapSprite, MAPFILE, tabPointsConvertis, nbPointsAffiches, tabPointeursCercle);
libererMemoireElementsAffiches(&carte, MAPFILE, tabPointsConvertis, nbPointsAffiches, tabPointeursCercle);
// On convertit les pixels retournés en coordonnées géograpiques...
conversionRec(&carre, &pointHautGauche, &pointBasDroite, &pointCentral, echelle);
conversionRec(&carre, &carte.pointHautGauche, &carte.pointBasDroite, &carte.pointCentral, carte.echelle);
// Moment incompréhensible du projet, il faut inverser les deux points...
Coordonnees tmp = pointHautGauche;
pointHautGauche = pointBasDroite;
pointBasDroite = tmp;
Coordonnees tmp = carte.pointHautGauche;
carte.pointHautGauche = carte.pointBasDroite;
carte.pointBasDroite = tmp;
// Après le zoom, quelque soit le mode initial, on partira toujours de l'affichage global
mode = GLOBAL;
@ -136,7 +133,7 @@ ErrEnum controlePoints(sfRenderWindow *window, const char *cheminFichier, Mode m
} while(true); // Ceci est bien entendu une fausse boucle infinie (cf. le test juste ci-dessus...)
libererMemoireElementsAffiches(mapTexture, mapSprite, MAPFILE, tabPointsConvertis, nbPointsAffiches, tabPointeursCercle);
libererMemoireElementsAffiches(&carte, MAPFILE, tabPointsConvertis, nbPointsAffiches, tabPointeursCercle);
sfFont_destroy(font);
free(tabPoints);

@ -19,6 +19,7 @@
#include "miscellaneous.h"
#include "controleAffichage.h"
#include "waiting.h"
#include "carte.h"
/**

@ -14,21 +14,6 @@ void freeTabGeneric(void ***tab, uint32_t nbElements)
}
void detruireCarte(sfTexture **mapTexture, sfSprite **mapSprite, const char *const cheminFichier)
{
sfTexture_destroy(*mapTexture);
*mapTexture = NULL;
sfSprite_destroy(*mapSprite);
*mapSprite = NULL;
if(remove(cheminFichier) == -1)
{
fprintf(stderr, "Le fichier \"%s\" n\'a pas pu être correctement supprimé: %s\n", cheminFichier, strerror(errno));
}
}
void detruireCercles(const uint32_t nbElements, sfCircleShape *tabPointeursCercle[nbElements])
{
for(uint32_t i = 0; i < nbElements; i++)
@ -51,12 +36,18 @@ void cleaningFunction(void)
}
void libererMemoireElementsAffiches(sfTexture *mapTexture, sfSprite *mapSprite, const char *const cheminFichier, PointConverti *tabPointsConvertis, uint32_t nbPointsAffiches, sfCircleShape *tabPointeursCercle[nbPointsAffiches])
void libererMemoireElementsAffiches(Carte *const carte, const char *const cheminFichier, PointConverti *tabPointsConvertis, uint32_t nbPointsAffiches, sfCircleShape *tabPointeursCercle[nbPointsAffiches])
{
// Si cette texture n'est pas nulle, c'est que l'utilisateur a affiché des points. Libérons la mémoire !
if(mapTexture != NULL)
if(carte->mapTexture != NULL)
{
detruireCarte(&mapTexture, &mapSprite, cheminFichier);
detruireCarte(carte);
if(remove(cheminFichier) == -1)
{
fprintf(stderr, "Le fichier \"%s\" n\'a pas pu être correctement supprimé: %s\n", cheminFichier, strerror(errno));
}
detruireCercles(nbPointsAffiches, tabPointeursCercle);
free(tabPointsConvertis);
}

@ -12,16 +12,6 @@
*/
void freeTabGeneric(void ***tab, uint32_t nbElements);
/**
* @brief Supprime une carte (fichier) et libère les pointeurs la contenant.
*
* @param mapTexture Pointeur sur le pointeur de la texture contenant la carte.
* @param mapSprite Pointeur sur le pointeur du sprite contenant la carte.
* @param cheminFichier Chemin relatif du fichier contenant la carte.
* @return Procédure.
*/
void detruireCarte(sfTexture **mapTexture, sfSprite **mapSprite, const char *const cheminFichier);
/**
* @brief Détruit un tableau d'objets de type 'sfCircleShape' grâce à leur adresse.
*
@ -41,12 +31,11 @@ void cleaningFunction(void);
/**
* @brief Libère la mémoire des éléments affichés sur une carte, et la carte elle-même
*
* @param mapTexture Pointeur sur le pointeur de la texture contenant la carte.
* @param mapSprite Pointeur sur le pointeur du sprite contenant la carte.
* @param carte Un pointeur sur une carte dont la mémoire est à supprimer !
* @param cheminFichier Chemin relatif du fichier contenant la carte.
* @param tabPointsConvertis Tableau contenant les coordonnées converties des points.
* @param nbPointsAffiches Nombre de points affichés sur la carte.
* @param tabPointeursCercle Tableau de pointeurs sur les cercles affichés.
* @return Procédure.
*/
void libererMemoireElementsAffiches(sfTexture *mapTexture, sfSprite *mapSprite, const char *const cheminFichier, PointConverti *tabPointsConvertis, uint32_t nbPointsAffiches, sfCircleShape *tabPointeursCercle[nbPointsAffiches]);
void libererMemoireElementsAffiches(Carte *const carte, const char *const cheminFichier, PointConverti *tabPointsConvertis, uint32_t nbPointsAffiches, sfCircleShape *tabPointeursCercle[nbPointsAffiches]);

@ -33,16 +33,16 @@ void getExtrema(Point const* const pts, uint32_t const taille, Coordonnees *cons
}
bool getBackgroundMap(const Coordonnees *const pointCentral, const uint8_t zoom)
bool getBackgroundMap(const Carte *const carte)
{
// Ici on fabrique notre """petite""" URL magique
char request[REQUESTSIZE] = "";
snprintf(request, REQUESTSIZE,
"https://maps.googleapis.com/maps/api/staticmap?center=%f,%f&size=%ux%u&scale=%u&zoom=%u&key=%s",
pointCentral->lat, pointCentral->lon,
carte->pointCentral.lat, carte->pointCentral.lon,
MAPSIZE, MAPSIZE,
MAPSCALE,
zoom,
carte->zoom,
APIKEY);
/* cURL Request */
@ -85,22 +85,22 @@ bool getBackgroundMap(const Coordonnees *const pointCentral, const uint8_t zoom)
}
void getZoomEchelle(const Coordonnees *const pointHautGauche, const Coordonnees *const pointBasDroite, uint8_t *const zoom, double *const echelle)
void getZoomEchelle(Carte *const carte)
{
const double distLat = RAYON * RADIANS(pointHautGauche->lon - pointBasDroite->lon);
const double distLon = RAYON * log(tan(PI / 4.0 + RADIANS(pointBasDroite->lat) / 2.0)
/ tan(PI / 4.0 + RADIANS(pointHautGauche->lat) / 2.0));
const double distLat = RAYON * RADIANS(carte->pointHautGauche.lon - carte->pointBasDroite.lon);
const double distLon = RAYON * log(tan(PI / 4.0 + RADIANS(carte->pointBasDroite.lat) / 2.0)
/ tan(PI / 4.0 + RADIANS(carte->pointHautGauche.lat) / 2.0));
// Calcul de la distance maximum entre les points les plus éloignés, que l'on devra
// pouvoir être en mesure d'afficher
const double distanceMaximale = distLat > distLon ? distLat : distLon;
// L'échelle faisant correspondre la taille de la carte à la réalité voulue
*echelle = (distanceMaximale + 1.0e-2 * BORDERSIZE / PPCM) / (1.0e-2 * MAPSIZE * MAPSCALE / PPCM);
carte->echelle = (distanceMaximale + 1.0e-2 * BORDERSIZE / PPCM) / (1.0e-2 * MAPSIZE * MAPSCALE / PPCM);
// Partie entière du zoom à cause de l'API google maps.
*zoom = floor(log2(CONSTANTE / (*echelle)) - 1);
carte->zoom = floor(log2(CONSTANTE / (carte->echelle)) - 1);
// L'échelle de la carte avec le zoom arrondi.
*echelle = CONSTANTE / pow(2.0, *zoom + 1);
carte->echelle = CONSTANTE / pow(2.0, carte->zoom + 1);
}

@ -35,20 +35,15 @@ void getExtrema(Point const* const pts, uint32_t const taille, Coordonnees *cons
/**
* @brief Télécharge une carte sous forme d'image à l'aide de l'API Google MAPS et de cURL.
*
* @param pointHautGauche Coordonnées du point le plus "en-haut à gauche".
* @param pointBasDroite Coordonnées du point le plus "en-bas à droite".
* @param zoom Zoom optimal de la carte !
* @param carte Pointeur sur la carte pour laquelle on va tenter de récupérer l'image.
* @return Un booléen si l'opération s'est bien déroulée... ou non.
*/
bool getBackgroundMap(const Coordonnees *const pointCentral, const uint8_t zoom);
bool getBackgroundMap(const Carte *const carte);
/**
* @brief Calcul le zoom et l'échelle correspondante à notre situation.
*
* @param pointHautGauche Coordonnées du point le plus "en-haut à gauche".
* @param pointBasDroite Coordonnées du point le plus "en-bas à droite".
* @param zoom Pointeur sur la variable qui contiendra le zoom !
* @param echelle Pointeur sur la variable qui contiendra l'échelle !
* @param carte Pointeur sur la carte avec laquelle on va calculer le zoom et l'échelle.
* @return Procédure.
*/
void getZoomEchelle(const Coordonnees *const pointHautGauche, const Coordonnees *const pointBasDroite, uint8_t *const zoom, double *const echelle);
void getZoomEchelle(Carte *const carte);

@ -16,6 +16,8 @@ typedef enum {NONE, AGGLOMERAT, ROUTE} TypePt;
typedef enum {NO_MODE, GLOBAL, PBP_AUTOMATIC, PBP_MANUAL} Mode;
typedef enum {FIRSTYPE, ROADMAP, SATELLITE, TERRAIN, HYBRID, LASTYPE} MapType;
typedef struct
{
double lat;
@ -80,3 +82,21 @@ typedef struct
sfVector2f positionHG;
sfVector2f positionBD;
} Rectangle;
typedef struct
{
uint8_t zoom;
MapType type;
double echelle;
sfSprite *mapSprite;
sfTexture *mapTexture;
Coordonnees pointHautGauche;
Coordonnees pointBasDroite;
Coordonnees pointCentral;
} Carte;
typedef struct
{
Carte **pile;
int16_t sommet;
} PileCartes;

@ -54,4 +54,7 @@ void afficherLoading(sfRenderWindow *const window, sfRenderTexture *renderTextur
*renderSprite = loadSpriteFromRenderTexture(renderTexture);
sfRenderWindow_drawSprite(window, *renderSprite, NULL);
sfRenderWindow_display(window);
sfTexture_destroy(texture);
sfSprite_destroy(sprite);
}