[Positioning] TopologyReaderCSV: read waypoints
Stock: add Waypoint list and support functions. Waypoint: - Use an unordered_set instead of a vector for the Building list. - Add functions add_building(), add_buildings() and remove_building(). - Add operator string(). cfg/waypoints.csv: change format (add building name).
This commit is contained in:
parent
208c989c53
commit
14902181af
|
@ -123,7 +123,10 @@ $(OBJ_DIR)/inputdatareader.o: \
|
||||||
$(OBJ_DIR)/configuration.o \
|
$(OBJ_DIR)/configuration.o \
|
||||||
$(OBJ_DIR)/posexcept.o
|
$(OBJ_DIR)/posexcept.o
|
||||||
$(OBJ_DIR)/topologyreadercsv.o: \
|
$(OBJ_DIR)/topologyreadercsv.o: \
|
||||||
$(OBJ_DIR)/textfilereader.o
|
$(OBJ_DIR)/csvfilereader.o \
|
||||||
|
$(OBJ_DIR)/area.o \
|
||||||
|
$(OBJ_DIR)/waypoint.o \
|
||||||
|
$(OBJ_DIR)/stock.o
|
||||||
$(OBJ_DIR)/referencepoint.o: \
|
$(OBJ_DIR)/referencepoint.o: \
|
||||||
$(OBJ_DIR)/point3d.o
|
$(OBJ_DIR)/point3d.o
|
||||||
$(OBJ_DIR)/waypoint.o: \
|
$(OBJ_DIR)/waypoint.o: \
|
||||||
|
|
|
@ -1,4 +1,11 @@
|
||||||
|
|
||||||
|
- Hachages
|
||||||
|
° Regrouper les surcharges de hash_value() dans un fichier
|
||||||
|
d'en-tête dédié.
|
||||||
|
° Éventuellement, ce fichier d'en-tête pourrait être utilisé comme
|
||||||
|
une interface et inclure directement <unordered_set> et
|
||||||
|
<unordered_map>.
|
||||||
|
|
||||||
- Tests unitaires
|
- Tests unitaires
|
||||||
° Finir le test de InputDataReader.
|
° Finir le test de InputDataReader.
|
||||||
° Finir le test de Input.
|
° Finir le test de Input.
|
||||||
|
@ -49,8 +56,6 @@
|
||||||
- « C++ en action »
|
- « C++ en action »
|
||||||
° Espaces de noms ? 109
|
° Espaces de noms ? 109
|
||||||
° Réserver l'espace mémoire des vector avec reserve(). 217
|
° Réserver l'espace mémoire des vector avec reserve(). 217
|
||||||
° Utiliser hash_map (maintenant unordered_map) plutôt que map s'il
|
|
||||||
n'y a pas besoin de trier. 232
|
|
||||||
° Copie de conteneur vers un flux (cas de certains operator<<). 275
|
° Copie de conteneur vers un flux (cas de certains operator<<). 275
|
||||||
|
|
||||||
- « Coder proprement »
|
- « Coder proprement »
|
||||||
|
|
|
@ -1,122 +1,124 @@
|
||||||
# Liste des points de passage.
|
# Liste des points de passage.
|
||||||
# Chaque ligne définit les trois coordonnées d'un point, de la forme :
|
# Chaque ligne définit les trois coordonnées d'un point, de la forme :
|
||||||
# X;Y;Z
|
# X;Y;Z;Nom du bâtiment 1;…;Nom du bâtiment n
|
||||||
|
# Chaque point doit appartenir au moins à un bâtiment.
|
||||||
|
|
||||||
# Note : pour les zones appartenant à la même pièce non-convexe (ex : Couloir N0 A et Couloir N0 B), on définit un point tous les 1,50 m.
|
# Note : pour les zones appartenant à la même pièce non-convexe (ex :
|
||||||
|
# Couloir N0 A et Couloir N0 B), on définit un point tous les 1,50 m.
|
||||||
# Idem pour les portes très larges.
|
# Idem pour les portes très larges.
|
||||||
|
|
||||||
### Rez-de-chaussée ###
|
### Rez-de-chaussée ###
|
||||||
|
|
||||||
# 0140
|
# 0140
|
||||||
6.05;6.50;0.00
|
6.05;6.50;0.00;Numerica
|
||||||
|
|
||||||
# 0130
|
# 0130
|
||||||
6.05;7.50;0.00
|
6.05;7.50;0.00;Numerica
|
||||||
|
|
||||||
# 0120
|
# 0120
|
||||||
6.05;13.50;0.00
|
6.05;13.50;0.00;Numerica
|
||||||
|
|
||||||
# 0130 / 0120
|
# 0130 / 0120
|
||||||
3.00;10.88;0.00
|
3.00;10.88;0.00;Numerica
|
||||||
|
|
||||||
# 0110
|
# 0110
|
||||||
6.05;14.50;0.00
|
6.05;14.50;0.00;Numerica
|
||||||
|
|
||||||
# 0100
|
# 0100
|
||||||
6.05;21.00;0.00
|
6.05;21.00;0.00;Numerica
|
||||||
|
|
||||||
# 0090
|
# 0090
|
||||||
6.05;22.25;0.00
|
6.05;22.25;0.00;Numerica
|
||||||
|
|
||||||
# 0080
|
# 0080
|
||||||
6.05;28.50;0.00
|
6.05;28.50;0.00;Numerica
|
||||||
|
|
||||||
# 0070
|
# 0070
|
||||||
6.05;29.50;0.00
|
6.05;29.50;0.00;Numerica
|
||||||
|
|
||||||
# WC N0
|
# WC N0
|
||||||
8.20;5.00;0.00
|
8.20;5.00;0.00;Numerica
|
||||||
|
|
||||||
# 0085
|
# 0085
|
||||||
8.20;8.50;0.00
|
8.20;8.50;0.00;Numerica
|
||||||
|
|
||||||
# 0075
|
# 0075
|
||||||
8.20;9.50;0.00
|
8.20;9.50;0.00;Numerica
|
||||||
|
|
||||||
# Couloir N0 A / B
|
# Couloir N0 A / B
|
||||||
8.20;11.50;0.00
|
8.20;11.50;0.00;Numerica
|
||||||
8.20;13.00;0.00
|
8.20;13.00;0.00;Numerica
|
||||||
8.20;14.50;0.00
|
8.20;14.50;0.00;Numerica
|
||||||
8.20;16.00;0.00
|
8.20;16.00;0.00;Numerica
|
||||||
|
|
||||||
# Couloir N0 A / C
|
# Couloir N0 A / C
|
||||||
8.20;23.70;0.00
|
8.20;23.70;0.00;Numerica
|
||||||
|
|
||||||
# Palier N0
|
# Palier N0
|
||||||
7.50;3.70;0.00
|
7.50;3.70;0.00;Numerica
|
||||||
|
|
||||||
|
|
||||||
### Escaliers N0 / N1 ###
|
### Escaliers N0 / N1 ###
|
||||||
|
|
||||||
# Couloir N0 C / Escalier NO-N1 A
|
# Couloir N0 C / Escalier NO-N1 A
|
||||||
8.95;22.60;0.00
|
8.95;22.60;0.00;Numerica
|
||||||
|
|
||||||
# Escalier NO-N1 A / Couloir N1 B
|
# Escalier NO-N1 A / Couloir N1 B
|
||||||
8.95;16.50;3.00
|
8.95;16.50;3.00;Numerica
|
||||||
|
|
||||||
# Palier NO / Escalier N0-N1 B1
|
# Palier NO / Escalier N0-N1 B1
|
||||||
5.00;1.25;0.00
|
5.00;1.25;0.00;Numerica
|
||||||
|
|
||||||
# Escalier N0-N1 B1 / Escalier N0-N1 B palier
|
# Escalier N0-N1 B1 / Escalier N0-N1 B palier
|
||||||
2.50;1.25;1.50
|
2.50;1.25;1.50;Numerica
|
||||||
|
|
||||||
# Escalier N0-N1 B palier / Escalier N0-N1 B2
|
# Escalier N0-N1 B palier / Escalier N0-N1 B2
|
||||||
2.50;2.75;1.50
|
2.50;2.75;1.50;Numerica
|
||||||
|
|
||||||
# Escalier N0-N1 B2 / Palier N1
|
# Escalier N0-N1 B2 / Palier N1
|
||||||
5.00;2.75;3.00
|
5.00;2.75;3.00;Numerica
|
||||||
|
|
||||||
|
|
||||||
### Premier étage ###
|
### Premier étage ###
|
||||||
|
|
||||||
# 1100
|
# 1100
|
||||||
6.05;6.50;3.00
|
6.05;6.50;3.00;Numerica
|
||||||
|
|
||||||
# 0190
|
# 0190
|
||||||
6.05;7.50;3.00
|
6.05;7.50;3.00;Numerica
|
||||||
|
|
||||||
# 0180
|
# 0180
|
||||||
6.05;13.50;3.00
|
6.05;13.50;3.00;Numerica
|
||||||
|
|
||||||
# 0190 / 0180
|
# 0190 / 0180
|
||||||
3.00;10.88;3.00
|
3.00;10.88;3.00;Numerica
|
||||||
|
|
||||||
# 1070
|
# 1070
|
||||||
6.05;14.50;3.00
|
6.05;14.50;3.00;Numerica
|
||||||
|
|
||||||
# 1060
|
# 1060
|
||||||
6.05;21.00;3.00
|
6.05;21.00;3.00;Numerica
|
||||||
|
|
||||||
# 1050
|
# 1050
|
||||||
6.05;27.75;3.00
|
6.05;27.75;3.00;Numerica
|
||||||
|
|
||||||
# WC N1
|
# WC N1
|
||||||
8.20;5.00;3.00
|
8.20;5.00;3.00;Numerica
|
||||||
|
|
||||||
# 1105
|
# 1105
|
||||||
8.20;9.50;3.00
|
8.20;9.50;3.00;Numerica
|
||||||
|
|
||||||
# 1095
|
# 1095
|
||||||
8.20;26.00;3.00
|
8.20;26.00;3.00;Numerica
|
||||||
|
|
||||||
# Couloir N1 A / B
|
# Couloir N1 A / B
|
||||||
8.20;11.50;3.00
|
8.20;11.50;3.00;Numerica
|
||||||
8.20;13.00;3.00
|
8.20;13.00;3.00;Numerica
|
||||||
8.20;14.50;3.00
|
8.20;14.50;3.00;Numerica
|
||||||
8.20;16.00;3.00
|
8.20;16.00;3.00;Numerica
|
||||||
|
|
||||||
# Couloir N1 A / C
|
# Couloir N1 A / C
|
||||||
8.20;23.70;3.00
|
8.20;23.70;3.00;Numerica
|
||||||
|
|
||||||
# Palier N1
|
# Palier N1
|
||||||
7.50;3.70;3.00
|
7.50;3.70;3.00;Numerica
|
||||||
|
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "building.hh"
|
#include "building.hh"
|
||||||
#include "area.hh"
|
#include "area.hh"
|
||||||
#include "waypoint.hh"
|
#include "waypoint.hh"
|
||||||
|
#include "stock.hh"
|
||||||
|
|
||||||
|
|
||||||
using namespace std ;
|
using namespace std ;
|
||||||
|
@ -28,11 +29,7 @@ Building::~Building()
|
||||||
// Empty Waypoint list
|
// Empty Waypoint list
|
||||||
for (unordered_set<Waypoint*>::const_iterator i = waypoints.begin() ;
|
for (unordered_set<Waypoint*>::const_iterator i = waypoints.begin() ;
|
||||||
i != waypoints.end() ; ++i)
|
i != waypoints.end() ; ++i)
|
||||||
{
|
Stock::waypoint_remove_building(**i, this) ;
|
||||||
// Delete current waypoint only if it is not linked to another building
|
|
||||||
if ((*i)->get_buildings().size() <= 1)
|
|
||||||
delete *i ;
|
|
||||||
}
|
|
||||||
waypoints.clear() ;
|
waypoints.clear() ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,8 +43,12 @@ void InputDataReader::initialise_topology_media()
|
||||||
void InputDataReader::initialise_topology_csv()
|
void InputDataReader::initialise_topology_csv()
|
||||||
{
|
{
|
||||||
if (! Configuration::is_configured("data-input.areas-csv-file"))
|
if (! Configuration::is_configured("data-input.areas-csv-file"))
|
||||||
throw no_topology_input_csv_file() ;
|
throw no_topology_input_csv_file("areas") ;
|
||||||
|
|
||||||
|
if (! Configuration::is_configured("data-input.waypoints-csv-file"))
|
||||||
|
throw no_topology_input_csv_file("waypoints") ;
|
||||||
|
|
||||||
TopologyReaderCSV(
|
TopologyReaderCSV(
|
||||||
Configuration::string_value("data-input.areas-csv-file")) ;
|
Configuration::string_value("data-input.areas-csv-file"),
|
||||||
|
Configuration::string_value("data-input.waypoints-csv-file")) ;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,9 +33,11 @@ topology_input_medium_type_unknown(const string &medium_name) throw():
|
||||||
" » is unknown!") {}
|
" » is unknown!") {}
|
||||||
|
|
||||||
|
|
||||||
no_topology_input_csv_file::no_topology_input_csv_file() throw():
|
no_topology_input_csv_file::
|
||||||
|
no_topology_input_csv_file(const string &type) throw():
|
||||||
posexcept(
|
posexcept(
|
||||||
"No topologyinput CSV file specified in the configuration!") {}
|
"No topology input CSV file specified in the configuration for "
|
||||||
|
+ type + "!") {}
|
||||||
|
|
||||||
|
|
||||||
malformed_topology::
|
malformed_topology::
|
||||||
|
|
|
@ -58,7 +58,7 @@ public:
|
||||||
class no_topology_input_csv_file: public posexcept
|
class no_topology_input_csv_file: public posexcept
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
no_topology_input_csv_file(void) throw() ;
|
no_topology_input_csv_file(const std::string &type) throw() ;
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,17 +6,26 @@ using std::tr1::unordered_map ;
|
||||||
using std::tr1::unordered_set ;
|
using std::tr1::unordered_set ;
|
||||||
|
|
||||||
|
|
||||||
/// Hash function, required to put ReferencePoint in a set
|
/* *** Hash functions, required to put points in a set *** */
|
||||||
size_t hash_value(const ReferencePoint &object)
|
|
||||||
|
inline size_t hash_value(const ReferencePoint &object)
|
||||||
|
{
|
||||||
|
return boost::hash_value(static_cast<string>(object)) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline size_t hash_value(const Point3D &object)
|
||||||
{
|
{
|
||||||
return boost::hash_value(static_cast<string>(object)) ;
|
return boost::hash_value(static_cast<string>(object)) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* *** Attribute definitions *** */
|
/* *** Attribute definitions *** */
|
||||||
|
|
||||||
unordered_map<string, Building> Stock::buildings ;
|
unordered_map<string, Building> Stock::buildings ;
|
||||||
|
|
||||||
|
unordered_map<Point3D, Waypoint> Stock::waypoints ;
|
||||||
|
|
||||||
unordered_map<string, Mobile> Stock::mobiles ;
|
unordered_map<string, Mobile> Stock::mobiles ;
|
||||||
|
|
||||||
unordered_map<string, AccessPoint> Stock::aps ;
|
unordered_map<string, AccessPoint> Stock::aps ;
|
||||||
|
@ -63,6 +72,36 @@ const Building& Stock::get_building(const string &name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Waypoint& Stock::
|
||||||
|
find_create_waypoint(const Point3D &point)
|
||||||
|
{
|
||||||
|
unordered_map<Point3D, Waypoint>::const_iterator i =
|
||||||
|
waypoints.find(point) ;
|
||||||
|
if (i != waypoints.end())
|
||||||
|
return i->second ;
|
||||||
|
|
||||||
|
Waypoint &waypoint = waypoints[point] ;
|
||||||
|
waypoint.set_coordinates(point) ;
|
||||||
|
return waypoint ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Stock::waypoint_remove_building(const Waypoint &point,
|
||||||
|
const Building *building)
|
||||||
|
{
|
||||||
|
unordered_map<Point3D, Waypoint>::iterator i =
|
||||||
|
waypoints.find(point) ;
|
||||||
|
|
||||||
|
Waypoint *waypoint = const_cast<Waypoint*>(&i->second) ;
|
||||||
|
waypoint->remove_building(building) ;
|
||||||
|
|
||||||
|
// If the Waypoint is not linked to any Building any more, we
|
||||||
|
// delete it
|
||||||
|
if (waypoint->get_1st_building() == NULL)
|
||||||
|
waypoints.erase(i) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mac The MAC address of the Mobile to search for.
|
* @param mac The MAC address of the Mobile to search for.
|
||||||
* It must be a valid MAC address, as no check is performed.
|
* It must be a valid MAC address, as no check is performed.
|
||||||
|
@ -131,7 +170,7 @@ const ReferencePoint& Stock::
|
||||||
find_create_reference_point(const ReferencePoint &point)
|
find_create_reference_point(const ReferencePoint &point)
|
||||||
{
|
{
|
||||||
// unordered_set::insert() do all the job: see the documentation at
|
// unordered_set::insert() do all the job: see the documentation at
|
||||||
// http://www.boost.org/doc/libs/1_41_0/doc/html/boost/unordered_set.html
|
// http://boost.org/doc/libs/1_42_0/doc/html/boost/unordered_set.html
|
||||||
pair<unordered_set<ReferencePoint>::iterator, bool> ret =
|
pair<unordered_set<ReferencePoint>::iterator, bool> ret =
|
||||||
reference_points.insert(point) ;
|
reference_points.insert(point) ;
|
||||||
return *ret.first ;
|
return *ret.first ;
|
||||||
|
@ -150,6 +189,12 @@ find_create_calibration_request(const CalibrationRequest &request)
|
||||||
void Stock::clear()
|
void Stock::clear()
|
||||||
{
|
{
|
||||||
buildings.clear() ;
|
buildings.clear() ;
|
||||||
|
|
||||||
|
// Waypoints are normally deleted in Building::~Building(), so we must
|
||||||
|
// not clear waypoints before buildings, but we clear it *after*, just
|
||||||
|
// in case.
|
||||||
|
waypoints.clear() ;
|
||||||
|
|
||||||
mobiles.clear() ;
|
mobiles.clear() ;
|
||||||
aps.clear() ;
|
aps.clear() ;
|
||||||
reference_points.clear() ;
|
reference_points.clear() ;
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define _OWLPS_POSITIONING_STOCK_HH_
|
#define _OWLPS_POSITIONING_STOCK_HH_
|
||||||
|
|
||||||
#include "building.hh"
|
#include "building.hh"
|
||||||
|
#include "waypoint.hh"
|
||||||
#include "mobile.hh"
|
#include "mobile.hh"
|
||||||
#include "accesspoint.hh"
|
#include "accesspoint.hh"
|
||||||
#include "referencepoint.hh"
|
#include "referencepoint.hh"
|
||||||
|
@ -17,6 +18,9 @@ private:
|
||||||
/// List of known Building
|
/// List of known Building
|
||||||
static std::tr1::unordered_map<std::string, Building> buildings ;
|
static std::tr1::unordered_map<std::string, Building> buildings ;
|
||||||
|
|
||||||
|
/// List of known Waypoint
|
||||||
|
static std::tr1::unordered_map<Point3D, Waypoint> waypoints ;
|
||||||
|
|
||||||
/// List of known Mobile
|
/// List of known Mobile
|
||||||
static std::tr1::unordered_map<std::string, Mobile> mobiles ;
|
static std::tr1::unordered_map<std::string, Mobile> mobiles ;
|
||||||
|
|
||||||
|
@ -35,6 +39,18 @@ public:
|
||||||
/// Look for a Building and create it if it does not exist
|
/// Look for a Building and create it if it does not exist
|
||||||
static const Building& find_create_building(const std::string &name) ;
|
static const Building& find_create_building(const std::string &name) ;
|
||||||
|
|
||||||
|
/// Look for a Waypoint and add it if it does not exist
|
||||||
|
static const Waypoint&
|
||||||
|
find_create_waypoint(const Waypoint &point) ;
|
||||||
|
/// \brief Look for a Waypoint from its coordinates and add it if it
|
||||||
|
/// does not exist
|
||||||
|
static const Waypoint&
|
||||||
|
find_create_waypoint(const Point3D &point) ;
|
||||||
|
/// \brief Delete a Building from the building list of a Waypoint;
|
||||||
|
/// delete the Waypoint if it is not linked to any Building any more
|
||||||
|
static void waypoint_remove_building(const Waypoint &point,
|
||||||
|
const Building *building) ;
|
||||||
|
|
||||||
/// Read the Mobile corresponding to a given MAC address
|
/// Read the Mobile corresponding to a given MAC address
|
||||||
static const Mobile& get_mobile(const std::string &mac) ;
|
static const Mobile& get_mobile(const std::string &mac) ;
|
||||||
/// Look for a Mobile and create it if it does not exist
|
/// Look for a Mobile and create it if it does not exist
|
||||||
|
@ -66,6 +82,17 @@ public:
|
||||||
/* *** Accessors *** */
|
/* *** Accessors *** */
|
||||||
|
|
||||||
|
|
||||||
|
inline const Waypoint& Stock::
|
||||||
|
find_create_waypoint(const Waypoint &point)
|
||||||
|
{
|
||||||
|
Waypoint& found =
|
||||||
|
const_cast<Waypoint&>(
|
||||||
|
find_create_waypoint(static_cast<Point3D>(point))) ;
|
||||||
|
found.add_buildings(point) ;
|
||||||
|
return found ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the Mobile corresponding to \em mac does not exist, it is created.
|
* If the Mobile corresponding to \em mac does not exist, it is created.
|
||||||
* @param mac The MAC address of the Mobile to search for. It must be a
|
* @param mac The MAC address of the Mobile to search for. It must be a
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#include "topologyreadercsv.hh"
|
#include "topologyreadercsv.hh"
|
||||||
#include "posexcept.hh"
|
#include "posexcept.hh"
|
||||||
#include "stock.hh"
|
#include "stock.hh"
|
||||||
#include "point3d.hh"
|
|
||||||
#include "area.hh"
|
#include "area.hh"
|
||||||
|
#include "waypoint.hh"
|
||||||
|
|
||||||
using namespace std ;
|
using namespace std ;
|
||||||
|
|
||||||
|
@ -11,8 +11,9 @@ using namespace std ;
|
||||||
/* *** Constructors *** */
|
/* *** Constructors *** */
|
||||||
|
|
||||||
|
|
||||||
TopologyReaderCSV::TopologyReaderCSV(const string &filename):
|
TopologyReaderCSV::TopologyReaderCSV(
|
||||||
file(filename)
|
const string &areas_file_name, const string &waypoints_file_name):
|
||||||
|
areas_file(areas_file_name), waypoints_file(waypoints_file_name)
|
||||||
{
|
{
|
||||||
read_topology() ;
|
read_topology() ;
|
||||||
}
|
}
|
||||||
|
@ -24,32 +25,58 @@ TopologyReaderCSV::TopologyReaderCSV(const string &filename):
|
||||||
|
|
||||||
void TopologyReaderCSV::read_topology()
|
void TopologyReaderCSV::read_topology()
|
||||||
{
|
{
|
||||||
while (file.next_line())
|
while (areas_file.next_line())
|
||||||
process_line() ;
|
process_area_line() ;
|
||||||
|
|
||||||
|
while (waypoints_file.next_line())
|
||||||
|
process_waypoint_line() ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void TopologyReaderCSV::process_line()
|
void TopologyReaderCSV::process_area_line()
|
||||||
{
|
{
|
||||||
string building_name ;
|
string building_name ;
|
||||||
if (! file.read_field(building_name))
|
if (! areas_file.read_field(building_name))
|
||||||
throw malformed_topology("Cannot read building name!") ;
|
throw malformed_topology("Cannot read building name!") ;
|
||||||
Building &building = const_cast<Building&>(
|
Building &building = const_cast<Building&>(
|
||||||
Stock::find_create_building(building_name)) ;
|
Stock::find_create_building(building_name)) ;
|
||||||
|
|
||||||
string name ;
|
string name ;
|
||||||
if (! file.read_field(name))
|
if (! areas_file.read_field(name))
|
||||||
throw malformed_topology("Cannot read area name!") ;
|
throw malformed_topology("Cannot read area name!") ;
|
||||||
|
|
||||||
Point3D p_min(read_point()) ;
|
Point3D p_min(read_point(areas_file)) ;
|
||||||
Point3D p_max(read_point()) ;
|
Point3D p_max(read_point(areas_file)) ;
|
||||||
|
|
||||||
Area *area = new Area(&building, name, p_min, p_max) ;
|
Area *area = new Area(&building, name, p_min, p_max) ;
|
||||||
building.add_area(area) ;
|
building.add_area(area) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Point3D TopologyReaderCSV::read_point()
|
void TopologyReaderCSV::process_waypoint_line()
|
||||||
|
{
|
||||||
|
Point3D coordinates(read_point(waypoints_file)) ;
|
||||||
|
Waypoint &waypoint_ref =
|
||||||
|
const_cast<Waypoint&>(Stock::find_create_waypoint(coordinates)) ;
|
||||||
|
|
||||||
|
vector<Building*> buildings ;
|
||||||
|
string building_name ;
|
||||||
|
while (waypoints_file.read_field(building_name))
|
||||||
|
buildings.push_back(const_cast<Building*>(
|
||||||
|
&Stock::find_create_building(building_name))) ;
|
||||||
|
if (buildings.empty())
|
||||||
|
throw malformed_topology("Cannot read building name!") ;
|
||||||
|
|
||||||
|
for (vector<Building*>::iterator i = buildings.begin() ;
|
||||||
|
i != buildings.end() ; ++i)
|
||||||
|
{
|
||||||
|
waypoint_ref.add_building(*i) ;
|
||||||
|
(*i)->add_waypoint(&waypoint_ref) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Point3D TopologyReaderCSV::read_point(CSVFileReader &file)
|
||||||
{
|
{
|
||||||
float coord[3] ;
|
float coord[3] ;
|
||||||
for (unsigned int i = 0 ; i < 3 ; ++i)
|
for (unsigned int i = 0 ; i < 3 ; ++i)
|
||||||
|
|
|
@ -7,22 +7,29 @@ class Point3D ;
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
/// Reads and registers to the Stock an Area list from a CSV file
|
/// \brief Reads and registers to the Stock Area and Waypoint lists
|
||||||
|
/// from CSV files
|
||||||
/**
|
/**
|
||||||
* CSV format is:
|
* CSV format for areas is:
|
||||||
* Building name;Room name;X1;Y1;Z1;X2;Y2;Z2
|
* Building name;Room name;X1;Y1;Z1;X2;Y2;Z2
|
||||||
|
*
|
||||||
|
* CSV format for waypoints is:
|
||||||
|
* X;Y;Z;Building name #1[;Building name #2[…[;Building name #n]]]
|
||||||
*/
|
*/
|
||||||
class TopologyReaderCSV
|
class TopologyReaderCSV
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
CSVFileReader file ;
|
CSVFileReader areas_file ;
|
||||||
|
CSVFileReader waypoints_file ;
|
||||||
|
|
||||||
void read_topology(void) ;
|
void read_topology(void) ;
|
||||||
void process_line(void) ;
|
void process_area_line(void) ;
|
||||||
Point3D read_point(void) ;
|
void process_waypoint_line(void) ;
|
||||||
|
Point3D read_point(CSVFileReader &file) ;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TopologyReaderCSV(const std::string &filename) ;
|
TopologyReaderCSV(const std::string &areas_file_name,
|
||||||
|
const std::string &waypoints_file_name) ;
|
||||||
|
|
||||||
~TopologyReaderCSV(void) {}
|
~TopologyReaderCSV(void) {}
|
||||||
} ;
|
} ;
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
#include "waypoint.hh"
|
#include "waypoint.hh"
|
||||||
|
#include "building.hh"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
using namespace std ;
|
using namespace std ;
|
||||||
|
using std::tr1::unordered_set ;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -20,7 +23,7 @@ Waypoint::Waypoint(const Building *_b,
|
||||||
): Point3D(_x, _y, _z)
|
): Point3D(_x, _y, _z)
|
||||||
{
|
{
|
||||||
if (_b != NULL)
|
if (_b != NULL)
|
||||||
buildings.push_back(const_cast<Building*>(_b)) ;
|
buildings.insert(const_cast<Building*>(_b)) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -32,7 +35,7 @@ Waypoint::Waypoint(const Building *_b,
|
||||||
Waypoint::Waypoint(const Building *_b, const Point3D &p): Point3D(p)
|
Waypoint::Waypoint(const Building *_b, const Point3D &p): Point3D(p)
|
||||||
{
|
{
|
||||||
if (_b != NULL)
|
if (_b != NULL)
|
||||||
buildings.push_back(const_cast<Building*>(_b)) ;
|
buildings.insert(const_cast<Building*>(_b)) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -73,6 +76,19 @@ bool Waypoint::operator==(const Waypoint &wp) const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Waypoint::operator string() const
|
||||||
|
{
|
||||||
|
ostringstream csv ;
|
||||||
|
csv << (Point3D) *this ;
|
||||||
|
|
||||||
|
for (unordered_set<Building*>::const_iterator i = buildings.begin() ;
|
||||||
|
i != buildings.end() ; ++i)
|
||||||
|
csv << ';' << (*i)->get_name() ;
|
||||||
|
|
||||||
|
return csv.str() ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ostream &operator<<(ostream &os, const Waypoint &wp)
|
ostream &operator<<(ostream &os, const Waypoint &wp)
|
||||||
{
|
{
|
||||||
|
@ -83,9 +99,9 @@ ostream &operator<<(ostream &os, const Waypoint &wp)
|
||||||
if (wp.buildings.empty())
|
if (wp.buildings.empty())
|
||||||
os << '\n' << "Belongs to no building!" ;
|
os << '\n' << "Belongs to no building!" ;
|
||||||
else
|
else
|
||||||
for (vector<Building*>::const_iterator i = wp.buildings.begin() ;
|
for (unordered_set<Building*>::const_iterator i =
|
||||||
i != wp.buildings.end() ; ++i)
|
wp.buildings.begin() ; i != wp.buildings.end() ; ++i)
|
||||||
os << '\n' << *i ;
|
os << '\n' << **i ;
|
||||||
|
|
||||||
return os ;
|
return os ;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,8 @@ class Building ;
|
||||||
|
|
||||||
#include "point3d.hh"
|
#include "point3d.hh"
|
||||||
|
|
||||||
|
#include <boost/tr1/unordered_set.hpp>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <vector>
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
/// Represents a junction point between several rooms (i.e. Area)
|
/// Represents a junction point between several rooms (i.e. Area)
|
||||||
|
@ -20,7 +20,7 @@ class Waypoint: public Point3D
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
/// List of Building associated with the Waypoint
|
/// List of Building associated with the Waypoint
|
||||||
std::vector<Building*> buildings ;
|
std::tr1::unordered_set<Building*> buildings ;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Waypoint(const Building *_b = NULL, const float &_x = 0,
|
Waypoint(const Building *_b = NULL, const float &_x = 0,
|
||||||
|
@ -38,13 +38,17 @@ public:
|
||||||
//@{
|
//@{
|
||||||
/// #buildings's first element read accessor
|
/// #buildings's first element read accessor
|
||||||
Building* get_1st_building(void) const ;
|
Building* get_1st_building(void) const ;
|
||||||
const std::vector<Building*>& get_buildings(void) const ;
|
const std::tr1::unordered_set<Building*>& get_buildings(void) const ;
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
/** @name Write accessors */
|
/** @name Write accessors */
|
||||||
//@{
|
//@{
|
||||||
/// Adds a Building to the \link #buildings building list\endlink
|
/// Adds a Building to the \link #buildings building list\endlink
|
||||||
void add_building(const Building *_b) ;
|
void add_building(const Building *_b) ;
|
||||||
|
/// Adds the Building list of \em source to #buildings
|
||||||
|
void add_buildings(const Waypoint &source) ;
|
||||||
|
/// Remove a Building from #buildings
|
||||||
|
void remove_building(const Building *_b) ;
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
/** @name Operators */
|
/** @name Operators */
|
||||||
|
@ -52,6 +56,7 @@ public:
|
||||||
const Waypoint& operator=(const Waypoint &wp) ;
|
const Waypoint& operator=(const Waypoint &wp) ;
|
||||||
bool operator==(const Waypoint &wp) const ;
|
bool operator==(const Waypoint &wp) const ;
|
||||||
bool operator!=(const Waypoint &wp) const ;
|
bool operator!=(const Waypoint &wp) const ;
|
||||||
|
operator std::string(void) const ;
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
/// Displays a Waypoint
|
/// Displays a Waypoint
|
||||||
|
@ -70,18 +75,14 @@ public:
|
||||||
*/
|
*/
|
||||||
inline Building* Waypoint::get_1st_building() const
|
inline Building* Waypoint::get_1st_building() const
|
||||||
{
|
{
|
||||||
try
|
if (buildings.empty())
|
||||||
{
|
return NULL ;
|
||||||
return buildings.at(0) ;
|
return *buildings.begin() ;
|
||||||
}
|
|
||||||
catch (std::out_of_range &e)
|
|
||||||
{
|
|
||||||
return NULL ;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline const std::vector<Building*>& Waypoint::get_buildings() const
|
inline const std::tr1::unordered_set<Building*>&
|
||||||
|
Waypoint::get_buildings() const
|
||||||
{
|
{
|
||||||
return buildings ;
|
return buildings ;
|
||||||
}
|
}
|
||||||
|
@ -101,7 +102,20 @@ inline const std::vector<Building*>& Waypoint::get_buildings() const
|
||||||
inline void Waypoint::add_building(const Building *_b)
|
inline void Waypoint::add_building(const Building *_b)
|
||||||
{
|
{
|
||||||
if (_b != NULL)
|
if (_b != NULL)
|
||||||
buildings.push_back(const_cast<Building*>(_b)) ;
|
buildings.insert(const_cast<Building*>(_b)) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void Waypoint::remove_building(const Building *_b)
|
||||||
|
{
|
||||||
|
if (_b != NULL)
|
||||||
|
buildings.erase(const_cast<Building*>(_b)) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void Waypoint::add_buildings(const Waypoint &source)
|
||||||
|
{
|
||||||
|
buildings.insert(source.buildings.begin(), source.buildings.end()) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -38,12 +38,14 @@ public:
|
||||||
b2.set_name("My Second Building") ;
|
b2.set_name("My Second Building") ;
|
||||||
TS_ASSERT_EQUALS(b2.get_name(), "My Second Building") ;
|
TS_ASSERT_EQUALS(b2.get_name(), "My Second Building") ;
|
||||||
|
|
||||||
Waypoint *wp1 = new Waypoint(&b2, 43, 45, 909) ;
|
const Waypoint &wp1 =
|
||||||
Waypoint *wp2 = new Waypoint(&b2, 12, 78, 2) ;
|
Stock::find_create_waypoint(Waypoint(&b2, 43,45,909)) ;
|
||||||
b2.add_waypoint(wp1) ;
|
const Waypoint &wp2 =
|
||||||
b2.add_waypoint(wp2) ;
|
Stock::find_create_waypoint(Waypoint(&b2, 12,78,2)) ;
|
||||||
waypoints1.insert(wp1) ;
|
b2.add_waypoint(&wp1) ;
|
||||||
waypoints1.insert(wp2) ;
|
b2.add_waypoint(&wp2) ;
|
||||||
|
waypoints1.insert(const_cast<Waypoint*>(&wp1)) ;
|
||||||
|
waypoints1.insert(const_cast<Waypoint*>(&wp2)) ;
|
||||||
TS_ASSERT_EQUALS(b2.get_waypoints(), waypoints1) ;
|
TS_ASSERT_EQUALS(b2.get_waypoints(), waypoints1) ;
|
||||||
|
|
||||||
Area *a1 = new Area(&b2, "area1") ;
|
Area *a1 = new Area(&b2, "area1") ;
|
||||||
|
@ -53,6 +55,8 @@ public:
|
||||||
areas1["area1"] = a1 ;
|
areas1["area1"] = a1 ;
|
||||||
areas1["area2"] = a2 ;
|
areas1["area2"] = a2 ;
|
||||||
TS_ASSERT_EQUALS(b2.get_areas(), areas1) ;
|
TS_ASSERT_EQUALS(b2.get_areas(), areas1) ;
|
||||||
|
|
||||||
|
// TODO: test deletion of waypoints from Stock after deletion of b2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,21 @@ public:
|
||||||
element_not_found) ;
|
element_not_found) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_waypoints(void)
|
||||||
|
{
|
||||||
|
Point3D coordinates(42,21,98) ;
|
||||||
|
const Building &building = Stock::find_create_building("Build") ;
|
||||||
|
Waypoint wp1(&building, coordinates) ;
|
||||||
|
const Waypoint
|
||||||
|
&wp1_ref1 = Stock::find_create_waypoint(wp1),
|
||||||
|
&wp1_ref2 = Stock::find_create_waypoint(coordinates) ;
|
||||||
|
TS_ASSERT_EQUALS(&wp1_ref1, &wp1_ref2) ;
|
||||||
|
|
||||||
|
Stock::waypoint_remove_building(wp1_ref1, &building) ;
|
||||||
|
// TODO: test if the waypoint was removed (needs a function
|
||||||
|
// Stock::get_waypoint()).
|
||||||
|
}
|
||||||
|
|
||||||
void test_mobiles(void)
|
void test_mobiles(void)
|
||||||
{
|
{
|
||||||
TS_ASSERT_THROWS(Stock::get_mobile("aa:bb:cc:dd:ee:ff"),
|
TS_ASSERT_THROWS(Stock::get_mobile("aa:bb:cc:dd:ee:ff"),
|
||||||
|
|
|
@ -5,30 +5,47 @@
|
||||||
class TopologyReaderCSV_test: public CxxTest::TestSuite
|
class TopologyReaderCSV_test: public CxxTest::TestSuite
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
std::string topology_file_name ;
|
std::string areas_file_name ;
|
||||||
|
std::string waypoints_file_name ;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
TopologyReaderCSV_test(void):
|
TopologyReaderCSV_test(void):
|
||||||
topology_file_name("/tmp/TopologyReaderCSV_topology_file.csv")
|
areas_file_name("/tmp/TopologyReaderCSV_areas_file.csv"),
|
||||||
|
waypoints_file_name("/tmp/TopologyReaderCSV_waypoints_file.csv")
|
||||||
{
|
{
|
||||||
Stock::clear() ;
|
Stock::clear() ;
|
||||||
|
|
||||||
std::ofstream topology_file(topology_file_name.c_str()) ;
|
std::ofstream areas_file(areas_file_name.c_str()) ;
|
||||||
topology_file
|
areas_file
|
||||||
<< "My building;My room #1;1;2;3;9;8;7\n"
|
<< "My building;My room #1;1;2;3;9;8;7\n"
|
||||||
<< "My building;Room #2;4;5;6;6;5;4\n"
|
<< "My building;Room #2;4;5;6;6;5;4\n"
|
||||||
<< "Building #2;My room #1;1;2;3;9;8;7\n"
|
<< "Building #2;My room #1;1;2;3;9;8;7\n"
|
||||||
<< "My building;Room #2;4;5;6;6;5;4\n"
|
<< "My building;Room #2;4;5;6;6;5;4\n"
|
||||||
<< "My building;Room #2;4;5;6;6;5;4\n" ;
|
<< "My building;Room #2;4;5;6;6;5;4\n" ;
|
||||||
topology_file.close() ;
|
areas_file.close() ;
|
||||||
|
|
||||||
|
std::ofstream waypoints_file(waypoints_file_name.c_str()) ;
|
||||||
|
waypoints_file
|
||||||
|
<< "1;2;3;My building\n"
|
||||||
|
<< "4;5;6;My building\n"
|
||||||
|
<< "1;2;3;Building #2\n"
|
||||||
|
<< "4;5;6;My building\n"
|
||||||
|
<< "9;8;7;Building #2;My building\n"
|
||||||
|
<< "4;5;6;My building\n" ;
|
||||||
|
waypoints_file.close() ;
|
||||||
|
|
||||||
|
TS_ASSERT_THROWS_NOTHING(
|
||||||
|
TopologyReaderCSV toporeader(areas_file_name,
|
||||||
|
waypoints_file_name)) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
~TopologyReaderCSV_test(void)
|
~TopologyReaderCSV_test(void)
|
||||||
{
|
{
|
||||||
Stock::clear() ;
|
Stock::clear() ;
|
||||||
TestUtil::remove_file(topology_file_name) ;
|
TestUtil::remove_file(areas_file_name) ;
|
||||||
|
TestUtil::remove_file(waypoints_file_name) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -44,11 +61,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void test_topologyreadercsv(void)
|
void test_areas(void)
|
||||||
{
|
{
|
||||||
TS_ASSERT_THROWS_NOTHING(
|
|
||||||
TopologyReaderCSV toporeader(topology_file_name)) ;
|
|
||||||
|
|
||||||
Building *building1 ;
|
Building *building1 ;
|
||||||
TS_ASSERT_THROWS_NOTHING(
|
TS_ASSERT_THROWS_NOTHING(
|
||||||
building1 = const_cast<Building*>(
|
building1 = const_cast<Building*>(
|
||||||
|
@ -80,4 +94,54 @@ public:
|
||||||
TS_ASSERT_EQUALS(*area_ptr, area1) ;
|
TS_ASSERT_EQUALS(*area_ptr, area1) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void test_waypoints(void)
|
||||||
|
{
|
||||||
|
Building *building1 ;
|
||||||
|
TS_ASSERT_THROWS_NOTHING(
|
||||||
|
building1 = const_cast<Building*>(
|
||||||
|
&Stock::get_building("My building"))) ;
|
||||||
|
Building *building2 ;
|
||||||
|
TS_ASSERT_THROWS_NOTHING(
|
||||||
|
building2 = const_cast<Building*>(
|
||||||
|
&Stock::get_building("Building #2"))) ;
|
||||||
|
|
||||||
|
Waypoint *w, *waypoint_ptr ;
|
||||||
|
|
||||||
|
TS_ASSERT_EQUALS(building1->get_waypoints().size(), 3u) ;
|
||||||
|
|
||||||
|
const Waypoint &waypoint1 =
|
||||||
|
Stock::find_create_waypoint(Waypoint(building1, 1,2,3)) ;
|
||||||
|
w = const_cast<Waypoint*>(&waypoint1) ;
|
||||||
|
|
||||||
|
TS_ASSERT(building1->get_waypoints().find(w) !=
|
||||||
|
building1->get_waypoints().end()) ;
|
||||||
|
waypoint_ptr = *building1->get_waypoints().find(
|
||||||
|
const_cast<Waypoint*>(&waypoint1)) ;
|
||||||
|
TS_ASSERT_EQUALS(waypoint_ptr, w) ;
|
||||||
|
|
||||||
|
const Waypoint &waypoint2 =
|
||||||
|
Stock::find_create_waypoint(Waypoint(building1, 4,5,6)) ;
|
||||||
|
w = const_cast<Waypoint*>(&waypoint2) ;
|
||||||
|
|
||||||
|
TS_ASSERT(building1->get_waypoints().find(w) !=
|
||||||
|
building1->get_waypoints().end()) ;
|
||||||
|
waypoint_ptr = *building1->get_waypoints().find(
|
||||||
|
const_cast<Waypoint*>(&waypoint2)) ;
|
||||||
|
TS_ASSERT_EQUALS(waypoint_ptr, w) ;
|
||||||
|
|
||||||
|
|
||||||
|
TS_ASSERT_EQUALS(building2->get_waypoints().size(), 2u) ;
|
||||||
|
|
||||||
|
const Waypoint &waypoint3 =
|
||||||
|
Stock::find_create_waypoint(Waypoint(building2, 1,2,3)) ;
|
||||||
|
w = const_cast<Waypoint*>(&waypoint3) ;
|
||||||
|
|
||||||
|
TS_ASSERT(building2->get_waypoints().find(w) !=
|
||||||
|
building2->get_waypoints().end()) ;
|
||||||
|
waypoint_ptr = *building2->get_waypoints().find(
|
||||||
|
const_cast<Waypoint*>(&waypoint3)) ;
|
||||||
|
TS_ASSERT_EQUALS(waypoint_ptr, w) ;
|
||||||
|
}
|
||||||
|
|
||||||
} ;
|
} ;
|
||||||
|
|
|
@ -47,10 +47,10 @@ public:
|
||||||
// Write & read accessors
|
// Write & read accessors
|
||||||
Building b2("My Second Building") ;
|
Building b2("My Second Building") ;
|
||||||
wp1.add_building(&b2) ;
|
wp1.add_building(&b2) ;
|
||||||
std::vector<Building*> vb1 ;
|
std::tr1::unordered_set<Building*> buildings ;
|
||||||
vb1.push_back(&b1) ;
|
buildings.insert(&b1) ;
|
||||||
vb1.push_back(&b2) ;
|
buildings.insert(&b2) ;
|
||||||
TS_ASSERT_EQUALS(wp1.get_buildings(), vb1) ;
|
TS_ASSERT_EQUALS(wp1.get_buildings(), buildings) ;
|
||||||
wp1.set_x(42) ;
|
wp1.set_x(42) ;
|
||||||
TS_ASSERT_EQUALS(wp1.get_x(), 42) ;
|
TS_ASSERT_EQUALS(wp1.get_x(), 42) ;
|
||||||
wp1.set_y(321) ;
|
wp1.set_y(321) ;
|
||||||
|
|
Loading…
Reference in New Issue