int CDetailTaxiDelayResult::GetFlightCountInIntervalTime(FlightConstraint& fltConstraint, ElapsedTime& estMinDelayTime, ElapsedTime& estMaxDelayTime, 
														vector<CAirsideFlightDelayReport::FltTypeDelayItem>& fltTypeDelayData)
{
	int nDelayTime = 0;

	for (int i=0; i<(int)fltTypeDelayData.size(); i++)
	{
		if (fltConstraint.fits(fltTypeDelayData[i].m_fltCons))
		{
			vector<CAirsideFlightDelayReport::FltDelayItem>::iterator iter = fltTypeDelayData[i].m_vDelayData.begin();
			for (; iter!=fltTypeDelayData[i].m_vDelayData.end(); iter++)
			{
				std::vector<CAirsideFlightDelayReport::FltNodeDelayItem>::iterator nodeDelayIter = (*iter).vNodeDelay.begin();
				for (; nodeDelayIter!=(*iter).vNodeDelay.end(); nodeDelayIter++)
				{
					if (estMinDelayTime.asSeconds()*100 <= (*nodeDelayIter).eActArriveTime
						&& (*nodeDelayIter).eActArriveTime < estMaxDelayTime.asSeconds()*100
						&& (*nodeDelayIter).nSegment == CAirsideFlightDelayReport::FltDelaySegment_Taxi)
					{
						nDelayTime += (*nodeDelayIter).delayTime;
					}
				}
			}
		}
	}

	return nDelayTime;
}
int CDetailFlightScheduleDelayResult::GetFlightCountInIntervalTime(FlightConstraint& fltConstraint, ElapsedTime& estMinDelayTime, ElapsedTime& estMaxDelayTime, 
														 vector<CAirsideFlightDelayReport::FltTypeDelayItem>& fltTypeDelayData)
{
	int nDelayCount = 0;
	for (int i=0; i<(int)fltTypeDelayData.size(); i++)
	{
		if (fltConstraint.fits(fltTypeDelayData[i].m_fltCons))
		{
			vector<CAirsideFlightDelayReport::FltDelayItem>::iterator iter = fltTypeDelayData[i].m_vDelayData.begin();
			for (; iter!=fltTypeDelayData[i].m_vDelayData.end(); iter++)
			{
				long lDelay = GetScheduleDelayTime(*iter);
				if (lDelay < 100)//ignore flight schedule 1sec
					continue;
				

				if (estMinDelayTime.asSeconds()*100 <= lDelay
					&& lDelay < estMaxDelayTime.asSeconds()*100)
				{
					nDelayCount++;
				}
			}
		}
	}
	return nDelayCount;
}
LRESULT CDlgDepartureSlotSpec::OnEndDbClickNoEditListItem( WPARAM wparam, LPARAM lparam)
{
	if(!m_pDepSlotSpec)return (0);	
	DepartureSlotItem* pItem = m_pDepSlotSpec->GetItem(m_nRowSel);
	if(!pItem)return (0);

	if(m_nColumnSel == 0)//Flight Type
	{
		if (m_pSelectFlightType == NULL)
			return (0);
		FlightConstraint fltType = (*m_pSelectFlightType)(NULL);
		char szBuffer[1024]={0};
		int xCount = m_wndListCtrl.GetItemCount();
		for(int n = 0;n<xCount;n++)
		{
			if(!m_wndListCtrl.GetItemText(n,0).Compare(szBuffer))
			{
				MessageBox(_T("This Flight Type had existed."));
				return (0);
			}
		}

		pItem->SetFltType(fltType);
		CString strFltType;
		pItem->GetFlightConstraint().screenPrint(strFltType);
		CString strString;		
		strString.Format("%s \t ", strFltType);
		m_wndListCtrl.SetItemText(m_nRowSel,m_nColumnSel,strString);
	}
	else if(m_nColumnSel == 2)//Time Range
	{
		CDlgTimeRange dlg(pItem->GetFromTime(), pItem->GetToTime());
		if(IDOK == dlg.DoModal())
		{
			pItem->SetFromTime(dlg.GetStartTime());
			pItem->SetToTime(dlg.GetEndTime());
			
			ElapsedTime estFromTime;
			estFromTime = pItem->GetFromTime();
			ElapsedTime estToTime;
			estToTime = pItem->GetToTime();
			CString strFromTime;
			strFromTime.Format("Day%d %02d:%02d:%02d", estFromTime.GetDay(), 
				estFromTime.GetHour(),
				estFromTime.GetMinute(),
				estFromTime.GetSecond());
			CString strToTime;
			strToTime.Format("Day%d %02d:%02d:%02d", estToTime.GetDay(), 
				estToTime.GetHour(),
				estToTime.GetMinute(),
				estToTime.GetSecond());
			CString strfromToTime;
			strfromToTime.Format("%s - %s", strFromTime, strToTime);
			m_wndListCtrl.SetItemText(m_nRowSel,m_nColumnSel,strfromToTime);
		}
	}

	return (0);
}
Beispiel #4
0
void GLBufferObjectSet::flushDeletedGLBufferObjects(double /*currentTime*/, double& availableTime)
{
    {
        OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
        if (!_pendingOrphanedGLBufferObjects.empty())
        {
            // OSG_NOTICE<<"GLBufferObjectSet::flushDeletedGLBufferObjects(..) handling orphans"<<std::endl;
            handlePendingOrphandedGLBufferObjects();
        }
    }

    if (_parent->getCurrGLBufferObjectPoolSize()<=_parent->getMaxGLBufferObjectPoolSize())
    {
        OSG_INFO<<"Plenty of space in GLBufferObject pool"<<std::endl;
        return;
    }

    // if nothing to delete return
    if (_orphanedGLBufferObjects.empty()) return;

    // if no time available don't try to flush objects.
    if (availableTime<=0.0) return;

    unsigned int numDeleted = 0;
    unsigned int sizeRequired = _parent->getCurrGLBufferObjectPoolSize() - _parent->getMaxGLBufferObjectPoolSize();
    unsigned int maxNumObjectsToDelete = static_cast<unsigned int>(ceil(double(sizeRequired) / double(_profile._size)));
    OSG_INFO<<"_parent->getCurrGLBufferObjectPoolSize()="<<_parent->getCurrGLBufferObjectPoolSize() <<" _parent->getMaxGLBufferObjectPoolSize()="<< _parent->getMaxGLBufferObjectPoolSize()<<std::endl;
    OSG_INFO<<"Looking to reclaim "<<sizeRequired<<", going to look to remove "<<maxNumObjectsToDelete<<" from "<<_orphanedGLBufferObjects.size()<<" orphans"<<std::endl;

    ElapsedTime timer;

    GLBufferObjectList::iterator itr = _orphanedGLBufferObjects.begin();
    for(;
        itr != _orphanedGLBufferObjects.end() && timer.elapsedTime()<availableTime && numDeleted<maxNumObjectsToDelete;
        ++itr)
    {

         (*itr)->deleteGLObject();

        ++numDeleted;
    }

    // OSG_NOTICE<<"Size before = "<<_orphanedGLBufferObjects.size();
    _orphanedGLBufferObjects.erase(_orphanedGLBufferObjects.begin(), itr);
    // OSG_NOTICE<<", after = "<<_orphanedGLBufferObjects.size()<<" numDeleted = "<<numDeleted<<std::endl;

    // update the number of TO's in this GLBufferObjectSet
    _numOfGLBufferObjects -= numDeleted;

    _parent->setCurrGLBufferObjectPoolSize( _parent->getCurrGLBufferObjectPoolSize() - numDeleted*_profile._size );

    // update the number of active and orphaned TextureObjects
    _parent->getNumberOrphanedGLBufferObjects() -= numDeleted;
    _parent->getNumberDeleted() += numDeleted;

    availableTime -= timer.elapsedTime();
}
Beispiel #5
0
otError Dhcp6Server::ProcessElapsedTime(Message &aMessage, uint16_t aOffset)
{
    otError error = OT_ERROR_NONE;
    ElapsedTime option;

    VerifyOrExit(((aMessage.Read(aOffset, sizeof(option), &option) == sizeof(option)) &&
                  (option.GetLength() == ((sizeof(option) - sizeof(Dhcp6Option))))),
                 error = OT_ERROR_PARSE);
exit:
    return error;
}
void CDlgDepartureSlotSpec::SetListContent()
{
	m_wndListCtrl.DeleteAllItems();
	//get values
	size_t nDepSlotCount = m_pDepSlotSpec->GetElementCount();
	for (size_t i = 0; i< nDepSlotCount; i++)
	{
		DepartureSlotItem* pItem = m_pDepSlotSpec->GetItem(i);

		//flight type
		FlightConstraint fltType = pItem->GetFlightConstraint();
		CString strFltType;
		fltType.screenPrint(strFltType);
		CString strString;		
		strString.Format("%s \t ", strFltType);
		m_wndListCtrl.InsertItem(i, strString);

		//SID
		m_wndListCtrl.SetItemText(i,1,pItem->GetSIDName());

		//Time Range
		ElapsedTime estFromTime;
		estFromTime = pItem->GetFromTime();
		ElapsedTime estToTime;
		estToTime = pItem->GetToTime();
		CString strFromTime;
		strFromTime.Format("Day%d %02d:%02d:%02d", estFromTime.GetDay(), 
			estFromTime.GetHour(),
			estFromTime.GetMinute(),
			estFromTime.GetSecond());
		CString strToTime;
		strToTime.Format("Day%d %02d:%02d:%02d", estToTime.GetDay(), 
			estToTime.GetHour(),
			estToTime.GetMinute(),
			estToTime.GetSecond());
		CString strfromToTime;
		strfromToTime.Format("%s - %s", strFromTime, strToTime);
		m_wndListCtrl.SetItemText(i, 2,strfromToTime);

		//first slot delay distribution
		m_wndListCtrl.SetItemText(i, 3,pItem->GetFirstSlotDelayProDisName());

		//inter slot delay distribution
		m_wndListCtrl.SetItemText(i, 4,pItem->GetInterSlotDelayProDisName());

		m_wndListCtrl.SetItemData(i, (DWORD_PTR)pItem);
	}
	m_wndListCtrl.SetItemState(nDepSlotCount - 1, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED);
}
//caculate the mid point of two log point
Point FireEvacuationEvent::CaculateCurPositionOfPerson( const ElapsedTime& _timeEvent , MobileElement* _pElement)
{
	Person* pPerson = (Person*)_pElement;
	Point locationPt,destPt;
	pPerson->getTerminalPoint(locationPt);
	pPerson->getTerminalDest(destPt);
	if( _timeEvent == time )
	{
		return destPt;
	}

	DistanceUnit dLength = ( _timeEvent.asSeconds() - time.asSeconds() ) * _pElement->getSpeed();
	Point ptCurrentPosition( destPt);
	
	if( ptCurrentPosition == locationPt )
	{
		return ptCurrentPosition;
	}
	
	Point ptVector( ptCurrentPosition, locationPt );
	ptVector.length( dLength );

	ptCurrentPosition += ptVector;

	ptCurrentPosition.setZ( destPt.getZ() );
	
	return ptCurrentPosition;
}
void LandsideIntersectLinkGroupInSim::WriteLog(const ElapsedTime& t)
{
	IntersectionLinkGroupEventStruct curEvent;
	curEvent.state=m_eState;
	curEvent.time=t.getPrecisely();
	m_logEntry.addEvent(curEvent);
}
Beispiel #9
0
  /** @brief wait for a synclink message
   *
   * @param[in]	TimeToWait the max time to wait in ms (default 250 ms)
   * @return	true if the Socket has received a SyncLink message before timeout
   */
