⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stmeditordoc.cpp

📁 一个简单的vc++开发的城市公交地图编辑器源代码及生成的地图样例
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	AddRgn(bsrgn,hitrgn);
	AddRgn(bsrgn,txtrgn);
}


void CSTMEditorDoc::CalcPathRgn(CRgn &pathrgn, int index)
{
	PATHINFO pi;
	pi=m_arrPath.GetAt(index);
	POINT	begin,end;
	begin=m_arrCross.GetAt(pi.begin_id).pos ;
	end=m_arrCross.GetAt(pi.end_id).pos ;
	POINT	rgnpts[4];
	if(begin.x==end.x)//vertical path
	{
		rgnpts[0].x=begin.x-2,rgnpts[0].y=begin.y;
		rgnpts[1].x=begin.x+2,rgnpts[1].y=begin.y;
		rgnpts[2].x=end.x+2,rgnpts[2].y=end.y;
		rgnpts[3].x=end.x-2,rgnpts[3].y=end.y;
	}else if(begin.y==end.y)//horizontical path
	{
		rgnpts[0].y=begin.y-2,rgnpts[0].x=begin.x;
		rgnpts[1].y=begin.y+2,rgnpts[1].x=begin.x;
		rgnpts[2].y=end.y+2,rgnpts[2].x=end.x;
		rgnpts[3].y=end.y-2,rgnpts[3].x=end.x;
	}else	//incline path
	{
		double k1,k2;
		k1=(double(end.y-begin.y))/(end.x-begin.x);
		k2=-1.0/k1;
		double dx=sqrt(9.0/(k2*k2+1));
		double dy=k2*dx;
		dx+=0.5;
		dy+=0.5;
		rgnpts[0].x=begin.x-(int)dx;
		rgnpts[0].y=begin.y-(int)dy;
		rgnpts[1].x=begin.x+(int)dx;
		rgnpts[1].y=begin.y+(int)dy;
		rgnpts[2].x=end.x+(int)dx;
		rgnpts[2].y=end.y+(int)dy;
		rgnpts[3].x=end.x-(int)dx;
		rgnpts[3].y=end.y-(int)dy;
	}
	pathrgn.CreatePolygonRgn(rgnpts,4,WINDING);
}

void CSTMEditorDoc::GetPathEffectRgn(CRgn& effectrgn,int index)
{
	BSINFO bsi;
	for(int i=0;i<m_arrBS.GetSize();i++)
	{
		bsi=m_arrBS.GetAt(i);
		if(bsi.path_id==index)
		{
			CRgn bsrgn;
			CalcBSRgn(bsrgn,i);
			AddRgn(effectrgn,bsrgn);
		}
	}
	CRgn pathrgn;
	CalcPathRgn(pathrgn,index);
	AddRgn(effectrgn,pathrgn);
}

void CSTMEditorDoc::RemovePath(CRgn &effectrgn,int index)
{
	ASSERT(index<m_arrPath.GetSize());
	BSINFO bsi;
	for(int i=m_arrBS.GetSize()-1;i>=0;i--)
	{
		bsi=m_arrBS.GetAt(i);
		if(bsi.path_id==index)
		{
			CRgn bsrgn;
			CalcBSRgn(bsrgn,i);
			AddRgn(effectrgn,bsrgn);
			m_arrBS.RemoveAt(i);
		}else if(bsi.path_id>index)
		{
			bsi.path_id--;
			m_arrBS.SetAt(i,bsi);
		}
	}

	//update traffic route infomation
	PATHINFO pi=m_arrPath.GetAt(index);
	TRAFFICROUTEINFO tri;
	for(i=m_arrTR.GetSize()-1;i>=0;i--)
	{
		tri=m_arrTR.GetAt(i);
		if(IsPathInTrafficRoute(pi,tri))
			RemoveTR(i);
		else
		{
			for(int j=0;j<tri.nStations;j++)
			{
				if(tri.pEI[j].eleType==ET_PATH &&
					tri.pEI[j].index>index)
					tri.pEI[j].index--;
			}
			m_arrTR.SetAt(i,tri);
		}
	}

	//update street infomation
	STREETINFO si;
	for(i=m_arrStreet.GetSize()-1;i>=0;i--)
	{
		si=m_arrStreet.GetAt(i);
		BOOL	bInStreet=FALSE;
		for(int j=0;j<si.nPathes;j++)
		{
			if(si.pPathID[j]==index)
			{
				bInStreet=TRUE;
				break;
			}else if(si.pPathID[j]>index)
			{
				si.pPathID[j]--;
			}
		}
		if(bInStreet)
			RemoveStreet(i);
		else
			m_arrStreet.SetAt(j,si);
	}

	//update select assembly
	ELEINFO selEI;
	for(i=m_arrSel.GetSize()-1;i>=0;i--)
	{
		selEI=m_arrSel.GetAt(i);
		if(selEI.eleType==ET_PATH &&
			selEI.index==index)
		{
			m_arrSel.RemoveAt(i);
		}
		if(selEI.eleType==ET_PATH &&
			selEI.index>index)
		{
			selEI.index--;
			m_arrSel.SetAt(i,selEI);
		}
	}
	CRgn pathrgn;
	CalcPathRgn(pathrgn,index);
	AddRgn(effectrgn,pathrgn);
	m_arrPath.RemoveAt(index);
	SetModifiedFlag();
}

