?? 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 + -