您的位置:首页 > 运维架构

Draw_extend使用OpenGL显示数据点

2016-01-12 16:22 375 查看
//alterload_map.dev
//safetyverion2016/1/12
#include<iostream>
#include<fstream>
#include<vector>
#include<stdlib.h>
#include<sstream>//使用istringstream必须包含的头文件
#include<string>
#include"string2num.hpp"
#include"map.hpp"
#include<windows.h>
#include<GL/glut.h>
usingnamespacestd;

voidtest_map(){

unsignedintsum;doubleSa;
doublenorth=polys[0]->north();
doublesouth=polys[0]->south();
doubleeast=polys[0]->east();
doublewest=polys[0]->west();
for(inti=0;i<polys.size();i++){
sum+=polys[i]->points.size();
Sa+=polys[i]->area();
}
for(inti=0;i<polys.size();i++){
//比较每一个polygon的边界值,求出整个地图的四个边界值
if(polys[i]->north()>=north)north=polys[i]->north();
if(polys[i]->south()<=south)south=polys[i]->south();
if(polys[i]->east()>=east)east=polys[i]->east();
if(polys[i]->west()<=west)west=polys[i]->west();
}

ofstreamout("map_para.txt");
if(out.is_open())
{
out<<"mapparameter:\n";
out<<"countpolygon="<<polys.size()<<endl;
out<<"size="<<sum<<endl;
out<<"area="<<Sa<<endl;
out<<"north="<<north<<endl;
out<<"south="<<south<<endl;
out<<"east="<<east<<endl;
out<<"west="<<west<<endl;
out.close();
}
}

voiddisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT);
//用蓝色色绘制各省边界
glColor3f(0.0,0.0,1.0);
glPolygonMode(GL_BACK,GL_LINE);
for(inti=0;i<polys.size();i++)
{
vector<MapPoint>points=polys[i]->points;
glBegin(GL_LINE_STRIP);
for(intj=0;j<points.size();j++)
{
glVertex3f(points[j].longitude,points[j].latitude,0.0);
}
glEnd();
}
glFlush();
}
voidinit(void)
{
//设置背景颜色
glClearColor(0,1.0,0,0.0);
//初始化观察值
glMatrixMode(GL_PROJECTION);//将矩阵模式设为投影
glLoadIdentity();//对矩阵进行单位化
glOrtho(110.0,118.0,30.0,38.0,-1.0,1.0);//构造平行投影矩阵
}

intmain(intargc,char*argv[]){
//数据文件请到http://files.cnblogs.com/opengl/HenanCounty.rar下载放到D盘根目录下并解压
stringfilename="HenanCounty.txt";//在当前工程目录下
//ReadData2num(filename);
polys=ReadMapData(filename);
test_map();

glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);//单缓存和RGB
glutInitWindowSize(500,500);
glutInitWindowPosition(100,100);
glutCreateWindow("Map_henan");
init();
glutDisplayFunc(display);//显示回调函数
glutMainLoop();

return0;
}




"HenanCounty.txt"是一份文本格式的地图:




单个整数代表点数(包含的点可能是某个省内市区的范围),整数n下面紧接着的数据行共有n行,是以经纬度表示的地理坐标。
程序运行结果:




关于地图的信息(多边形数目、总点数、面积、边界)通过test_map()函数写入map_para.txt



目前算得的面积还有问题,这通过边界值就可以看出来,这还有待解决。

string2num.hpp定义了模板函数用于字符串形式的数字向基本数值类型的转化(其实这个定义比较多余<sstream>里面定义的字符串处理类包含此功能)

#ifndef_STRING2NUM_HPP_
#define_STRING2NUM_HPP_
#include<sstream>//使用istringstream必须包含的头文件
#include<string>
usingnamespacestd;
//模板函数:将string类型变量转换为常用的数值类型bymaowei
template<classType>
TypestringToNum(conststring&str)
{
istringstreamiss(str);
Typenum;
iss>>num;
returnnum;
}

