在MFC中绘制地图以及地理坐标与屏幕坐标转换详解(附工程源码)

版权声明:未经允许不得以任何形式转载,谢谢! https://blog.csdn.net/XTAOTWO/article/details/84112050

在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工程,在【画图】菜单下添加一个子菜单【画湖北】,并添加事件处理程序。

(2)利用前面博客【c++中txt文件的读取以及在MFC中读取txt坐标数据并完成图形绘制】中讲的文件指针的方法来读取湖北省的坐标文件,如下图所示。

(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);

最终效果如下:

源码和数据下载地址:

链接:https://pan.baidu.com/s/1CX-P5yPMMvEL-wnnWGp07w
提取码:h654 
 

若链接失效,请留言。

 

 

展开阅读全文

没有更多推荐了,返回首页