⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lesson5view.cpp

📁 这是一个基于gdal处理HDF程序,只实现了基本的功能,细节没进行处理,需要GDAL支持,抛砖引玉,希望认识更多的GDAL开发人员
💻 CPP
字号:
// Lesson5View.cpp : implementation of the CLesson5View class
//

#include "stdafx.h"
#include "Lesson5.h"

#include "Lesson5Doc.h"
#include "Lesson5View.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CLesson5View

IMPLEMENT_DYNCREATE(CLesson5View, CView)

BEGIN_MESSAGE_MAP(CLesson5View, CView)
	//{{AFX_MSG_MAP(CLesson5View)
	ON_WM_CREATE()
	ON_WM_DESTROY()
	ON_WM_PAINT()
	ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
	ON_WM_SIZE()
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CLesson5View construction/destruction

CLesson5View::CLesson5View()
{
	// TODO: add construction code here
	this->m_GLPixelIndex = 0;
    this->m_hGLContext = NULL;
}

CLesson5View::~CLesson5View()
{
}

BOOL CLesson5View::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs
	/*OpenGL需要窗口加上WS_CLIPCHILDREN(创建父窗口使用的Windows风格,用于重绘时裁剪子窗口所覆盖的区域)
	和 WS_CLIPSIBLINGS(创建子窗口使用的Windows风格,用于重绘时剪裁其他子窗口所覆盖的区域)风格*/
	cs.style |= (WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
	return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CLesson5View drawing

void CLesson5View::OnDraw(CDC* pDC)
{
	CLesson5Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here
}

/////////////////////////////////////////////////////////////////////////////
// CLesson5View printing

BOOL CLesson5View::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}

void CLesson5View::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void CLesson5View::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CLesson5View diagnostics

#ifdef _DEBUG
void CLesson5View::AssertValid() const
{
	CView::AssertValid();
}

void CLesson5View::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CLesson5Doc* CLesson5View::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CLesson5Doc)));
	return (CLesson5Doc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CLesson5View message handlers

BOOL CLesson5View::SetWindowPixelFormat(HDC hDC)
{
	//定义窗口的像素格式
  PIXELFORMATDESCRIPTOR pixelDesc=                    // /告诉窗口我们所希望的东东,即窗口使用的像素格式
	{
        sizeof(PIXELFORMATDESCRIPTOR),                    // 上述格式描述符的大小
            1,                                // 版本号
            PFD_DRAW_TO_WINDOW |                        // 格式支持窗口
            PFD_SUPPORT_OPENGL |                        // 格式必须支持OpenGL
            PFD_DOUBLEBUFFER,                        // 必须支持双缓冲
            PFD_TYPE_RGBA,                            // 申请 RGBA 格式
            24,                                // 选定色彩深度
            0, 0, 0, 0, 0, 0,                        // 忽略的色彩位
            0,                                // 无Alpha缓存
            0,                                // 忽略Shift Bit
            0,                                // 无累加缓存
            0, 0, 0, 0,                            // 忽略聚集位
            16,                                // 16位 Z-缓存 (深度缓存)
            0,                                // 无蒙板缓存
            0,                                // 无辅助缓存
            PFD_MAIN_PLANE,                            // 主绘图层
            0,                                // Reserved
            0, 0, 0                                // 忽略层遮罩
    };


    this->m_GLPixelIndex = ChoosePixelFormat(hDC,&pixelDesc);
    if(this->m_GLPixelIndex==0)
    {

        this->m_GLPixelIndex = 1;
        if(DescribePixelFormat(hDC,this->m_GLPixelIndex,sizeof(PIXELFORMATDESCRIPTOR),&pixelDesc)==0)
        {
			MessageBox("不能设置像素格式","错误",MB_OK|MB_ICONEXCLAMATION);
            return FALSE;
        }
    }

    if(SetPixelFormat(hDC,this->m_GLPixelIndex,&pixelDesc)==FALSE)
    {
		MessageBox("不能设置像素格式","错误",MB_OK|MB_ICONEXCLAMATION);
        return FALSE;
    }

    return TRUE;

}

int CLesson5View::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CView::OnCreate(lpCreateStruct) == -1)
        return -1;
    
    // TODO: Add your specialized creation code here
    HWND hWnd = this->GetSafeHwnd();    
    HDC hDC = ::GetDC(hWnd);
    if(this->SetWindowPixelFormat(hDC)==FALSE)
    {

        return 0;
    }
    if(this->CreateViewGLContext(hDC)==FALSE)
    {
		MessageBox("不能创建OpenGL渲染描述表","错误",MB_OK|MB_ICONEXCLAMATION);
        return 0;
    }

    return 0;

}