bool MsgSocket::WaitSyncLinkMsg(unsigned int TimeToWait/* = 250 */)
{
	ElapsedTime CountWaitedTime;
	while( connected == true )
	{
		if ( ReceivedSyncLinkMsg() )
		{
			return true;
		}
		if ( CountWaitedTime.Get() >= TimeToWait )
		{
			return false;
		}
		Thread::Sleep(10);
	}
	return false;
}
Beispiel #10
0
void GLBufferObjectSet::flushDeletedGLBufferObjects(double currentTime, double& availableTime)
{
    // if nothing to delete return
    if (_orphanedGLBufferObjects.empty()) return;

    // if no time available don't try to flush objects.
    if (availableTime<=0.0) return;

    // if we don't have too many orphaned texture objects then don't bother deleting them, as we can potentially reuse them later.
    if (_parent->getNumberOrphanedGLBufferObjects()<=s_minimumNumberOfGLBufferObjectsToRetainInCache) return;

    unsigned int numDeleted = 0;
    unsigned int maxNumObjectsToDelete = _parent->getNumberOrphanedGLBufferObjects()-s_minimumNumberOfGLBufferObjectsToRetainInCache;
    if (maxNumObjectsToDelete>4) maxNumObjectsToDelete = 4;

    ElapsedTime timer;

    GLBufferObjectList::iterator itr = _orphanedGLBufferObjects.begin();
    for(;
        itr != _orphanedGLBufferObjects.end() && timer.elapsedTime()<availableTime && numDeleted<maxNumObjectsToDelete;
        ++itr)
    {

         (*itr)->deleteGLObject();

        ++numDeleted;
    }

    // OSG_NOTIFY(osg::NOTICE)<<"Size before = "<<_orphanedGLBufferObjects.size();
    _orphanedGLBufferObjects.erase(_orphanedGLBufferObjects.begin(), itr);
    //OSG_NOTIFY(osg::NOTICE)<<", after = "<<_orphanedGLBufferObjects.size()<<" numDeleted = "<<numDeleted<<std::endl;

    // update the number of TO's in this GLBufferObjectSet
    _numOfGLBufferObjects -= numDeleted;

    _parent->setCurrGLBufferObjectPoolSize( _parent->getCurrGLBufferObjectPoolSize() - numDeleted*_profile._size );

    // update the number of active and orphaned TextureOjects
    _parent->getNumberOrphanedGLBufferObjects() -= numDeleted;
    _parent->getNumberActiveGLBufferObjects() += numDeleted;
    _parent->getNumberDeleted() += numDeleted;

    availableTime -= timer.elapsedTime();
}
AirsideFlightConflict* AirsideFlightConflict::ReadLog( ArctermFile& inFile )
{
	long varInt;
	//char strbuf[MAX_STRBUF_SIZE];
	//get id
	int uUId;
	inFile.getInteger( uUId );

	////delay type
	//inFile.getInteger(varInt);
	AirsideFlightConflict* theConflict = new AirsideFlightConflict();
	if(theConflict) // read data
	{		
		theConflict->m_nUniqueID = uUId;

		inFile.getInteger(varInt);
		ElapsedTime tTime; tTime.setPrecisely(varInt);
		theConflict->m_tTime = tTime;

		inFile.getInteger(varInt);
		theConflict->m_nReportAreaID =varInt;

		inFile.getInteger(varInt);
		theConflict->m_nFltUID = varInt;

		inFile.getInteger(varInt);
		theConflict->m_nConflictMobileID = varInt;

		inFile.getInteger(varInt);
		theConflict->m_eConflictType =(FlightConflict::ConflictType)varInt;

		inFile.getInteger(varInt);
		theConflict->m_eLocationType = (FlightConflict::LocationType)varInt;

		inFile.getInteger(varInt);
		theConflict->m_eOperationType = (FlightConflict::OperationType)varInt;

		inFile.getInteger(varInt);
		theConflict->m_eActionType = (FlightConflict::ActionType)varInt;

	}
	inFile.getLine();
	return theConflict;
}
void CDlgDepartureSlotSpec::OnNewDepartureSlotItem()
{
	DepartureSlotItem* pItem = new DepartureSlotItem();
	if(!pItem)return;
	pItem->SetProjID(m_nProjID);
	pItem->setAirportDB(m_pAirportDB);
	FlightConstraint fltType;
	pItem->SetFltType(fltType);
	pItem->SetSID(-2);

	ElapsedTime elapsedtimeFrom;
	elapsedtimeFrom.set(0);
	pItem->SetFromTime(elapsedtimeFrom);
	ElapsedTime elapsedtimeTo;
	elapsedtimeTo.set(86399);
	pItem->SetToTime(elapsedtimeTo);

	pItem->SetFirstSlotDelayProDisName(_T("U[20~30]"));
	pItem->SetFirstSlotDelayProDisType(UNIFORM);
	pItem->SetFirstSlotDelayPrintDis(_T("Uniform:20;30"));
	pItem->SetInterSlotDelayProDisName(_T("U[20~30]"));
	pItem->SetInterSlotDelayProDisType(UNIFORM);
	pItem->SetInterSlotDelayPrintDis(_T("Uniform:20;30"));

	
	CString strFltType;
	fltType.screenPrint(strFltType);
	CString strString;
	strString.Format("%s \t ", strFltType);
	int nCount = m_wndListCtrl.GetItemCount();
	m_wndListCtrl.InsertItem(nCount, strString);
	m_wndListCtrl.SetItemText(nCount, 1,_T("All"));
	CString strInit;
	strInit.Format("Day1 00:00:00 - Day1 23:59:59");
	m_wndListCtrl.SetItemText(nCount, 2,strInit);
	m_wndListCtrl.SetItemText(nCount,3,pItem->GetFirstSlotDelayProDisName());
	m_wndListCtrl.SetItemText(nCount,4,pItem->GetInterSlotDelayProDisName());
	m_wndListCtrl.SetItemData(nCount, (DWORD_PTR)pItem);
	m_pDepSlotSpec->AddNewItem(pItem);

	m_wndListCtrl.SetItemState(nCount, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED);
	GetDlgItem(IDSAVE)->EnableWindow(TRUE);
}
void CRunwayDetailExitResult::Draw3DChart(CARC3DChart& chartWnd, CParameters *pParameter)
{
	if(pParameter == NULL)
		return ;
	C2DChartData c2dGraphData;

	c2dGraphData.m_strChartTitle.Format(_T("Runway Exit Detail Delay"))  ;

	c2dGraphData.m_strYtitle = _T("Number of aircrafts");
	c2dGraphData.m_strXtitle = _T("Date and time") ;

	//set footer
	CString strFooter(_T(""));
	strFooter.Format(_T("%s %s,%s "),_T("Runway Exit Detail Delay"), pParameter->getStartTime().printTime(), pParameter->getEndTime().printTime());
	bool bCommaFlag = true;
	c2dGraphData.m_strFooter = strFooter;

	int intervalSize = 0 ;
	ElapsedTime IntervalTime ;
	IntervalTime = (pParameter->getEndTime() - pParameter->getStartTime()) ;
	intervalSize = IntervalTime.asSeconds() / pParameter->getInterval() ;

	CTimeIntervalFlightData* PTimeIntervalData = NULL ;
	IntervalTime = pParameter->getStartTime() ;
	CString timeInterval ;
	ElapsedTime startTime = pParameter->getStartTime();
	ElapsedTime endtime ;
	for (int i = 0 ; i < intervalSize ;i++)
	{
		endtime = startTime + ElapsedTime(pParameter->getInterval()) ;
		timeInterval.Format(_T("%s-%s"),startTime.printTime(),endtime.printTime()) ;
		startTime = endtime ;
		c2dGraphData.m_vrXTickTitle.push_back(timeInterval) ;
	}

	CRunwayExitRepDataItem* RunwayExitRepDataItem = NULL ;
	CString Strval ;
	int size = (int)( m_ReportBaseData->GetData()->size() );
	for (int i = 0 ; i < size; i++)
	{
		RunwayExitRepDataItem = m_ReportBaseData->GetData()->at(i) ;
		Strval.Format(_T("%s %s"),RunwayExitRepDataItem->m_RunwayName,RunwayExitRepDataItem->m_RunwayExitName) ;
		c2dGraphData.m_vrLegend.push_back(Strval);

		std::vector<double> segmentData ;

		CTimeIntervalFlightData* TimerIntervalData = NULL ;
		for (int j = 0 ; j < (int)RunwayExitRepDataItem->GetData()->size() ;j++)
		{
			TimerIntervalData = RunwayExitRepDataItem->GetData()->at(j) ;
			segmentData.push_back((long)TimerIntervalData->m_FlightData.size()) ;
		}
		c2dGraphData.m_vr2DChartData.push_back(segmentData);
	}
	chartWnd.DrawChart(c2dGraphData);
}
Beispiel #14
0
//called by updateApproachingPerson()
// put a person from wait location to it's destination slot
void CLoader::putBagToSlot( Person *aPerson, ElapsedTime curTime)
{
	TerminalMobElementBehavior* spTerminalBehavior = aPerson->getTerminalBehavior();
	if (spTerminalBehavior == NULL)
	{
		return;
	}

	int _iDestSlot = spTerminalBehavior->GetDestinationSlot();
	assert( _iDestSlot!= -1 );
	if( m_pSlots[ _iDestSlot ].first != NULL )
	{
		writeLogEvent (aPerson, curTime, BeginService);
	
		aPerson->kill(curTime);

		throw new ARCConveyorSimultaneousServiceError( aPerson->getPersonErrorMsg(), 
			getID()->GetIDString(),_T(""), curTime.printTime() );
	}
	
	startUpIfNeed( curTime+1l );
	
	// remove from approaching list
	int index = m_approaching.findItem (aPerson);
	assert( index != INT_MAX );
	m_approaching.removeItem (index);
	spTerminalBehavior->SetDestinationSlot( -1 );
	
	// add the element to the processor
	m_iOccapuiedCount++;
	m_pSlots[_iDestSlot].first = aPerson;
	m_pSlots[_iDestSlot].second = curTime+1l;
	
	// write the element's log
	
	aPerson->setTerminalDestination( slotsPath.getSlotPoint( _iDestSlot ) );
 	
	aPerson->setState( MovingInConveyor );
	aPerson->writeLogEntry( curTime+1l, false );


	writeLogEvent (aPerson, curTime+1l, BeginService);	
}
bool VisitorTerminalBehavior::StickNonPaxDestProcsOverload( const ElapsedTime& _curTime )
{
	m_pPerson->regetAttatchedNopax();
	ProcessorDistribution* pNextProcDistribution = m_pProcessor->getNextDestinations ( m_pPerson->getType(), m_nInGateDetailMode );
	if(pNextProcDistribution ==NULL ) return false;
	CSinglePaxTypeFlow* pProcessSingleFlow=NULL;
	ProcessorID* pProcessCurID=NULL;

	pNextProcDistribution->getDestinationGroup( RANDOM);


	ASSERT( pNextProcDistribution!=NULL);

	CFlowChannel* pInChannel=NULL;
	ProcessorArray aryOverloadDestProcs;
	ProcessorArray aryDestProcs;

	//defined for function FindDestProcessors,
	//if can not find the destination processor for 1:1 reason
	//or 1*1 reason, remember it.
	//throw exception after test every processor in distribution.
	bool bOneToOneReason = false;
	bool bOneXOneReason = false;

	do
	{
		pInChannel=NULL;
		if( static_cast<CProcessorDistributionWithPipe*>(pNextProcDistribution)->GetOneXOneState()==ChannelEnd)
		{
			pInChannel=m_FlowChannelList.PopChannel();
			m_FlowChannelList.PushChannel(pInChannel);//restore channel info for next time to use.
		}
		m_pProcessor->FindDestProcessors( m_pPerson, pNextProcDistribution, 
			pInChannel, _curTime, pProcessSingleFlow, pProcessCurID,
			aryDestProcs, bOneToOneReason, bOneXOneReason);
		Processor::PruneInvalidDestProcs(getTerminal(), m_pPerson, &aryDestProcs, NULL, &aryOverloadDestProcs );

		if(aryDestProcs.getCount()>0 && noExceptions (&aryDestProcs) && IfBaggageProcAllowed( &aryDestProcs, pNextProcDistribution ))
			return false;


	}while( pNextProcDistribution->getDestinationGroup( SEQUENTIAL) ) ;

	//check zeropercent dest group.
	if(aryDestProcs.getCount()==0)
	{
		while(pNextProcDistribution->getZeropercentDestGroup())
		{
			pInChannel=NULL;
			if( static_cast<CProcessorDistributionWithPipe*>(pNextProcDistribution)->GetOneXOneState()==ChannelEnd)
			{	
				pInChannel=m_FlowChannelList.PopChannel();
				m_FlowChannelList.PushChannel(pInChannel);//restore channel info for next time to use.
			}
			m_pProcessor->FindDestProcessors( m_pPerson, pNextProcDistribution, 
				pInChannel, _curTime, pProcessSingleFlow, pProcessCurID, 
				aryDestProcs, bOneToOneReason, bOneXOneReason);
			ASSERT( aryDestProcs.getCount()>0);

			Processor::PruneInvalidDestProcs(getTerminal(), m_pPerson, &aryDestProcs, NULL, &aryOverloadDestProcs );

			if(aryDestProcs.getCount()>0 && noExceptions (&aryDestProcs) && IfBaggageProcAllowed( &aryDestProcs, pNextProcDistribution ))
				return false;

		}
	}

	if(bOneToOneReason)
	{
		CString str = "Can't find processor to correspond to "+ m_pProcessor->getID()->GetIDString()+ " by 1:1";
		throw new ARCDestProcessorUnavailableError( getPersonErrorMsg(), 
			m_pProcessor->getID()->GetIDString(), str, _curTime.PrintDateTime());
	}
	if(bOneXOneReason)
	{
		CString str = "Cannot find processor to correspond to "+ pInChannel->GetInChannelProc()->getID()->GetIDString()+ " by 1:x:1";
		throw new ARCDestProcessorUnavailableError( getPersonErrorMsg(),
			m_pProcessor->getID()->GetIDString(), str, _curTime.PrintDateTime());
	}

	//if(aryDestProcs.getCount()>0) return false;//not need to stick.
	if(aryOverloadDestProcs.getCount()>0)
	{
		Processor* pAnOverloadProc=NULL;
		WaitingPair waitPair;
		Passenger* pOwner = GetOwner();
		if (pOwner)
		{
			waitPair.first= pOwner->getID();
			waitPair.second =m_pProcessor->getIndex();

			for( int i=0; i<aryOverloadDestProcs.getCount(); i++)
			{
				pAnOverloadProc= aryOverloadDestProcs.getItem( i );
				pAnOverloadProc->AddWaitingPair( waitPair );	// add pax id and processor idx to the dest processor.
			}
			return true;
		}
		
	}
	return false;

}
Beispiel #16
0
int MovingTrain::move(ElapsedTime currentTime,bool bNoLog)
{
	PLACE_METHOD_TRACK_STRING();
	switch(state)
	{
	case Birth:
		{
			InitTrain();
			state = TrainFreeMoving;
			generateEvent(currentTime,false);
		}
		break;
	case TrainFreeMoving:
		{
			if (m_iPreState == Birth)
			{
				GetSchedule(currentTime);
			}
			else
			{
				GetSchedule(currentTime - m_TrainLogEntry.GetTurnAroundTime());
			}

			int nCount = m_movePath.size();
			double dPrevHeading = 0.0;

			for( int i=0; i<nCount; i++ )
			{
				CViehcleMovePath movePath = m_movePath[i];
				int nPathCount = movePath.GetCount();
				float fPrevHeading;
				for( int z=0; z<nPathCount; z++ )
				{
					CStateTimePoint timePt = movePath.GetItem( z );
					TrainEventStruct event;
					ElapsedTime t;
					event.time = timePt.GetTime();
					t.setPrecisely(event.time);
					if (currentTime < t)
					{
						currentTime = t;
					}
					event.x = (float)timePt.getX();
					event.y = (float)timePt.getY();
					event.z = (short)timePt.getZ();
					if( z < nPathCount - 1 )
					{
						CStateTimePoint nextTimePt = movePath.GetItem( z+1 );
						double dNewHeading = ( nextTimePt - timePt ).getHeading();
						event.heading = (float)dNewHeading;
						fPrevHeading = event.heading;
					}
					else
					{
						event.heading = fPrevHeading;
					}
					event.state = timePt.GetState();
					m_TrainLogEntry.addEvent( event );
				}
			}
			ElapsedTime delayTime;
			delayTime.setPrecisely(01l); 

			generateEvent(currentTime - delayTime,false);//notify passenger train arrival
			m_iPreState = state;
			state = TrainArriveAtStation;
		}
		break;
	case TrainArriveAtStation:
		{
			if (m_nFlowIndex + 1 == (int)m_TrainFlow.size())
			{
				m_nFlowIndex = 0;
			}
			m_nFlowIndex++;
			IntegratedStation* pSourceStation = GetSourceStation(m_nFlowIndex);
			pSourceStation->SetTrain(this);
			ElapsedTime delayTime;
			delayTime.setPrecisely(01l); 
			generateEvent(currentTime + delayTime,false);//for correct time to leave
			state = TrainWaitForLeave;
		}
		break;
	case TrainWaitForLeave:
		{
			currentTime += m_TrainLogEntry.GetTurnAroundTime();
			generateEvent(currentTime,false);
			m_iPreState = state;
			state = TrainLeaveStation;
		}
		break;
	case TrainLeaveStation:
		{
			if (m_TrainLogEntry.GetEndTime() < currentTime)
			{
				generateEvent(currentTime,false);
				state = Death;
			}
			else
			{
				generateEvent(currentTime,false);
				m_iPreState = state;
				state = TrainFreeMoving;
			}
			IntegratedStation* pSourceStation = GetSourceStation(m_nFlowIndex);
			pSourceStation->ClearStationTrain(this);
			ClearThisStationPerson(pSourceStation);

		}
		break;
	case Death:
		{
			FlushLog();
		}
		break;
	default:
		break;
	}
	return TRUE;
}
	HighwayGraph
	(	WaypointQuadtree &all_waypoints,
		std::list<HighwaySystem*> &highway_systems,
		DatacheckEntryList *datacheckerrors,
		unsigned int numthreads,
		ElapsedTime &et
	)
	{	// loop for each Waypoint, create a unique name and vertex,
		// unless it's a point not in or colocated with any active
		// or preview system, or is colocated and not at the front
		// of its colocation list
		unsigned int counter = 0;
		std::cout << et.et() << "Creating unique names and vertices" << std::flush;
		for (Waypoint *w : all_waypoints.point_list())
		{	if (counter % 10000 == 0) std::cout << '.' << std::flush;
			counter++;
			// skip if this point is occupied by only waypoints in devel systems
			if (!w->is_or_colocated_with_active_or_preview()) continue;
			// skip if colocated and not at front of list
			if (w->colocated && w != w->colocated->front()) continue;

			// come up with a unique name that brings in its meaning

			// start with the canonical name
			std::string point_name = w->canonical_waypoint_name(waypoint_naming_log);
			bool good_to_go = 1;

			// if that's taken, append the region code
			if (vertex_names.find(point_name) != vertex_names.end())
			{	point_name += "|" + w->route->region->code;
				waypoint_naming_log.push_back("Appended region: " + point_name);
				good_to_go = 0;
			}

			// if that's taken, see if the simple name is available
			if (!good_to_go && vertex_names.find(point_name) != vertex_names.end())
			{	std::string simple_name = w->simple_waypoint_name();
				if (vertex_names.find(simple_name) == vertex_names.end())
				{	waypoint_naming_log.push_back("Revert to simple: " + simple_name + " from (taken) " + point_name);
					point_name = simple_name;
					good_to_go = 1;
				}
				else	good_to_go = 0;
			}

			// if we have not yet succeeded, add !'s until we do
			if (!good_to_go) while (vertex_names.find(point_name) != vertex_names.end())
			{	point_name += "!";
				waypoint_naming_log.push_back("Appended !: " + point_name);
			}

			// we're good; now construct a vertex
			if (!w->colocated)
				vertices[w] = new HGVertex(w, &*(vertex_names.insert(point_name).first), datacheckerrors, numthreads);
			else	vertices[w] = new HGVertex(w->colocated->front(), &*(vertex_names.insert(point_name).first), datacheckerrors, numthreads);
					      // deleted by HighwayGraph::clear
		}
		std::cout << '!' << std::endl;
		//#include "../../debug/unique_names.cpp"

		// create edges
		counter = 0;
		std::cout << et.et() << "Creating edges" << std::flush;
		for (HighwaySystem *h : highway_systems)
		{	if (h->devel()) continue;
			if (counter % 6 == 0) std::cout << '.' << std::flush;
			counter++;
			for (Route &r : h->route_list)
			  for (HighwaySegment *s : r.segment_list)
			    if (!s->concurrent || s == s->concurrent->front())
			      new HGEdge(s, this);
			      // deleted by ~HGVertex, called by HighwayGraph::clear
		}
		std::cout << '!' << std::endl;

		// compress edges adjacent to hidden vertices
		counter = 0;
		std::cout << et.et() << "Compressing collapsed edges" << std::flush;
		for (std::pair<const Waypoint*, HGVertex*> wv : vertices)
		{	if (counter % 10000 == 0) std::cout << '.' << std::flush;
			counter++;
			if (!wv.second->visibility)
			{	// cases with only one edge are flagged as HIDDEN_TERMINUS
				if (wv.second->incident_c_edges.size() < 2)
				{	wv.second->visibility = 2;
					continue;
				}
				// if >2 edges, flag HIDDEN_JUNCTION, mark as visible, and do not compress
				if (wv.second->incident_c_edges.size() > 2)
				{	datacheckerrors->add(wv.first->colocated->front()->route,
							     wv.first->colocated->front()->label,
							     "", "", "HIDDEN_JUNCTION", std::to_string(wv.second->incident_c_edges.size()));
					wv.second->visibility = 2;
					continue;
				}
				// if edge clinched_by sets mismatch, set visibility to 1
				// (visible in traveled graph; hidden in collapsed graph)
				// first, the easy check, for whether set sizes mismatch
				if (wv.second->incident_t_edges.front()->segment->clinched_by.size()
				 != wv.second->incident_t_edges.back()->segment->clinched_by.size())
					wv.second->visibility = 1;
				// next, compare clinched_by sets; look for any element in the 1st not in the 2nd
				else for (TravelerList *t : wv.second->incident_t_edges.front()->segment->clinched_by)
					if (wv.second->incident_t_edges.back()->segment->clinched_by.find(t)
					 == wv.second->incident_t_edges.back()->segment->clinched_by.end())
					{	wv.second->visibility = 1;
						break;
					}
				// construct from vertex this time
				if (wv.second->visibility == 1)
					new HGEdge(wv.second, HGEdge::collapsed);
				else if ((wv.second->incident_c_edges.front() == wv.second->incident_t_edges.front()
				       && wv.second->incident_c_edges.back()  == wv.second->incident_t_edges.back())
				      || (wv.second->incident_c_edges.front() == wv.second->incident_t_edges.back()
				       && wv.second->incident_c_edges.back()  == wv.second->incident_t_edges.front()))
					new HGEdge(wv.second, HGEdge::collapsed | HGEdge::traveled);
				else {	new HGEdge(wv.second, HGEdge::collapsed);
					new HGEdge(wv.second, HGEdge::traveled);
					// Final collapsed edges are deleted by ~HGVertex, called by HighwayGraph::clear.
					// Partially collapsed edges created during the compression process are deleted
					// upon detachment from all graphs.
				     }
			}
		}
		std::cout << '!' << std::endl;

		// print summary info
		std::cout << et.et() << "   Simple graph has " << vertices.size() << " vertices, " << simple_edge_count() << " edges." << std::endl;
		std::cout << et.et() << "Collapsed graph has " << num_collapsed_vertices() << " vertices, " << collapsed_edge_count() << " edges." << std::endl;
		std::cout << et.et() << " Traveled graph has " << num_traveled_vertices() << " vertices, " << traveled_edge_count() << " edges." << std::endl;
	} // end ctor
