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

📄 map.cpp

📁 gps 可以打开.gps
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	{
		
		m_pData = new double[--points*2];//
		m_nMaxPoint = points;
		
		for(i=0; i<points; i++)
		{
			ar.ReadString(buf, BUFSIZ - 1);
			for(j=0; j<BUFSIZ - 1 && buf[j]==' '; j++);
			f1 = atof(buf+j);//经度
			*(m_pData+2*i) = f1;
			for(; j<BUFSIZ - 1 && buf[j]!=' '; j++);
			f2 = atof(buf+j+1);//纬度
			*(m_pData+2*i+1) = f2;
			//保存对象边界值
			m_fMinX = m_fMinX < f1 ? m_fMinX : f1;
			m_fMinY = m_fMinY < f2 ? m_fMinY : f2;
			m_fMaxX = m_fMaxX > f1 ? m_fMaxX : f1;
			m_fMaxY = m_fMaxY > f2 ? m_fMaxY : f2;
			
		}
		
		ar.ReadString(buf, BUFSIZ - 1);//读出最后一点
		ar.ReadString(buf, BUFSIZ - 1);//读Pen数据
		ar.ReadString(buf, BUFSIZ - 1);//读Brush数据
		for(i=0; i<BUFSIZ -1 && buf[i]!=','; i++);//检索第一个逗号(,)
		m_nColor = atoi(buf+i+1);//获得填充颜色
		//转换颜色位定义
		//由于MapInfo与Windows使用不同的位定义RGB颜色,必须转换
		int c_red = m_nColor & 0xff0000;//红色分量
		int c_blue = m_nColor & 0xff;//兰色分量
		m_nColor =  (m_nColor & 0xff00) + (c_red >> 16) + (c_blue << 16);
	}
	else
	{
		
		m_pData = new double[points*2];//
		m_nMaxPoint = points;
		for(i=0; i<points; i++)
		{
			ar.ReadString(buf, BUFSIZ - 1);
			for(j=0; j<BUFSIZ - 1 && buf[j]==' '; j++);
			f1 = atof(buf+j);//经度
			*(m_pData+2*i) = f1;
			for(; j<BUFSIZ - 1 && buf[j]!=' '; j++);
			f2 = atof(buf+j+1);//纬度
			*(m_pData+2*i+1) = f2;
			//保存对象边界值
			m_fMinX = m_fMinX < f1 ? m_fMinX : f1;
			m_fMinY = m_fMinY < f2 ? m_fMinY : f2;
			m_fMaxX = m_fMaxX > f1 ? m_fMaxX : f1;
			m_fMaxY = m_fMaxY > f2 ? m_fMaxY : f2;
			
		}
		
        CString str;
		ar.ReadString(str);
		m_nColor = atoi(LPCTSTR(str));//读当前多边形端点数
	}
	
	m_pDoc->m_fMinX=m_fMinX;m_pDoc->m_fMaxX=m_fMaxX;
	m_pDoc->m_fMinY=m_fMinY;m_pDoc->m_fMaxY=m_fMaxY;
	
}

void CMapRegion::Draw(CDC* pDC)
{
	if((m_nMaxPoint < 2) | (!IsInView()))
		return;

	long* data = m_pDoc->m_pData;
	CPen pen(PS_SOLID, 1, m_nColor), *oldpen;
	CBrush brush(m_nColor), *oldbrush;
	
	m_pDoc->ConvToXYs(m_pData, data, m_nMaxPoint);
	m_pDoc->LPtoDPs(data, m_nMaxPoint);
	
	//设置DC笔和刷的颜色
	oldpen = pDC->SelectObject(&pen);
	oldbrush = pDC->SelectObject(&brush);

	pDC->Polygon((LPPOINT)data, m_nMaxPoint);

	//恢复DC设置
	pDC->SelectObject(oldpen);
	pDC->SelectObject(oldbrush);
	//删除资源
	pen.DeleteObject();
	brush.DeleteObject();
}