void CSTMEditorDoc::AddRgn(CRgn &rgnSrc, const CRgn & rgnAdd)
{
	ASSERT(rgnAdd.m_hObject);
	if(!rgnSrc.m_hObject)
	{
		rgnSrc.CreateRectRgnIndirect(CRect(0,0,0,0));
		rgnSrc.CopyRgn((CRgn *)&rgnAdd);
	}else
	{
		rgnSrc.CombineRgn(&rgnSrc,(CRgn *)&rgnAdd,RGN_OR);
	}
}

void CSTMEditorDoc::MoveBS(int index, POINT newPt)
{
	BSINFO	bsi=m_arrBS.GetAt(index);
	PATHINFO	pi=m_arrPath.GetAt(bsi.path_id);
	POINT	begin,end;
	begin=m_arrCross.GetAt(pi.begin_id).pos ;
	end=m_arrCross.GetAt(pi.end_id).pos;
	// calculate the intersection of the path and the line which throught the newPt and vertical to the path 
	if(begin.x==end.x)//vertical
	{
		bsi.pos.y=newPt.y;
	}else if(begin.y==end.y)//horizontical
	{
		bsi.pos.x=newPt.x;
	}else
	{
		double k1,k2;
		k1=(double(end.y-begin.y))/(end.x-begin.x);
		k2=-1.0/k1;
		bsi.pos.x=int(((k1*begin.x-begin.y)-(k2*newPt.x-newPt.y))/(k1-k2));
		bsi.pos.y=int(((k2*begin.y+begin.x)-(k1*newPt.y+newPt.x))/(k2-k1));
	}
	BOOL isoverflow=FALSE;
	if(bsi.pos.x<min(begin.x,end.x)||bsi.pos.x>max(begin.x,end.x))
	{
		isoverflow=TRUE;
	}
	if(!isoverflow&&(bsi.pos.y<min(begin.y,end.y)||bsi.pos.y>max(begin.y,end.y)))
	{
		isoverflow=TRUE;
	}
	if(!isoverflow)
	{
		m_arrBS.SetAt(index,bsi);
		SetModifiedFlag();
	}
}

void CSTMEditorDoc::MoveCross(int index, POINT newPos)
{
	CROSSINFO ci;
	ci=m_arrCross.GetAt(index);
	PATHINFO pi;
	BSINFO		bsi;
	for(int i=0;i<m_arrPath.GetSize();i++)
	{
		pi=m_arrPath.GetAt(i);
		if(pi.begin_id==index||pi.end_id==index)
		{
			POINT	oldbegin,oldend;
			POINT	newbegin,newend;
			oldbegin=m_arrCross.GetAt(pi.begin_id).pos;
			oldend=m_arrCross.GetAt(pi.end_id).pos;
			if(pi.begin_id==index)
			{
				newbegin=newPos;
				newend=oldend;
			}else //if(pi.end_id==index)
			{
				newbegin=oldbegin;
				newend=newPos;
			}
			for(int j=0;j<m_arrBS.GetSize();j++)
			{
				bsi=m_arrBS.GetAt(j);
				if(bsi.path_id==i)
				{
					//按原车站在道路上的位置相对关系调整车站位置
					bsi.pos.x=newbegin.x+(bsi.pos.x-oldbegin.x)*(newend.x-newbegin.x)/(oldend.x-oldbegin.x);
					bsi.pos.y=newbegin.y+(bsi.pos.y-oldbegin.y)*(newend.y-newbegin.y)/(oldend.y-oldbegin.y);
					m_arrBS.SetAt(j,bsi);
				}
			}
		}
	}
	ci.pos=newPos;
	m_arrCross.SetAt(index,ci);
	SetModifiedFlag();
}