BOOL CLesson5View::CreateViewGLContext(HDC hDC)
{ //产生绘制环境(RC)并使之成为当前绘制环境
	
	this->m_hGLContext = wglCreateContext(hDC);
    if(this->m_hGLContext==NULL)
    {//创建失败
        return FALSE;
    }
    if(wglMakeCurrent(hDC,this->m_hGLContext)==FALSE)
    {//选为当前RC失败
        return FALSE;
    }

    return TRUE;
	
}



void CLesson5View::OnDestroy() 
{
	CView::OnDestroy();
	
	// TODO: Add your message handler code here
	if(wglGetCurrentContext()!=NULL)
    {
        wglMakeCurrent(NULL,NULL);
    }
    if(this->m_hGLContext!=NULL)
    {
        wglDeleteContext(this->m_hGLContext);
        this->m_hGLContext = NULL;
    }
}


int nBufferSizeX,nBufferSizeY;//定义图象窗口长宽
void CLesson5View::OnPaint() 
{
	CPaintDC dc(this); // device context for painting
	
	// TODO: Add your message handler code here
	
	// Do not call CView::OnPaint() for painting messages
	//  glLoadIdentity();
   // glClear(GL_COLOR_BUFFER_BIT);
   /* glBegin(GL_POLYGON);
        glColor4f(1.0f,0.0f,0.0f,1.0f);
        glVertex2f(100.0f,50.0f);
        glColor4f(0.0f,1.0f,0.0f,1.0f);
        glVertex2f(450.0f,400.0f);
        glColor4f(0.0f,0.0f,1.0f,1.0f);
        glVertex2f(450.0f,50.0f);
    glEnd();*/
//	glDrawPixels(nBufferSizeX, nBufferSizeY, GL_LUMINANCE, GL_UNSIGNED_BYTE, pafScanblock1);
   // glFlush();
//	SwapBuffers(dc.m_hDC);
}