/*//-----------------------------------------------------------------------
//路经 搜索 
-------------------------------------------------------------------------*///
void CMapLayer::PathSearch(CPoint point) //路径搜索入口函数
{

	HPEN hPen;
    hPen=CreatePen(PS_SOLID,2,RGB(255,0,0));
	m_pDoc->m_pMemDC->SelectObject(hPen);

	bool star=false;
	CPoint pt1,pt2;
	double sx,sy,dx,dy;
	//  double x,y;
//	long x3,y3;
	
	if(n_point)                    //如果第一点没有获取,获取第一点
	{

/*		    CString sc,sb,zc,zb;
			sc.Format("%.6f",starX);//对象坐标
			sb.Format("%.6f",starY);//对象坐标
			zb.Format("%.6f",endX);//对象坐标
			zc.Format("%.6f",endY);//对象坐标
		AfxMessageBox(sc+"//"+sb+","+zb+"//"+zc);	*/
        
		m_pDoc->DrawMap(m_pDoc->m_pMemDC);
		SetFirstPoint(point, sx, sy);
		starX=sx;starY=sy;	

//		starX=120.629840 ;starY=30.494097;

//		m_pDoc->ConvToXY(pt1.x,pt1.y, x3, y3);
//		m_pDoc->LPtoDP(x3, y3);

        n_point=false;
	}
	else if(!n_point)                     //如果第一点已经获取,获取第二点
	{
		SetFirstPoint(point,dx,dy);

		if(starX==dx && starY==dy)    //如果两次选择的同一个点返回
		     return;

		endX=dx;endY=dy;
//		endX=120.520070;endY=30.507421;
 
		 

//			AfxMessageBox("察看d值");	

//		m_pDoc->ConvToXY(pt2.x,pt2.y, x3, y3);
//		m_pDoc->LPtoDP(x3, y3);		        
		n_point=true;		
		star=true;
	}

	if (star)                       //如果两点都已经存在,执行路径搜索	
	{

//		long x1,y1,x2,y2;
		star=false;
		struct NODE *path;//, *Node;		
		//	  sx=pt1.x;sy=pt1.y;dx=pt2.x;dy=pt2.y;	
		path =(struct NODE *) FindPath(starX,starY,endX,endY);

        DrawPath(path, endX,endY);

/*		m_pDoc->ConvToXY(endX,endY, x1, y1);
		m_pDoc->LPtoDP(x1, y1);

		m_pDoc->m_pMemDC->MoveTo(x1,y1);
		while (path->Parent != NULL)
		{
			path=path->Parent;
	    	m_pDoc->ConvToXY(path->x,path->y, x2, y2);
	    	m_pDoc->LPtoDP(x2, y2);
			m_pDoc->m_pMemDC->LineTo(x2,y2);
		}
		m_pDoc->m_pMemDC->LineTo(x2,y2);
		// Free Nodes up
		Node=OPEN->NextNode;*/
//		while (Node != NULL)
//		{
//			free(Node);
//			Node=Node->NextNode;
//		}
	//	Node=CLOSED->NextNode;
	//	while (Node != NULL)
	//	{
	//		free(Node);
	//		Node=Node->NextNode;
	//	}
	}
   DeleteObject(hPen);
}
void CMapLayer::SetFirstPoint(CPoint point,double &x,double &y)
{          //从屏幕上获取离鼠标点击位置最近的点
	double f1,f2;
	double jing,wei;
	CPoint pt=point;
	double dd[512][100];
	double min;
	
	double f3,f4;
	long x3,y3;

	m_pDoc->DPtoLP(pt.x, pt.y);//转换为逻辑坐标
	m_pDoc->ConvToJW(pt.x, pt.y, jing, wei);//转换为经纬度
	
	for(int n=0;n<m_pDoc->ONum;n++)
	{                                //将点击点到各点的距离 存储到数组中
		int p=pline[n].pointnum;
		for(int i=0;i<p;i++)
		{
			f1=	*(pline[n].longitude+i);	
			f2=	*(pline[n].latitude+i);	
	//		m_pDoc->ConvToXY(f1,f2, x1, y1);
	//		m_pDoc->LPtoDP(x1, y1);			
		    dd[n][i]=m_pDoc->GetDistance(jing,wei,f1,f2)*100000;//将数据存入字符数组 //从而判断最近的点
		}		
	}	
	min=dd[0][0];            //将第一个值赋给最小最小变量,以便下面比较
	for(int m=0;m<m_pDoc->ONum;m++) 
	{                          //查找出数组中的最小值
		int p=pline[m].pointnum;
		for(int i=0;i<p;i++)
		{
			if(dd[m][i]<min)
			{
				min=dd[m][i];
			}
		}
	}
	for(int b=0;b<m_pDoc->ONum;b++) 
	{                          //查找出数组中的最小值对应的数组中的 元素
		int p=pline[b].pointnum;
		for(int i=0;i<p;i++)
		{
			if(min==dd[b][i])
			{
			
				f3= *(pline[b].longitude+i);
				f4= *(pline[b].latitude+i);
     			x =f3; y=f4;

				m_pDoc->ConvToXY(f3,f4, x3, y3);
				m_pDoc->LPtoDP(x3, y3);

				m_pDoc->m_pMemDC->Ellipse(x3-4,y3-4,x3+4,y3+4);	
			}
		}
	}	
}

struct NODE* CMapLayer::FindPath(double sx, double sy, double dx, double dy)
{               //寻找最佳路径,参数定为起始点的坐标,经纬度
	///long sx, long sy:其应为起点,包含字节点;dx,dy是终点
//AfxMessageBox("程序进入FindPath函数");

	struct NODE *Node, *BestNode;

 //   TileNumDest=TileNum((int)dx,(int)dy);//得到目标位置,作判断用
       //生成Open和Closed表
    OPEN=(struct NODE *)calloc(1,sizeof( struct NODE ));
    CLOSED=(struct NODE *)calloc(1,sizeof( struct NODE ));
            //生成起始节点,并放入Open表中
    Node=(struct NODE *)calloc(1,sizeof( struct NODE ));
    Node->g=0;
	       //这是计算h值
    Node->h=m_pDoc->GetDistance(sx, sy, dx, dy);  // should really use sqrt().
    Node->f=Node->g+Node->h;    //这是计算f值,即估价值
    Node->x=sx;
    Node->y=sy;

    OPEN->NextNode=Node;        /* make Open List point to first node */

                            /*从Open表中取得一个估价值最好的节点??///如何取得??
	如果该节点是目标节点就退出,否则生成子节点*/
	for(;;)      
	{
		BestNode=(struct NODE *)ReturnBestNode();  //获得股价值最好的一个节点
		
		if(BestNode->x == dx && BestNode->y == dy)//子节点与终点相同,返回路径
			break;
	                                  	///不同进行下一节点搜索,
	                                      	////判断数组中权重最小的点,得出该点坐标经纬度,将该点从OPEN表中删除
	                                        	///将该点加入CLOSE表中////进行下一循环判断		
		//AfxMessageBox("寻找下一点!");
		FindNext(BestNode,dx,dy);
	}	
	return (BestNode);
}

void CMapLayer::FindNext(struct NODE *BestNode,double dx, double dy)
{         //寻找下一点

    double f1,f2,x1,y1,x2,y2;
	for(int n=0;n<m_pDoc->ONum;n++)
	{                                //查找与起点相通的子节点
		int p=pline[n].pointnum;
		for(int i=0;i<p;i++)
		{
			f1=	*(pline[n].longitude+i);	
			f2=	*(pline[n].latitude+i);	
			if(BestNode->x==f1 && BestNode->y==f2)         //查找包含起始点的线
			{
				if(i>=0 && i<p)        //获得与起始点相通的点
				{             ///将字节点存储到数组中
					if(i>0)       //上一点
					{
						x1=	*(pline[n].longitude+i-1);	
						y1=	*(pline[n].latitude+i-1);
					    GenerateSucc(BestNode,x1, y1, dx, dy);

					}     ///将子节点加入到OPEN表中,表中应该存储g(n)+h(n)
					////g(n)表示从起点到这一点的距离,h(n)表示节点到终点的距离					
					if(i==0 || i<p)         //下一点
					{
						x2=	*(pline[n].longitude+i+1);
                        y2=	*(pline[n].latitude+i+1);
						GenerateSucc(BestNode,x2, y2, dx, dy);

					}
				}
			}
			//			dd[n][i]=(ABS((jing-f1)*(jing-f1))      //将数据存入字符数组
			//				+ABS((wei-f2)*(wei-f2)))*10000;       //从而判断最近的点   
		}		
	} 

}

void CMapLayer::GenerateSucc(NODE *BestNode,double x, double y, double dx, double dy)
{           ///BestNode:是上一点,x\y 是当前点,dx/dy:是终点
//AfxMessageBox("GenerateSucc");
    double g,c=0,d;
    d=m_pDoc->GetDistance(BestNode->x ,BestNode->y,x,y);

    struct NODE *Old,*Successor;
	   //计算子节点的 g 值
    g=BestNode->g+d;	    /* g(Successor)=g(BestNode)+cost of getting from BestNode to Successor */
	/*判断当前点在OPEN CLOSE表中的情况*/
	   //子节点在Open表中吗?
    if ((Old=CheckOPEN(x,y)) != NULL) /* if equal to NULL then not in OPEN list, else it returns the Node in Old */
    {   //若在
			     ///比较Open表中的估价值和当前的估价值(只要比较g值就可以了)
		if (g < Old->g)  /* if our new g value is < Old's then reset Old's parent to point to BestNode */
		{
			Old->Parent=BestNode;
			Old->g=g;
			Old->f=g+Old->h;
			
			
			NODE *q,*p=OPEN->NextNode, *temp=OPEN->NextNode;
			while(p!=NULL && p->x != Old->x && p->y != Old->y)
			{
				q=p;
				p=p->NextNode;
			}
			if( p->x == Old->x && p->y == Old->y)
			{
				if(p==OPEN->NextNode)
				{
					temp = temp->NextNode;
					OPEN ->NextNode = temp;
				}
				else
					q->NextNode = p->NextNode;
			}
			Insert(Old); // Insert Successor on OPEN list wrt f 
		} 	
    }
	///在Closed表中吗?
	else if ((Old=CheckCLOSED(x,y)) != NULL) /* if equal to NULL then not in OPEN list, else it returns the Node in Old */
    {        ////若在
		
		//比较Closed表中的估价值和当前的估价值(只要比较g值就可以了)
		if (g < Old->g)  /* if our new g value is < Old's then reset Old's parent to point to BestNode */
		{
			Old->Parent=BestNode;
			Old->g=g;
			Old->f=g+Old->h;         //再依次更新Old的所有子节点的估价值
			//	PropagateDown(Old);      
			/* Since we changed the g value of Old, we need
			to propagate this new value downwards, i.e.
			do a Depth-First traversal of the tree! */
			Insert(Old); // Insert Successor on OPEN list wrt f 
		} 
		

	}
    else      //不在Open表中也不在Close表中
    {          //生成新的节点
		Successor=(struct NODE *)calloc(1,sizeof( struct NODE ));
		Successor->Parent=BestNode;
		Successor->g=g;
		Successor->h=m_pDoc->GetDistance(x,y,dx,dy);  // should do sqrt(), but since we don't really
		Successor->f=g+Successor->h;     // care about the distance but just which branch looks
		Successor->x=x;                  // better this should suffice. Anyayz it's faster.
		Successor->y=y;
		      //再插入Open表中,同时排序
		Insert(Successor);     /* Insert Successor on OPEN list wrt f */
		//		for(c=0;c<8;c++)
		//			if (BestNode->Child[c] == NULL) /* Add Old to the list of BestNode's Children (or Successors). */
		//				break;
		//			BestNode->Child[c]=Successor;
    }
	
	
}