void CSTMEditorDoc::GetCrossEffectRgn(CRgn &effectrgn, int index)
{
	ASSERT(index<m_arrCross.GetSize());
	PATHINFO pi;
	for(int i=m_arrPath.GetSize()-1;i>=0;i--)
	{
		pi=m_arrPath.GetAt(i);
		if(pi.begin_id==index||pi.end_id==index)
		{
			CRgn pathrgn;
			GetPathEffectRgn(pathrgn,i);
			AddRgn(effectrgn,pathrgn);
		}
	}
	CRgn	crossrgn;
	CalcCrossRgn(crossrgn,index);
	AddRgn(effectrgn,crossrgn);
}

BOOL CSTMEditorDoc::GetFocusInfo(POINT pt)
{
	BOOL	bfind=FALSE;
	RECT rc;
	int index=0;
	ELEINFO	curEI=m_focusEI;
	m_focusEI.eleType=ET_NULL,m_focusEI.index=-1;
	if(!bfind&&CanHilite(ET_CROSS)) //find cross
	{
		POINT	tmppt;
		for(index=0;index<m_arrCross.GetSize();index++)
		{
			tmppt=m_arrCross.GetAt(index).pos;
			rc=CalcCrossRect(tmppt);
			if(PtInRect(&rc,pt))
			{
				m_focusEI.eleType=ET_CROSS;
				m_focusEI.index=index;
				bfind=TRUE;
				break;
			}
		}
	}
	if(!bfind&&CanHilite(ET_BS)) //find bus station
	{
		BSINFO	tmpbsi;
		for(index=0;index<m_arrBS.GetSize();index++)
		{
			tmpbsi=m_arrBS.GetAt(index);
			rc=CalcBSRect(tmpbsi.pos);
			if(PtInRect(&rc,pt))
			{
				m_focusEI.eleType=ET_BS;
				m_focusEI.index=index;
				bfind=TRUE;
				break;
			}
		}
	}

	if(!bfind&&CanHilite(ET_ADDRESS)) //find address
	{
		ADDRESSINFO	ai;
		for(index=0;index<m_arrAddress.GetSize();index++)
		{
			ai=m_arrAddress.GetAt(index);
			rc=CalcAddressRect(ai.pos);
			if(PtInRect(&rc,pt))
			{
				m_focusEI.eleType=ET_ADDRESS;
				m_focusEI.index=index;
				bfind=TRUE;
				break;
			}
		}
	}

	if(!bfind&&CanHilite(ET_PATH))
	{
		PATHINFO	tmppi;
		for(index=0;index<m_arrPath.GetSize();index++)
		{
			tmppi=m_arrPath.GetAt(index);
			CRgn pathrgn;
			CalcPathRgn(pathrgn,index);
			if(pathrgn.PtInRegion(pt))
			{
				m_focusEI.eleType=ET_PATH;
				m_focusEI.index=index;
				bfind=TRUE;
				break;
			}
		}
	}

	m_preFocusEI=curEI;//save old focus infomation
	if((m_preFocusEI.eleType!=m_focusEI.eleType)||
		(m_preFocusEI.index!=m_focusEI.index))
		m_bFocusChanged=TRUE;
	else
		m_bFocusChanged=FALSE;
	return bfind;
}

int CSTMEditorDoc::AddCross(CROSSINFO ci)
{
	int	index=m_arrCross.Add(ci);
	ELEINFO	selEI;
	selEI.eleType=ET_CROSS;
	selEI.index=index;
	m_arrSel.RemoveAll();
	m_arrSel.Add(selEI);
	SetModifiedFlag();
	return index;
}

int CSTMEditorDoc::AddPath(PATHINFO pi)
{
	if(IsPathExisted(pi)) return -1;//add path error
	int	index=m_arrPath.Add(pi);
	ELEINFO	selEI;
	selEI.eleType=ET_PATH;
	selEI.index=index;
	m_arrSel.RemoveAll();
	m_arrSel.Add(selEI);
	SetModifiedFlag();
	return index;
}

