[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:
Matteo Cypriani 2010-04-13 10:47:10 +02:00
parent 208c989c53
commit 14902181af
17 changed files with 345 additions and 113 deletions

View File

@ -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: \

View File

@ -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
° 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 »

View File

@ -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

1 # Liste des points de passage.
2 # Chaque ligne définit les trois coordonnées d'un point, de la forme :
3 # X;Y;Z # X;Y;Z;Nom du bâtiment 1;…;Nom du bâtiment n
4 # Chaque point doit appartenir au moins à un bâtiment.
5 # 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 :
6 # Idem pour les portes très larges. # Couloir N0 A et Couloir N0 B), on définit un point tous les 1,50 m.
7 # Idem pour les portes très larges.
8 ### Rez-de-chaussée ###
9 # 0140
10 6.05;6.50;0.00 6.05;6.50;0.00;Numerica
11 # 0130
12 6.05;7.50;0.00 6.05;7.50;0.00;Numerica
13 # 0120
14 6.05;13.50;0.00 6.05;13.50;0.00;Numerica
15 # 0130 / 0120
16 3.00;10.88;0.00 3.00;10.88;0.00;Numerica
17 # 0110
18 6.05;14.50;0.00 6.05;14.50;0.00;Numerica
19 # 0100
20 6.05;21.00;0.00 6.05;21.00;0.00;Numerica
21 # 0090
22 6.05;22.25;0.00 6.05;22.25;0.00;Numerica
23 # 0080
24 6.05;28.50;0.00 6.05;28.50;0.00;Numerica
25 # 0070
26 6.05;29.50;0.00 6.05;29.50;0.00;Numerica
27 # WC N0
28 8.20;5.00;0.00 8.20;5.00;0.00;Numerica
29 # 0085
30 8.20;8.50;0.00 8.20;8.50;0.00;Numerica
31 # 0075
32 8.20;9.50;0.00 8.20;9.50;0.00;Numerica
33 # Couloir N0 A / B
34 8.20;11.50;0.00 8.20;11.50;0.00;Numerica
35 8.20;13.00;0.00 8.20;13.00;0.00;Numerica
36 8.20;14.50;0.00 8.20;14.50;0.00;Numerica
37 8.20;16.00;0.00 8.20;16.00;0.00;Numerica
38 # Couloir N0 A / C
39 8.20;23.70;0.00 8.20;23.70;0.00;Numerica
40 # Palier N0
41 7.50;3.70;0.00 7.50;3.70;0.00;Numerica
42 ### Escaliers N0 / N1 ###
43 # Couloir N0 C / Escalier NO-N1 A
44 8.95;22.60;0.00 8.95;22.60;0.00;Numerica
45 # Escalier NO-N1 A / Couloir N1 B
46 8.95;16.50;3.00 8.95;16.50;3.00;Numerica
47 # Palier NO / Escalier N0-N1 B1
48 5.00;1.25;0.00 5.00;1.25;0.00;Numerica
49 # Escalier N0-N1 B1 / Escalier N0-N1 B palier
50 2.50;1.25;1.50 2.50;1.25;1.50;Numerica
51 # Escalier N0-N1 B palier / Escalier N0-N1 B2
52 2.50;2.75;1.50 2.50;2.75;1.50;Numerica
53 # Escalier N0-N1 B2 / Palier N1
54 5.00;2.75;3.00 5.00;2.75;3.00;Numerica
55 ### Premier étage ###
56 # 1100
57 6.05;6.50;3.00 6.05;6.50;3.00;Numerica
58 # 0190
59 6.05;7.50;3.00 6.05;7.50;3.00;Numerica
60 # 0180
61 6.05;13.50;3.00 6.05;13.50;3.00;Numerica
62 # 0190 / 0180
63 3.00;10.88;3.00 3.00;10.88;3.00;Numerica
64 # 1070
65 6.05;14.50;3.00 6.05;14.50;3.00;Numerica
66 # 1060
67 6.05;21.00;3.00 6.05;21.00;3.00;Numerica
68 # 1050
69 6.05;27.75;3.00 6.05;27.75;3.00;Numerica
70 # WC N1
71 8.20;5.00;3.00 8.20;5.00;3.00;Numerica
72 # 1105
73 8.20;9.50;3.00 8.20;9.50;3.00;Numerica
74 # 1095
75 8.20;26.00;3.00 8.20;26.00;3.00;Numerica
76 # Couloir N1 A / B
77 8.20;11.50;3.00 8.20;11.50;3.00;Numerica
78 8.20;13.00;3.00 8.20;13.00;3.00;Numerica
79 8.20;14.50;3.00 8.20;14.50;3.00;Numerica
80 8.20;16.00;3.00 8.20;16.00;3.00;Numerica
81 # Couloir N1 A / C
82 8.20;23.70;3.00 8.20;23.70;3.00;Numerica
83 # Palier N1
84 7.50;3.70;3.00 7.50;3.70;3.00;Numerica
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124

View File

@ -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<Waypoint*>::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() ;
}

View File

@ -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")) ;
}

View File

@ -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::

View File

@ -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() ;
} ;

View File

@ -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<string>(object)) ;
}
inline size_t hash_value(const Point3D &object)
{
return boost::hash_value(static_cast<string>(object)) ;
}
/* *** Attribute definitions *** */
unordered_map<string, Building> Stock::buildings ;
unordered_map<Point3D, Waypoint> Stock::waypoints ;
unordered_map<string, Mobile> Stock::mobiles ;
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.
* 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<unordered_set<ReferencePoint>::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() ;

View File

@ -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<std::string, Building> buildings ;
/// List of known Waypoint
static std::tr1::unordered_map<Point3D, Waypoint> waypoints ;
/// List of known Mobile
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
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<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.
* @param mac The MAC address of the Mobile to search for. It must be a

View File

@ -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<Building&>(
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<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] ;
for (unsigned int i = 0 ; i < 3 ; ++i)

View File

@ -7,22 +7,29 @@ class Point3D ;
#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
*
* 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) {}
} ;

View File

@ -1,7 +1,10 @@
#include "waypoint.hh"
#include "building.hh"
#include <sstream>
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<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)
{
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)
{
@ -83,9 +99,9 @@ ostream &operator<<(ostream &os, const Waypoint &wp)
if (wp.buildings.empty())
os << '\n' << "Belongs to no building!" ;
else
for (vector<Building*>::const_iterator i = wp.buildings.begin() ;
i != wp.buildings.end() ; ++i)
os << '\n' << *i ;
for (unordered_set<Building*>::const_iterator i =
wp.buildings.begin() ; i != wp.buildings.end() ; ++i)
os << '\n' << **i ;
return os ;
}

View File

@ -5,8 +5,8 @@ class Building ;
#include "point3d.hh"
#include <boost/tr1/unordered_set.hpp>
#include <ostream>
#include <vector>
#include <stdexcept>
/// 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<Building*> buildings ;
std::tr1::unordered_set<Building*> 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<Building*>& get_buildings(void) const ;
const std::tr1::unordered_set<Building*>& 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<Building*>& Waypoint::get_buildings() const
inline const std::tr1::unordered_set<Building*>&
Waypoint::get_buildings() const
{
return buildings ;
}
@ -101,7 +102,20 @@ inline const std::vector<Building*>& Waypoint::get_buildings() const
inline void Waypoint::add_building(const Building *_b)
{
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()) ;
}

View File

@ -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<Waypoint*>(&wp1)) ;
waypoints1.insert(const_cast<Waypoint*>(&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
}

View File

@ -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"),

View File

@ -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<Building*>(
@ -80,4 +94,54 @@ public:
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) ;
}
} ;

View File

@ -47,10 +47,10 @@ public:
// Write & read accessors
Building b2("My Second Building") ;
wp1.add_building(&b2) ;
std::vector<Building*> vb1 ;
vb1.push_back(&b1) ;
vb1.push_back(&b2) ;
TS_ASSERT_EQUALS(wp1.get_buildings(), vb1) ;
std::tr1::unordered_set<Building*> 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) ;