|
|
|
@ -5,26 +5,23 @@
|
|
|
|
|
/******* Misc. very usefull functions *******/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Retourne la position du Point "p" dans le tableau "tab" de taille "size", ou -1 en cas d'échec. */
|
|
|
|
|
inline int point_tab_idx(const Point *tab, unsigned int &size, const Point &p)
|
|
|
|
|
{
|
|
|
|
|
for (unsigned int i = 0 ; i < size ; i++)
|
|
|
|
|
if (tab[i] == p)
|
|
|
|
|
return i ;
|
|
|
|
|
|
|
|
|
|
return -1 ;
|
|
|
|
|
/* Tronque le float "f" à "n" décimales et le retourne */
|
|
|
|
|
inline float round_float(float f, int n)
|
|
|
|
|
{
|
|
|
|
|
n = pow(10, n) ;
|
|
|
|
|
float f_dec = modff(f, &f) ;
|
|
|
|
|
f_dec = floor(f_dec * n) / n ;
|
|
|
|
|
|
|
|
|
|
return f + f_dec ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Retourne la position du Point "p" dans le vector "v", ou -1 en cas d'échec. */
|
|
|
|
|
inline int point_vector_idx(const vector<Point> &v, const Point &p)
|
|
|
|
|
/* Tronque le float "f" à 2 décimales et le retourne */
|
|
|
|
|
inline float round_float_2(float f)
|
|
|
|
|
{
|
|
|
|
|
for (unsigned int i = 0 ; i < v.size() ; i++)
|
|
|
|
|
if (v[i] == p)
|
|
|
|
|
return i ;
|
|
|
|
|
|
|
|
|
|
return -1 ;
|
|
|
|
|
return round_float(f, 2) ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -234,11 +231,15 @@ Server::Server(const string &ip_addr, const int &listen_port)
|
|
|
|
|
/* Bind */
|
|
|
|
|
bind(sockListen, (struct sockaddr *)&server_addr, sizeof(server_addr));
|
|
|
|
|
|
|
|
|
|
makeReferencePointListFromFile(DEFAULT_REF_POINT_FILE) ; // Initialisation de "reference_point_list".
|
|
|
|
|
makeApListFromFile(DEFAULT_AP_FILE) ; // Initialisation de "access_point_list".
|
|
|
|
|
makeTopologyFromFile(DEFAULT_TOPOLOGY_FILE) ; // Initialisation de "area_list".
|
|
|
|
|
makeWaypointListFromFile(DEFAULT_WAYPOINT_FILE) ; // Initialisation de "waypoint_list" et "waypoint_matrix".
|
|
|
|
|
makeReferencePointListFromFile(DEFAULT_REF_POINT_FILE) ; // Initialisation de "reference_point_list".
|
|
|
|
|
|
|
|
|
|
if (! checkTopology()) // Vérifications.
|
|
|
|
|
exit 1 ; // Si problème, on quitte.
|
|
|
|
|
|
|
|
|
|
makeReferencePointDistances() ; // Initialisation de "reference_point_matrix".
|
|
|
|
|
makeApListFromFile(DEFAULT_AP_FILE) ; // Initialisation de "access_point_list".
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG_T
|
|
|
|
|
cout << "//<-- Server::Server()" << endl ; fflush(stdout) ;
|
|
|
|
@ -305,6 +306,57 @@ map<string, Area> Server::inWhichAreas(const Point &p)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Retourne true si les points "p1" et "p2" sont dans la même zone (ou ont au moins une zone en commun s'ils appartiennent à plusieurs zones).
|
|
|
|
|
*/
|
|
|
|
|
bool Server::inTheSameArea(const Point &p1, const Point &p2)
|
|
|
|
|
{
|
|
|
|
|
#ifdef DEBUG_T
|
|
|
|
|
cout << "//--> Server::inTheSameArea()" << endl ; fflush(stdout) ;
|
|
|
|
|
#endif // DEBUG_T
|
|
|
|
|
|
|
|
|
|
map<string, Area> // Liste des zones comportant les points p1 et p2 :
|
|
|
|
|
zones1(inWhichAreas(p1)),
|
|
|
|
|
zones2(inWhichAreas(p2)) ;
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG_2
|
|
|
|
|
cout << " zones1 (" << zones1.size() << ") : [" ;
|
|
|
|
|
for (map<string, Area>::iterator it1 = zones1.begin() ; it1 != zones1.end() ; it1++)
|
|
|
|
|
cout << it1->first << ',' ;
|
|
|
|
|
cout << "\b]" ;
|
|
|
|
|
cout << " zones2 (" << zones2.size() << ") : [" ;
|
|
|
|
|
for (map<string, Area>::iterator it1 = zones2.begin() ; it1 != zones2.end() ; it1++)
|
|
|
|
|
cout << it1->first << ',' ;
|
|
|
|
|
cout << "\b]" ;
|
|
|
|
|
#endif // DEBUG_2
|
|
|
|
|
|
|
|
|
|
if (zones1.size() == 0 || zones2.size() == 0) // Si aucune zone ne contient p1 ou p2,
|
|
|
|
|
{
|
|
|
|
|
#ifdef DEBUG_T
|
|
|
|
|
cout << "//<-- Server::inTheSameArea()" << endl ; fflush(stdout) ;
|
|
|
|
|
#endif // DEBUG_T
|
|
|
|
|
|
|
|
|
|
return false ; // on quitte.
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (map<string, Area>::iterator it1 = zones1.begin() ; it1 != zones1.end() ; it1++) // Parcours des zones :
|
|
|
|
|
for (map<string, Area>::iterator it2 = zones2.begin() ; it2 != zones2.end() ; it2++)
|
|
|
|
|
if (it1->second == it2->second) // Si les deux zones sont identiques,
|
|
|
|
|
{
|
|
|
|
|
#ifdef DEBUG_T
|
|
|
|
|
cout << "//<-- Server::inTheSameArea()" << endl ; fflush(stdout) ;
|
|
|
|
|
#endif // DEBUG_T
|
|
|
|
|
return true ; // p1 et p2 sont dans la même zone.
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG_T
|
|
|
|
|
cout << "//<-- Server::inTheSameArea()" << endl ; fflush(stdout) ;
|
|
|
|
|
#endif // DEBUG_T
|
|
|
|
|
|
|
|
|
|
return false ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Cherche les points de passage communs aux zones "z1" et "z2".
|
|
|
|
|
* Retourne un vector<Point> contenant la liste de ces points.
|
|
|
|
|
*/
|
|
|
|
@ -316,11 +368,11 @@ vector<Point> Server::areaConnection(const Area &z1, const Area &z2)
|
|
|
|
|
|
|
|
|
|
vector<Point> points ;
|
|
|
|
|
|
|
|
|
|
for (unsigned int i = 0 ; i < reference_point_list.size() ; i++)
|
|
|
|
|
for (unsigned int i = 0 ; i < waypoint_list.size() ; i++)
|
|
|
|
|
{
|
|
|
|
|
map<string, Area> areas(inWhichAreas(reference_point_list[i])) ;
|
|
|
|
|
map<string, Area> areas(inWhichAreas(waypoint_list[i])) ;
|
|
|
|
|
if (areas.find(z1.getName()) != areas.end() && areas.find(z2.getName()) != areas.end())
|
|
|
|
|
points.push_back(reference_point_list[i]) ;
|
|
|
|
|
points.push_back(waypoint_list[i]) ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG_T
|
|
|
|
@ -343,11 +395,11 @@ vector<Point> Server::areaConnection(const Area &z)
|
|
|
|
|
|
|
|
|
|
vector<Point> points ;
|
|
|
|
|
|
|
|
|
|
for (unsigned int i = 0 ; i < reference_point_list.size() ; i++)
|
|
|
|
|
for (unsigned int i = 0 ; i < waypoint_list.size() ; i++)
|
|
|
|
|
{
|
|
|
|
|
map<string, Area> areas(inWhichAreas(reference_point_list[i])) ;
|
|
|
|
|
map<string, Area> areas(inWhichAreas(waypoint_list[i])) ;
|
|
|
|
|
if (areas.find(z.getName()) != areas.end())
|
|
|
|
|
points.push_back(reference_point_list[i]) ;
|
|
|
|
|
points.push_back(waypoint_list[i]) ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG_T
|
|
|
|
@ -373,6 +425,10 @@ float Server::distanceTopology(const Point &p1, const Point &p2)
|
|
|
|
|
|
|
|
|
|
if (zones1.size() == 0 || zones2.size() == 0) // Si aucune zone ne contient p1 ou p2,
|
|
|
|
|
{
|
|
|
|
|
#ifdef DEBUG_2
|
|
|
|
|
cout << "Aucune zone ne contient " << p1 << " (" << zones1.size() << " zones) ou " << p2 << " (" << zones2.size() << " zones)." << endl ;
|
|
|
|
|
#endif // DEBUG_2
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG_T
|
|
|
|
|
cout << "//<-- Server::distanceTopology()" << endl ; fflush(stdout) ;
|
|
|
|
|
#endif // DEBUG_T
|
|
|
|
@ -387,8 +443,13 @@ float Server::distanceTopology(const Point &p1, const Point &p2)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* *** Cas de la même zone *** */
|
|
|
|
|
|
|
|
|
|
if (z1 == z2) // Si les points sont dans la même zone,
|
|
|
|
|
{
|
|
|
|
|
#ifdef DEBUG_2
|
|
|
|
|
cout << p1 << " et " << p2 << " sont dans la même zone." << endl ;
|
|
|
|
|
#endif // DEBUG_2
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG_T
|
|
|
|
|
cout << "//<-- Server::distanceTopology()" << endl ; fflush(stdout) ;
|
|
|
|
|
#endif // DEBUG_T
|
|
|
|
@ -397,9 +458,15 @@ float Server::distanceTopology(const Point &p1, const Point &p2)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* *** Cas de deux zones voisines *** */
|
|
|
|
|
/* *** Cas de deux zones voisines (connectées directement) *** */
|
|
|
|
|
|
|
|
|
|
if ((connection = areaConnection(z1, z2)).size() != 0) // Si les points sont dans deux zones voisines,
|
|
|
|
|
{ // la distance entre eux est la distance euclidienne de chacun jusqu'au plus proche point de passage entre les deux zones.
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG_2
|
|
|
|
|
cout << p1 << " et " << p2 << " sont dans deux zones voisines." << endl ;
|
|
|
|
|
#endif // DEBUG_2
|
|
|
|
|
|
|
|
|
|
float dist = p1.distance(connection[0]) + p2.distance(connection[0]) ;
|
|
|
|
|
for (unsigned int i = 1 ; i < connection.size() ; i++) // Recherche du point de passage offrant la plus courte distance
|
|
|
|
|
{
|
|
|
|
@ -417,6 +484,11 @@ float Server::distanceTopology(const Point &p1, const Point &p2)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* *** Les points sont dans des zones non-voisines *** */
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG_2
|
|
|
|
|
cout << p1 << " et " << p2 << " sont dans des zones non-voisines." << endl ;
|
|
|
|
|
#endif // DEBUG_2
|
|
|
|
|
|
|
|
|
|
vector<Point> // Liste des points de passage appartenant respectivement à z1 et à z2.
|
|
|
|
|
wp_z1(areaConnection(z1)),
|
|
|
|
|
wp_z2(areaConnection(z2)) ;
|
|
|
|
@ -436,10 +508,13 @@ float Server::distanceTopology(const Point &p1, const Point &p2)
|
|
|
|
|
unsigned int i1, i2 ;
|
|
|
|
|
for (i1 = 0 ; i1 < wp_z1.size() ; i1++) // Recherche des premiers indices valides (où il existe un chemin entre les points de passage)
|
|
|
|
|
{
|
|
|
|
|
wp_z1_idx = point_vector_idx(waypoint_list, wp_z1[i1]) ;
|
|
|
|
|
wp_z1_idx = pointIndex(waypoint_list, wp_z1[i1]) ;
|
|
|
|
|
for (i2 = 0 ; i2 < wp_z2.size() ; i2++)
|
|
|
|
|
{
|
|
|
|
|
wp_z2_idx = point_vector_idx(waypoint_list, wp_z2[i2]) ;
|
|
|
|
|
wp_z2_idx = pointIndex(waypoint_list, wp_z2[i2]) ;
|
|
|
|
|
if (wp_z2_idx < 0)
|
|
|
|
|
continue ;
|
|
|
|
|
|
|
|
|
|
if (waypoint_matrix[wp_z1_idx][wp_z2_idx] != -1) // Si c'est bon,
|
|
|
|
|
break ; // on arrête le parcours.
|
|
|
|
|
}
|
|
|
|
@ -461,7 +536,7 @@ float Server::distanceTopology(const Point &p1, const Point &p2)
|
|
|
|
|
|
|
|
|
|
for (unsigned int j = i2 + 1 ; j < wp_z2.size() ; j++) // Fin du parcours :
|
|
|
|
|
{
|
|
|
|
|
wp_z2_idx = point_vector_idx(waypoint_list, wp_z2[j]) ;
|
|
|
|
|
wp_z2_idx = pointIndex(waypoint_list, wp_z2[j]) ;
|
|
|
|
|
if (waypoint_matrix[wp_z1_idx][wp_z2_idx] == -1)
|
|
|
|
|
continue ;
|
|
|
|
|
tmp_dist = p1.distance(wp_z1[i1]) + waypoint_matrix[wp_z1_idx][wp_z2_idx] + p2.distance(wp_z2[j]) ;
|
|
|
|
@ -474,8 +549,8 @@ float Server::distanceTopology(const Point &p1, const Point &p2)
|
|
|
|
|
for (unsigned int j = 0 ; j < wp_z2.size() ; j++)
|
|
|
|
|
{
|
|
|
|
|
// Indice des points de passage wp_z1[i] et wp_z2[j] dans la liste des points de passage :
|
|
|
|
|
wp_z1_idx = point_vector_idx(waypoint_list, wp_z1[i]) ;
|
|
|
|
|
wp_z2_idx = point_vector_idx(waypoint_list, wp_z2[j]) ;
|
|
|
|
|
wp_z1_idx = pointIndex(waypoint_list, wp_z1[i]) ;
|
|
|
|
|
wp_z2_idx = pointIndex(waypoint_list, wp_z2[j]) ;
|
|
|
|
|
|
|
|
|
|
if (waypoint_matrix[wp_z1_idx][wp_z2_idx] == -1) // S'il n'existe aucun chemin entre les deux points de passage
|
|
|
|
|
continue ;
|
|
|
|
@ -505,7 +580,7 @@ float Server::distanceTopology(const Point &p1, const Point &p2)
|
|
|
|
|
|
|
|
|
|
/* FONCTION POUR RÉTRO-COMPATIBILITÉ.
|
|
|
|
|
* Recherche un point de coordonnées (x;y;z) dans la liste reference_point_list, retourne true s'il existe, false sinon. */
|
|
|
|
|
bool Server::pointExists(const float &x, const float &y, const float &z)const
|
|
|
|
|
inline bool Server::pointExists(const float &x, const float &y, const float &z) const
|
|
|
|
|
{
|
|
|
|
|
#ifdef DEBUG_T
|
|
|
|
|
cout << "//--> Server::pointExists(&float, &float, &float)" << endl ; fflush(stdout) ;
|
|
|
|
@ -524,7 +599,7 @@ bool Server::pointExists(const float &x, const float &y, const float &z)const
|
|
|
|
|
|
|
|
|
|
/* FONCTION POUR RÉTRO-COMPATIBILITÉ.
|
|
|
|
|
* Recherche un Point dans la liste reference_point_list, retourne true s'il existe, false sinon. */
|
|
|
|
|
bool Server::pointExists(const Point &p)const
|
|
|
|
|
inline bool Server::pointExists(const Point &p) const
|
|
|
|
|
{
|
|
|
|
|
#ifdef DEBUG_T
|
|
|
|
|
cout << "//--> Server::pointExists(&Point)" << endl ; fflush(stdout) ;
|
|
|
|
@ -542,7 +617,7 @@ bool Server::pointExists(const Point &p)const
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Recherche un point de coordonnées (x;y;z) dans la liste "point_list", retourne true s'il existe, false sinon. */
|
|
|
|
|
bool Server::pointExists(const vector<ReferencePoint> &point_list, const float &x, const float &y, const float &z) const
|
|
|
|
|
inline bool Server::pointExists(const vector<ReferencePoint> &point_list, const float &x, const float &y, const float &z) const
|
|
|
|
|
{
|
|
|
|
|
#ifdef DEBUG_T
|
|
|
|
|
cout << "//--> Server::pointExists(&vector<ReferencePoint>, &float, &float, &float)" << endl ; fflush(stdout) ;
|
|
|
|
@ -560,34 +635,24 @@ bool Server::pointExists(const vector<ReferencePoint> &point_list, const float &
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Recherche un Point dans la liste "point_list", retourne true s'il existe, false sinon. */
|
|
|
|
|
bool Server::pointExists(const vector<ReferencePoint> &point_list, const Point &p) const
|
|
|
|
|
inline bool Server::pointExists(const vector<ReferencePoint> &point_list, const Point &p) const
|
|
|
|
|
{
|
|
|
|
|
#ifdef DEBUG_T
|
|
|
|
|
cout << "//--> Server::pointExists(&vector<ReferencePoint>, &Point)" << endl ; fflush(stdout) ;
|
|
|
|
|
#endif // DEBUG_T
|
|
|
|
|
|
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
|
|
for (i = 0 ; i < point_list.size() ; i++)
|
|
|
|
|
if (p == point_list[i].getCoordinates())
|
|
|
|
|
{
|
|
|
|
|
#ifdef DEBUG_T
|
|
|
|
|
cout << "//<-- Server::pointExists(&vector<ReferencePoint>, &Point)" << endl ; fflush(stdout) ;
|
|
|
|
|
#endif // DEBUG_T
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
bool ret = (pointIndex(point_list, p) != -1) ;
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG_T
|
|
|
|
|
cout << "//<-- Server::pointExists(&vector<ReferencePoint>, &Point)" << endl ; fflush(stdout) ;
|
|
|
|
|
#endif // DEBUG_T
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
return ret ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Do not forget to call pointExists() before this one */
|
|
|
|
|
unsigned int Server::pointIndex(const float &x, const float &y, const float &z)const
|
|
|
|
|
inline int Server::pointIndex(const float &x, const float &y, const float &z) const
|
|
|
|
|
{
|
|
|
|
|
#ifdef DEBUG_T
|
|
|
|
|
cout << "//--> Server::pointIndex(&float, &float, &float)" << endl ; fflush(stdout) ;
|
|
|
|
@ -604,8 +669,7 @@ unsigned int Server::pointIndex(const float &x, const float &y, const float &z)c
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Do not forget to call pointExists() before this one */
|
|
|
|
|
unsigned int Server::pointIndex(const Point &p)const
|
|
|
|
|
inline int Server::pointIndex(const Point &p) const
|
|
|
|
|
{
|
|
|
|
|
#ifdef DEBUG_T
|
|
|
|
|
cout << "//--> Server::pointIndex(&Point)" << endl ; fflush(stdout) ;
|
|
|
|
@ -622,7 +686,7 @@ unsigned int Server::pointIndex(const Point &p)const
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
unsigned int Server::pointIndex(const vector<ReferencePoint> &point_list, const float &x, const float &y, const float &z) const
|
|
|
|
|
inline int Server::pointIndex(const vector<ReferencePoint> &point_list, const float &x, const float &y, const float &z) const
|
|
|
|
|
{
|
|
|
|
|
#ifdef DEBUG_T
|
|
|
|
|
cout << "//--> Server::pointIndex(&vector<ReferencePoint>, &float, &float, &float)" << endl ; fflush(stdout) ;
|
|
|
|
@ -639,7 +703,7 @@ unsigned int Server::pointIndex(const vector<ReferencePoint> &point_list, const
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
unsigned int Server::pointIndex(const vector<ReferencePoint> &point_list, const Point &p) const
|
|
|
|
|
inline int Server::pointIndex(const vector<ReferencePoint> &point_list, const Point &p) const
|
|
|
|
|
{
|
|
|
|
|
#ifdef DEBUG_T
|
|
|
|
|
cout << "//--> Server::pointIndex(&vector<ReferencePoint>, &Point)" << endl ; fflush(stdout) ;
|
|
|
|
@ -647,8 +711,8 @@ unsigned int Server::pointIndex(const vector<ReferencePoint> &point_list, const
|
|
|
|
|
|
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
|
|
for (i = 0 ; i < reference_point_list.size() ; i++)
|
|
|
|
|
if (p == reference_point_list[i].getCoordinates())
|
|
|
|
|
for (i = 0 ; i < point_list.size() ; i++)
|
|
|
|
|
if (p == point_list[i].getCoordinates())
|
|
|
|
|
{
|
|
|
|
|
#ifdef DEBUG_T
|
|
|
|
|
cout << "//<-- Server::pointIndex(&vector<ReferencePoint>, &Point)" << endl ; fflush(stdout) ;
|
|
|
|
@ -660,7 +724,44 @@ unsigned int Server::pointIndex(const vector<ReferencePoint> &point_list, const
|
|
|
|
|
cout << "//<-- Server::pointIndex(&vector<ReferencePoint>, &Point)" << endl ; fflush(stdout) ;
|
|
|
|
|
#endif // DEBUG_T
|
|
|
|
|
|
|
|
|
|
return 0; // Should never happen
|
|
|
|
|
return -1 ; // Point non trouvé
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Retourne la position du Point "p" dans le tableau à une dimension "point_tab" de taille "size", ou -1 en cas d'échec. */
|
|
|
|
|
inline int Server::pointIndex(const Point *point_tab, unsigned int &size, const Point &p) const
|
|
|
|
|
{
|
|
|
|
|
for (unsigned int i = 0 ; i < size ; i++)
|
|
|
|
|
if (point_tab[i] == p)
|
|
|
|
|
return i ;
|
|
|
|
|
|
|
|
|
|
return -1 ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Retourne la position du Point "p" dans le vector "point_list", ou -1 en cas d'échec. */
|
|
|
|
|
inline int Server::pointIndex(const vector<Point> &point_list, const Point &p) const
|
|
|
|
|
{
|
|
|
|
|
#ifdef DEBUG_T
|
|
|
|
|
cout << "//--> Server::pointIndex(&vector<Point>, &Point)" << endl ; fflush(stdout) ;
|
|
|
|
|
#endif // DEBUG_T
|
|
|
|
|
|
|
|
|
|
for (unsigned int i = 0 ; i < point_list.size() ; i++)
|
|
|
|
|
if (point_list[i] == p)
|
|
|
|
|
{
|
|
|
|
|
#ifdef DEBUG_T
|
|
|
|
|
cout << "//<-- Server::pointIndex(&vector<Point>, &Point)" << endl ; fflush(stdout) ;
|
|
|
|
|
#endif // DEBUG_T
|
|
|
|
|
return i ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG_T
|
|
|
|
|
cout << "//<-- Server::pointIndex(&vector<Point>, &Point)" << endl ; fflush(stdout) ;
|
|
|
|
|
#endif // DEBUG_T
|
|
|
|
|
|
|
|
|
|
return -1 ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -1131,12 +1232,12 @@ Point Server::interlink(const vector<Measurement> &m, const int &client_idx)cons
|
|
|
|
|
dist_vect.clear();
|
|
|
|
|
centres.clear();
|
|
|
|
|
|
|
|
|
|
/* Return position */
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG_T
|
|
|
|
|
cout << "//<-- Server::interlink()" << endl ; fflush(stdout) ;
|
|
|
|
|
#endif // DEBUG_T
|
|
|
|
|
|
|
|
|
|
/* Return position */
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -1403,7 +1504,7 @@ void Server::makeTopologyFromFile(const string &filename)
|
|
|
|
|
cerr << "Erreur ! Déclaration multiple de la zone « " << infos[0] << " »." << endl ; // on le signale ;
|
|
|
|
|
else // sinon on l'ajoute :
|
|
|
|
|
{
|
|
|
|
|
area_list[infos[0]] = Area(infos[0], string2float(infos[1]), string2float(infos[2]), string2float(infos[3]), string2float(infos[4]), string2float(infos[5]), string2float(infos[6])) ;
|
|
|
|
|
area_list[infos[0]] = Area(infos[0], string2float(infos[1]), string2float(infos[3]), string2float(infos[2]), string2float(infos[4]), string2float(infos[5]), string2float(infos[6])) ;
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
|
cout << " ajoutée." << endl ;
|
|
|
|
|
#endif // DEBUG
|
|
|
|
@ -1438,11 +1539,13 @@ void Server::makeWaypointListFromFile(const string &filename)
|
|
|
|
|
cout << "//--> Server::makeWaypointListFromFile()" << endl ; fflush(stdout) ;
|
|
|
|
|
#endif // DEBUG_T
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* *** Lecture du fichier *** */
|
|
|
|
|
|
|
|
|
|
ifstream input_file ;
|
|
|
|
|
char buffer[BUFFER_LENGTH] ;
|
|
|
|
|
vector<string> infos ;
|
|
|
|
|
set<Point> point_list ;
|
|
|
|
|
// Point p_cur, p_tmp ;
|
|
|
|
|
|
|
|
|
|
input_file.open(filename.c_str());
|
|
|
|
|
if (input_file.fail())
|
|
|
|
@ -1471,16 +1574,16 @@ void Server::makeWaypointListFromFile(const string &filename)
|
|
|
|
|
|
|
|
|
|
infos = explode(buffer, ';') ;
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
|
cout << "Point de passage : " << buffer ; fflush(stdout);
|
|
|
|
|
cout << "Point de passage : " << buffer << ' ' ; fflush(stdout);
|
|
|
|
|
#endif // DEBUG
|
|
|
|
|
|
|
|
|
|
/* Ajout du point lu */
|
|
|
|
|
Point tmp_pt(string2float(infos[0]), string2float(infos[1]), string2float(infos[2])) ;
|
|
|
|
|
if (! point_list.insert(tmp_pt).second)
|
|
|
|
|
cerr << "Point " << tmp_pt << " dupliqué !" << endl ;
|
|
|
|
|
else
|
|
|
|
|
cerr << "Point " << tmp_pt << " non ajouté ! Peut-être est-il dupliqué ?" << endl ;
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
|
cout << " traité." << endl ; fflush(stdout);
|
|
|
|
|
else
|
|
|
|
|
cout << "traité." << endl ; fflush(stdout);
|
|
|
|
|
#endif // DEBUG
|
|
|
|
|
|
|
|
|
|
infos.clear() ;
|
|
|
|
@ -1490,7 +1593,8 @@ void Server::makeWaypointListFromFile(const string &filename)
|
|
|
|
|
input_file.close() ; // Lecture du fichier terminée
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Construction de la matrice */
|
|
|
|
|
/* *** Construction de la matrice des distances *** */
|
|
|
|
|
|
|
|
|
|
unsigned int nb_pts = point_list.size() ; // Nombre de points
|
|
|
|
|
unsigned int cur_idx = 0 ; // Itérateur sur l'indice de la matrice.
|
|
|
|
|
waypoint_list.reserve(nb_pts) ; // Vector contenant tous les points (attribut du serveur)
|
|
|
|
@ -1502,19 +1606,19 @@ void Server::makeWaypointListFromFile(const string &filename)
|
|
|
|
|
waypoint_matrix[i][k] = -1 ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
|
cout << "--> Liste des points de passage (" << nb_pts << ") :" << endl ; fflush(stdout);
|
|
|
|
|
#endif // DEBUG
|
|
|
|
|
|
|
|
|
|
/* Calcul des distances */
|
|
|
|
|
|
|
|
|
|
/* Initialisation (voisinage de premier ordre de chaque point */
|
|
|
|
|
for (set<Point>::iterator it = point_list.begin() ; it != point_list.end() ; it++, cur_idx++) // Pour chaque point enregistré
|
|
|
|
|
{
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
|
cout << *it << " :" ;
|
|
|
|
|
#endif // DEBUG
|
|
|
|
|
|
|
|
|
|
waypoint_list[cur_idx] = *it ; // Ajout du point dans waypoint_list // FIXME : utiliser plutôt push_back() ?
|
|
|
|
|
waypoint_list.push_back(*it) ; // Ajout du point dans waypoint_list
|
|
|
|
|
waypoint_matrix[cur_idx][cur_idx] = 0 ; // La distance du point à lui-même est nulle
|
|
|
|
|
|
|
|
|
|
for (unsigned int k = 0 ; k < cur_idx ; k++) // Pour chacun des point précédent
|
|
|
|
@ -1522,9 +1626,12 @@ void Server::makeWaypointListFromFile(const string &filename)
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
|
cout << " / " << waypoint_list[k] ;
|
|
|
|
|
#endif // DEBUG
|
|
|
|
|
float dist = it->distance(waypoint_list[k]) ; // On calcule la distance
|
|
|
|
|
waypoint_matrix[cur_idx][k] = dist ; // et on l'insère dans le tableau,
|
|
|
|
|
waypoint_matrix[k][cur_idx] = dist ; // dans les deux sens.
|
|
|
|
|
if (inTheSameArea(waypoint_list[cur_idx], waypoint_list[k])) // Si le point est dans la même zone,
|
|
|
|
|
{
|
|
|
|
|
float dist = it->distance(waypoint_list[k]) ; // on calcule la distance
|
|
|
|
|
waypoint_matrix[cur_idx][k] = dist ; // et on l'insère dans le tableau,
|
|
|
|
|
waypoint_matrix[k][cur_idx] = dist ; // dans les deux sens.
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
@ -1532,9 +1639,54 @@ void Server::makeWaypointListFromFile(const string &filename)
|
|
|
|
|
#endif // DEBUG
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG_2
|
|
|
|
|
/* Premier affichage de la matrice */
|
|
|
|
|
cout << "--> Matrice des distances entre points de passage (après initialisation) :\n\t\t|" ;
|
|
|
|
|
for (unsigned int k = 0 ; k < nb_pts ; k++)
|
|
|
|
|
cout << ' ' << waypoint_list[k] << "\t|" ;
|
|
|
|
|
cout << endl ;
|
|
|
|
|
for (unsigned int k = 0 ; k < nb_pts ; k++)
|
|
|
|
|
{
|
|
|
|
|
cout << waypoint_list[k] << "\t|" ;
|
|
|
|
|
for (unsigned int l = 0 ; l < nb_pts ; l++)
|
|
|
|
|
cout << '\t' << waypoint_matrix[k][l] << "\t|" ;
|
|
|
|
|
cout << endl ;
|
|
|
|
|
}
|
|
|
|
|
cout << endl ;
|
|
|
|
|
#endif // DEBUG_2
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Itérations suivantes */
|
|
|
|
|
bool comput_done = true ;
|
|
|
|
|
while (comput_done)
|
|
|
|
|
{
|
|
|
|
|
comput_done = false ;
|
|
|
|
|
|
|
|
|
|
for (unsigned int i = 0 ; i < nb_pts ; i++)
|
|
|
|
|
for (unsigned int j = 0 ; j < nb_pts ; j++)
|
|
|
|
|
if (waypoint_matrix[i][j] > 0)
|
|
|
|
|
for (unsigned int k = 0 ; k < nb_pts ; k++)
|
|
|
|
|
if (waypoint_matrix[j][k] > 0)
|
|
|
|
|
{
|
|
|
|
|
/* /!\
|
|
|
|
|
* NE PAS OPTIMISER (g++ -O0) !
|
|
|
|
|
* Avec l'option d'optimisation de GCC (-O1, -O2 ou -O3), le test :
|
|
|
|
|
* (tmp_dist < round_float_2(waypoint_matrix[i][k]) || waypoint_matrix[i][k] == -1)
|
|
|
|
|
* est vrai, même si les deux comparaisons sont fausses.
|
|
|
|
|
* Cela semble provenir de la variable tmp_dist.
|
|
|
|
|
*/
|
|
|
|
|
float tmp_dist = round_float_2(waypoint_matrix[j][k] + waypoint_matrix[i][j]) ;
|
|
|
|
|
if (tmp_dist < round_float_2(waypoint_matrix[i][k]) || waypoint_matrix[i][k] == -1)
|
|
|
|
|
{
|
|
|
|
|
waypoint_matrix[i][k] = tmp_dist ;
|
|
|
|
|
comput_done = true ;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
|
/* Affichage de la matrice */
|
|
|
|
|
/* Deuxième affichage de la matrice */
|
|
|
|
|
cout << "--> Matrice des distances entre points de passage :\n\t\t|" ;
|
|
|
|
|
for (unsigned int k = 0 ; k < nb_pts ; k++)
|
|
|
|
|
cout << ' ' << waypoint_list[k] << "\t|" ;
|
|
|
|
@ -1546,7 +1698,6 @@ void Server::makeWaypointListFromFile(const string &filename)
|
|
|
|
|
cout << '\t' << waypoint_matrix[k][l] << "\t|" ;
|
|
|
|
|
cout << endl ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cout << endl ;
|
|
|
|
|
#endif // DEBUG
|
|
|
|
|
|
|
|
|
@ -1558,6 +1709,123 @@ void Server::makeWaypointListFromFile(const string &filename)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Vérifie la cohérence de la topologie décrite dans les fichiers de configuration.
|
|
|
|
|
* Retourne false si un problème est détecté, true sinon.
|
|
|
|
|
* /!\ La liste des *points de passage*, leur *matrice de distances*, ainsi que la liste des *points de référence*, DOIVENT ÊTRE INITIALISÉES avant l'appel à cette fonction. Il faut donc appeler makeWaypointListFromFile() et makeReferencePointListFromFile() avant checkTopology().
|
|
|
|
|
*/
|
|
|
|
|
bool Server::checkTopology()
|
|
|
|
|
{
|
|
|
|
|
#ifdef DEBUG_T
|
|
|
|
|
cout << "//--> Server::checkTopology()" << endl ; fflush(stdout) ;
|
|
|
|
|
#endif // DEBUG_T
|
|
|
|
|
|
|
|
|
|
bool ret = true ;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* *** Recherche de points de passage n'appartenant à aucune zone *** */
|
|
|
|
|
|
|
|
|
|
for (unsigned int i = 0 ; i < waypoint_list.size() ; i++)
|
|
|
|
|
{
|
|
|
|
|
map<string, Area> areas(inWhichAreas(waypoint_list[i])) ;
|
|
|
|
|
if (areas.empty())
|
|
|
|
|
{
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
|
cout << "Le point de passage " << waypoint_list[i] << " n'appartient à aucune zone !" << endl ;
|
|
|
|
|
#endif // DEBUG
|
|
|
|
|
|
|
|
|
|
ret = false ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG_2
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
cout << "Le point de passage " << waypoint_list[i] << " appartient aux zones suivantes :" << endl ;
|
|
|
|
|
for (map<string, Area>::iterator it = areas.begin() ; it != areas.end() ; it++)
|
|
|
|
|
cout << '\t' << it->first << endl ;
|
|
|
|
|
}
|
|
|
|
|
#endif // DEBUG_2
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* *** Recherche de points de référence n'appartenant à aucune zone *** */
|
|
|
|
|
|
|
|
|
|
for (unsigned int i = 0 ; i < reference_point_list.size() ; i++)
|
|
|
|
|
{
|
|
|
|
|
map<string, Area> areas(inWhichAreas((Point) reference_point_list[i])) ;
|
|
|
|
|
if (areas.empty())
|
|
|
|
|
{
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
|
cout << "Le point de référence " << (Point) reference_point_list[i] << " n'appartient à aucune zone !" << endl ;
|
|
|
|
|
#endif // DEBUG
|
|
|
|
|
|
|
|
|
|
ret = false ; // À modifier si on veut permettre aux points de référence de n'appartenir à aucune zone.
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG_2
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
cout << "Le point de référence " << (Point) reference_point_list[i] << " appartient aux zones suivantes :" << endl ;
|
|
|
|
|
for (map<string, Area>::iterator it = areas.begin() ; it != areas.end() ; it++)
|
|
|
|
|
cout << '\t' << it->first << endl ;
|
|
|
|
|
}
|
|
|
|
|
#endif // DEBUG_2
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* *** Recherche des pièces non connectées (et liste des connexions entre pièces) *** */
|
|
|
|
|
|
|
|
|
|
set<string> connected_areas ; // Liste des zones connectées à au moins une autre zone (on n'enregistre que le nom des zones, dupliquer toutes les zones étant inutile).
|
|
|
|
|
|
|
|
|
|
for (map<string, Area>::iterator it1 = area_list.begin() ; it1 != area_list.end() ; it1++)
|
|
|
|
|
for (map<string, Area>::iterator it2 = area_list.begin() ; it2 != area_list.end() ; it2++)
|
|
|
|
|
{
|
|
|
|
|
if (it1 == it2)
|
|
|
|
|
continue ;
|
|
|
|
|
|
|
|
|
|
vector<Point> connect(areaConnection(it1->second, it2->second)) ;
|
|
|
|
|
|
|
|
|
|
if (!connect.empty())
|
|
|
|
|
{
|
|
|
|
|
connected_areas.insert(it1->first) ; // Ajout de la zone à la liste des zones connectées.
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
|
cout << "Les zones « " << it1->first << " » et « " << it2->first << " » sont connectées par les points suivants :" << endl ;
|
|
|
|
|
for (unsigned int i = 0 ; i < connect.size() ; i++)
|
|
|
|
|
cout << '\t' << connect[i] << endl ;
|
|
|
|
|
#endif // DEBUG
|
|
|
|
|
}
|
|
|
|
|
#ifdef DEBUG_2
|
|
|
|
|
else
|
|
|
|
|
cout << "Les zones « " << it1->first << " » et « " << it2->first << " » ne sont pas connectées." << endl ;
|
|
|
|
|
#endif // DEBUG_2
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (connected_areas.size() != area_list.size())
|
|
|
|
|
{
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
|
map<string, Area> orphan_areas(area_list) ; // Liste des zones orphelines (non-connectées). Copie de la liste des zones (on devrait utiliser un set ne contenant que les noms, comme pour "connected_areas", mais c'est plus compliqué à coder alors on ne va pas s'embêter, surtout pour un affichage de débogage).
|
|
|
|
|
|
|
|
|
|
for (set<string>::iterator it = connected_areas.begin() ; it != connected_areas.end() ; it++)
|
|
|
|
|
orphan_areas.erase(*it) ; // On supprime chaque zone connectée de la liste des zones orphelines.
|
|
|
|
|
|
|
|
|
|
cout << "Les zones suivantes ne sont connectées à aucune autre :" << endl ;
|
|
|
|
|
for (map<string, Area>::iterator it = orphan_areas.begin() ; it != orphan_areas.end() ; it++)
|
|
|
|
|
cout << '\t' << it->first << endl ;
|
|
|
|
|
#endif // DEBUG
|
|
|
|
|
|
|
|
|
|
ret = false ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG_T
|
|
|
|
|
cout << "//<-- Server::checkTopology()" << endl ; fflush(stdout) ;
|
|
|
|
|
#endif // DEBUG_T
|
|
|
|
|
|
|
|
|
|
return ret ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Calcule la distance entre tous les points de référence en tenant compte de la topologie (initialise reference_point_matrix).
|
|
|
|
|
* /!\ La liste des *points de passage*, leur *matrice de distances*, ainsi que la liste des *points de référence*, DOIVENT ÊTRE INITIALISÉES avant l'appel à cette fonction. Il faut donc appeler makeWaypointListFromFile() et makeReferencePointListFromFile() avant makeReferencePointDistances().
|
|
|
|
|
*/
|
|
|
|
|