zoukankan      html  css  js  c++  java
  • Draw_extend使用OpenGL显示数据点

    //alter load_map.dev
    //safety verion 2016/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>
        using namespace std;
        
        void test_map(){
        
        unsigned int sum;double Sa;
        double north=polys[0]->north();
        double south=polys[0]->south();
        double east=polys[0]->east();
        double west=polys[0]->west();
        for(int i=0;i<polys.size();i++){
            sum+=polys[i]->points.size();
            Sa+=polys[i]->area();
        }
        for(int i=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();
        }
        
        ofstream out("map_para.txt");
            if(out.is_open())
            {
                out <<"map parameter:
    ";
                out<<"count polygon="<<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();
            }
    }
    
        
        
    void display(void)
    {   
        glClear (GL_COLOR_BUFFER_BIT);   
        //用蓝色色绘制各省边界
        glColor3f (0.0, 0.0, 1.0);
        glPolygonMode(GL_BACK, GL_LINE);    
        for(int i=0;i<polys.size();i++)
        {       
            vector<MapPoint> points=polys[i]->points;
            glBegin(GL_LINE_STRIP);
            for(int j=0;j<points.size();j++)
            {           
                glVertex3f (points[j].longitude, points[j].latitude, 0.0);       
            }
            glEnd();
        }   
        glFlush();
    }
    void init (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);   //构造平行投影矩阵
    }
    
        
        
         int main(int argc, char *argv[]){
        //数据文件请到http://files.cnblogs.com/opengl/HenanCounty.rar下载放到D盘根目录下并解压
        string filename="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();
        
        return 0;  
        }
     
    "HenanCounty.txt"是一份文本格式的地图:

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

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

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

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

    #ifndef _STRING2NUM_HPP_
    #define _STRING2NUM_HPP_
    #include<sstream>  //使用istringstream必须包含的头文件 
    #include<string>
    using namespace std;
    //模板函数:将string类型变量转换为常用的数值类型  by maowei
    template <class Type>
    Type stringToNum(const string& str)
    {
        istringstream iss(str);
        Type num;
        iss>>num;
        return num;
    }
    
    #endif

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

    #ifndef _MAP_HPP_
    #define _MAP_HPP_
    #include <vector>
    #include <math.h>
    using namespace std;
        class MapPoint
    {
    public:
        double longitude;//经度 
        double latitude;//纬度 
        MapPoint(){}
        MapPoint(double x,double y){longitude=x;latitude=y;}
    };
    class Map
    {
    public:
        int mapsize;
        vector<MapPoint> points; //多边形的顶点序列
        Map(){}
        Map(int i){mapsize=i;}
    };
    
    
    //unsigned int count,num;
    //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%translate from origin
    class Polygon
    {
    public:
        vector<MapPoint> points; //多边形的顶点序列
        double area(void){
            double A=0;unsigned int N=points.size();
            for(int i=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);
            return A/2;
        }
        double north(void){
            double N=points[0].latitude;
            for(int i=0;i<points.size();i++){if(points[i].latitude>=N)N=points[i].latitude;    }
            return N;
        } 
        double south(void){
            double S=points[0].latitude;
            for(int i=0;i<points.size();i++){if(points[i].latitude<=S)S=points[i].latitude;    }
            return S;
        } 
        double east(void){
            double E=points[0].longitude;
            for(int i=0;i<points.size();i++){if(points[i].longitude>=E)E=points[i].longitude;    }
            return E;
        } 
        double west(void){
            double W=points[0].longitude;
            for(int i=0;i<points.size();i++){if(points[i].longitude<=W)W=points[i].longitude;    }
            return W;
        } 
    };
    vector<Polygon*> polys; //多边形集合
    vector<Polygon*> ReadMapData(const string filename)
    {
        int PointCount;
        vector<Polygon*> polygons;
        ifstream fs(filename.c_str());
        while(fs.eof()!=true)
        {
            Polygon* poly=new Polygon;
            fs>>PointCount;
           // cout<<PointCount<<endl;
            for(int i=0;i<PointCount;i++)
            {
                MapPoint p;
                fs>>p.longitude>>p.latitude;
                poly->points.push_back(p);
            }
            polygons.push_back(poly);
    
        }
        return polygons;
    }
    //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    
    Map ReadData2num(const string str)  //逐行读取 并转化为常用数据类型 by mememagic
    {
        cout<<"start read map"<<endl;
        ifstream fin(str.c_str());  
        if (! fin.is_open())
            { cout << "Error opening file"; exit (1); }
        string s;  Map Imap;   
        int Size=0,i=0;bool flag;
        while( getline(fin,s) ) 
        {    
            if(i==Size){int s_i=stringToNum<int>(s);Size=s_i+1;i=0;//count+=s_i;num++;
            //cout << "(vertex num): " << s_i << endl;
            }
            else
            {
            istringstream is(s);//采用istringstream从string对象str中读取字符 
            string s1;double x,y;
            while(is>>s1){
                double s_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;
            MapPoint p(x,y);
            Imap.points.push_back(p);
            }  
            i++;
        }
        return Imap;
    }
    
    
    
    #endif

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

    
    
  • 相关阅读:
    H: Dave的组合数组(二分法)
    G: Dave的时空迷阵(next数组)
    计蒜客 X的平方根(二分法)
    最短路径四种方法
    POJ 2001 Shortest Prefixes(字典树活用)
    HDU 1671 Phone List (qsort字符串排序与strncmp的使用 /字典树)
    快速排序原理
    抓捕盗窃犯
    Hash函数
    Monkey King(左偏树 可并堆)
  • 原文地址:https://www.cnblogs.com/mememagic/p/5124757.html
Copyright © 2011-2022 走看看