$treeview $search $mathjax
00001 // ////////////////////////////////////////////////////////////////////// 00002 // Import section 00003 // ////////////////////////////////////////////////////////////////////// 00004 // STL 00005 #include <cassert> 00006 #include <vector> 00007 // StdAir 00008 #include <stdair/basic/BasConst_Inventory.hpp> 00009 #include <stdair/bom/BomManager.hpp> 00010 #include <stdair/bom/BomRoot.hpp> 00011 #include <stdair/bom/Inventory.hpp> 00012 #include <stdair/bom/FlightPeriod.hpp> 00013 #include <stdair/bom/SegmentPeriod.hpp> 00014 #include <stdair/factory/FacBomManager.hpp> 00015 #include <stdair/service/Logger.hpp> 00016 // AirTSP 00017 #include <airtsp/bom/ReachableUniverse.hpp> 00018 #include <airtsp/bom/OriginDestinationSet.hpp> 00019 #include <airtsp/bom/SegmentPathPeriod.hpp> 00020 #include <airtsp/command/SegmentPathGenerator.hpp> 00021 00022 namespace AIRTSP { 00023 00024 // //////////////////////////////////////////////////////////////////// 00025 void SegmentPathGenerator:: 00026 createSegmentPathNetwork (const stdair::BomRoot& iBomRoot) { 00027 00028 // Build the list of single-segment segment path objects. 00029 const stdair::InventoryList_T& lInventoryList = 00030 stdair::BomManager::getList<stdair::Inventory> (iBomRoot); 00031 for (stdair::InventoryList_T::const_iterator itInv = lInventoryList.begin(); 00032 itInv != lInventoryList.end(); ++itInv) { 00033 const stdair::Inventory* lCurrentInventory_ptr = *itInv; 00034 assert (lCurrentInventory_ptr != NULL); 00035 00036 // 00037 createSinglePaths (*lCurrentInventory_ptr); 00038 } 00039 00040 // Build the list of i-fixed-length segment path objects. In other words, 00041 // build the whole segment path network. 00042 for (stdair::NbOfSegments_T i = 2; 00043 i <= stdair::MAXIMAL_NUMBER_OF_SEGMENTS_IN_OND; ++i) { 00044 buildSegmentPathNetwork (iBomRoot, i); 00045 } 00046 } 00047 00048 // //////////////////////////////////////////////////////////////////// 00049 void SegmentPathGenerator:: 00050 createSinglePaths (const stdair::Inventory& iInventory) { 00051 00052 const stdair::FlightPeriodList_T& lFlightPeriodList = 00053 stdair::BomManager::getList<stdair::FlightPeriod> (iInventory); 00054 for (stdair::FlightPeriodList_T::const_iterator itFlightPeriod = 00055 lFlightPeriodList.begin(); 00056 itFlightPeriod != lFlightPeriodList.end(); ++itFlightPeriod) { 00057 const stdair::FlightPeriod* lCurrentFlightPeriod_ptr = *itFlightPeriod; 00058 assert (lCurrentFlightPeriod_ptr != NULL); 00059 00060 // 00061 createSinglePaths (*lCurrentFlightPeriod_ptr); 00062 } 00063 } 00064 00065 // //////////////////////////////////////////////////////////////////// 00066 void SegmentPathGenerator:: 00067 createSinglePaths (const stdair::FlightPeriod& iFlightPeriod) { 00068 00069 const stdair::SegmentPeriodList_T& lSegmentPeriodList = 00070 stdair::BomManager::getList<stdair::SegmentPeriod> (iFlightPeriod); 00071 for (stdair::SegmentPeriodList_T::const_iterator itSegmentPeriod = 00072 lSegmentPeriodList.begin(); 00073 itSegmentPeriod != lSegmentPeriodList.end(); ++itSegmentPeriod) { 00074 stdair::SegmentPeriod* lCurrentSegmentPeriod_ptr = *itSegmentPeriod; 00075 assert (lCurrentSegmentPeriod_ptr != NULL); 00076 00077 // 00078 createSinglePath (*lCurrentSegmentPeriod_ptr); 00079 } 00080 } 00081 00082 // //////////////////////////////////////////////////////////////////// 00083 void SegmentPathGenerator:: 00084 createSinglePath (stdair::SegmentPeriod& ioSegmentPeriod) { 00085 00086 // Retrieve the BOM tree root 00087 const stdair::AirportCode_T& lOrigin = ioSegmentPeriod.getBoardingPoint(); 00088 const stdair::FlightPeriod& lFlightPeriod = 00089 stdair::BomManager::getParent<stdair::FlightPeriod> (ioSegmentPeriod); 00090 const stdair::Inventory& lInventory = 00091 stdair::BomManager::getParent<stdair::Inventory> (lFlightPeriod); 00092 stdair::BomRoot& lBomRoot = 00093 stdair::BomManager::getParent<stdair::BomRoot> (lInventory); 00094 00095 // Retrieve the ReachableUniverse (if existing) which corresponds 00096 // to the origin. If it does not exist, then create one. 00097 ReachableUniverse* lReachableUniverse_ptr = 00098 stdair::BomManager::getObjectPtr<ReachableUniverse> (lBomRoot, lOrigin); 00099 if (lReachableUniverse_ptr == NULL) { 00100 ReachableUniverseKey lKey (lOrigin); 00101 lReachableUniverse_ptr = 00102 &stdair::FacBom<ReachableUniverse>::instance().create (lKey); 00103 stdair::FacBomManager::addToListAndMap (lBomRoot, *lReachableUniverse_ptr); 00104 stdair::FacBomManager::linkWithParent (lBomRoot, *lReachableUniverse_ptr); 00105 } 00106 assert (lReachableUniverse_ptr != NULL); 00107 00108 // 00109 createSinglePath (*lReachableUniverse_ptr, ioSegmentPeriod); 00110 } 00111 00112 // //////////////////////////////////////////////////////////////////// 00113 void SegmentPathGenerator:: 00114 createSinglePath (ReachableUniverse& ioReachableUniverse, 00115 stdair::SegmentPeriod& ioSegmentPeriod) { 00116 00117 const stdair::AirportCode_T& lDestination = ioSegmentPeriod.getOffPoint(); 00118 00119 // Retrieve the origin-destination set (if existing) which corresponds 00120 // to the destination. If it does not exist, then create one. 00121 OriginDestinationSet* lOriginDestinationSet_ptr = 00122 stdair::BomManager::getObjectPtr<OriginDestinationSet>(ioReachableUniverse, 00123 lDestination); 00124 if (lOriginDestinationSet_ptr == NULL) { 00125 OriginDestinationSetKey lKey (lDestination); 00126 00127 lOriginDestinationSet_ptr = 00128 &stdair::FacBom<OriginDestinationSet>::instance().create (lKey); 00129 stdair::FacBomManager::addToListAndMap (ioReachableUniverse, 00130 *lOriginDestinationSet_ptr); 00131 stdair::FacBomManager::linkWithParent (ioReachableUniverse, 00132 *lOriginDestinationSet_ptr); 00133 } 00134 assert (lOriginDestinationSet_ptr != NULL); 00135 00136 // Create a segment path period and add it to the corresponding 00137 // origin-destination set and reachable-universe. 00138 const stdair::FlightPeriod& lFlightPeriod = 00139 stdair::BomManager::getParent<stdair::FlightPeriod> (ioSegmentPeriod); 00140 const stdair::PeriodStruct& lPeriodOfFlight = lFlightPeriod.getPeriod(); 00141 00142 // The departure period of the segment is the departure period of 00143 // the flight plus the boarding date offset of the segment. 00144 const stdair::DateOffset_T& lBoardingDateOffset = 00145 ioSegmentPeriod.getBoardingDateOffset(); 00146 00147 const stdair::PeriodStruct lPeriodOfSegment = 00148 lPeriodOfFlight.addDateOffset (lBoardingDateOffset); 00149 00150 const stdair::Duration_T& lBoardingTime = ioSegmentPeriod.getBoardingTime(); 00151 const stdair::Duration_T& lElapsed = ioSegmentPeriod.getElapsedTime(); 00152 00153 DateOffsetList_T lDateOffsetList; 00154 const stdair::DateOffset_T lFirstDateOffset (0); 00155 lDateOffsetList.push_back (lFirstDateOffset); 00156 00157 const SegmentPathPeriodKey lSegmentPathKey (lPeriodOfSegment, 00158 lBoardingTime, lElapsed, 00159 lDateOffsetList, 1); 00160 00161 SegmentPathPeriod& lSegmentPathPeriod = 00162 stdair::FacBom<SegmentPathPeriod>::instance().create (lSegmentPathKey); 00163 00170 addSegmentPathPeriod (ioReachableUniverse, lSegmentPathPeriod); 00171 00172 // Link the SegmentPathPeriod object with its parent, namely 00173 // OriginDestinationSet 00174 stdair::FacBomManager::addToList (*lOriginDestinationSet_ptr, 00175 lSegmentPathPeriod); 00176 stdair::FacBomManager::linkWithParent (*lOriginDestinationSet_ptr, 00177 lSegmentPathPeriod); 00178 00179 // Link the SegmentPathPeriod and SegmentPeriod objects. Note that 00180 // the SegmentPeriod object has already a parent, namely FlightPeriod. 00181 stdair::FacBomManager::addToList (lSegmentPathPeriod, 00182 ioSegmentPeriod); 00183 } 00184 00185 // //////////////////////////////////////////////////////////////////// 00186 void SegmentPathGenerator:: 00187 addSegmentPathPeriod (ReachableUniverse& ioReachableUniverse, 00188 const SegmentPathPeriod& iSegmentPathPeriod) { 00189 00190 const stdair::NbOfSegments_T& lNbOfSegments = 00191 iSegmentPathPeriod.getNbOfSegments(); 00192 00193 assert (lNbOfSegments > 0 00194 && lNbOfSegments <= stdair::MAXIMAL_NUMBER_OF_SEGMENTS_IN_OND); 00195 00196 // If needed, initialise the list of lists with empty fixed-length 00197 // segment path period lists. 00198 00199 SegmentPathPeriodListList_T& lSegmentPathPeriodListList = 00200 ioReachableUniverse._segmentPathPeriodListList; 00201 while (lSegmentPathPeriodListList.size() < lNbOfSegments) { 00202 SegmentPathPeriodLightList_T lSegmentPathPeriodList; 00203 lSegmentPathPeriodListList.push_back (lSegmentPathPeriodList); 00204 } 00205 00206 // Retrieve the i-fixed-length segment path period list (i = number of 00207 // segments). 00208 SegmentPathPeriodLightList_T& lSegmentPathPeriodList = 00209 lSegmentPathPeriodListList.at (lNbOfSegments-1); 00210 00211 // Add the SegmentPathPeriod to that fixed-length-path list. 00212 lSegmentPathPeriodList.push_back (&iSegmentPathPeriod); 00213 } 00214 00215 // //////////////////////////////////////////////////////////////////// 00216 void SegmentPathGenerator:: 00217 buildSegmentPathNetwork (const stdair::BomRoot& iBomRoot, 00218 const stdair::NbOfSegments_T& lNbOfSegments) { 00219 00225 const ReachableUniverseList_T& lReachableUniverseList = 00226 stdair::BomManager::getList<ReachableUniverse> (iBomRoot); 00227 for (ReachableUniverseList_T::const_iterator itReachableUniverse = 00228 lReachableUniverseList.begin(); 00229 itReachableUniverse != lReachableUniverseList.end(); 00230 ++itReachableUniverse) { 00231 ReachableUniverse* lReachableUniverse_ptr = *itReachableUniverse; 00232 assert (lReachableUniverse_ptr != NULL); 00233 00234 // 00235 buildSegmentPathNetwork (*lReachableUniverse_ptr, lNbOfSegments); 00236 } 00237 } 00238 00239 // //////////////////////////////////////////////////////////////////// 00240 void SegmentPathGenerator:: 00241 buildSegmentPathNetwork (ReachableUniverse& ioReachableUniverse, 00242 const stdair::NbOfSegments_T& iNbOfSegments) { 00243 00244 // The goal of that method is to build the i-fixed-length 00245 // segment path period objects, knowing that all the 00246 // lower-fixed-length segment path period objects have already been 00247 // built during the previous steps. Once an i-fixed-length 00248 // segment path period object is created, it is added to the list of 00249 // the (fixed-length segment path period object) lists. 00250 00251 // Hence, at that iteration, by construction, the list of the 00252 // (fixed-length segment path period object) lists should already get 00253 // a size of i-1, if there were such possibilities (in terms of 00254 // segment path period). In that case, at the end of the method, its 00255 // size should be of i. 00256 00257 // If the size of the list of the (fixed-length segment path period 00258 // object) lists is (strictly) less than i-1, it means that that 00259 // reachable universe has no more possibilities of destinations. We 00260 // are thus done at that stage. 00261 const SegmentPathPeriodListList_T& lSegmentPathPeriodListList = 00262 ioReachableUniverse.getSegmentPathPeriodListList(); 00263 const unsigned short lNbOfSegments_m1 = iNbOfSegments - 1; 00264 assert (lNbOfSegments_m1 >= 0); 00265 if (lSegmentPathPeriodListList.size() < lNbOfSegments_m1) { 00266 return; 00267 } 00268 00269 // Retrieve the (i-1)-fixed-length segment path period list (i = number of 00270 // segments). 00271 00272 // Note that a STL vector starts at 0, whereas the number of segments 00273 // starts at 1. Hence, (i-1) for the length (in number of segments) 00274 // corresponds to [iNbOfSegments-2] for the STL vector. 00275 00276 // As the lSegmentPathPeriodListList may change during the next loop 00277 // iterations (as some SegmentPathPeriod objects are created and linked to 00278 // ReachableUniverse), we need to take the initial copy of that list. 00279 const SegmentPathPeriodLightList_T lSegmentPathPeriodLightList_im1 = 00280 lSegmentPathPeriodListList.at (iNbOfSegments-2); 00281 00282 // Iterate on the (i-1)-fixed-length segment path period objects, in order 00283 // to build a i-fixed-length segment path period objects. 00284 // There are two steps: 00285 // 1. Retrieve the airport-dates at a (i-1) length (in number of segments) 00286 // of the origin airport-date. 00287 // 2. From each of such (i-1) airport-date, add the single-segment pathes 00288 // to the (i-1)-length pathes, so as to make i-length pathes. 00289 for (SegmentPathPeriodLightList_T::const_iterator itSegmentPathPeriodList = 00290 lSegmentPathPeriodLightList_im1.begin(); 00291 itSegmentPathPeriodList != lSegmentPathPeriodLightList_im1.end(); 00292 ++itSegmentPathPeriodList) { 00293 const SegmentPathPeriod* lSegmentPathPeriod_im1_ptr = 00294 *itSegmentPathPeriodList; 00295 assert (lSegmentPathPeriod_im1_ptr != NULL); 00296 00297 // Get the reachable-universe departing from the destination of 00298 // the current segment path period. 00299 const stdair::AirportCode_T& lDestination_im1 = 00300 lSegmentPathPeriod_im1_ptr->getDestination(); 00301 const stdair::BomRoot& lBomRoot = 00302 stdair::BomManager::getParent<stdair::BomRoot> (ioReachableUniverse); 00303 const ReachableUniverse* lReachableUniverseFromDestination_im1_ptr = 00304 stdair::BomManager::getObjectPtr<ReachableUniverse> (lBomRoot, 00305 lDestination_im1); 00306 00307 // If there is no ReachableUniverse corresponding to the destination (off 00308 // point of the last SegmentDate), it means that the destination is 00309 // an end point (no other SegmentDate is starting from there). 00310 // Hence, there is nothing else to do for now for that (final) 00311 // destination, and we can process the next (i-1)-segment path period. 00312 if (lReachableUniverseFromDestination_im1_ptr == NULL) { 00313 continue; 00314 } 00315 assert (lReachableUniverseFromDestination_im1_ptr != NULL); 00316 00317 // Retrieve the single-segment segment path period list, 00318 // so as to make a i-length SegmentPathPeriod. 00319 const SegmentPathPeriodListList_T& 00320 lSegmentPathPeriodListListFromDestination_im1 = 00321 lReachableUniverseFromDestination_im1_ptr-> 00322 getSegmentPathPeriodListList(); 00323 assert (lSegmentPathPeriodListListFromDestination_im1.size() >= 1); 00324 00325 // As the lSegmentPathPeriodListListFromDestination_im1 may change during 00326 // the next loop iterations (as some SegmentPathPeriod objects are 00327 // created and linked to ReachableUniverse), we need to take the initial 00328 // copy of that list. 00329 const SegmentPathPeriodLightList_T lSingleSegmentPathPeriodLightListFromDestination_im1 = 00330 lSegmentPathPeriodListListFromDestination_im1.at (0); 00331 00332 for (SegmentPathPeriodLightList_T::const_iterator 00333 itSegmentPathPeriodFromDestination_im1 = 00334 lSingleSegmentPathPeriodLightListFromDestination_im1.begin(); 00335 itSegmentPathPeriodFromDestination_im1 00336 != lSingleSegmentPathPeriodLightListFromDestination_im1.end(); 00337 ++itSegmentPathPeriodFromDestination_im1) { 00338 const SegmentPathPeriod* lSingleSegmentPathPeriodFromDestination_im1_ptr= 00339 *itSegmentPathPeriodFromDestination_im1; 00340 assert (lSingleSegmentPathPeriodFromDestination_im1_ptr != NULL); 00341 00342 // Check if the (i-1)-length segment path period can be fused with the 00343 // single segment segment path period in order to create an i-length 00344 // segment path period. The function will return a valid or non-valid 00345 // segment path period key. 00346 00347 // The two segment path period above can be fused (and will produce a 00348 // valid new segment path period key) if: 00349 // 1. A passenger can connect from the last segment of the 00350 // first segment path and the first segment of the next segment path. 00351 // These two segments should not create another segment. 00352 // 2. There is no circle within the new segment path. 00353 // 3. The intersection of the two periods is non-empty. 00354 SegmentPathPeriodKey lSegmentPathPeriodKey_i = 00355 lSegmentPathPeriod_im1_ptr->connectWithAnotherSegment (*lSingleSegmentPathPeriodFromDestination_im1_ptr); 00356 00357 if (lSegmentPathPeriodKey_i.isValid () == false) { 00358 continue; 00359 } 00360 00361 // Get the off point of the single-segment SegmentPathPeriod 00362 // attached to the intermediate destination (im1). That off point is 00363 // at a length i of the initial ReachableUniverse: (i-1) + 1. 00364 const stdair::AirportCode_T& lDestination_i = 00365 lSingleSegmentPathPeriodFromDestination_im1_ptr->getDestination(); 00366 00367 // Build the i-length SegmentPathPeriod 00368 // Get the parameters of the last segment 00369 stdair::SegmentPeriod* lSegmentPeriod_1_ptr = 00370 lSingleSegmentPathPeriodFromDestination_im1_ptr->getFirstSegmentPeriod(); 00371 assert (lSegmentPeriod_1_ptr != NULL); 00372 00373 // Calculate the number of airlines flown by the i-length 00374 // segment path period 00375 const stdair::FlightPeriod& lFlightPeriod = stdair::BomManager:: 00376 getParent<stdair::FlightPeriod> (*lSegmentPeriod_1_ptr); 00377 const stdair::Inventory& lInventory = 00378 stdair::BomManager::getParent<stdair::Inventory> (lFlightPeriod); 00379 const stdair::AirlineCode_T& lAirlineCode_1 =lInventory.getAirlineCode(); 00380 stdair::NbOfAirlines_T lNbOfAirlines_i = 00381 lSegmentPathPeriod_im1_ptr->getNbOfAirlines(); 00382 if (lSegmentPathPeriod_im1_ptr->isAirlineFlown(lAirlineCode_1) == false){ 00383 ++lNbOfAirlines_i; 00384 } 00385 lSegmentPathPeriodKey_i.setNbOfAirlines (lNbOfAirlines_i); 00386 00387 // Create the new segment path and add it to the dedicated lists. 00388 OriginDestinationSet* lOriginDestinationSet_ptr = stdair::BomManager:: 00389 getObjectPtr<OriginDestinationSet>(ioReachableUniverse,lDestination_i); 00390 if (lOriginDestinationSet_ptr == NULL) { 00391 OriginDestinationSetKey lKey (lDestination_i); 00392 lOriginDestinationSet_ptr = 00393 &stdair::FacBom<OriginDestinationSet>::instance().create (lKey); 00394 stdair::FacBomManager::addToListAndMap (ioReachableUniverse, 00395 *lOriginDestinationSet_ptr); 00396 stdair::FacBomManager::linkWithParent (ioReachableUniverse, 00397 *lOriginDestinationSet_ptr); 00398 } 00399 assert (lOriginDestinationSet_ptr != NULL); 00400 00401 00402 SegmentPathPeriod& lSegmentPathPeriod_i = stdair:: 00403 FacBom<SegmentPathPeriod>::instance().create (lSegmentPathPeriodKey_i); 00404 stdair::FacBomManager::addToList (*lOriginDestinationSet_ptr, 00405 lSegmentPathPeriod_i); 00406 stdair::FacBomManager::linkWithParent (*lOriginDestinationSet_ptr, 00407 lSegmentPathPeriod_i); 00408 00409 // Clone the list of SegmentPeriod references of the given 00410 // SegmentPathPeriod object (passed as the second parameter). 00411 stdair::FacBomManager:: 00412 cloneHolder<stdair::SegmentPeriod> (lSegmentPathPeriod_i, 00413 *lSegmentPathPeriod_im1_ptr); 00414 00415 00416 // Add the SegmentPeriod reference to the dedicated list within 00417 // the SegmentPathPeriod. Note that this must be done before 00418 // the link between the SegmentPathPeriod and 00419 // ReachableUniverse, as that latter method uses the number of 00420 // segments within the SegmentPathPeriod object. 00421 stdair::FacBomManager::addToList (lSegmentPathPeriod_i, 00422 *lSegmentPeriod_1_ptr); 00423 00431 addSegmentPathPeriod (ioReachableUniverse, lSegmentPathPeriod_i); 00432 } 00433 } 00434 } 00435 }