#endif


map.hpp包括了基本类的定义,这是在map_origin.cpp的基础上修改得到的,主要是增加了一些获取地图信息相关的函数。其中多边形容器的定义部分值得充分学习消化。

#ifndef_MAP_HPP_
#define_MAP_HPP_
#include<vector>
#include<math.h>
usingnamespacestd;
classMapPoint
{
public:
doublelongitude;//经度
doublelatitude;//纬度
MapPoint(){}
MapPoint(doublex,doubley){longitude=x;latitude=y;}
};
classMap
{
public:
intmapsize;
vector<MapPoint>points;//多边形的顶点序列
Map(){}
Map(inti){mapsize=i;}
};

//unsignedintcount,num;
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%translatefromorigin
classPolygon
{
public:
vector<MapPoint>points;//多边形的顶点序列
doublearea(void){
doubleA=0;unsignedintN=points.size();
for(inti=0;i<(N-1);i++){
A+=fabs(points[i].longitude*points[i+1].latitude-points[i].latitude*points[i+1].longitude);
}
A+=fabs(points[N-1].longitude*points[0].latitude-points[N-1].latitude*points[0].longitude);
returnA/2;
}
doublenorth(void){
doubleN=points[0].latitude;
for(inti=0;i<points.size();i++){if(points[i].latitude>=N)N=points[i].latitude;}
returnN;
}
doublesouth(void){
doubleS=points[0].latitude;
for(inti=0;i<points.size();i++){if(points[i].latitude<=S)S=points[i].latitude;}
returnS;
}
doubleeast(void){
doubleE=points[0].longitude;
for(inti=0;i<points.size();i++){if(points[i].longitude>=E)E=points[i].longitude;}
returnE;
}
doublewest(void){
doubleW=points[0].longitude;
for(inti=0;i<points.size();i++){if(points[i].longitude<=W)W=points[i].longitude;}
returnW;
}
};
vector<Polygon*>polys;//多边形集合
vector<Polygon*>ReadMapData(conststringfilename)
{
intPointCount;
vector<Polygon*>polygons;
ifstreamfs(filename.c_str());
while(fs.eof()!=true)
{
Polygon*poly=newPolygon;
fs>>PointCount;
//cout<<PointCount<<endl;
for(inti=0;i<PointCount;i++)
{
MapPointp;
fs>>p.longitude>>p.latitude;
poly->points.push_back(p);
}
polygons.push_back(poly);

}
returnpolygons;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

MapReadData2num(conststringstr)//逐行读取并转化为常用数据类型bymememagic
{
cout<<"startreadmap"<<endl;
ifstreamfin(str.c_str());
if(!fin.is_open())
{cout<<"Erroropeningfile";exit(1);}
strings;MapImap;
intSize=0,i=0;boolflag;
while(getline(fin,s))
{
if(i==Size){ints_i=stringToNum<int>(s);Size=s_i+1;i=0;//count+=s_i;num++;
//cout<<"(vertexnum):"<<s_i<<endl;
}
else
{
istringstreamis(s);//采用istringstream从string对象str中读取字符
strings1;doublex,y;
while(is>>s1){
doubles_d=stringToNum<double>(s1);
if(!flag){x=s_d;flag=!flag;}
else{y=s_d;flag=!flag;}
//cout<<s_d<<'';
}
//cout<<"x="<<x<<''<<"y="<<y<<endl;
MapPointp(x,y);
Imap.points.push_back(p);
}
i++;
}
returnImap;
}

#endif


与Draw_v1相比,这个程序有了不少变化:数据来源不再靠手工在命令窗口输入,而是一个有确定“格式”的简单文本,数据量也较大,程序里面对数据的处理代码自然不同;多边形容器(vector<Polygon*>polys)是对图形(vector<Shape>)容器的拓展;利用OpenGL实现了数据的可视化(关于OpenGL绘图的原理有待进一步学习理解).


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: