コード例 #1
0
//check if the line through the congestion area, 
BOOL CCongestionAreaManager::CheckAndHandleCongestion(Person* pPerson, ElapsedTime eventTime, BOOL bAreaCong)
{
	//check the data
	TerminalMobElementBehavior* spTerminalBehavior = pPerson->getTerminalBehavior();
	Point ptStart;
	pPerson->getTerminalPoint(ptStart);
	int nFloor = (int)ptStart.getZ() / 100;
	if( !m_vGrid[nFloor]->IsValidCongestionArea() )
		return FALSE;

	Point ptEnd;
	pPerson->getTerminalDest(ptEnd);
	if(SAMEPOINT(ptStart, ptEnd) || !SAMEFLOAT(ptStart.getZ(), ptEnd.getZ()) )
		return FALSE;

	CCongestionAreaCell* pCell = NULL;
	Point ptDest = Point(0.0, 0.0, 0.0);

	//the line between start and end,
	//then get the intersect point between the line and the congestion area
	Point ptIntersect = Point(0.0, 0.0, ptStart.getZ());
	BOOL bExist = m_vGrid[nFloor]->GetInterSectPoint(ptStart, ptEnd, ptIntersect);
	if (!bExist)
		return FALSE;

//	pCell = m_vGrid[nFloor]->GetCell(ptIntersect);
	//		if(pCell == NULL)
	//			return FALSE;

	if(pCell = m_vGrid[nFloor]->GetCell(ptStart))
		pCell->EnterCell(pPerson->GetAdminGroupSize());//start cell

	if (pCell)
	{
		ptIntersect = m_vGrid[nFloor]->GetNearestPoint(ptStart,ptEnd);
	}
	ptDest = ptIntersect;

	//save the old destination point, old speed and old location

	
	if (spTerminalBehavior)
	{
		spTerminalBehavior->SetOldDestPoint(ptEnd);
		spTerminalBehavior->SetOldSpeed(pPerson->getSpeed());
		spTerminalBehavior->SetOldLocation(ptStart);
		spTerminalBehavior->processBillboard(eventTime);
		//set the new destination
		pPerson->setTerminalDestination(ptDest);
		//calculate the time and add event
		ElapsedTime time = eventTime + pPerson->moveTime();
		CongestionAreaEvent* event = new CongestionAreaEvent;
		event->init(pPerson, time,false);
		event->addEvent();
	}
	
	return TRUE;
}
コード例 #2
0
LWPOLY *
lwpoly_grid(LWPOLY *poly, gridspec *grid)
{
	LWPOLY *opoly;
	int ri;
	POINTARRAY **newrings = NULL;
	int nrings = 0;
	double minvisiblearea;

	/*
	 * TODO: control this assertion
	 * it is assumed that, since the grid size will be a pixel,
	 * a visible ring should show at least a white pixel inside,
	 * thus, for a square, that would be grid_xsize*grid_ysize
	 */
	minvisiblearea = grid->xsize * grid->ysize;

	nrings = 0;

	POSTGIS_DEBUGF(3, "grid_polygon3d: applying grid to polygon with %d rings",
	         poly->nrings);

	for (ri=0; ri<poly->nrings; ri++)
	{
		POINTARRAY *ring = poly->rings[ri];
		POINTARRAY *newring;

#if POSTGIS_DEBUG_LEVEL >= 4
		POINT2D p1, p2;
		getPoint2d_p(ring, 0, &p1);
		getPoint2d_p(ring, ring->npoints-1, &p2);
		if ( ! SAMEPOINT(&p1, &p2) )
			POSTGIS_DEBUG(4, "Before gridding: first point != last point");
#endif

		newring = ptarray_grid(ring, grid);

		/* Skip ring if not composed by at least 4 pts (3 segments) */
		if ( newring->npoints < 4 )
		{
			pfree(newring);

			POSTGIS_DEBUGF(3, "grid_polygon3d: ring%d skipped ( <4 pts )", ri);

			if ( ri ) continue;
			else break; /* this is the external ring, no need to work on holes */
		}

#if POSTGIS_DEBUG_LEVEL >= 4
		getPoint2d_p(newring, 0, &p1);
		getPoint2d_p(newring, newring->npoints-1, &p2);
		if ( ! SAMEPOINT(&p1, &p2) )
			POSTGIS_DEBUG(4, "After gridding: first point != last point");
#endif

		POSTGIS_DEBUGF(3, "grid_polygon3d: ring%d simplified from %d to %d points", ri,
		         ring->npoints, newring->npoints);

		/*
		 * Add ring to simplified ring array
		 * (TODO: dinamic allocation of pts_per_ring)
		 */
		if ( ! nrings )
		{
			newrings = palloc(sizeof(POINTARRAY *));
		}
		else
		{
			newrings = repalloc(newrings, sizeof(POINTARRAY *)*(nrings+1));
		}
		if ( ! newrings )
		{
			elog(ERROR, "Out of virtual memory");
			return NULL;
		}
		newrings[nrings++] = newring;
	}

	POSTGIS_DEBUGF(3, "grid_polygon3d: simplified polygon with %d rings", nrings);

	if ( ! nrings ) return NULL;

	opoly = lwpoly_construct(poly->srid, NULL, nrings, newrings);
	return opoly;
}
コード例 #3
0
//process congestion event and generate the next event
int CCongestionAreaManager::ProcessCongestionEvent(CongestionAreaEvent* pEvent, ElapsedTime eventTime)
{
	Person* pPerson = (Person*)pEvent->GetMobileElement();
	if(pPerson == NULL)
		return 0;
	
	// step1. Leave Cell
	TerminalMobElementBehavior* spTerminalBehavior = pPerson->getTerminalBehavior();
	if (spTerminalBehavior == NULL)
	{
		return 0;
	}
	Point floorpt;
	pPerson->getTerminalPoint(floorpt);
	int nFloor = int(floorpt.getZ()) / 100;

	CCongestionAreaCell* pCell = m_vGrid[nFloor]->GetCell(spTerminalBehavior->GetOldLocation());
	if(pCell != NULL)// && pPerson->GetOldLocation() != pPerson->GetOldStartPoint()
	{
		if(pCell->GetPersonsCount()==0)
		{
			CString str;
			str.Format("1-%d", pPerson->getID());
			AfxMessageBox(str);
		}
		pCell->LeaveCell(pPerson->GetAdminGroupSize());
	}
	// step2. Enter Cell
	Point ptDest;
	pPerson->getTerminalDest(ptDest);
	pCell = m_vGrid[nFloor]->GetCell(ptDest);
//	ASSERT(pCell != NULL);//if the cell is null, last time has already exit
	if(pCell != NULL)
		pCell->EnterCell(pPerson->GetAdminGroupSize());
	// setp3. save the current point as old location
	spTerminalBehavior->SetOldLocation(ptDest);
	// setp4. Write log
	pPerson->writeLogEntry(eventTime, false,false);
	// step5. Next event.
	//calculate the next event destination;
    Point pt;
	pPerson->getTerminalPoint(pt);
	const Point& ptOld = spTerminalBehavior->GetOldDestPoint();
	Point ptNext = /*pt.GetDistancePoint(ptOld, STEPDIST)*/m_vGrid[nFloor]->GetNearestPoint(pt,ptOld);
	//if get null, leaving the congestion area, reset the old destionation and speed;
	//if the ptNext equal ptOld, the person arrived at the end next processor
	pCell = m_vGrid[nFloor]->GetCell(ptNext);
	if(pCell == NULL //the end point not in the congestion area
		|| SAMEPOINT(ptNext, ptOld) ) //the end point in the congestion area,but get the end
	{	
		//if the person leaving the congestion area, leave the current cell,
		CCongestionAreaCell* pPreCell = m_vGrid[nFloor]->GetCell(spTerminalBehavior->GetOldLocation());
		if(pPreCell != NULL)
		{
			if(pPreCell->GetPersonsCount()==0)
			{
				CString str;
				str.Format("2-%d", pPerson->getID());
				AfxMessageBox(str);
			}

			pPreCell->LeaveCell(pPerson->GetAdminGroupSize());
		}
		pPerson->setTerminalDestination(spTerminalBehavior->GetOldDestPoint());
		pPerson->setSpeed(spTerminalBehavior->GetOldSpeed());
		if(pCell == NULL && pPerson->getState() != WalkOnPipe)
		{
			//pPerson->setLocation(ptNext); 
			if(CheckAndHandleCongestion(pPerson, eventTime, TRUE))
				return 1;
			else
				spTerminalBehavior->processGeneralMovementHelp(eventTime);
		}
		else
			spTerminalBehavior->processGeneralMovementHelp(eventTime);
		return 0;
	}

	//reset the new speed to calculate the next event time;
	int nCount = pCell->GetPersonsCount();
	DistanceUnit dSpeed = GetNewSpeed(pPerson, nCount);
	pPerson->setSpeed(dSpeed);
	pPerson->setTerminalDestination(ptNext);
	//Add the next event to the event list;
	ElapsedTime time = eventTime + pPerson->moveTime();
	CongestionAreaEvent* event = new CongestionAreaEvent;
	event->init(pPerson, time,false);
	event->addEvent();
	
	return 1;
}