struct NODE* CMapLayer::ReturnBestNode(void)
{
    struct NODE *tmp;
    if (OPEN->NextNode == NULL)
	{
		AfxMessageBox("无法到达终点!!");
		exit(0);
//		goto ReFindPath;

	}
	else
	{
/* Pick Node with lowest f, in this case it's the first node in list
   because we sort the OPEN list wrt lowest f. Call it BESTNODE. */
      tmp=OPEN->NextNode;   // point to first node on OPEN
      OPEN->NextNode=tmp->NextNode;    // Make OPEN point to nextnode or NULL.
/* Next take BESTNODE (or temp in this case) and put it on CLOSED */
    tmp->NextNode=CLOSED->NextNode;
    CLOSED->NextNode=tmp;
	}
    return(tmp);
	
}

struct NODE * CMapLayer::CheckOPEN(double x, double y)
{
    struct NODE *tmp;
	
    tmp=OPEN->NextNode;
    while (tmp != NULL)
    {
		if (tmp->x==x && tmp->y == y)
			return (tmp);
		else
			tmp=tmp->NextNode;
    }
	return (NULL);
	
}
struct NODE * CMapLayer::CheckCLOSED(double x, double y)
{
    struct NODE *tmp;

    tmp=CLOSED->NextNode;

    while (tmp != NULL)
    {
	if (tmp->x==x && tmp->y == y)
	  return (tmp);
	else
	  tmp=tmp->NextNode;
    }
  return (NULL);

}

void CMapLayer::Insert(NODE *Successor)
{
    struct NODE *tmp1,*tmp2;
    double f;

    if (OPEN->NextNode == NULL)  //如果OPEN表的NextNode为空,插入Successor
      {
	OPEN->NextNode=Successor;
	return;
      }

       /* insert into OPEN successor wrt f */

    f=Successor->f;
    tmp1=OPEN;
    tmp2=OPEN->NextNode;

    while ((tmp2 != NULL) && (tmp2->f < f))
    {
      tmp1=tmp2;
      tmp2=tmp2->NextNode;
    }
	Successor->NextNode=tmp2;
	tmp1->NextNode=Successor;
}


void CMapLayer::DrawPath(NODE *path, long endx, long endy)
{
//	struct NODE *Node;
	    long x1,x2,y1,y2;
		m_pDoc->ConvToXY(endX,endY, x1, y1);
		m_pDoc->LPtoDP(x1, y1);

		m_pDoc->m_pMemDC->MoveTo(x1,y1);
		while (path->Parent != NULL)
		{
			path=path->Parent;
	    	m_pDoc->ConvToXY(path->x,path->y, x2, y2);
	    	m_pDoc->LPtoDP(x2, y2);
			m_pDoc->m_pMemDC->LineTo(x2,y2);
		}
		m_pDoc->m_pMemDC->LineTo(x2,y2);
		// Free Nodes up
/*		Node=OPEN->NextNode;

		while (Node != NULL)
		{
			free(Node);
			Node=Node->NextNode;
		}
		Node=CLOSED->NextNode;
		while (Node != NULL)
		{
			free(Node);
			Node=Node->NextNode;
		}*/
}

⌨️ 快捷键说明

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