int CSTMEditorDoc::AddBS(BSINFO bsi)
{
	int	index=m_arrBS.Add(bsi);
	ELEINFO	selEI;
	selEI.eleType=ET_BS;
	selEI.index=index;
	m_arrSel.RemoveAll();
	m_arrSel.Add(selEI);
	SetModifiedFlag();
	return index;
}

//estimate if the specified element type can be hilited
BOOL CSTMEditorDoc::CanHilite(ELETYPE et)
{
	BOOL	ret=TRUE;
	switch(m_selTool)
	{
	case ST_CROSS:
		if(et!=ET_CROSS&&et!=ET_PATH)
			ret=FALSE;
		break;
	case ST_PATH:
		if(et!=ET_CROSS && et!=ET_PATH)
			ret=FALSE;
		break;
	case ST_BS:
		if(et!=ET_PATH && et!=ET_BS)
			ret=FALSE;
		break;
	case ST_ADDRESS:
		if(et!=ET_ADDRESS)
			ret=FALSE;
		break;
	case ST_TRAFFIC:
		if(et!=ET_CROSS&&et!=ET_BS)
			ret=FALSE;
		break;
	case ST_STREET:
		if(et!=ET_PATH)
			ret=FALSE;
		break;
	default:
		break;
	}
	return ret;
}

//get element state
ELESTATE CSTMEditorDoc::GetElementState(ELEINFO ei)
{
	ELESTATE es=ES_NORMAL;
	if(ei.eleType==m_focusEI.eleType &&
		ei.index==m_focusEI.index)
		es=ES_FOCUS;
	else {
		ELEINFO selEI;
		for(int i=0;i<m_arrSel.GetSize();i++)
		{
			selEI=m_arrSel.GetAt(i);
			if(ei.eleType==selEI.eleType &&
				ei.index==selEI.index)
			{
				es=ES_SELECTED;
				break;
			}
		}
	}
	return es;
}

void CSTMEditorDoc::SelectElements(ELEINFO *ei,int count)
{
	m_arrSel.RemoveAll();
	for(int i=0;i<count;i++)
		m_arrSel.Add(*(ei+i));
}

BOOL CSTMEditorDoc::IsPathExisted(PATHINFO pi)
{
	PATHINFO tmppi;
	for(int i=0;i<m_arrPath.GetSize();i++)
	{
		tmppi=m_arrPath.GetAt(i);
		if(tmppi.begin_id==pi.begin_id &&
			tmppi.end_id==pi.end_id)
		{
			return TRUE;
		}
	}
	return FALSE;
}

void CSTMEditorDoc::RemoveTrafficRouteInfo()
{
	TRAFFICROUTEINFO tri;
	for(int i=0;i<m_arrTR.GetSize();i++)
	{
		tri=m_arrTR.GetAt(i);
		ASSERT(tri.nStations!=0);
		delete []tri.pEI;
	}
	m_arrTR.RemoveAll();
}

int CSTMEditorDoc::AddTR(TRAFFICROUTEINFO tri)
{
	if(tri.nStations<2) return -1;
	BOOL	bCanAdd=TRUE;
	ELEINFO	ei;
	ELEINFO	precross={ET_NULL,-1};
	int  ipath=-1;

	CArray<ELEINFO,ELEINFO&> m_arrRoutePath;
	
	ei=tri.pEI[0];
	if(ei.eleType==ET_BS)
		ipath=m_arrBS.GetAt(ei.index).path_id;
	else
		precross=ei;
	ELEINFO	pathEI;
	pathEI.eleType=ET_PATH;
	if(ipath!=-1) {
		pathEI.index=ipath;
		m_arrRoutePath.Add(pathEI);
	}

	for(int i=1;i<tri.nStations;i++)
	{
		ei=tri.pEI[i];
		if(ei.eleType==ET_BS)
		{
			if(ipath!=-1)
			{
				int		pathindex=m_arrBS.GetAt(ei.index).path_id;
				if(pathindex!=ipath)
				{
					bCanAdd=FALSE;
					break;
				}
			}else //ipath==-1 
			{
				ASSERT(precross.index!=-1);
				int		pathindex=m_arrBS.GetAt(ei.index).path_id;
				PATHINFO pi=m_arrPath.GetAt(pathindex);
				if(pi.begin_id!=precross.index&&pi.end_id!=precross.index)
				{
					bCanAdd=FALSE;
					break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -