From 14902181afa1293c2eb29ac14bfc9c7eb5a5b6a4 Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Tue, 13 Apr 2010 10:47:10 +0200 Subject: [PATCH] [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). --- owlps-positioning/Makefile | 5 +- owlps-positioning/TODO | 9 +- owlps-positioning/cfg/waypoints.csv | 86 ++++++++++--------- owlps-positioning/src/building.cc | 7 +- owlps-positioning/src/inputdatareader.cc | 8 +- owlps-positioning/src/posexcept.cc | 6 +- owlps-positioning/src/posexcept.hh | 2 +- owlps-positioning/src/stock.cc | 51 ++++++++++- owlps-positioning/src/stock.hh | 27 ++++++ owlps-positioning/src/topologyreadercsv.cc | 49 ++++++++--- owlps-positioning/src/topologyreadercsv.hh | 19 ++-- owlps-positioning/src/waypoint.cc | 26 ++++-- owlps-positioning/src/waypoint.hh | 40 ++++++--- owlps-positioning/tests/building_test.hh | 16 ++-- owlps-positioning/tests/stock_test.hh | 15 ++++ .../tests/topologyreadercsv_test.hh | 84 +++++++++++++++--- owlps-positioning/tests/waypoint_test.hh | 8 +- 17 files changed, 345 insertions(+), 113 deletions(-) diff --git a/owlps-positioning/Makefile b/owlps-positioning/Makefile index a113c83..3faaa5d 100644 --- a/owlps-positioning/Makefile +++ b/owlps-positioning/Makefile @@ -123,7 +123,10 @@ $(OBJ_DIR)/inputdatareader.o: \ $(OBJ_DIR)/configuration.o \ $(OBJ_DIR)/posexcept.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)/point3d.o $(OBJ_DIR)/waypoint.o: \ diff --git a/owlps-positioning/TODO b/owlps-positioning/TODO index 21ac4e9..44729f2 100644 --- a/owlps-positioning/TODO +++ b/owlps-positioning/TODO @@ -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 et + . + - Tests unitaires ° Finir le test de InputDataReader. ° Finir le test de Input. @@ -49,8 +56,6 @@ - « C++ en action » ° Espaces de noms ? 109 ° 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 - « Coder proprement » diff --git a/owlps-positioning/cfg/waypoints.csv b/owlps-positioning/cfg/waypoints.csv index 79b0f6f..a53bc24 100644 --- a/owlps-positioning/cfg/waypoints.csv +++ b/owlps-positioning/cfg/waypoints.csv @@ -1,122 +1,124 @@ # Liste des points de passage. # 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. ### Rez-de-chaussée ### # 0140 -6.05;6.50;0.00 +6.05;6.50;0.00;Numerica # 0130 -6.05;7.50;0.00 +6.05;7.50;0.00;Numerica # 0120 -6.05;13.50;0.00 +6.05;13.50;0.00;Numerica # 0130 / 0120 -3.00;10.88;0.00 +3.00;10.88;0.00;Numerica # 0110 -6.05;14.50;0.00 +6.05;14.50;0.00;Numerica # 0100 -6.05;21.00;0.00 +6.05;21.00;0.00;Numerica # 0090 -6.05;22.25;0.00 +6.05;22.25;0.00;Numerica # 0080 -6.05;28.50;0.00 +6.05;28.50;0.00;Numerica # 0070 -6.05;29.50;0.00 +6.05;29.50;0.00;Numerica # WC N0 -8.20;5.00;0.00 +8.20;5.00;0.00;Numerica # 0085 -8.20;8.50;0.00 +8.20;8.50;0.00;Numerica # 0075 -8.20;9.50;0.00 +8.20;9.50;0.00;Numerica # Couloir N0 A / B -8.20;11.50;0.00 -8.20;13.00;0.00 -8.20;14.50;0.00 -8.20;16.00;0.00 +8.20;11.50;0.00;Numerica +8.20;13.00;0.00;Numerica +8.20;14.50;0.00;Numerica +8.20;16.00;0.00;Numerica # Couloir N0 A / C -8.20;23.70;0.00 +8.20;23.70;0.00;Numerica # Palier N0 -7.50;3.70;0.00 +7.50;3.70;0.00;Numerica ### Escaliers N0 / N1 ### # 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 -8.95;16.50;3.00 +8.95;16.50;3.00;Numerica # 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 -2.50;1.25;1.50 +2.50;1.25;1.50;Numerica # 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 -5.00;2.75;3.00 +5.00;2.75;3.00;Numerica ### Premier étage ### # 1100 -6.05;6.50;3.00 +6.05;6.50;3.00;Numerica # 0190 -6.05;7.50;3.00 +6.05;7.50;3.00;Numerica # 0180 -6.05;13.50;3.00 +6.05;13.50;3.00;Numerica # 0190 / 0180 -3.00;10.88;3.00 +3.00;10.88;3.00;Numerica # 1070 -6.05;14.50;3.00 +6.05;14.50;3.00;Numerica # 1060 -6.05;21.00;3.00 +6.05;21.00;3.00;Numerica # 1050 -6.05;27.75;3.00 +6.05;27.75;3.00;Numerica # WC N1 -8.20;5.00;3.00 +8.20;5.00;3.00;Numerica # 1105 -8.20;9.50;3.00 +8.20;9.50;3.00;Numerica # 1095 -8.20;26.00;3.00 +8.20;26.00;3.00;Numerica # Couloir N1 A / B -8.20;11.50;3.00 -8.20;13.00;3.00 -8.20;14.50;3.00 -8.20;16.00;3.00 +8.20;11.50;3.00;Numerica +8.20;13.00;3.00;Numerica +8.20;14.50;3.00;Numerica +8.20;16.00;3.00;Numerica # Couloir N1 A / C -8.20;23.70;3.00 +8.20;23.70;3.00;Numerica # Palier N1 -7.50;3.70;3.00 +7.50;3.70;3.00;Numerica diff --git a/owlps-positioning/src/building.cc b/owlps-positioning/src/building.cc index 21ce865..8ac8cbf 100644 --- a/owlps-positioning/src/building.cc +++ b/owlps-positioning/src/building.cc @@ -1,6 +1,7 @@ #include "building.hh" #include "area.hh" #include "waypoint.hh" +#include "stock.hh" using namespace std ; @@ -28,11 +29,7 @@ Building::~Building() // Empty Waypoint list for (unordered_set::const_iterator i = waypoints.begin() ; i != waypoints.end() ; ++i) - { - // Delete current waypoint only if it is not linked to another building - if ((*i)->get_buildings().size() <= 1) - delete *i ; - } + Stock::waypoint_remove_building(**i, this) ; waypoints.clear() ; } diff --git a/owlps-positioning/src/inputdatareader.cc b/owlps-positioning/src/inputdatareader.cc index b1fd91d..66d8ac3 100644 --- a/owlps-positioning/src/inputdatareader.cc +++ b/owlps-positioning/src/inputdatareader.cc @@ -43,8 +43,12 @@ void InputDataReader::initialise_topology_media() void InputDataReader::initialise_topology_csv() { 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( - Configuration::string_value("data-input.areas-csv-file")) ; + Configuration::string_value("data-input.areas-csv-file"), + Configuration::string_value("data-input.waypoints-csv-file")) ; } diff --git a/owlps-positioning/src/posexcept.cc b/owlps-positioning/src/posexcept.cc index 6469bb9..e107c3c 100644 --- a/owlps-positioning/src/posexcept.cc +++ b/owlps-positioning/src/posexcept.cc @@ -33,9 +33,11 @@ topology_input_medium_type_unknown(const string &medium_name) throw(): " » 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( - "No topologyinput CSV file specified in the configuration!") {} + "No topology input CSV file specified in the configuration for " + + type + "!") {} malformed_topology:: diff --git a/owlps-positioning/src/posexcept.hh b/owlps-positioning/src/posexcept.hh index b257cca..072baca 100644 --- a/owlps-positioning/src/posexcept.hh +++ b/owlps-positioning/src/posexcept.hh @@ -58,7 +58,7 @@ public: class no_topology_input_csv_file: public posexcept { public: - no_topology_input_csv_file(void) throw() ; + no_topology_input_csv_file(const std::string &type) throw() ; } ; diff --git a/owlps-positioning/src/stock.cc b/owlps-positioning/src/stock.cc index 8df4a1e..7346a05 100644 --- a/owlps-positioning/src/stock.cc +++ b/owlps-positioning/src/stock.cc @@ -6,17 +6,26 @@ using std::tr1::unordered_map ; using std::tr1::unordered_set ; -/// Hash function, required to put ReferencePoint in a set -size_t hash_value(const ReferencePoint &object) +/* *** Hash functions, required to put points in a set *** */ + +inline size_t hash_value(const ReferencePoint &object) +{ + return boost::hash_value(static_cast(object)) ; +} + +inline size_t hash_value(const Point3D &object) { return boost::hash_value(static_cast(object)) ; } + /* *** Attribute definitions *** */ unordered_map Stock::buildings ; +unordered_map Stock::waypoints ; + unordered_map Stock::mobiles ; unordered_map 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::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::iterator i = + waypoints.find(point) ; + + Waypoint *waypoint = const_cast(&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. * 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) { // 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::iterator, bool> ret = reference_points.insert(point) ; return *ret.first ; @@ -150,6 +189,12 @@ find_create_calibration_request(const CalibrationRequest &request) void Stock::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() ; aps.clear() ; reference_points.clear() ; diff --git a/owlps-positioning/src/stock.hh b/owlps-positioning/src/stock.hh index 18a9d7e..3f59ec8 100644 --- a/owlps-positioning/src/stock.hh +++ b/owlps-positioning/src/stock.hh @@ -2,6 +2,7 @@ #define _OWLPS_POSITIONING_STOCK_HH_ #include "building.hh" +#include "waypoint.hh" #include "mobile.hh" #include "accesspoint.hh" #include "referencepoint.hh" @@ -17,6 +18,9 @@ private: /// List of known Building static std::tr1::unordered_map buildings ; + /// List of known Waypoint + static std::tr1::unordered_map waypoints ; + /// List of known Mobile static std::tr1::unordered_map mobiles ; @@ -35,6 +39,18 @@ public: /// Look for a Building and create it if it does not exist 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 static const Mobile& get_mobile(const std::string &mac) ; /// Look for a Mobile and create it if it does not exist @@ -66,6 +82,17 @@ public: /* *** Accessors *** */ +inline const Waypoint& Stock:: +find_create_waypoint(const Waypoint &point) +{ + Waypoint& found = + const_cast( + find_create_waypoint(static_cast(point))) ; + found.add_buildings(point) ; + return found ; +} + + /** * 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 diff --git a/owlps-positioning/src/topologyreadercsv.cc b/owlps-positioning/src/topologyreadercsv.cc index 122ba91..70266d9 100644 --- a/owlps-positioning/src/topologyreadercsv.cc +++ b/owlps-positioning/src/topologyreadercsv.cc @@ -1,8 +1,8 @@ #include "topologyreadercsv.hh" #include "posexcept.hh" #include "stock.hh" -#include "point3d.hh" #include "area.hh" +#include "waypoint.hh" using namespace std ; @@ -11,8 +11,9 @@ using namespace std ; /* *** Constructors *** */ -TopologyReaderCSV::TopologyReaderCSV(const string &filename): - file(filename) +TopologyReaderCSV::TopologyReaderCSV( + const string &areas_file_name, const string &waypoints_file_name): + areas_file(areas_file_name), waypoints_file(waypoints_file_name) { read_topology() ; } @@ -24,32 +25,58 @@ TopologyReaderCSV::TopologyReaderCSV(const string &filename): void TopologyReaderCSV::read_topology() { - while (file.next_line()) - process_line() ; + while (areas_file.next_line()) + process_area_line() ; + + while (waypoints_file.next_line()) + process_waypoint_line() ; } -void TopologyReaderCSV::process_line() +void TopologyReaderCSV::process_area_line() { string building_name ; - if (! file.read_field(building_name)) + if (! areas_file.read_field(building_name)) throw malformed_topology("Cannot read building name!") ; Building &building = const_cast( Stock::find_create_building(building_name)) ; string name ; - if (! file.read_field(name)) + if (! areas_file.read_field(name)) throw malformed_topology("Cannot read area name!") ; - Point3D p_min(read_point()) ; - Point3D p_max(read_point()) ; + Point3D p_min(read_point(areas_file)) ; + Point3D p_max(read_point(areas_file)) ; Area *area = new Area(&building, name, p_min, p_max) ; building.add_area(area) ; } -Point3D TopologyReaderCSV::read_point() +void TopologyReaderCSV::process_waypoint_line() +{ + Point3D coordinates(read_point(waypoints_file)) ; + Waypoint &waypoint_ref = + const_cast(Stock::find_create_waypoint(coordinates)) ; + + vector buildings ; + string building_name ; + while (waypoints_file.read_field(building_name)) + buildings.push_back(const_cast( + &Stock::find_create_building(building_name))) ; + if (buildings.empty()) + throw malformed_topology("Cannot read building name!") ; + + for (vector::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] ; for (unsigned int i = 0 ; i < 3 ; ++i) diff --git a/owlps-positioning/src/topologyreadercsv.hh b/owlps-positioning/src/topologyreadercsv.hh index 15eea3a..65727af 100644 --- a/owlps-positioning/src/topologyreadercsv.hh +++ b/owlps-positioning/src/topologyreadercsv.hh @@ -7,22 +7,29 @@ class Point3D ; #include -/// 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 + * + * CSV format for waypoints is: + * X;Y;Z;Building name #1[;Building name #2[…[;Building name #n]]] */ class TopologyReaderCSV { protected: - CSVFileReader file ; + CSVFileReader areas_file ; + CSVFileReader waypoints_file ; void read_topology(void) ; - void process_line(void) ; - Point3D read_point(void) ; + void process_area_line(void) ; + void process_waypoint_line(void) ; + Point3D read_point(CSVFileReader &file) ; public: - TopologyReaderCSV(const std::string &filename) ; + TopologyReaderCSV(const std::string &areas_file_name, + const std::string &waypoints_file_name) ; ~TopologyReaderCSV(void) {} } ; diff --git a/owlps-positioning/src/waypoint.cc b/owlps-positioning/src/waypoint.cc index 7ebcd86..07af7fe 100644 --- a/owlps-positioning/src/waypoint.cc +++ b/owlps-positioning/src/waypoint.cc @@ -1,7 +1,10 @@ #include "waypoint.hh" +#include "building.hh" +#include using namespace std ; +using std::tr1::unordered_set ; @@ -20,7 +23,7 @@ Waypoint::Waypoint(const Building *_b, ): Point3D(_x, _y, _z) { if (_b != NULL) - buildings.push_back(const_cast(_b)) ; + buildings.insert(const_cast(_b)) ; } @@ -32,7 +35,7 @@ Waypoint::Waypoint(const Building *_b, Waypoint::Waypoint(const Building *_b, const Point3D &p): Point3D(p) { if (_b != NULL) - buildings.push_back(const_cast(_b)) ; + buildings.insert(const_cast(_b)) ; } @@ -73,6 +76,19 @@ bool Waypoint::operator==(const Waypoint &wp) const } +Waypoint::operator string() const +{ + ostringstream csv ; + csv << (Point3D) *this ; + + for (unordered_set::const_iterator i = buildings.begin() ; + i != buildings.end() ; ++i) + csv << ';' << (*i)->get_name() ; + + return csv.str() ; +} + + ostream &operator<<(ostream &os, const Waypoint &wp) { @@ -83,9 +99,9 @@ ostream &operator<<(ostream &os, const Waypoint &wp) if (wp.buildings.empty()) os << '\n' << "Belongs to no building!" ; else - for (vector::const_iterator i = wp.buildings.begin() ; - i != wp.buildings.end() ; ++i) - os << '\n' << *i ; + for (unordered_set::const_iterator i = + wp.buildings.begin() ; i != wp.buildings.end() ; ++i) + os << '\n' << **i ; return os ; } diff --git a/owlps-positioning/src/waypoint.hh b/owlps-positioning/src/waypoint.hh index f726804..9c7de6e 100644 --- a/owlps-positioning/src/waypoint.hh +++ b/owlps-positioning/src/waypoint.hh @@ -5,8 +5,8 @@ class Building ; #include "point3d.hh" +#include #include -#include #include /// Represents a junction point between several rooms (i.e. Area) @@ -20,7 +20,7 @@ class Waypoint: public Point3D { protected: /// List of Building associated with the Waypoint - std::vector buildings ; + std::tr1::unordered_set buildings ; public: Waypoint(const Building *_b = NULL, const float &_x = 0, @@ -38,13 +38,17 @@ public: //@{ /// #buildings's first element read accessor Building* get_1st_building(void) const ; - const std::vector& get_buildings(void) const ; + const std::tr1::unordered_set& get_buildings(void) const ; //@} /** @name Write accessors */ //@{ /// Adds a Building to the \link #buildings building list\endlink 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 */ @@ -52,6 +56,7 @@ public: const Waypoint& operator=(const Waypoint &wp) ; bool operator==(const Waypoint &wp) const ; bool operator!=(const Waypoint &wp) const ; + operator std::string(void) const ; //@} /// Displays a Waypoint @@ -70,18 +75,14 @@ public: */ inline Building* Waypoint::get_1st_building() const { - try - { - return buildings.at(0) ; - } - catch (std::out_of_range &e) - { - return NULL ; - } + if (buildings.empty()) + return NULL ; + return *buildings.begin() ; } -inline const std::vector& Waypoint::get_buildings() const +inline const std::tr1::unordered_set& +Waypoint::get_buildings() const { return buildings ; } @@ -101,7 +102,20 @@ inline const std::vector& Waypoint::get_buildings() const inline void Waypoint::add_building(const Building *_b) { if (_b != NULL) - buildings.push_back(const_cast(_b)) ; + buildings.insert(const_cast(_b)) ; +} + + +inline void Waypoint::remove_building(const Building *_b) +{ + if (_b != NULL) + buildings.erase(const_cast(_b)) ; +} + + +inline void Waypoint::add_buildings(const Waypoint &source) +{ + buildings.insert(source.buildings.begin(), source.buildings.end()) ; } diff --git a/owlps-positioning/tests/building_test.hh b/owlps-positioning/tests/building_test.hh index 50e2f53..ca40335 100644 --- a/owlps-positioning/tests/building_test.hh +++ b/owlps-positioning/tests/building_test.hh @@ -38,12 +38,14 @@ public: b2.set_name("My Second Building") ; TS_ASSERT_EQUALS(b2.get_name(), "My Second Building") ; - Waypoint *wp1 = new Waypoint(&b2, 43, 45, 909) ; - Waypoint *wp2 = new Waypoint(&b2, 12, 78, 2) ; - b2.add_waypoint(wp1) ; - b2.add_waypoint(wp2) ; - waypoints1.insert(wp1) ; - waypoints1.insert(wp2) ; + const Waypoint &wp1 = + Stock::find_create_waypoint(Waypoint(&b2, 43,45,909)) ; + const Waypoint &wp2 = + Stock::find_create_waypoint(Waypoint(&b2, 12,78,2)) ; + b2.add_waypoint(&wp1) ; + b2.add_waypoint(&wp2) ; + waypoints1.insert(const_cast(&wp1)) ; + waypoints1.insert(const_cast(&wp2)) ; TS_ASSERT_EQUALS(b2.get_waypoints(), waypoints1) ; Area *a1 = new Area(&b2, "area1") ; @@ -53,6 +55,8 @@ public: areas1["area1"] = a1 ; areas1["area2"] = a2 ; TS_ASSERT_EQUALS(b2.get_areas(), areas1) ; + + // TODO: test deletion of waypoints from Stock after deletion of b2 } diff --git a/owlps-positioning/tests/stock_test.hh b/owlps-positioning/tests/stock_test.hh index 26fbf20..be3625b 100644 --- a/owlps-positioning/tests/stock_test.hh +++ b/owlps-positioning/tests/stock_test.hh @@ -34,6 +34,21 @@ public: 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) { TS_ASSERT_THROWS(Stock::get_mobile("aa:bb:cc:dd:ee:ff"), diff --git a/owlps-positioning/tests/topologyreadercsv_test.hh b/owlps-positioning/tests/topologyreadercsv_test.hh index 4f9c794..95b9863 100644 --- a/owlps-positioning/tests/topologyreadercsv_test.hh +++ b/owlps-positioning/tests/topologyreadercsv_test.hh @@ -5,30 +5,47 @@ class TopologyReaderCSV_test: public CxxTest::TestSuite { private: - std::string topology_file_name ; + std::string areas_file_name ; + std::string waypoints_file_name ; public: 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() ; - std::ofstream topology_file(topology_file_name.c_str()) ; - topology_file + std::ofstream areas_file(areas_file_name.c_str()) ; + areas_file << "My building;My room #1;1;2;3;9;8;7\n" << "My building;Room #2;4;5;6;6;5;4\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" ; - 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) { 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 ; TS_ASSERT_THROWS_NOTHING( building1 = const_cast( @@ -80,4 +94,54 @@ public: TS_ASSERT_EQUALS(*area_ptr, area1) ; } + + void test_waypoints(void) + { + Building *building1 ; + TS_ASSERT_THROWS_NOTHING( + building1 = const_cast( + &Stock::get_building("My building"))) ; + Building *building2 ; + TS_ASSERT_THROWS_NOTHING( + building2 = const_cast( + &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(&waypoint1) ; + + TS_ASSERT(building1->get_waypoints().find(w) != + building1->get_waypoints().end()) ; + waypoint_ptr = *building1->get_waypoints().find( + const_cast(&waypoint1)) ; + TS_ASSERT_EQUALS(waypoint_ptr, w) ; + + const Waypoint &waypoint2 = + Stock::find_create_waypoint(Waypoint(building1, 4,5,6)) ; + w = const_cast(&waypoint2) ; + + TS_ASSERT(building1->get_waypoints().find(w) != + building1->get_waypoints().end()) ; + waypoint_ptr = *building1->get_waypoints().find( + const_cast(&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(&waypoint3) ; + + TS_ASSERT(building2->get_waypoints().find(w) != + building2->get_waypoints().end()) ; + waypoint_ptr = *building2->get_waypoints().find( + const_cast(&waypoint3)) ; + TS_ASSERT_EQUALS(waypoint_ptr, w) ; + } + } ; diff --git a/owlps-positioning/tests/waypoint_test.hh b/owlps-positioning/tests/waypoint_test.hh index 0919034..cb4380c 100644 --- a/owlps-positioning/tests/waypoint_test.hh +++ b/owlps-positioning/tests/waypoint_test.hh @@ -47,10 +47,10 @@ public: // Write & read accessors Building b2("My Second Building") ; wp1.add_building(&b2) ; - std::vector vb1 ; - vb1.push_back(&b1) ; - vb1.push_back(&b2) ; - TS_ASSERT_EQUALS(wp1.get_buildings(), vb1) ; + std::tr1::unordered_set buildings ; + buildings.insert(&b1) ; + buildings.insert(&b2) ; + TS_ASSERT_EQUALS(wp1.get_buildings(), buildings) ; wp1.set_x(42) ; TS_ASSERT_EQUALS(wp1.get_x(), 42) ; wp1.set_y(321) ;