This repository has been archived on 2023-11-03. You can view files and clone it, but cannot push or open issues or pull requests.
GINPA/Modele/conversion.c

181 lines
4.4 KiB
C

#include "conversion.h"
inline double getRatio(const double echelle)
{
// Un ratio pour passer des distances (en mètres) à des pixels sur l'écran !
return (1.0e2 * PPCM) / echelle;
}
void conversionCoordonneesPixels(sfVector2f *const destinationPix, const Coordonnees *const sourceGPS, const Coordonnees *const pointCentral, const double echelle)
{
const double ratio = getRatio(echelle);
double diff;
if (fabs(sourceGPS->lon - pointCentral->lon) < 180)
{
diff = sourceGPS->lon - pointCentral->lon;
}
else
{
if (pointCentral->lon<0)
{
if(sourceGPS->lon > 0)
{
diff = sourceGPS->lon - 360 - pointCentral->lon;
}
else
{
diff = sourceGPS->lon - pointCentral->lon;
}
}
else
{
if(sourceGPS->lon < 0)
{
diff = 360 + sourceGPS->lon - pointCentral->lon;
}
else
{
diff = pointCentral->lon - sourceGPS->lon;
}
}
}
destinationPix->x = (ratio * RAYON * RADIANS(diff) / REALMAPSIZE + 0.5) * WIDTH;
destinationPix->y = (ratio * RAYON * log(tan(PI / 4.0 + RADIANS(pointCentral->lat) / 2.0) / tan(PI / 4.0 + RADIANS(sourceGPS->lat) / 2.0)) / REALMAPSIZE + 0.5) * HEIGHT;
}
void conversionPixelsCoordonnees(Coordonnees *const destinationGPS, const sfVector2f *const sourcePix, const Coordonnees *const pointCentral, const double echelle)
{
const double ratio = getRatio(echelle);
destinationGPS->lon = DEGRES((sourcePix->x / WIDTH - 0.5) * REALMAPSIZE / (ratio * RAYON)) + pointCentral->lon;
if (destinationGPS->lon < -180)
{
destinationGPS->lon = 360 + destinationGPS->lon;
}
else if (destinationGPS->lon > 180)
{
destinationGPS->lon -= 360;
}
destinationGPS->lat = DEGRES(2 * atan(tan(PI / 4 + RADIANS(pointCentral->lat) / 2.0) / exp((sourcePix->y / HEIGHT - 0.5) * REALMAPSIZE / (ratio * RAYON))) - PI / 2);
}
void conversionPoints(Point *tabPoint, uint32_t nbElements, const Coordonnees *const pointCentral, const double echelle)
{
if(tabPoint == NULL)
{
fprintf(stderr, "%s\n", strerror(errno));
return;
}
for(uint32_t i = 0; i < nbElements; i++)
{
conversionCoordonneesPixels(&tabPoint[i].posConv, &tabPoint[i].pos, pointCentral, echelle);
}
}
void conversionRec(const Rectangle *const rec, Coordonnees *const hg, Coordonnees *const bd, const Coordonnees *const pointCentral, const double echelle)
{
conversionPixelsCoordonnees(hg, &rec->positionHG, pointCentral, echelle);
conversionPixelsCoordonnees(bd, &rec->positionBD, pointCentral, echelle);
}
void conversionAgglos(Agglomerat *agglo, uint32_t nbAgglos, const Coordonnees *const pointCentral, const double echelle)
{
if(agglo == NULL)
{
fprintf(stderr, "%s\n", strerror(errno));
return;
}
for(uint32_t i = 0; i < nbAgglos; i++)
{
conversionCoordonneesPixels(&agglo[i].moyConv,&agglo[i].moy,pointCentral,echelle);
}
}
char** conversionDates(Point *tabInitial, uint32_t nbElements)
{
char **tabConverti = calloc(nbElements, sizeof(*tabConverti));
if(tabConverti == NULL)
{
fprintf(stderr, "Allocation impossible (1).\n");
return NULL;
}
for(uint32_t i = 0; i < nbElements; i++)
{
tabConverti[i] = calloc(DATESIZE, sizeof(*tabConverti[i]));
if(tabConverti[i] == NULL)
{
fprintf(stderr, "Allocation impossible (2).\n");
for(int32_t j = i - 1; j >= 0; j--)
{
free(tabConverti[j]);
}
free(tabConverti);
return NULL;
}
strcpy(tabConverti[i], ctime(&tabInitial[i].date));
}
return tabConverti;
}
char* getRidOfAccents(char *const input)
{
static const char *accents = "ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïðòóôõöùúûüýÿ";
static const char *noAccent = "AAAAAACEEEEIIIIOOOOOUUUUYaaaaaaceeeeiiiioooooouuuuyy";
char *output = calloc(strlen(input) + 1, sizeof(*output));
if(output == NULL)
{
fprintf(stderr, "getRidOfAccents() -> Allocation mémoire impossible: %s\n", strerror(errno));
return NULL;
}
uint32_t nbAccent = 0;
/* Pour comprendre le code qui suit : les accents
* sont codés sur deux cases d'une chaîne de caractères.
* Par exemple si une chaine s commence par 'é', s[0]
* et s[1] correspondraient au caractère 'é'. */
for(uint32_t i = 0; input[i] != '\0'; i++)
{
bool filled = false;
for(uint8_t j = 0; accents[j] != '\0'; j += 2)
{
if(input[i] == accents[j] && input[i + 1] == accents[j + 1])
{
output[i++ - nbAccent++] = noAccent[j / 2];
filled = true;
}
}
if(!filled)
{
output[i - nbAccent] = input[i];
}
}
return output;
}