void CLesson5View::OnFileOpen() 
{
	// TODO: Add your command handler code here
	char  szFilter[] = "GeoTiff (*.tif)|*.tif|All Files (*.*)|*.*||";
	CString filePath("");
     CFileDialog fileOpenDlg(TRUE, "tif", NULL,OFN_HIDEREADONLY,szFilter);
	 if (fileOpenDlg.DoModal() !=IDOK)
		return;
    else
     {
          VERIFY(filePath = fileOpenDlg.GetPathName());
     }
 
     CString strFilePath(filePath);
     GDALDataset *poDataset;   //GDAL数据集
     GDALAllRegister();
     poDataset = (GDALDataset *) GDALOpen(strFilePath, GA_ReadOnly );

GDALRasterBand *poBand1; //遥感的一个波段
using namespace std; 
vector <GDALDataset *> datasets; 

     if( poDataset == NULL )
     {
         AfxMessageBox("文件打开失败!!!");
         return;
     } 
	GDALDriver * driver=poDataset->GetDriver ();
    string papszMetadata=GDALGetDriverShortName((GDALDriverH)poDataset);    
    int index=papszMetadata.find_first_of("hdf");
    if(index<0)
        index=papszMetadata.find_first_of("HDF");
	 if(index)
    {
        char ** SUBDATASETS = GDALGetMetadata( (GDALDatasetH)poDataset, "SUBDATASETS" );
        if( CSLCount(SUBDATASETS) > 0 )
        {
            for(int  i = 0; SUBDATASETS[i] != NULL; i++ )
            {
                if(i%2==0)
                {
                    string tmpstr=string(SUBDATASETS[i]);
                    tmpstr=tmpstr.substr(tmpstr.find_first_of("=")+1);
                    const char *tmpfilename=tmpstr.c_str();
                    GDALDataset * tmpdt=(GDALDataset *) GDALOpen(tmpfilename, GA_ReadOnly);
                    if(tmpdt)
                    {
                        datasets.push_back(tmpdt);
                    }
                }            
            }
        }
        else
        {
            int bandCount=poDataset->GetRasterCount();
            if(bandCount>0)
            {
                	poBand1=poDataset->GetRasterBand(1);
            }
        }
    }
    if(!datasets.empty())
    {
        int count=datasets.size();
        int bandCount=0;
        for(int i=0;i<count;i++)
        {  
            bandCount+=datasets[i]->GetRasterCount();
            if(datasets[i]->GetRasterCount()>0)
            {
                poBand1=datasets[i]->GetRasterBand(1);
            }
        }
        //for(i=0;i<count;i++)
       // {
         //   delete datasets[i];
          //  datasets[i]=NULL;
      //  }
       // datasets.reserve(0);
    }

	//获取图像的尺寸
    //获取图像窗口尺寸
//	CRect rect;
   // GetClientRect(rect);

	int nImgSizeX=poDataset->GetRasterXSize(); //图象宽度
    int nImgSizeY=poDataset->GetRasterYSize(); //图象高度
	
	/*此处以后建立金子塔*/

	
	nBufferSizeY=800;//nImgSizeY; //图象窗口的高度
	
	float m_fXYRation;
	m_fXYRation = (float)nImgSizeX/(float)nImgSizeY; //图象高宽比
	 //根据图象高宽比和窗口高度计算出需要的窗口宽度,就是说先让纵向铺满
	 //而横向由图象比例决定
	nBufferSizeX = (int)(m_fXYRation*(float)nBufferSizeY); 
	 while( sizeof(BYTE)*(nBufferSizeX) % 4 != 0 )             //重要,如果不修正,可能出现偏差, 修正nBufferSizeX使其为4的倍数
		++nBufferSizeX;

	BYTE *pafScanblock1;
	pafScanblock1 = (BYTE *) CPLMalloc(sizeof(BYTE)*(nBufferSizeX)*(nBufferSizeY)); //分配内存空间
	//利用RasterIO分配到内存
	//注意1、此处GF_Read 需要看是为读还是写 2、GDT_Byte后面需由图象类型决定
	poBand1->RasterIO( GF_Read, 0, 0,nImgSizeX,nImgSizeY,pafScanblock1,nBufferSizeX,nBufferSizeY, GDT_Byte,0, 0 );
	GDALClose(poDataset);
		//翻转图象
	BYTE temp;
	   for(int i=0; i<int(nBufferSizeY/2); i++)
		 for(int j=0; j<nBufferSizeX; j++)
			 {
			  temp = pafScanblock1[i*nBufferSizeX+j];
			  pafScanblock1[i*nBufferSizeX+j] = pafScanblock1[(nBufferSizeY-i-1)*nBufferSizeX+j];
			  pafScanblock1[(nBufferSizeY-i-1)*nBufferSizeX+j] = temp;
			 }
		 glLoadIdentity();
    glClear(GL_COLOR_BUFFER_BIT);
	glDrawPixels(nBufferSizeX, nBufferSizeY, GL_LUMINANCE, GL_UNSIGNED_BYTE, pafScanblock1);
	glFlush();
	CPaintDC dc(this);
	SwapBuffers(dc.m_hDC);
}

void CLesson5View::OnSize(UINT nType, int cx, int cy) 
{
	CView::OnSize(nType, cx, cy);
	
	// TODO: Add your message handler code here
	GLsizei width,height;
    GLdouble aspect;
    width = cx;
    height = cy;
    if(cy==0)
    {
        aspect = (GLdouble)width;
    }
    else
    {
        aspect = (GLdouble)width/(GLdouble)height;
    }
    glViewport(0,0,width,height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0.0,500.0*aspect,0.0,500.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -