📄 map.cpp
字号:
////map.cpp
///////
#include "stdafx.h"
#include "map.h"
#include "MapTestDoc.h"
#include "resource.h"
#define ABS( a ) ( ((a) >= 0 ) ? (a) : -(a) ) //定义一个绝对值
struct obj_point point[512];
struct obj_pline pline[512];
struct obj_region region[512];
struct NODE *OPEN;
struct NODE *CLOSED;
//******************************************
//**************CMapObject******************
//******************************************
CMapObject::CMapObject()
{
m_pData = NULL;
m_fMinX=120;
m_fMaxX=-180;
m_fMinY=90;
m_fMaxY=-90;
p=0;
}
bool CMapObject::IsInView() //视图
{
long x1, y1, x2, y2;
x1 = 0, y1 = 0;
x2 = m_pDoc->m_nViewWidth, y2 = m_pDoc->m_nVeiwHeight;
m_pDoc->DPtoLP(x1, y1); //屏幕坐标转换为地图逻辑坐标
m_pDoc->DPtoLP(x2, y2); //屏幕坐标转换为地图逻辑坐标
CRect rect1(x1, y1, x2, y2);
m_pDoc->ConvToXY(m_fMinX, m_fMaxY, x1, y1);//经纬度(度)->直角坐标
m_pDoc->ConvToXY(m_fMaxX, m_fMinY, x2, y2);//经纬度(度)->直角坐标
CRect rect2(x1, y1, x2, y2);
CRect rect;
return rect.IntersectRect(rect1, rect2);
}
//*******************************************
//*********** CMapPLine *********************
//*******************************************
CMapPLine::CMapPLine(CMapTestDoc* pDoc, CArchive& ar, int points)
{
int i,j;
char buf[BUFSIZ];
double f1, f2;
m_nStyle = IDS_PLINE;//保存图元类型
m_pData = new double[points*2];//申请数据空间
m_nMaxPoint = points;//保存最大点数
m_pDoc = pDoc;
m_fMinX = m_pDoc->m_fMinX;m_fMaxX=m_pDoc->m_fMaxX; //从m_pDoc中读取上次保存的数据
m_fMinY = m_pDoc->m_fMinY;m_fMaxY=m_pDoc->m_fMaxY;
if(m_pDoc->mif_gps) //读取MIF文件中的线信息
{
// m_fMinX = m_pDoc->m_fMinX;m_fMaxX=m_pDoc->m_fMaxX; //从m_pDoc中读取上次保存的数据
// m_fMinY = m_pDoc->m_fMinY;m_fMaxY=m_pDoc->m_fMaxY;
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);//读Pen数据
for(i=0; i<BUFSIZ -1 && buf[i]!=','; i++);//检索第一个逗号(,)
for(; i<BUFSIZ -1 && buf[i]!=','; i++);//检索第一个逗号(,)
for(j=i+1; j<BUFSIZ -1 && buf[j]!=','; j++);//检索第一个逗号(,)
m_nColor = atof(buf+j+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//读取GPS文件中的线信息
{
int ONum=0;
ONum=m_pDoc->ONum;
pline[ONum].longitude = new double[points];//申请数据空间
pline[ONum].latitude = new double[points];//申请数据空间
pline[ONum].pointnum =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;
*(pline[ONum].longitude+i) = f1;
for(; j<BUFSIZ - 1 && buf[j]!=' '; j++);//跳过空格间隔
f2 = atof(buf+j+1);//纬度
*(m_pData+2*i+1) = f2;
*(pline[ONum].latitude+i) = 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));//读当前多边形端点数
ONum++;
m_pDoc->ONum=ONum;
}
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 CMapPLine::Draw(CDC* pDC)
{
if((m_nMaxPoint < 2) | (!IsInView()))
return;
// CPen pen(PS_SOLID, 1, m_nColor/* 此时 m_nColor = 0 */), *oldpen;
// oldpen = pDC->SelectObject(&pen);//设置绘制笔颜色
long* data = m_pDoc->m_pData;
CPen pen(PS_SOLID, 1, m_nColor/* 此时 m_nColor = 0 */), *oldpen;
m_pDoc->ConvToXYs(m_pData, data, m_nMaxPoint);//经纬度(度)->直角坐标多点转换
m_pDoc->LPtoDPs(data, m_nMaxPoint);//将逻辑坐标转换为显示坐标
oldpen = pDC->SelectObject(&pen);//设置绘制笔颜色
pDC->Polyline((LPPOINT)data, m_nMaxPoint);//画折线
pDC->SelectObject(oldpen);//恢复DC缺省值
//删除资源
pen.DeleteObject();
}
//*******************************************
//*********** CMapLayer ********************
//*******************************************
CString CMapLayer::GetFirstPara(CString& str) //读取mif数据,读取对象名称标示字符串
{
int i, j;
char* buf;
buf = (char*)LPCTSTR(str);
for(i=0;i<BUFSIZ - 1 && buf[i] == ' '; i++);
for(j=i;j<BUFSIZ - 1 && buf[j] != ' '; j++);
return str.Mid(i, j-i);
}
int CMapLayer::GetSecondPara(CString& str) //读取对象个数
{
int i, j;
char* buf;
buf = (char*)LPCTSTR(str);
for(i=0;i<BUFSIZ - 1 && buf[i] == ' '; i++);//去除第一项前导空格
for(;i<BUFSIZ - 1 && buf[i] != ' '; i++);//到第一项结束
for(;i<BUFSIZ - 1 && buf[i] == ' '; i++);//去除第二项前导空格
for(j=i;j<BUFSIZ - 1 && buf[j] != ' '; j++);
return atoi(LPCTSTR(str.Mid(i, j-i)));
}
CString CMapLayer::GetObjectName(CString &str)
{
int i, j;
char* buf;
buf = (char*)LPCTSTR(str);
for(i=0;i<BUFSIZ - 1 && buf[i] == ' '; i++);//去除第一项前导空格
for(;i<BUFSIZ - 1 && buf[i] != ' '; i++);//到第一项结束
for(j=i; j<BUFSIZ - 1 && buf[j] != '\"'; j++);//去掉前导空格和前引号
for(j=++i; j<BUFSIZ - 1 && buf[j] != '\"'; j++);//去掉后引号
buf[j] = '\0';
return buf+i;
}
CMapLayer::CMapLayer()
{
m_fMinX=180;
m_fMaxX=-180;
m_fMinY=90;
m_fMaxY=-90;
n_point=false;
n_CancelFind=false;
}
CMapLayer::~CMapLayer()
{
int i;
int j=m_aObject.GetSize();
for(i=0; i<j; i++)
{//删除全部海图图元
delete m_aObject.GetAt(i);
}
//清理图元指针列表
m_aObject.RemoveAll();
}
CMapLayer::CMapLayer(CMapTestDoc *pDoc, CArchive &ar)
{
CString str, str1;
int p=0,j,k;
CMapObject* object;
m_pDoc = pDoc;
m_nMaxPoint = 0;
m_bCanDraw = true;
while(ar.ReadString(str))
{
str1=GetFirstPara(str); //读取对象名称字符串
if(str1=="Pline" || str1=="PL")
{//折线图元
j=GetSecondPara(str);//读折线端点数
object = new CMapPLine(pDoc, ar, j);
m_aObject.Add(object);
m_nMaxPoint = m_nMaxPoint > object->m_nMaxPoint ? m_nMaxPoint : object->m_nMaxPoint;
///////////////////////////////////////
//保存对象边界值
m_fMinX = m_fMinX < object->m_fMinX ? m_fMinX : object->m_fMinX;
m_fMaxX = m_fMaxX > object->m_fMaxX ? m_fMaxX : object->m_fMaxX;
m_fMinY = m_fMinY < object->m_fMinY ? m_fMinY : object->m_fMinY;
m_fMaxY = m_fMaxY > object->m_fMaxY ? m_fMaxY : object->m_fMaxY;
}
else if(str1=="Point"||str1=="P")
{
object = new CMapPoint(pDoc,ar,str);
m_aObject.Add(object);
//m_nMaxPoint = m_nMaxPoint > object->m_nMaxPoint ? m_nMaxPoint : object->m_nMaxPoint;
m_fMinX = m_fMinX < object->m_fMinX ? m_fMinX : object->m_fMinX;
m_fMinY = m_fMinY < object->m_fMinY ? m_fMinY : object->m_fMinY;
Num[p][0]=object->m_fMinX;
Num[p][1]=object->m_fMinY;
p++;
object->p=p;
}
else if(str1=="Text")
{
object = new CMapText(pDoc, ar);
m_aObject.Add(object);
m_nMaxPoint = m_nMaxPoint > object->m_nMaxPoint ? m_nMaxPoint : object->m_nMaxPoint;
///////////////////////////////////////
//保存对象边界值
m_fMinX = m_fMinX < object->m_fMinX ? m_fMinX : object->m_fMinX;
m_fMinY = m_fMinY < object->m_fMinY ? m_fMinY : object->m_fMinY;
m_fMaxX = m_fMaxX > object->m_fMaxX ? m_fMaxX : object->m_fMaxX;
m_fMaxY = m_fMaxY > object->m_fMaxY ? m_fMaxY : object->m_fMaxY;
}
else if(str1=="Region" || str1=="Rg")
{//区域图元
j=GetSecondPara(str); //读多边形个数
for(int i=0;i<j;i++)
{//创建多边形对象
ar.ReadString(str);
k = atoi(LPCTSTR(str));//读当前多边形端点数
object = new CMapRegion(pDoc, ar,k);
m_aObject.Add(object);
m_nMaxPoint = m_nMaxPoint > object->m_nMaxPoint ? m_nMaxPoint : object->m_nMaxPoint;
///////////////////////////////////////
//保存对象边界值
m_fMinX = m_fMinX < object->m_fMinX ? m_fMinX : object->m_fMinX;
m_fMaxX = m_fMaxX > object->m_fMaxX ? m_fMaxX : object->m_fMaxX;
m_fMinY = m_fMinY < object->m_fMinY ? m_fMinY : object->m_fMinY;
m_fMaxY = m_fMaxY > object->m_fMaxY ? m_fMaxY : object->m_fMaxY;
}
}
}
}
void CMapLayer::Draw(CDC *pDC, long style)
{
int i;
int j = m_aObject.GetSize(); //返回图元对象数组中图元个数
for(i=0; i<j; i++)
{
CMapObject* object = m_aObject.GetAt(i);
if(object->m_nStyle == style)
object->Draw(pDC);
}
}
CMapText::CMapText(CMapTestDoc *pDoc, CArchive &ar)
{
int i, j;
char buf[BUFSIZ];
m_nMaxPoint = 2; //图元端点点数
m_pDoc = pDoc;
m_nStyle = IDS_TEXT;
ar.ReadString(buf, BUFSIZ - 1);//读需显示字符串
for(i=0; i<BUFSIZ - 1 && buf[i] != '\"'; i++);//去掉前导空格和前引号
for(j=++i; j<BUFSIZ - 1 && buf[j] != '\"'; j++);//去掉后引号
buf[j] = '\0';
m_strText = buf+i;
ar.ReadString(buf, BUFSIZ - 1 );
for(i=0; i<BUFSIZ - 1 && buf[i]==' '; i++);
m_fMinX = atof(buf+i);//第一点经度
for(; i<BUFSIZ - 1 && buf[i]!=' '; i++);
m_fMinY = atof(buf + ++i);//第一点纬度
for(; i<BUFSIZ - 1 && buf[i]!=' '; i++);
m_fMaxX = atof(buf + ++i);//第二点经度
for(; i<BUFSIZ - 1 && buf[i]!=' '; i++);
m_fMaxY = atof(buf + ++i);//第二点纬度
}
void CMapText::Draw(CDC *pDC)
{
long x1, y1;//左上角
long x2, y2;//右下角
long fontheight;
//转换经纬度到屏幕坐标
m_pDoc->ConvToXY(m_fMaxX, m_fMaxY, x2, y1);//经纬度(度)->直角坐标
m_pDoc->ConvToXY(m_fMinX, m_fMinY, x1, y2);
m_pDoc->LPtoDP(x1, y1); //地图逻辑坐标转换为屏幕坐标
m_pDoc->LPtoDP(x2, y2);
CRect rect(x1, y1, x2, y2);//定义字符输出区域
//计算字符高度
fontheight = rect.Width() * 2 / m_strText.GetLength();
if((!fontheight) | (!IsInView()))
return;
CFont font, *oldfont;
font.CreateFont(fontheight, 0, 0, 0, FW_NORMAL, false, false, false,
DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY, DEFAULT_PITCH, "宋体");//创建字体
//设置DC字体和背景模式
oldfont = pDC->SelectObject(&font);
int oldbkmode;
oldbkmode = pDC->SetBkMode(TRANSPARENT);//文字背景透明
pDC->TextOut(x1, y1, m_strText);
//恢复DC设置
pDC->SelectObject(oldfont);
pDC->SetBkMode(oldbkmode);
font.DeleteObject();//删除CFont资源
}
CMapPoint::CMapPoint(CMapTestDoc *pDoc,CArchive& ar,CString str)
{
int i,j,k;
char* buf;
buf = (char*)LPCTSTR(str);
m_pDoc = pDoc;
m_nStyle = IDS_POINT;
for(i=0; i<BUFSIZ - 1 && buf[i]==' '; i++); ///跳过前导空格
for(;i<BUFSIZ - 1 && buf[i] != ' '; i++);//到第一项结束
m_fMinX = m_pDoc->m_fMinX;m_fMaxX=m_pDoc->m_fMaxX; //从m_pDoc中读取上次保存的数据
m_fMinY = m_pDoc->m_fMinY;m_fMaxY=m_pDoc->m_fMaxY;
if(m_pDoc->mif_gps) //读取MIF文件中的信息
{
for(;i<BUFSIZ - 1 && buf[i] == ' '; i++);//去除第二项前导空格
for(j=i;j<BUFSIZ - 1 && buf[j] != ' '; j++);
m_fMinX = atof(LPCTSTR(str.Mid(i, j-i)));//点经度
for(;j<BUFSIZ - 1 && buf[j] == ' '; j++);//去除第三项前导空格
for(k=j; k<BUFSIZ - 1 && buf[k] != ' '; k++);
m_fMinY = atof(LPCTSTR(str.Mid(j-1,k-j)));//点纬度
//保存对象边界值
m_fMinX = m_fMinX < m_fMinX ? m_fMinX : m_fMinX;
m_fMinY = m_fMinY < m_fMinY ? m_fMinY : m_fMinY;
m_fMaxX = m_fMaxX > m_fMinX ? m_fMaxX : m_fMinX;
m_fMaxY = m_fMaxY > m_fMinY ?m_fMaxY : m_fMinY;
}
else //读取GPS文件中的信息
{
int ONum=0;
ONum=m_pDoc->ONum;
for(;i<BUFSIZ - 1 && buf[i] != '\"'; i++);//到第一项结束
for(;i<BUFSIZ - 1 && buf[i] == '\"'; i++);//去除第二项前导空格
for(j=i;j<BUFSIZ - 1 && buf[j] != '\"'; j++);
point[ONum].name= str.Mid(i, j-i);
//读取对象经纬度
ar.ReadString(buf, BUFSIZ - 1);
for(j=0; j<BUFSIZ - 1 && buf[j]==' '; j++);//跳过前导空格
point[ONum].longitude = atof(buf+j);//经度
for(; j<BUFSIZ - 1 && buf[j]!=' '; j++);//跳过空格间隔
point[ONum].latitude =atof(buf+j+1);//纬度
ONum++;
m_pDoc->ONum=ONum;
}
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 CMapPoint::Draw(CDC *pDC)
{
long x, y;//点坐标
CFont font, *oldfont;
font.CreateFont(10, 0, 0, 0, FW_NORMAL, false, false, false,
DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY, DEFAULT_PITCH, "宋体");//创建字体
int oldbkmode;
//设置DC字体和背景模式
oldfont = pDC->SelectObject(&font);
oldbkmode = pDC->SetBkMode(TRANSPARENT);//文字背景透明
CPen pen(PS_SOLID, 1, m_nColor/* 此时 m_nColor = 0 */), *oldpen;
oldpen = pDC->SelectObject(&pen);//设置绘制笔颜色
if(!m_pDoc->mif_gps) //绘制打开的GPS文件中的信息
{
for(int n=0;n<m_pDoc->ONum;n++)
{
long x1,y1;
m_pDoc->ConvToXY(point[n].longitude,point[n].latitude, x1, y1);
m_pDoc->LPtoDP(x1, y1);
int m=point[n].name.GetLength();
pDC->Ellipse(x1+3,y1+3,x1-3,y1-3);
pDC->TextOut(x1-m,y1,point[n].name);
}
}
else //绘制MIF文件中的信息
{
//转换经纬度到屏幕坐标
m_pDoc->ConvToXY(m_fMinX, m_fMinY, x, y);
m_pDoc->LPtoDP(x, y);
// pDC->SetPixel(x1, y1, 0);// 绘像素点
pDC->Ellipse(x-2,y-2,x+2,y+2);
Nam[p]=m_pDoc->Nam[p-1];
pDC->TextOut(x,y,Nam[p]);
// AfxMessageBox(Nam[p]);
}
pDC->SelectObject(oldpen);//恢复DC缺省值
//删除资源
pen.DeleteObject();
}
//*********** CMapRegion ********************
//*******************************************
CMapRegion::CMapRegion(CMapTestDoc* pDoc, CArchive& ar, int points)
{
int i, j;
char buf[BUFSIZ];
double f1, f2;
m_pDoc = pDoc;
m_nStyle = IDS_POLYGON;
m_fMinX = m_pDoc->m_fMinX;m_fMaxX=m_pDoc->m_fMaxX; //从m_pDoc中读取上次保存的数据
m_fMinY = m_pDoc->m_fMinY;m_fMaxY=m_pDoc->m_fMaxY;
if(m_pDoc->mif_gps) //读取MIF文件中的线信息
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -