1. 程式人生 > >在MFC中繪製地圖以及地理座標與螢幕座標轉換詳解(附工程原始碼)

在MFC中繪製地圖以及地理座標與螢幕座標轉換詳解(附工程原始碼)

在MFC中繪圖時,因為都是以畫素為單位的,所以我們只能以整數作為引數。如果我們想要把一幅地圖資料繪製在MFC視窗中,地圖的座標資料肯定的含有小數位的,這樣我們就不能直接在MFC中繪製地圖了,這就涉及到地理座標向螢幕座標的轉換。

1、地理座標轉螢幕座標

首先我們看一張圖(圖片來源於網路,若涉及版權,請聯絡我刪除),這張圖片直接的描述了螢幕座標和地理座標之間的關係,採用的相似比法,其實就是對一個圖形,按照一定的比例因子,進行縮放。但是這裡需要多進行一步處理,因為螢幕座標的起始點在左上角,向右位X軸正方向,向下位Y軸正方向,而在地理座標系中,座標起始點在左下方,向右位X軸正反向,向上位Y軸正方向,所以在計算Y軸方向比例因子時,要將螢幕最大值減去y軸座標,這樣兩個座標資料才有可比性,相當於是把螢幕座標的原點移到左下角了。

計算過程如下:

兩個座標的轉換是通過相似比的來實現的,根據上圖我們可以得到如下的公式

已知地理座標的範圍:minlon   minlat    maxlon   maxlat

螢幕的尺寸: 寬  W   高   H

則X方向的比例尺為

ScaleX = W /(maxlon - minlon)

Y方向的比例尺為

ScaleY = H / (maxlat - minlat)

設地理座標為(lon , lat),其對應的螢幕座標為(x , y)

則有一下等式成立

x      / (lon - minlon) =  ScaleX

y       / (maxlat - lat) =  ScaleY

【注意】這裡的Y座標,因為兩個座標系的Y軸方向時相反的,所以為了保證他們的一直,我們做了一些處理,使他們的值具有可比性

x = (lon - minlon) * ScaleX;

y = (maxlat - lat) * ScaleY;

螢幕座標轉地理座標可反向計算,這裡就不再詳細分析。

 2、在MFC視窗中繪製湖北省地圖

(1)MFC工程建立的詳細步驟就不再細說,這裡我沿用上次部落格建立的MFC工程,在【畫圖】選單下新增一個子選單【畫湖北】,並新增事件處理程式。

(3)這裡讀進去的是地理座標,將地理座標轉換為螢幕座標

我們假設ScaleX = ScaleY = 0.01;

地理座標的範圍為minlon   minlat    maxlon   maxlat

根據上面的公式,得到如下計算公式,這裡的計算結果因為“/”的關係,自動轉成了整數,所以不需要我們在進行一次轉換。

將地理座標乘以3600,是為了保證資料的精度,將度轉換為秒

points[i].x=(x-minlon)*3600/100;

points[i].y=(maxlat-y)*3600/100;

(4)最後呼叫繪圖函式繪製湖北省的邊界。

完整程式碼如下:

//定義一個點陣列
	CPoint points[1000];
	//定義一個檔案指標
	FILE *fp;
	//初始化檔案指標,r表示只讀
	fp = fopen("E:/hubei.txt", "r");

	float x,y;
	int i=0;
	//判斷檔案指標是否為空
	while (!feof(fp)){
		//若不為空,則往後讀取兩位整數型別,儲存到X,Y中,讀取的同時,檔案指標也會向後移
		//假設比例尺為1:100
		//為了保證資料的精度,將單位度轉換為秒
		int minlon=108 , minlat=29 ,  maxlon=117 , maxlat=34;
		fscanf(fp, "%f%f", &x, &y);
		points[i].x=(x-minlon)*3600/100;
		points[i].y=(maxlat-y)*3600/100;

		i++;
	}
	//關閉檔案,這一步很重要,C++程式設計中,所有開啟的檔案,最後一定要關閉
	fclose(fp);
	//構造一個DC,傳入當前物件.表示在當前物件使用.
	CClientDC dc(this);
	//建立一個畫筆.(線的型別, 寬度, 顏色);
	CPen pen(PS_SOLID, 1, RGB(255, 0, 255));
	//把畫筆選到設定描述表當中.覆蓋預設畫筆.
	dc.SelectObject(&pen);
	//polygon方法的兩個引數分別為構成線的點集,以及點的個數
	dc.Polygon(points,i);

最終效果如下:

原始碼和資料下載地址:

若連結失效,請留言。