📄 map.cpp
字号:
{
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 + -