AirTSP Logo  1.01.10
C++ Simulated Airline Travel Solution Provider (TSP) Library
Loading...
Searching...
No Matches
SegmentPathPeriod.cpp
Go to the documentation of this file.
1// //////////////////////////////////////////////////////////////////////
2// Import section
3// //////////////////////////////////////////////////////////////////////
4// STL
5#include <cassert>
6#include <sstream>
7// Boost.Serialization
8#include <boost/archive/text_iarchive.hpp>
9#include <boost/archive/text_oarchive.hpp>
10#include <boost/serialization/access.hpp>
11// StdAir
12#include <stdair/basic/BasConst_General.hpp>
13#include <stdair/basic/BasConst_Inventory.hpp>
14#include <stdair/basic/BasConst_Period_BOM.hpp>
15#include <stdair/basic/BasConst_TravelSolution.hpp>
16#include <stdair/bom/Inventory.hpp>
17#include <stdair/bom/FlightPeriod.hpp>
18#include <stdair/bom/SegmentPeriod.hpp>
19#include <stdair/bom/BomManager.hpp>
20// AirTSP
22
23namespace AIRTSP {
24
25 // ////////////////////////////////////////////////////////////////////
26 SegmentPathPeriod::SegmentPathPeriod()
27 : _key (stdair::PeriodStruct (stdair::BOOST_DEFAULT_DATE_PERIOD,
28 stdair::DEFAULT_DOW_STRING),
29 stdair::NULL_BOOST_TIME_DURATION, stdair::NULL_BOOST_TIME_DURATION,
31 stdair::DEFAULT_NBOFAIRLINES),
32 _parent (NULL) {
33 assert (false);
34 }
35
36 // ////////////////////////////////////////////////////////////////////
37 SegmentPathPeriod::SegmentPathPeriod (const SegmentPathPeriod& iSPP)
38 : _key (iSPP._key), _parent (NULL) {
39 assert (false);
40 }
41
42 // ////////////////////////////////////////////////////////////////////
43 SegmentPathPeriod::SegmentPathPeriod (const Key_T& iKey)
44 : _key (iKey), _parent (NULL) {
45 }
46
47 // ////////////////////////////////////////////////////////////////////
50
51 // ////////////////////////////////////////////////////////////////////
52 std::string SegmentPathPeriod::toString() const {
53 std::ostringstream oStr;
54 oStr << _key.toString();
55 return oStr.str();
56 }
57
58 // ////////////////////////////////////////////////////////////////////
59 void SegmentPathPeriod::serialisationImplementationExport() const {
60 std::ostringstream oStr;
61 boost::archive::text_oarchive oa (oStr);
62 oa << *this;
63 }
64
65 // ////////////////////////////////////////////////////////////////////
66 void SegmentPathPeriod::serialisationImplementationImport() {
67 std::istringstream iStr;
68 boost::archive::text_iarchive ia (iStr);
69 ia >> *this;
70 }
71
72 // ////////////////////////////////////////////////////////////////////
73 template<class Archive>
74 void SegmentPathPeriod::serialize (Archive& ioArchive,
75 const unsigned int iFileVersion) {
76 ioArchive & _key;
77 }
78
79 // ////////////////////////////////////////////////////////////////////
80 // Explicit template instantiation
81 namespace ba = boost::archive;
82 template
83 void SegmentPathPeriod::serialize<ba::text_oarchive> (ba::text_oarchive&,
84 unsigned int);
85 template
86 void SegmentPathPeriod::serialize<ba::text_iarchive> (ba::text_iarchive&,
87 unsigned int);
88 // ////////////////////////////////////////////////////////////////////
89
90 // ////////////////////////////////////////////////////////////////////
91 stdair::SegmentPeriod* SegmentPathPeriod::getLastSegmentPeriod () const {
92 // Retrieve the last segment of the list
93 const stdair::SegmentPeriodList_T& lSegmentPeriodList =
94 stdair::BomManager::getList<stdair::SegmentPeriod> (*this);
95 stdair::SegmentPeriodList_T::const_reverse_iterator itLastSegment =
96 lSegmentPeriodList.rbegin();
97
98 if (itLastSegment == lSegmentPeriodList.rend()) {
99 return NULL;
100 }
101
102 stdair::SegmentPeriod* oSegment_ptr = *itLastSegment;
103 assert (oSegment_ptr != NULL);
104
105 return oSegment_ptr;
106 }
107
108 // ////////////////////////////////////////////////////////////////////
109 stdair::SegmentPeriod* SegmentPathPeriod::getFirstSegmentPeriod () const{
110 // Retrieve the first segment of the list
111 const stdair::SegmentPeriodList_T& lSegmentPeriodList =
112 stdair::BomManager::getList<stdair::SegmentPeriod> (*this);
113 stdair::SegmentPeriodList_T::const_iterator itFirstSegment =
114 lSegmentPeriodList.begin();
115
116 if (itFirstSegment == lSegmentPeriodList.end()) {
117 return NULL;
118 }
119
120 stdair::SegmentPeriod* oSegment_ptr = *itFirstSegment;
121 assert (oSegment_ptr != NULL);
122
123 return oSegment_ptr;
124 }
125
126 // ////////////////////////////////////////////////////////////////////
127 const stdair::AirportCode_T& SegmentPathPeriod::getDestination () const {
128 const stdair::SegmentPeriod* lLastSegment_ptr = getLastSegmentPeriod();
129 assert (lLastSegment_ptr != NULL);
130 return lLastSegment_ptr->getOffPoint();
131 }
132
133 // ////////////////////////////////////////////////////////////////////
135 isAirlineFlown (const stdair::AirlineCode_T& iAirlineCode) const {
136 bool oAirlineFlown = false;
137
138 const stdair::SegmentPeriodList_T& lSegmentPeriodList =
139 stdair::BomManager::getList<stdair::SegmentPeriod> (*this);
140 for (stdair::SegmentPeriodList_T::const_iterator itSegmentPeriod =
141 lSegmentPeriodList.begin();
142 itSegmentPeriod != lSegmentPeriodList.end(); ++itSegmentPeriod) {
143 const stdair::SegmentPeriod* lSegmentPeriod_ptr = *itSegmentPeriod;
144 assert (lSegmentPeriod_ptr != NULL);
145
146 const stdair::FlightPeriod& lFlightPeriod =
147 stdair::BomManager::getParent<stdair::FlightPeriod>(*lSegmentPeriod_ptr);
148 const stdair::Inventory& lInventory =
149 stdair::BomManager::getParent<stdair::Inventory> (lFlightPeriod);
150 const stdair::AirlineCode_T& lSegmentAirlineCode =
151 lInventory.getAirlineCode ();
152 if (lSegmentAirlineCode == iAirlineCode) {
153 oAirlineFlown = true;
154 break;
155 }
156 }
157
158 return oAirlineFlown;
159 }
160
161 // ////////////////////////////////////////////////////////////////////
163 connectWithAnotherSegment(const SegmentPathPeriod& iSingleSegmentPath) const {
164 SegmentPathPeriodKey oSegmentPathPeriodKey;
165
166 // Retrieve the (only) segment period of the single segment path.
167 const stdair::SegmentPeriod* lNextSegmentPeriod_ptr =
168 iSingleSegmentPath.getFirstSegmentPeriod();
169 assert (lNextSegmentPeriod_ptr != NULL);
170
171 // Retrive the last segment period of the current segment path and check
172 // if the combination of the last segment and the next segment that we
173 // want to add to the current segment path will create a new segment
174 // (i.e., the two segment period belongs to the same flight number).
175 const stdair::SegmentPeriod* lLastSegmentPeriod_ptr = getLastSegmentPeriod ();
176 assert (lLastSegmentPeriod_ptr != NULL);
177 const stdair::FlightPeriod& lLastFlightPeriod = stdair::BomManager::
178 getParent<stdair::FlightPeriod> (*lLastSegmentPeriod_ptr);
179 const stdair::Inventory& lLastInventory =
180 stdair::BomManager::getParent<stdair::Inventory> (lLastFlightPeriod);
181
182 const stdair::FlightPeriod& lNextFlightPeriod = stdair::BomManager::
183 getParent<stdair::FlightPeriod> (*lNextSegmentPeriod_ptr);
184 const stdair::Inventory& lNextInventory =
185 stdair::BomManager::getParent<stdair::Inventory> (lNextFlightPeriod);
186
187 if (lLastFlightPeriod.getFlightNumber()==lNextFlightPeriod.getFlightNumber()
188 && lLastInventory.getAirlineCode() == lNextInventory.getAirlineCode()) {
189 return oSegmentPathPeriodKey;
190 }
191
192 // Check if the new segment period will create a circle.
193 const stdair::AirportCode_T& lDestination =
194 lNextSegmentPeriod_ptr->getOffPoint();
195 if (checkCircle (lDestination) == true) {
196 return oSegmentPathPeriodKey;
197 }
198
199 // Check if a passenger can connect from the last segment of the
200 // current segment path to the first segment of the to-be-added
201 // segment path. If yes, build a new departure period for the new
202 // segment path.
203 DateOffsetList_T lBoardingDateOffsetList =
205 const stdair::PeriodStruct& lCurrentDeparturePeriod = getDeparturePeriod();
206 const stdair::PeriodStruct& lNextDeparturePeriod =
207 iSingleSegmentPath.getDeparturePeriod();
208 const stdair::Duration_T& lLastOffTime =
209 lLastSegmentPeriod_ptr->getOffTime();
210 const stdair::Duration_T& lNextBoardingTime =
211 lNextSegmentPeriod_ptr->getBoardingTime();
212 // If the next boarding time is later than the last off time, check if
213 // the passengers will have enough time for the transfer. If the next
214 // boarding time is earlier than the last off time, check if the passengers
215 // can connect to a flight in the next day.
216 if (lNextBoardingTime >= lLastOffTime) {
217 const stdair::Duration_T lStopTime = lNextBoardingTime - lLastOffTime;
218 if (lStopTime < stdair::DEFAULT_MINIMAL_CONNECTION_TIME) {
219 return oSegmentPathPeriodKey;
220 } else {
221 // Calulcate the date offset of the next segment compare to
222 // the first one. In this case, this value is equal to the offset
223 // of the off date of the last segment compare to the boarding date
224 // of the first segment.
225 const stdair::DateOffset_T& lLastBoardingDateOffset =
226 lBoardingDateOffsetList.at (getNbOfSegments() - 1);
227 const stdair::DateOffset_T lNextBoardingDateOffset =
228 lLastBoardingDateOffset + lLastSegmentPeriod_ptr->getOffDateOffset()
229 - lLastSegmentPeriod_ptr->getBoardingDateOffset();
230 const stdair::DateOffset_T lNegativeNextBoardingDateOffset =
231 stdair::DateOffset_T (0) - lNextBoardingDateOffset;
232
233 // Compute the adjusted departure period of the next segment by
234 // substracting the origin one with the boarding date offset.
235 const stdair::PeriodStruct lAdjustedNextDeparturePeriod =
236 lNextDeparturePeriod.addDateOffset (lNegativeNextBoardingDateOffset);
237
238 // Build the intersection of the two periods.
239 const stdair::PeriodStruct lNewDeparturePeriod =
240 lCurrentDeparturePeriod.intersection (lAdjustedNextDeparturePeriod);
241 stdair::Duration_T lNewElapsed = getElapsedTime() + lStopTime +
242 lNextSegmentPeriod_ptr->getElapsedTime();
243 lBoardingDateOffsetList.push_back (lNextBoardingDateOffset);
244 oSegmentPathPeriodKey.setPeriod (lNewDeparturePeriod);
245 oSegmentPathPeriodKey.setElapsedTime (lNewElapsed);
246 }
247 } else {
248 const stdair::Duration_T lStopTime =
249 lNextBoardingTime - lLastOffTime + stdair::Duration_T (24, 0, 0);
250 if (lStopTime < stdair::DEFAULT_MINIMAL_CONNECTION_TIME) {
251 return oSegmentPathPeriodKey;
252 } else {
253 // Calulcate the date offset of the next segment compare to
254 // the first one.
255 const stdair::DateOffset_T& lLastBoardingDateOffset =
256 lBoardingDateOffsetList.at (getNbOfSegments() - 1);
257 const stdair::DateOffset_T lNextBoardingDateOffset =
258 lLastBoardingDateOffset + lLastSegmentPeriod_ptr->getOffDateOffset()
259 - lLastSegmentPeriod_ptr->getBoardingDateOffset() +
260 stdair::DateOffset_T (1);
261 const stdair::DateOffset_T lNegativeNextBoardingDateOffset =
262 stdair::DateOffset_T (0) - lNextBoardingDateOffset;
263
264 // Compute the adjusted departure period of the next segment by
265 // substracting the origin one with the boarding date offset.
266 const stdair::PeriodStruct lAdjustedNextDeparturePeriod =
267 lNextDeparturePeriod.addDateOffset (lNegativeNextBoardingDateOffset);
268
269 // Build the intersection of the two periods.
270 const stdair::PeriodStruct lNewDeparturePeriod =
271 lCurrentDeparturePeriod.intersection (lAdjustedNextDeparturePeriod);
272 stdair::Duration_T lNewElapsed = getElapsedTime() + lStopTime +
273 lNextSegmentPeriod_ptr->getElapsedTime();
274 lBoardingDateOffsetList.push_back (lNextBoardingDateOffset);
275 oSegmentPathPeriodKey.setPeriod (lNewDeparturePeriod);
276 oSegmentPathPeriodKey.setElapsedTime (lNewElapsed);
277 }
278 }
279
280 const stdair::Duration_T& lBoardingTime = getBoardingTime();
281 oSegmentPathPeriodKey.setBoardingTime (lBoardingTime);
282 oSegmentPathPeriodKey.setBoardingDateOffsetList (lBoardingDateOffsetList);
283
284 return oSegmentPathPeriodKey;
285 }
286
287 // ////////////////////////////////////////////////////////////////////
289 checkCircle (const stdair::AirlineCode_T& iDestination) const {
290 const stdair::SegmentPeriodList_T& lSegmentPeriodList =
291 stdair::BomManager::getList<stdair::SegmentPeriod> (*this);
292 for (stdair::SegmentPeriodList_T::const_iterator itSegment =
293 lSegmentPeriodList.begin();
294 itSegment != lSegmentPeriodList.end(); ++itSegment) {
295 const stdair::SegmentPeriod* lCurrentSegment_ptr = *itSegment;
296 assert (lCurrentSegment_ptr != NULL);
297 const stdair::AirlineCode_T& lCurrentBoardingPoint =
298 lCurrentSegment_ptr->getBoardingPoint();
299 if (lCurrentBoardingPoint == iDestination) {
300 return true;
301 }
302 }
303 return false;
304 }
305
306 // ////////////////////////////////////////////////////////////////////
308 isDepartureDateValid (const stdair::Date_T& iDepartureDate) const {
309 const stdair::PeriodStruct& lPeriod = getDeparturePeriod ();
310
311 // Check if the departure date is within the date range.
312 const stdair::DatePeriod_T& lDeparturePeriod = lPeriod.getDateRange ();
313 if (lDeparturePeriod.contains (iDepartureDate) == false) {
314 return false;
315 }
316
317 // Check if the departure date is valid within the DOW.
318 // 0 = Sunday, 1 = Monday, etc.
319 const short lDay = iDepartureDate.day_of_week ();
320 const stdair::DoWStruct& lDoW = lPeriod.getDoW ();
321 if (lDoW.getStandardDayOfWeek (lDay) == false) {
322 return false;
323 }
324
325 return true;
326 }
327
328}
Class representing a segment/path.
bool checkCircle(const stdair::AirportCode_T &) const
const stdair::PeriodStruct & getDeparturePeriod() const
const DateOffsetList_T & getBoardingDateOffsetList() const
const stdair::AirportCode_T & getDestination() const
stdair::SegmentPeriod * getLastSegmentPeriod() const
stdair::SegmentPeriod * getFirstSegmentPeriod() const
const stdair::Duration_T & getElapsedTime() const
void serialize(Archive &ar, const unsigned int iFileVersion)
Key_T connectWithAnotherSegment(const SegmentPathPeriod &) const
bool isDepartureDateValid(const stdair::Date_T &) const
const stdair::NbOfSegments_T getNbOfSegments() const
bool isAirlineFlown(const stdair::AirlineCode_T &) const
const stdair::Duration_T & getBoardingTime() const
std::vector< stdair::DateOffset_T > DateOffsetList_T
Forward declarations.
Structure representing the key of a segment/path.
void setElapsedTime(const stdair::Duration_T &iElapsed)
void setPeriod(const stdair::PeriodStruct &iPeriod)
void setBoardingTime(const stdair::Duration_T &iBoardingTime)
const std::string toString() const
void setBoardingDateOffsetList(const DateOffsetList_T &iList)