| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357 | // Domain.cpp : implementation file//#include "stdafx.h"//#include "OTSData.h"#include "Domain.h"#include "XMLSerialization.h"namespace OTSDATA {	using namespace xmls;	// CDomain		// constructor		CDomain::CDomain()	{		// initialization		Init();	}	CDomain::CDomain(DOMAIN_SHAPE a_nShape, CRect a_rectDomain)	{		// initialization		Init();		// assign class members		m_nShape = a_nShape;		m_rectDomain = a_rectDomain;	}	// copy constructor	CDomain::CDomain(const CDomain& a_oSource)	{		// can't copy itself		if (&a_oSource == this)		{			return;		}		// copy data over		Duplicate(a_oSource);	}	// copy constructor	CDomain::CDomain(CDomain* a_poSource)	{		// input check		ASSERT(a_poSource);		if (!a_poSource)		{			return;		}		// can't copy itself		if (a_poSource == this)		{			return;		}		// copy data over		Duplicate(*a_poSource);	}	// =operator		CDomain& CDomain::operator=(const CDomain& a_oSource)	{		// cleanup		Cleanup();		// copy the class data over		Duplicate(a_oSource);		// return class		return *this;	}	// ==operator	BOOL CDomain::operator==(const CDomain& a_oSource)	{		return m_nShape == a_oSource.m_nShape && m_rectDomain == a_oSource.m_rectDomain;	}	// destructor	CDomain::~CDomain()	{		// cleanup		Cleanup();	}	// CDomain functions 	// public	// check if the region is valid	BOOL CDomain::IsInvalid() const	{		return (m_nShape < DOMAIN_SHAPE::MIN) || m_nShape > DOMAIN_SHAPE::MAX || m_rectDomain.IsRectEmpty();	}	void CDomain::SetPolygonPoint(const std::vector<CPoint> a_PolygonPoint)	{		std::vector<CPoint> ps = a_PolygonPoint;		m_PolygonPoint.clear();		for (auto p : ps)		{			m_PolygonPoint.push_back(p);		}	}	// check if have common area with the given domain	BOOL CDomain::IntersectDomain(const CDomain& a_oDomain)	{		// return FALSE if any domain of the two is invalid		if (IsInvalid() || a_oDomain.IsInvalid())		{			return FALSE;		}		// create two CRgn objects with the two region objects		CRect rectCur, rectGiven;		rectCur = GetDomainRect();		rectGiven = a_oDomain.GetDomainRect();		CRgn rgnCur, rgnGiven, rgnTest;		BOOL bRgnCur, bRgnGiven;		bRgnCur = rgnTest.CreateEllipticRgnIndirect(rectCur);		if (IsRound())		{			bRgnCur = rgnCur.CreateEllipticRgnIndirect(rectCur);		}		else		{			bRgnCur = rgnCur.CreateRectRgnIndirect(rectCur);		}		if (a_oDomain.IsRound())		{			bRgnGiven = rgnGiven.CreateEllipticRgnIndirect(rectGiven);		}		else		{			rgnGiven.CreateRectRgnIndirect(rectGiven);		}		// combine the two CRgn objects with RGN_AND 		int nCombineResult = rgnTest.CombineRgn(&rgnCur, &rgnGiven, RGN_AND);		// return TRUE if combine success and combine result is not empty		return (nCombineResult != ERROR) && (nCombineResult != NULLREGION);	}	// check if the point is in domain	BOOL CDomain::PtInDomain(const CPoint& a_poiCheck) const	{		// return FALSE if is invalid		if (IsInvalid())		{			return FALSE;		}		// check sharp		if (IsRound())		{			// round			double dRoundRegionRadius = (double)GetDomainRect().Width() / 2000.0;			dRoundRegionRadius = dRoundRegionRadius * dRoundRegionRadius;			double dDisToRegioCenter;			double dX, dY;			dX = (double)abs(GetDomainCenter().x - a_poiCheck.x) / 1000;			dY = (double)abs(GetDomainCenter().y - a_poiCheck.y) / 1000;			dX = dX * dX;			dY = dY * dY;			dDisToRegioCenter = dX + dY;			if (dRoundRegionRadius >= dDisToRegioCenter)			{				// in region				return TRUE;			}			else			{				// not in region				return FALSE;			}		}		else		{			// rectangle			// use CRect method			return GetDomainRect().PtInRect(a_poiCheck);		}	}	// check if the given domain is in domain	BOOL CDomain::DomainInDomain(const CDomain& a_oDomain)	{		// return FALSE if any domain of the two is invalid		if (IsInvalid() || a_oDomain.IsInvalid())		{			return FALSE;		}		// create two CRgn objects with the two domain objects		CRect rectCur, rectGiven;		rectCur = GetDomainRect();		rectGiven = a_oDomain.GetDomainRect();		CRgn rgnCur, rgnGiven, rgnTest;		BOOL bRgnCur, bRgnGiven;		bRgnCur = rgnTest.CreateEllipticRgnIndirect(rectCur);		if (IsRound())		{			bRgnCur = rgnCur.CreateEllipticRgnIndirect(rectCur);		}		else		{			bRgnCur = rgnCur.CreateRectRgnIndirect(rectCur);		}		if (a_oDomain.IsRound())		{			bRgnGiven = rgnGiven.CreateEllipticRgnIndirect(rectGiven);		}		else		{			bRgnGiven = rgnGiven.CreateRectRgnIndirect(rectGiven);		}		// combine the two CRgn objects with RGN_AND 		int nCombineResult = rgnTest.CombineRgn(&rgnCur, &rgnGiven, RGN_AND);		// return FALSE if combine failed or combine result is empty		if (nCombineResult == ERROR || nCombineResult == NULLREGION)		{			return FALSE;		}		// the combined region equals the test domain means that the test domain is in the domain, return TRUE		return rgnTest.EqualRgn(&rgnGiven);	}	// cleanup 	void CDomain::Cleanup()	{		// need to do nothing at the moment		m_PolygonPoint.clear();	}	// initialization	void CDomain::Init()	{		m_nShape = DOMAIN_SHAPE::INVALID;		m_rectDomain = CRect(0, 0, 0, 0);		m_PolygonPoint.clear();	}	// duplication 	void CDomain::Duplicate(const CDomain& a_oSource)	{		// initialization		Init();		// copy data over		m_nShape = a_oSource.m_nShape;		m_rectDomain = a_oSource.m_rectDomain;		m_PolygonPoint = a_oSource.m_PolygonPoint;	}	void CDomain::Serialize(bool isStoring, tinyxml2::XMLDocument* classDoc, tinyxml2::XMLElement* rootNode)	{		xmls::Slo slo;		xmls::xInt xnShape;		xmls::xRect xRecDomain;		xmls::xString xPolygonPoint;		//register at this time point can ensure that the objects aren't nullptr especialy the smart pointer object.		//Slo::Clear();		slo.Register("shape", &xnShape);		slo.Register("rectDomian", &xRecDomain);		slo.Register("PolygonPoint", &xPolygonPoint);		if (isStoring)		{			xnShape = (int)m_nShape;			if (m_nShape == DOMAIN_SHAPE::POLYGON)			{				CString polygonPoints = _T("");				if (m_PolygonPoint.size() > 0)				{					for (size_t i = 0; i < m_PolygonPoint.size(); i++)					{						CString X = _T("");						X.Format(_T("%ld"), m_PolygonPoint[i].x);						CString Y = _T("");						Y.Format(_T("%ld"), m_PolygonPoint[i].y);						//polygonPoints.Format(_T("%ld"), m_PolygonPoint[i].y);						polygonPoints.Append(X);						polygonPoints.Append(",");						polygonPoints.Append(Y);						polygonPoints.Append("_");					}				}				xPolygonPoint = polygonPoints;			}			//we have to save the rectangle parameter according to the previouse rule.(left,top,width,height or centerX centerY,diamiter,0)			xRecDomain = xRect(m_rectDomain, (int)m_nShape);			slo.Serialize(true, classDoc, rootNode);		}		else		{			slo.Serialize(false, classDoc, rootNode);			m_nShape = (DOMAIN_SHAPE)xnShape.value();			m_rectDomain = xRecDomain.value();			if (m_nShape == DOMAIN_SHAPE::POLYGON)			{				std::vector<std::string> point;				SplitString(xPolygonPoint.value(), point, "_");				for (int i = 0; i < point.size(); i++)				{					std::vector<std::string> pointTemp;					SplitString(point[i], pointTemp, ",");					/*m_PolygonPoint[i].x = stoll(pointTemp[0], 0, 0);					m_PolygonPoint[i].y = stoll(pointTemp[1], 0, 0);*/					long x = atoi(pointTemp[0].c_str());					long y = atoi(pointTemp[1].c_str());					m_PolygonPoint.push_back(CPoint(x, y));				}			}			//do the regulation			int nCentreX = m_rectDomain.left;			int nCentreY = m_rectDomain.top;			int nWidth;			int nHeight;			int nDiameter;			if (m_nShape == DOMAIN_SHAPE::ROUND)			{				nDiameter = m_rectDomain.right;				// create domain						m_rectDomain.left = 0;				m_rectDomain.top = 0;				m_rectDomain.right = nDiameter;				m_rectDomain.bottom = nDiameter;				this->OffsetDomain(CPoint(nCentreX - (nDiameter / 2), nCentreY - (nDiameter / 2)));			}			else if (m_nShape == DOMAIN_SHAPE::RECTANGLE)			{				nWidth = m_rectDomain.right;				nHeight = m_rectDomain.bottom;				m_rectDomain.left = 0;				m_rectDomain.top = 0;				m_rectDomain.right = nWidth;				m_rectDomain.bottom = nHeight;				this->OffsetDomain(CPoint(nCentreX - (nWidth / 2), nCentreY - (nHeight / 2)));			}		}	}}
 |