Beispiel #18
0
// generate baggage moving logs on baggage device 
void BaggageProcessor::GenerateBaggageLogsOnMovingPath( Person* _pOwner, PersonID _nBaggage , bool _bBaggageComeFirst, const ElapsedTime& _curTime)
{
	Person* pBaggage = (Person*)findElement( _nBaggage );
	

	if(_pOwner==NULL || pBaggage==NULL )return;

	TerminalMobElementBehavior* spBagTerminalBehavior = (TerminalMobElementBehavior*)pBaggage->getBehavior(MobElementBehavior::TerminalBehavior);
	TerminalMobElementBehavior* spOwnerTerminalBehavior = (TerminalMobElementBehavior*)_pOwner->getBehavior(MobElementBehavior::TerminalBehavior);

	Point baggagePt,ownerPurePt;
	pBaggage->getTerminalPoint(baggagePt);
	_pOwner->getTerminalPureLocation(ownerPurePt);

	if (spBagTerminalBehavior == NULL || spOwnerTerminalBehavior == NULL)
		return;
	int iBaggageStandPos = spBagTerminalBehavior->GetPosIdxOnBaggageProc();
	int iOwnerStandPos = spOwnerTerminalBehavior->GetPosIdxOnBaggageProc();

	ElapsedTime eventTime;
	int nPointCount = m_bagUtil.GetPosCount();	
	if( _bBaggageComeFirst )
	{
		ElapsedTime bagEntryTime = spBagTerminalBehavior->GetEntryBagDeviceTime();
		ElapsedTime paxEntryTime =spOwnerTerminalBehavior->GetEntryBagDeviceTime();
		ElapsedTime circleTime = m_bagUtil.GetCircleTime();

		// iCircleCount means the count that baggage has already moved circle arourd on baggage device when its owner came.
		int iCircleCount = (paxEntryTime - bagEntryTime).asSeconds() / circleTime.asSeconds();

		// write the midst point which bag moved on device circlely.
		eventTime = bagEntryTime;
		for( int i=0; i<iCircleCount; ++i )
		{
			int iBagPos = iBaggageStandPos;
			do 
			{
				pBaggage->setTerminalDestination( m_bagUtil.GetNextPos( iBagPos ) );
				eventTime += m_bagUtil.GetItemAt( iBagPos ).GetCostTime();
				((PaxVisitor*)pBaggage)->writeLogEntry( eventTime, false );
				++iBagPos;
				iBagPos = iBagPos % nPointCount;
			} while( iBagPos != iBaggageStandPos );
		}
		//write the midst points in order to let baggage move to its owner on bag moving path
		int iBagPos = iBaggageStandPos;
		while( eventTime < _curTime )
		{
			eventTime += m_bagUtil.GetItemAt( iBagPos ).GetCostTime();
			if( eventTime < _curTime )
			{
				pBaggage->setTerminalDestination( m_bagUtil.GetNextPos( iBagPos ) );			
				((PaxVisitor*)pBaggage)->writeLogEntry( eventTime, false );
				++iBagPos;
				iBagPos = iBagPos % nPointCount;
			}				
		}
		while( iBagPos != iOwnerStandPos )
		{
			pBaggage->setTerminalDestination( m_bagUtil.GetNextPos( iBagPos ) );
			eventTime += m_bagUtil.GetItemAt( iBagPos ).GetCostTime();
			((PaxVisitor*)pBaggage)->writeLogEntry( eventTime, false );
			++iBagPos;
			iBagPos = iBagPos % nPointCount;
		}
		int nBaggageCount = (int)((Passenger*)_pOwner)->GetBags().size();
		Point pDestination = spOwnerTerminalBehavior->getPureLocation();
		float fDir = (nBaggageCount> (MAX_GROUP-1)) ? (float)0.0 : _pOwner->m_pRotation[nBaggageCount+1];
		pDestination.offsetCoords( baggagePt, (double)fDir, GROUP_OFFSET );
		pBaggage->setTerminalDestination( pDestination);
		eventTime += pBaggage->moveTime();
		((PaxVisitor*)pBaggage)->writeLogEntry( eventTime, false );
	}
	else// pax come first , then baggage move to the point which its owner stand .
	{
		// write the midst points in order to let baggage move to its owner on bag moving path
		eventTime = _curTime;
		while( iBaggageStandPos != iOwnerStandPos )
		{
			pBaggage->setTerminalDestination( m_bagUtil.GetNextPos( iBaggageStandPos ) );
			eventTime += m_bagUtil.GetItemAt( iBaggageStandPos ).GetCostTime();
			((PaxVisitor*)pBaggage)->writeLogEntry( eventTime, false );
			++iBaggageStandPos;
			iBaggageStandPos = iBaggageStandPos % nPointCount;
		}
		int nBaggageCount = (int)((Passenger*)_pOwner)->GetBags().size();
		Point pDestination = ownerPurePt;
		float fDir = (nBaggageCount> (MAX_GROUP-1)) ? (float)0.0 : _pOwner->m_pRotation[nBaggageCount+1];
		pDestination.offsetCoords( baggagePt, (double)fDir, GROUP_OFFSET );
		pBaggage->setTerminalDestination( pDestination);
		eventTime += pBaggage->moveTime();
		((PaxVisitor*)pBaggage)->writeLogEntry( eventTime, false );
	}

//	TRACE("\nEnd BagLog Write:   %s, %s\n",_curTime.printTime(), eventTime.printTime() );
	
	((PaxTerminalBehavior*)spOwnerTerminalBehavior)->SetMaxTime(eventTime);
	// clear 
	m_vBaggages.erase( std::find( m_vBaggages.begin(), m_vBaggages.end(), _nBaggage ) );


	// write log for baggage device
 	{
 		ProcEventStruct event;
 		event.time = (long)eventTime;
 		event.type = (unsigned char) BagLeaveBaggageProc;
 		event.element =  pBaggage->getID();
 		event.lLoad = -1;
 		event.lReason = m_lReason;
 		logEntry.addEvent (event);
 	}

//	std::vector<Person*> vBaggages;
	((Passenger*)_pOwner)->GetBags().push_back(pBaggage);
	m_vectBagStillOnReclaim.push_back( BagStillOnReclaim(_nBaggage, eventTime, 1)/*pBaggage->GetActiveGroupSize()) */);
	// owner to pick bag up
	if (_pOwner->getLogEntry().getBagCount()== (int)((Passenger*)_pOwner)->GetBags().size())
	{
		m_vOwners.erase( std::find( m_vOwners.begin(), m_vOwners.end(), _pOwner->getID() ) );
		spOwnerTerminalBehavior->pickupBag( ((Passenger*)_pOwner)->GetBags(), ((PaxTerminalBehavior*)spOwnerTerminalBehavior)->GetMaxTime() );	
		((Passenger*)_pOwner)->GetBags().clear();

//		m_vectBagStillOnReclaim.push_back( BagStillOnReclaim(_nBaggage, ((Passenger*)_pOwner)->GetMaxTime(), pBaggage->GetActiveGroupSize()) );
		WakeupWaitingBaggageInPrevProc(((PaxTerminalBehavior*)spOwnerTerminalBehavior)->GetMaxTime());


		// if user defined dependent processor in behavior,
		// need wake up mobile elements waiting in dependent processors.
		WakeupWaitingPaxInDependentProc( ((PaxTerminalBehavior*)spOwnerTerminalBehavior)->GetMaxTime() );
	}
}
void CDetailStandUtilizationPercentageChartResult::GenerateResult(std::vector<CStandOperationReportData*>& vResult,CParameters *pParameter)
{
	ASSERT(pParameter);

	std::vector<long> vSchedStandTimeOccupany;
	std::vector<long> vActualStandTimeOccupany;

	CalculateStandOccupancyTime(true, vResult, vSchedStandTimeOccupany);
	CalculateStandOccupancyTime(false, vResult, vActualStandTimeOccupany);

	for (int nScheduleUnuse = 0; nScheduleUnuse < m_nUnuseScheduleStandCount; nScheduleUnuse++)
	{
		vSchedStandTimeOccupany.push_back(0l);
	}

	for (int nActualUnuse = 0; nActualUnuse < m_nUnuseActualStandCount; nActualUnuse++)
	{
		vActualStandTimeOccupany.push_back(0l);
	}

	std::sort(vSchedStandTimeOccupany.begin(), vSchedStandTimeOccupany.end());
	std::sort(vActualStandTimeOccupany.begin(), vActualStandTimeOccupany.end());

	std::reverse(vSchedStandTimeOccupany.begin(), vSchedStandTimeOccupany.end());
	std::reverse(vActualStandTimeOccupany.begin(), vActualStandTimeOccupany.end());

	long lSchedStandTimeOccupany = 0l;
	if (!vSchedStandTimeOccupany.empty())
	{
		lSchedStandTimeOccupany = vSchedStandTimeOccupany.front();
	}

	long lActualStandTimeOccupany = 0l;
	if (!vActualStandTimeOccupany.empty())
	{
		lActualStandTimeOccupany = vActualStandTimeOccupany.front();
	}

	int nIntervalSize = 0;
	ElapsedTime lMaxOccupancyTime  = ElapsedTime(max(lSchedStandTimeOccupany, lActualStandTimeOccupany));
	int nDuration = pParameter->getEndTime().asSeconds() - pParameter->getStartTime().asSeconds();
	nIntervalSize = int((double)lMaxOccupancyTime.asSeconds() / (double)(nDuration)*100)/10 ;

    if(lMaxOccupancyTime.asSeconds()%(nDuration*100*10) != 0)
        nIntervalSize += 1;

	if (nIntervalSize ==0)
		nIntervalSize = 1;

	CString strTimeInt(_T(""));
	for (int i = 0 ; i < 10 ;i++)
	{
		strTimeInt.Format(_T("%d"),(i+1)*10);
		m_vXAxisTitle.push_back(strTimeInt);
	}

	StandOccupancyData SchedItem;
	SchedItem.m_sName = _T("Schedule");
	StandOccupancyData ActualItem;
	ActualItem.m_sName = _T("Actual");	

	size_t nSchedSize = vSchedStandTimeOccupany.size();
	size_t nActualSize = vActualStandTimeOccupany.size();

	int nStart = 0;
	int nEnd = 0;

	for (int i =0; i< nIntervalSize; i++)
	{
		nStart = i *10;
		nEnd = (i+1) *10;

		int nSchedCount = 0;
		for (size_t j = 0; j < nSchedSize; j++)
		{
			int nPercent = ((double)vSchedStandTimeOccupany.at(j))/nDuration*100;

			if( nStart <= nPercent && nPercent < nEnd)
				nSchedCount++;
		}
		SchedItem.m_vStandData.push_back(nSchedCount);

		int nActualCount = 0;
		for (size_t j = 0; j < nActualSize; j++)
		{
			int nPercent = ((double)vActualStandTimeOccupany.at(j))/nDuration*100;

			if( nStart <= nPercent && nPercent < nEnd)
				nActualCount++;						
		}
		ActualItem.m_vStandData.push_back(nActualCount);
	}

	for(int i = nIntervalSize; i < 10; i++)
	{
		SchedItem.m_vStandData.push_back(0);	
		ActualItem.m_vStandData.push_back(0);
	}

	m_vOccupancyData.push_back(SchedItem);
	m_vOccupancyData.push_back(ActualItem);
}
void CDetailDelayResult::GenerateResult(vector<CAirsideFlightDelayReport::FltTypeDelayItem>& fltTypeDelayData,CParameters *pParameter)
{
	ASSERT(pParameter != NULL);

	ClearAllData();

	ElapsedTime estMinDelayTime = pParameter->getStartTime();
	ElapsedTime estMaxDelayTime = pParameter->getEndTime();

	long lMinDelayTime = estMinDelayTime.asSeconds();
	long lMaxDelayTime = estMaxDelayTime.asSeconds();

	//delay time error
	if (lMaxDelayTime < lMinDelayTime)
	{
		return;
	}

	m_estStartTime = estMinDelayTime;
	m_estEndTime   = estMaxDelayTime;

	long lUserIntervalTime = pParameter->getInterval();
	ElapsedTime estUserIntervalTime = ElapsedTime(lUserIntervalTime);

	long lDelayTimeSegmentCount = 0;             //the count of the delayTime segment
	if (0 < lUserIntervalTime)
	{
        estMinDelayTime = ElapsedTime(lMinDelayTime);
        lDelayTimeSegmentCount = (lMaxDelayTime - lMinDelayTime) / (lUserIntervalTime);

        if((lMaxDelayTime - lMinDelayTime) % (lUserIntervalTime) != 0)
            lDelayTimeSegmentCount += 1;
	}
	else
	{
		lDelayTimeSegmentCount= ClacTimeRange(estMaxDelayTime, estMinDelayTime, estUserIntervalTime);
	}

	bool bSetTimeRange = false;
	for (int j=0; j<(int)pParameter->getFlightConstraintCount(); j++)
	{
		FlightConstraint flightConstraint = pParameter->getFlightConstraint(j);

		CDetailFlightDelayData *pDetailFlightDelayData = new CDetailFlightDelayData;
		pDetailFlightDelayData->m_fltCons = flightConstraint;

		for (long i=0; i<lDelayTimeSegmentCount; i++)
		{
			ElapsedTime estTempMinDelayTime = estMinDelayTime + ElapsedTime(estUserIntervalTime.asSeconds()*i);
			ElapsedTime estTempMaxDelayTime = estMinDelayTime + ElapsedTime(estUserIntervalTime.asSeconds()*(i + 1));

            if(estTempMaxDelayTime > estMaxDelayTime)
                estTempMaxDelayTime = estMaxDelayTime;

			if (!bSetTimeRange)
			{
				CString strTimeRange = _T("");
				//strTimeRange.Format(_T("%s-%s"), estTempMinDelayTime.printTime(), estTempMaxDelayTime.printTime());
				strTimeRange.Format(_T("%02d:%02d-%02d:%02d"), estTempMinDelayTime.asHours(), estTempMinDelayTime.GetMinute(), estTempMaxDelayTime.asHours(), estTempMaxDelayTime.GetMinute());
				m_vTimeRange.push_back(strTimeRange);
			}			

			pDetailFlightDelayData->m_vData.push_back(GetFlightCountInIntervalTime(flightConstraint, estTempMinDelayTime, estTempMaxDelayTime, fltTypeDelayData)/100);  //second
		}

		bSetTimeRange = true;

		m_vFlightData.push_back(pDetailFlightDelayData);
	}
}
bool EnrouteQueueCapacityInSim::PushBackExitEnrouteQCapacity( const ElapsedTime& eTime, AirsideFlightInSim* pFlight )
{
	TaxiRouteInSim* pTaxiRoute = pFlight->GetAndAssignOutBoundRoute();
	if (pTaxiRoute == NULL)
		return true;

	
	pTaxiRoute->InitRoute(pFlight,eTime);
	FlightHoldListInTaxiRoute& taxiRouteList = pTaxiRoute->GetHoldList();

	CString strTime = eTime.printTime();

	for (int i = 0; i < taxiRouteList.GetCount(); i++)
	{
		const HoldInTaxiRoute& theHold = taxiRouteList.ItemAt(i);
		if (theHold.m_pNode->GetNodeInput().GetRunwayIntersectItemList().size() == 0)
			continue;
		
		RunwayIntersectItem* pRwItem = theHold.m_pNode->GetNodeInput().GetRunwayIntersectItemList()[0];
		int nRwID = pRwItem->GetObjectID();
		RunwayInSim* pRunway = pFlight->GetAirTrafficController()->GetAirsideResourceManager()->GetAirportResource()->getRunwayResource()->GetRunwayByID(nRwID);
		HoldPositionInSim* pCrossHold = pRunway->GetHoldPosition( theHold.m_nHoldId );
		if (pCrossHold == NULL)
			continue;
			
		size_t nCount = m_pEnrouteQueueCapacity->GetElementCount();

		for (size_t i = 0; i < nCount; i++)
		{
			AirsideEnrouteQCapacityTimeRange* pQCapacityTimeRange = m_pEnrouteQueueCapacity->GetItem(i);

			TimeRange* pTimeRange = pQCapacityTimeRange->getTimeRange();
			if (eTime < pTimeRange->GetStartTime() || eTime > pTimeRange->GetEndTime())
				continue;

			size_t iEnrouteCount = pQCapacityTimeRange->getEnrouteQCapacity()->GetElementCount();

			for (size_t j = 0; j < iEnrouteCount; j++)
			{
				AirsideEnrouteQCapacityItem* pCapacityItem = pQCapacityTimeRange->getEnrouteQCapacity()->GetItem(j);

				int nExitID = pCapacityItem->getTakeOffPosition()->GetID();
				if(nExitID < 0)
					continue;

				LogicRunwayInSim* pRwyPort = m_pAirportres->getRunwayResource()->GetLogicRunway(pCapacityItem->getTakeOffPosition()->GetRunwayID(),pCapacityItem->getTakeOffPosition()->GetRunwayMark());
				if(!pRwyPort)
					continue;
				RunwayExitInSim* pRwyExit = pRwyPort->GetExitByID(nExitID); 
				if(!pRwyExit)
					continue;

				HoldPositionInSim* pHold = pRwyExit->getHoldPosition();
				if(!pHold)
					continue;

				if (pCrossHold != pHold)
					continue;
				
				if(!pHold->IsFlightInQueue(pFlight))
				{
					double dQueueLength = pHold->GetTakeoffQueueLength();
					double dMaxQueue = pCapacityItem->getMaxLength() * 100;
					if (dQueueLength > dMaxQueue )
					{
						pHold->AddEnrouteWaitList(pFlight);
						return false;
					}
				}
			}
		}
	}
	
	
	return true;
}
void AirsideRunwayUtilizationReport::CDetailRunwayUtilizationChart::Draw3DChart( CARC3DChart& chartWnd, CParameters *pParameter )
{
	if(pParameter == NULL)
		return;

	ElapsedTime eTimeInterval = ElapsedTime(pParameter->getInterval());//interval is 10 seconds

	//min, max occupancy time
	ElapsedTime eStartTime = pParameter->getStartTime();
	ElapsedTime eEndTime = pParameter->getEndTime();



	CString strLabel = _T("");
	C2DChartData c2dGraphData;

	c2dGraphData.m_strChartTitle = _T(" Runway Utilization Report");
	c2dGraphData.m_strYtitle = _T("Time(min)");
	c2dGraphData.m_strXtitle = _T("Time of day");
	if(m_bParameterIsDefault)
		c2dGraphData.m_strXtitle += _T("(Based on partial data only)");


	//get all legends
	std::vector<CString> vLegends; 
	vLegends.push_back(_T("Occupied"));
	vLegends.push_back(_T("Idle"));
	c2dGraphData.m_vrLegend = vLegends;


	c2dGraphData.m_vr2DChartData.resize(vLegends.size()) ;


	int nActiveRunwayCount = GetActiveRunwayCount();
	ElapsedTime nTotalIntTime = ElapsedTime( nActiveRunwayCount * eTimeInterval.asSeconds() * 1L);
	//x tick, runway
	for (;eStartTime < eEndTime + eTimeInterval; eStartTime += eTimeInterval)
	{

		CString strTick;
		strTick.Format(_T("%s - %s"),eStartTime.PrintDateTime(),(eStartTime + eTimeInterval).PrintDateTime());
		c2dGraphData.m_vrXTickTitle.push_back(strTick);

		//get the chart data
		ElapsedTime eTimeOccupied = ElapsedTime(0L);
		GetOccupyTimeBetween(eStartTime,eStartTime + eTimeInterval, eTimeOccupied);

		c2dGraphData.m_vr2DChartData[0].push_back(eTimeOccupied.asMinutes());
		
		c2dGraphData.m_vr2DChartData[1].push_back((nTotalIntTime  - eTimeOccupied).asMinutes());

	}

	//set footer
	CString strFooter(_T(""));
	strFooter.Format(_T("%s %s,%s "), c2dGraphData.m_strChartTitle,
		pParameter->getStartTime().printTime(), 
		pParameter->getEndTime().printTime());


	bool bCommaFlag = true;
	CAirsideRunwayUtilizationReportParam* pParam = (CAirsideRunwayUtilizationReportParam*)pParameter;
	//for (int i=0; i<(int)pParam->getFlightConstraintCount(); i++)
	//{
	//	FlightConstraint fltCons = pParam->getFlightConstraint(i);

	//	CString strFlight(_T(""));
	//	fltCons.screenPrint(strFlight.GetBuffer(1024));

	//	if (bCommaFlag)
	//	{
	//		bCommaFlag = false;
	//		strFooter.AppendFormat("%s", strFlight);
	//	}
	//	else
	//	{
	//		strFooter.AppendFormat(",%s", strFlight);
	//	}
	//}
	c2dGraphData.m_strFooter = strFooter;


	//std::vector<CString> vLegends;
	////get the legend
	//int nLegendCount = m_vRunwayOperationDetail->at(0)->m_vWakeVortexDetailValue.size();
	//for (int nLegend = 0; nLegend < nLegendCount; ++nLegend)
	//{
	//	CString strLegend;
	//	strLegend.Format(_T("%s-%s"),
	//		m_vRunwayOperationDetail->at(0)->m_vWakeVortexDetailValue[nLegend].m_strClassLeadName,
	//		m_vRunwayOperationDetail->at(0)->m_vWakeVortexDetailValue[nLegend].m_strClassTrailName);
	//	vLegends.push_back(strLegend);

	//}


	chartWnd.DrawChart(c2dGraphData);
}
void AirsideRunwayUtilizationReport::CDetailRunwayOccupancyChart::Draw3DChart( CARC3DChart& chartWnd, CParameters *pParameter )
{
	ElapsedTime eTimeInterval(10L);//interval is 10 seconds

	//min, max occupancy time
	ElapsedTime eMinTime;
	ElapsedTime eMaxTime;

	GetMinMaxOccupancyTime(eMinTime,eMaxTime);
	//
	eMinTime = ElapsedTime((eMinTime.asSeconds() - eMinTime.asSeconds()%eTimeInterval.asSeconds() )* 1L);


	CString strLabel = _T("");
	C2DChartData c2dGraphData;

	c2dGraphData.m_strChartTitle = _T(" Runway Occupancy Report");


	c2dGraphData.m_strYtitle = _T("Number of Aircrafts");
	c2dGraphData.m_strXtitle = _T("Occupancy(seconds)");

	//get all legends
	std::vector<CString> vLegends; 
	int nRunwayOccCount = (int)m_vRunwayOccu.size();
	for (int nRunwayOcc = 0; nRunwayOcc < nRunwayOccCount; ++nRunwayOcc)
	{
		 CDetailRunwayOccupancyItem * pItem = m_vRunwayOccu[nRunwayOcc];
		 if(pItem == NULL)
			 continue;
		 CString strMark = pItem->runwayMark.m_strMarkName;
		 vLegends.push_back(_T("Total Runway ") + strMark);
		 vLegends.push_back(_T("Landings Runway ") + strMark);
		 vLegends.push_back(_T("TakeOffs Runway ") + strMark);

	}
	c2dGraphData.m_vrLegend = vLegends;


	c2dGraphData.m_vr2DChartData.resize(vLegends.size()) ;

	//x tick, runway
	for (; eMinTime < eMaxTime ; eMinTime += eTimeInterval)
	{

		CString strTick;
		strTick.Format(_T("%d - %d"),eMinTime.asSeconds(),(eMinTime + eTimeInterval).asSeconds());
		c2dGraphData.m_vrXTickTitle.push_back(strTick);

		//get the chart data
		int nLegend = 0;
		int nRunwayCount = (int)m_vRunwayOccu.size();
		for (int nRunway = 0; nRunway < nRunwayCount; ++nRunway)
		{
			CDetailRunwayOccupancyItem * pItem = m_vRunwayOccu[nRunway];
			if(pItem == NULL)
				continue;
			int nLandingCount = 0;
			int nTakeOffCount = 0;
			pItem->GetOperationCount(eMinTime,eMinTime + eTimeInterval,nLandingCount,nTakeOffCount);
			c2dGraphData.m_vr2DChartData[nLegend].push_back(nLandingCount + nTakeOffCount);
			nLegend += 1;

			c2dGraphData.m_vr2DChartData[nLegend].push_back(nLandingCount);			
			nLegend += 1;

			c2dGraphData.m_vr2DChartData[nLegend].push_back(nTakeOffCount);
			nLegend += 1;
		}
	}

	//set footer
	CString strFooter(_T(""));
	strFooter.Format(_T("%s %s,%s "), c2dGraphData.m_strChartTitle,
		pParameter->getStartTime().printTime(), 
		pParameter->getEndTime().printTime());


	bool bCommaFlag = true;
	CAirsideRunwayUtilizationReportParam* pParam = (CAirsideRunwayUtilizationReportParam*)pParameter;
	//for (int i=0; i<(int)pParam->getFlightConstraintCount(); i++)
	//{
	//	FlightConstraint fltCons = pParam->getFlightConstraint(i);

	//	CString strFlight(_T(""));
	//	fltCons.screenPrint(strFlight.GetBuffer(1024));

	//	if (bCommaFlag)
	//	{
	//		bCommaFlag = false;
	//		strFooter.AppendFormat("%s", strFlight);
	//	}
	//	else
	//	{
	//		strFooter.AppendFormat(",%s", strFlight);
	//	}
	//}
	c2dGraphData.m_strFooter = strFooter;

	chartWnd.DrawChart(c2dGraphData);



}
void FltConflictChartResultByLocationAndTimeOfDay::Draw3DChart(CARC3DChart& chartWnd, CParameters *pParameter)
{
	if (m_pData == NULL || pParameter == NULL)
		return;

	CString strLabel = _T("");
	C2DChartData c2dGraphData;

	c2dGraphData.m_strChartTitle = _T(" Conflicts by location and time of day ");
	c2dGraphData.m_strYtitle = _T("Number of conflicts");
	c2dGraphData.m_strXtitle = _T("Time of day");

	AirsideFlightConflictPara* pConflictPara = (AirsideFlightConflictPara*)pParameter;

	ElapsedTime tTimeInterval = ElapsedTime(pConflictPara->getInterval());
	ElapsedTime tStartTime = pConflictPara->getStartTime();
	ElapsedTime tEndTime = pConflictPara->getEndTime();

	//calculate interval count
	int nIntCount = (tEndTime.asSeconds() - tStartTime.asSeconds())/pConflictPara->getInterval();
	if ((tEndTime.asSeconds() - tStartTime.asSeconds())%pConflictPara->getInterval() > 0)
		nIntCount++;

	//statistic count
	std::map< int,std::vector<double> > vACLocationConflicts;	
	std::map< int,std::vector<double> > vGSELocationConflicts;
	m_pData->SortItemsByLocationType();

	std::vector<double> vACConflictCount; 
	std::vector<double> vGSEConflictCount;
	int nACLocation = -1;
	int nGSELocation = -1;

	vACConflictCount.clear();
	vACConflictCount.resize(nIntCount,0);
	vGSEConflictCount.clear();
	vGSEConflictCount.resize(nIntCount,0);

	int nItemCount = m_pData->m_vDataItemList.size();
	for (int i = 0; i < nItemCount; i++)
	{
		FlightConflictReportData::ConflictDataItem* pItem = m_pData->m_vDataItemList.at(i);
		int nConfType = pItem->m_nConflictType;
		if (nConfType == 0 &&(pItem->m_nLocationType > nACLocation || pItem->m_nLocationType < nACLocation))	//a new ac-ac operation type
		{
			//record conflict count
			if (nACLocation >=0)
				vACLocationConflicts.insert(std::map< int,std::vector<double> > ::value_type(nACLocation,vACConflictCount));

			//clear for new statistic
			vACConflictCount.clear();
			vACConflictCount.resize(nIntCount,0);
			nACLocation = pItem->m_nLocationType;
		}

		if (nConfType == 1 &&(pItem->m_nLocationType > nGSELocation || pItem->m_nLocationType < nGSELocation))	//a new ac-gse operation type
		{
			if (nGSELocation >=0 )
				vGSELocationConflicts.insert(std::map< int,std::vector<double> > ::value_type(nGSELocation,vGSEConflictCount));

			vGSEConflictCount.clear();
			vGSEConflictCount.resize(nIntCount,0);
			nGSELocation = pItem->m_nLocationType;	
		}

		int nIntervalIdx = pItem->GetInIntervalIndex(pParameter);
		vector<double>::pointer ptr;
		if (nConfType ==0)
		{
			ptr = &vACConflictCount[nIntervalIdx];
			(*ptr) +=1;
		}
		else
		{
			ptr = &vGSEConflictCount[nIntervalIdx];
			(*ptr) +=1;
		}
	}

	if (nACLocation >=0)			//need add the last statistic data
		vACLocationConflicts.insert(std::map< int,std::vector<double> > ::value_type(nACLocation,vACConflictCount));
	if (nGSELocation >=0)
		vGSELocationConflicts.insert(std::map< int,std::vector<double> > ::value_type(nGSELocation,vGSEConflictCount));



	//draw
	ElapsedTime tRangeStart = tStartTime;

	for(int i = 0; i < nIntCount; i++)
	{		
		CString strTimeRange;
		ElapsedTime tRangeEnd = tRangeStart + ElapsedTime(pConflictPara->getInterval()) - 1L;
		if (tRangeEnd > pConflictPara->getEndTime())
			tRangeEnd = pConflictPara->getEndTime();

		strTimeRange.Format("%s -%s", tRangeStart.printTime(),tRangeEnd.printTime());
		c2dGraphData.m_vrXTickTitle.push_back(strTimeRange);
		tRangeStart = tRangeEnd + 1L;
	}
	
	//legend
	std::vector<CString> vLegend;
	for (int i = 0; i <  FlightConflict::LOCATION_FIELD; i++)
	{
		CString strName =  FlightConflict::LOCATIONTYPE[i];
		CString strLegend;
		std::vector<double> vConflicts;

		vConflicts = vACLocationConflicts[i];
		if (!vConflicts.empty())
		{
			strLegend.Format("%s AC-AC Conflicts",strName);
			vLegend.push_back(strLegend);	
			c2dGraphData.m_vr2DChartData.push_back(vConflicts);
		}

		vConflicts = vGSELocationConflicts[i];
		if (!vConflicts.empty())
		{
			strLegend.Format("%s AC-GSE Conflicts", strName);
			vLegend.push_back(strLegend);		
			c2dGraphData.m_vr2DChartData.push_back(vConflicts);	
		}
	
	}
	c2dGraphData.m_vrLegend = vLegend;

	chartWnd.DrawChart(c2dGraphData);

}
CPoint2008 HeadingAirRouteSegInSim::GetVectorAvailablePosition(ElapsedTime tEnter,ElapsedTime tExit, double dSped1, double dSped2, AirsideResource* pNextRes,AirsideFlightInSim* pFlight)
{
	CPoint2008 FirstPoint = m_pFirstIntersection->getInputPoint()->GetPosition();
	CPoint2008 SecondPoint = m_pSecondIntersection->getInputPoint()->GetPosition();
	ElapsedTime tTime = ElapsedTime(FirstPoint.distance(SecondPoint)/dSped1);

	if (tTime >= tExit - tEnter )
	{
		return SecondPoint;
	}

	double dDist = (dSped1+dSped2) * (tExit.asSeconds() - tEnter.asSeconds())/2;

	if (m_HeadingType == Direct)
	{
		CLine2008 routeline(FirstPoint, m_WPExtentPoint);
		CPoint2008 projectPoint = routeline.getProjectPoint(SecondPoint);
		double dDistToSecond = projectPoint.distance(SecondPoint);
		double dDistToFirst = projectPoint.distance(FirstPoint);

		double dLength = 0;
	//	if (projectPoint.distance(m_WPExtentPoint) < FirstPoint.distance(m_WPExtentPoint)) // projection point in the line segment
		{
			//double dValue = dDist - dDistToFirst;
			//dLength = ( dValue * dValue + dDistToSecond* dDistToSecond)/(2.0 * dValue);

			//c*c = a*a + b*b - 2*a*b*cosa
			double dDistS = FirstPoint.distance(SecondPoint);
			double dDistA = dDist;
			double dDistance = dDistA*dDistA - dDistS*dDistS;
			double dCosA = dDistToFirst / dDistS;
			double dDividend =  2*(dDistA - dDistS*dCosA);
			if (dDividend  == 0.0)
			{
				dLength = dDistS;
			}
			else
			{
				dLength = dDistance / dDividend;
			}
		}
// 		else
// 		{
// 			double dValue = dDist + dDistToFirst;
// 			dLength = (dValue * dValue + dDistToSecond* dDistToSecond)/(2.0*dValue);
// 		}

		return routeline.getInlinePoint(dLength/routeline.GetLineLength());
	}

	//Aligned
	CPoint2008 projectPoint = GetProjectionPosition(FirstPoint,pNextRes,pFlight);
	CLine2008 projectLine = GetAlignProjectLine((AirRouteSegInSim*)pNextRes,pFlight);

	double dDistToProject = FirstPoint.distance(projectPoint);		// the vertical distance from first waypoint to next segment
	double dDistProjectToSecondPoint = projectPoint.distance(SecondPoint);		// the distance from project point of first waypoint on the line of next segment to the second waypoint

	double dMinDist = dDistToProject + dDistProjectToSecondPoint;
	double dRate = (dDist- dMinDist)/2.0;

	if (dRate < 0)
	{
		dRate = 0;
		dDist = dMinDist;
	}
	
	int nIn = projectLine.contains(projectPoint);
	if (nIn >0 || ( nIn <=0 && projectPoint.distance(projectLine.GetPoint1()) > projectPoint.distance(projectLine.GetPoint2())))
	{
		dRate += dDistProjectToSecondPoint;
	}

	CLine2008 routeLine(FirstPoint, m_WPExtentPoint);
	CPoint2008 PropPoint = routeLine.getInlinePoint(dRate/routeLine.GetLineLength());
	projectPoint = projectLine.getProjectPoint(PropPoint);

	return PropPoint;
}
int FlightInHoldEvent::Process()
{
	if (m_pCFlight->GetMode() == OnTerminate)
		return 0;


	//ASSERT(m_pCFlight->GetUID() != 34);
	double totalLength = m_pHold->GetPath().GetTotalLength();
	double dist = 0.0;
	if (m_pCFlight->GetResource() == m_pHold)	//already enter hold
		dist = m_pCFlight->GetDistInResource() + double(time - m_pCFlight->GetTime())* m_pCFlight->GetSpeed();

	CPoint2008 pos = m_pHold->GetDistancePoint(((int)dist)% ((int)totalLength));

	if (pos == m_pCFlight->GetPosition())
		pos.setZ(m_pCFlight->GetCurState().m_dAlt);
	else
	{

		//flight down to next height level, the descend angle must no more than 3 degree
		double dAlt =  m_pHold->getAvailableHeight(m_pCFlight);
		if (dAlt != m_pCFlight->GetCurState().m_dAlt)
		{
			double dStep = m_pHold->getAvailableHeight(m_pCFlight) - m_pCFlight->GetCurState().m_dAlt;
			double dStepHeight = (dist-m_pCFlight->GetDistInResource())*tan(ARCMath::DegreesToRadians(3.0));
			if (dStep >0)
				dAlt = m_pCFlight->GetCurState().m_dAlt + (dStepHeight<dStep?dStepHeight:dStep);
			else 
				dAlt = m_pCFlight->GetCurState().m_dAlt - (dStepHeight<-dStep?dStepHeight:-dStep);				
		}
		pos.setZ(dAlt);
	}

	ClearanceItem nextItem(m_pHold,OnWaitInHold,((int)dist)% ((int)totalLength));
	nextItem.SetPosition(pos);
	nextItem.SetTime(time);
	nextItem.SetSpeed(m_pCFlight->GetSpeed());
	nextItem.SetAltitude(pos.getZ());

	m_pCFlight->PerformClearanceItem(nextItem);

	if (m_pHold != NULL)		//the flight max holding time cannot exceed 24h
	{
		AirWayPointInSim* pWaypoint = m_pHold->GetWaypointInSim();
		ElapsedTime tEnter = m_pHold->GetOccupyInstance(m_pCFlight).GetEnterTime();
		if (tEnter + MAXHOLDINGTIME <= time)
		{

			CString strWarn;
			strWarn.Format("The Flight's holding time in %s too long",m_pHold->PrintResource()) ;
			CString strError = _T("AIRCRAFT TERMINATE");
			AirsideSimErrorShown::SimWarning(m_pCFlight,strWarn,strError);

			ClearanceItem newItem(NULL, OnTerminate,0);
			nextItem.SetTime(time);
			nextItem.SetSpeed(0);

			m_pCFlight->PerformClearanceItem(newItem);
			return 0;
		}

		ElapsedTime tMinLap = ElapsedTime((0.33*totalLength)/m_pCFlight->GetSpeed());
		if (m_tHoldTime >= 0L && (m_tHoldTime - tEnter) < tMinLap)
		{
			m_tHoldTime = tEnter + tMinLap;
		}
	}


	if(m_pHold->GetHeadFlightCount(m_pCFlight)>0)	//the flight is not at the lowest level in hold
	{
		double stepLength = totalLength/8.0;
		ElapsedTime nextTime = time + ElapsedTime(stepLength/m_pCFlight->GetSpeed());
		if (m_tHoldTime > 0L && nextTime > m_tHoldTime )
			m_tHoldTime = (nextTime + 10L);

		//ASSERT(m_pCFlight->GetUID() != 31);
		FlightInHoldEvent* pNextEvent = new FlightInHoldEvent(m_pCFlight,m_pHold, m_tHoldTime);
		pNextEvent->setTime(nextTime);
		pNextEvent->addEvent();

		return 0;
	}

	CPoint2008 WPpos = m_pHold->GetDistancePoint(0.0);
//	ElapsedTime dTime = ElapsedTime(pos.distance(WPpos)/m_pCFlight->GetSpeed());

	double dMoveDist = totalLength - m_pCFlight->GetDistInResource();
	ElapsedTime dTime = ElapsedTime(dMoveDist/m_pCFlight->GetSpeed());

	if ((m_tHoldTime >0L && (time+dTime) >= m_tHoldTime))
	{
		ClearanceItem newItem((AirsideResource*)m_pHold->GetWaypointInSim() ,OnWaitInHold, 0.0);
		WPpos.setZ(pos.getZ());
		newItem.SetPosition(WPpos);
		newItem.SetTime(time+dTime);
		newItem.SetSpeed(m_pCFlight->GetSpeed());
		newItem.SetAltitude(pos.getZ());
		Clearance nextClearance;
		ClearanceItem newItemCopy = newItem;
		bool bExit = m_pHold->GetAirRouteNetwork()->IsFlightNeedHolding(m_pCFlight,m_pHold,newItemCopy,nextClearance);
		if (bExit)
		{
			if (m_pCFlight->GetCurDelayLog()->mConflictLocation == FlightConflict::RUNWAY )
			{
				ElapsedTime tAvailableTime = newItem.GetTime();
				ElapsedTime tDelay = m_pCFlight->GetCurDelayLog()->mDelayTime;
				ElapsedTime tStartTime = tAvailableTime - tDelay;
				ResourceDesc resDesc;
				m_pCFlight->GetLandingRunway()->getDesc(resDesc);
				AirsideFlightRunwayDelayLog* pLog = new AirsideFlightRunwayDelayLog(resDesc, tStartTime.asSeconds(), OnLanding, tAvailableTime.asSeconds(), tDelay.asSeconds(), FlightRunwayDelay::LandingRoll);
				pLog->sReasonDetail = "Wave crossings";
				m_pCFlight->LogEventItem(pLog);
			}

			m_pCFlight->EndDelay(newItem);			//end holding delay
			if (nextClearance.GetItemCount())
			{
				ClearanceItem& firstItem = nextClearance.ItemAt(0);
				ElapsedTime startTime = time;
				ElapsedTime endTime = firstItem.GetTime();
				ElapsedTime detaTime = endTime - startTime;
				CString strStartTime = startTime.printTime();
				CString strEndTime = endTime.printTime();
				if (detaTime > 0l && firstItem.GetPosition() == newItem.GetPosition())
				{
					double dHeight = 0.0;
					if (firstItem.GetTime() == newItem.GetTime())
					{
						double stepLength = totalLength/8.0;
						ElapsedTime nextTime = ElapsedTime(stepLength/m_pCFlight->GetSpeed());
						startTime += nextTime;
						CPoint2008 pt;
						for (; startTime < endTime; startTime += nextTime)
						{
							stepIt(startTime,pt);
						}
						stepIt(endTime,pt);
						dHeight = pt.getZ();
					}
					else
					{
						double stepLength = totalLength/8.0;
						ElapsedTime nextTime = ElapsedTime(stepLength/m_pCFlight->GetSpeed());
						startTime += nextTime;
						CPoint2008 pt;
						ElapsedTime tPreTime;
						ElapsedTime tNextTime;
						for (; startTime < endTime; startTime += nextTime)
						{
							double dRouteDist = m_pCFlight->GetDistInResource();
							CPoint2008 flightPos = m_pHold->GetDistancePoint(((int)dRouteDist)% ((int)totalLength));
							ElapsedTime dMoveTime = ElapsedTime(flightPos.distance(WPpos)/m_pCFlight->GetSpeed());
							ElapsedTime tSumTime = startTime + dMoveTime;
							if (tSumTime >= endTime)
							{
								tNextTime = tSumTime - endTime;
								break;
							}
							else
							{
								tPreTime = endTime - tSumTime;
							}
							stepIt(startTime,pt);
						}
						if (tPreTime.getPrecisely() || tNextTime.getPrecisely())
						{
							double dRate = tPreTime / (tPreTime + tNextTime);
							ElapsedTime tMoveTime = nextTime * dRate;
							stepIt(startTime + tMoveTime - nextTime,pt);
						}
						
						//step end item
						{
							CPoint2008 WPpos = m_pHold->GetDistancePoint(0.0);
							ClearanceItem newItem((AirsideResource*)m_pHold->GetWaypointInSim() ,OnWaitInHold, 0.0);
							//WPpos.setZ(pt.getZ());
							double dAlt =  m_pHold->getAvailableHeight(m_pCFlight);
							if (dAlt != m_pCFlight->GetCurState().m_dAlt)
							{
								double dStep = m_pHold->getAvailableHeight(m_pCFlight) - m_pCFlight->GetCurState().m_dAlt;
								double dStepHeight = (dist-m_pCFlight->GetDistInResource())*tan(ARCMath::DegreesToRadians(3.0));
								if (dStep >0)
									dAlt = m_pCFlight->GetCurState().m_dAlt + (dStepHeight<dStep?dStepHeight:dStep);
								else 
									dAlt = m_pCFlight->GetCurState().m_dAlt - (dStepHeight<-dStep?dStepHeight:-dStep);				
							}

							dHeight = dAlt;
							WPpos.setZ(dAlt);
							newItem.SetPosition(WPpos);
							newItem.SetTime(endTime);
							newItem.SetSpeed(m_pCFlight->GetSpeed());
							//	newItem.SetAltitude(pt.getZ());
							newItem.SetAltitude(dAlt);
							m_pCFlight->PerformClearanceItem(newItem);
						}
					}

					firstItem.SetPosition(WPpos);
				//	firstItem.SetAltitude(pt.getZ());
					firstItem.SetAltitude(dHeight);
				}
				else
				{
					m_pCFlight->PerformClearanceItem(newItem);
				}
			}
			else
			{
				m_pCFlight->PerformClearanceItem(newItem);
			}
			m_pCFlight->PerformClearance(nextClearance);
			FlightWakeupEvent* pEvent = new FlightWakeupEvent(m_pCFlight);
			pEvent->setTime(m_pCFlight->GetTime());
			pEvent->addEvent();

		}

		return 0;
	}

	double stepLength = totalLength/8.0;
	ElapsedTime nextTime = time + ElapsedTime(stepLength/m_pCFlight->GetSpeed());
	if ( m_tHoldTime > 0L && nextTime > m_tHoldTime)
		nextTime = m_tHoldTime;

	//ASSERT(m_pCFlight->GetUID() != 31);
	FlightInHoldEvent* pNextEvent = new FlightInHoldEvent(m_pCFlight,m_pHold, m_tHoldTime);
	pNextEvent->setTime(nextTime);
	pNextEvent->addEvent();

	return 0;
	
}
double CFlightFuelBurningCalculator::CalculateFuelBurnByEvenFlightLog( AirsideFlightLogEntry& logEntry ,int _fromIndx,int _toIndex ,AirsideFlightDescStruct& _flttype,CFlightFuelBurnReportItem& _reportItem)
{
	ARCEventLog* pLog = NULL ;
	FlightFuelState _Atstate ;
	FlightFuelState _PriAtState = STATE_UNKNOW ;
	AirsideFlightEventStruct _PriFlightEventlog  ;
	double totalFuelBurning = 0 ;
	double stateFuelBurn = 0 ;
	BOOL _arrBeginTime = FALSE;
	BOOL _arrEndTIme = FALSE;
	BOOL _DepBeginTime = FALSE;
	BOOL _dependTime = FALSE;
	for (int i = _fromIndx ; i <=_toIndex;i++)
	{
 		AirsideFlightEventStruct event = logEntry.getEvent(i);
		
		_Atstate = JuedgeWhichStateBelongTo((AirsideMobileElementMode)event.mode) ;

			if(event.mode <= OnHeldAtStand)
			{
				if(!_arrBeginTime)
				{
					_reportItem.m_ArrFromTime.setPrecisely(event.time) ;
					_arrBeginTime = TRUE ;
				}
				if(i == _toIndex)
				{
					_reportItem.m_ArrToTime.setPrecisely(event.time) ;
				}
			}else
			{
				if(_arrBeginTime && _arrEndTIme == FALSE)
				{
					_reportItem.m_ArrToTime.setPrecisely(event.time) ;
					_arrEndTIme = TRUE ;
				}
				if(!_DepBeginTime)
				{
					_reportItem.m_DepFromTime.setPrecisely(event.time) ;
					_DepBeginTime  = TRUE ;
				}
				if(i == _toIndex)
				{
					_reportItem.m_DepToTime.setPrecisely(event.time) ;
				}
			}
		if(_Atstate != _PriAtState)
		{
			if(_PriAtState != STATE_UNKNOW) //another state ,calculate fuel 
			{
				stateFuelBurn = GetFuelBurnAtEachStateByFlightType(_PriAtState,_flttype) ;
				ElapsedTime intervaltime ;
				intervaltime.setPrecisely(event.time - _PriFlightEventlog.time) ;
				if(event.mode < OnHeldAtStand)
				{
					_reportItem.m_FuelBurnArrival += stateFuelBurn/3600 * intervaltime.asSeconds() ;
				}
				else
				{
					_reportItem.m_FuleBurnDep += stateFuelBurn/3600 * intervaltime.asSeconds() ;
				}
			}
			_PriAtState = _Atstate ;
			_PriFlightEventlog = event ;
		}else
		{
			if(_PriAtState != STATE_UNKNOW && i == _toIndex) //all the log are in the one state .
			{
				stateFuelBurn = GetFuelBurnAtEachStateByFlightType(_PriAtState,_flttype) ;
				ElapsedTime intervaltime ;
				intervaltime.setPrecisely(event.time - _PriFlightEventlog.time) ;
				if(event.mode < OnHeldAtStand)
				{
					_reportItem.m_FuelBurnArrival += stateFuelBurn/3600 * intervaltime.asSeconds() ;
				}
				else
				{
					_reportItem.m_DepToTime.setPrecisely(event.time) ;
					_reportItem.m_FuleBurnDep += stateFuelBurn/3600 * intervaltime.asSeconds() ;
				}
			}
		}

	}
	return _reportItem.m_FuleBurnDep + _reportItem.m_FuelBurnArrival ;
}