Qgs开发18-读取栅格数据

Qgs开发-读取栅格数据

[email protected]

2014年10月28日

 

1  目的:加载栅格并取得指定点(经纬度或行/列号)的像素值

2 原理:计算像素值位置,读取数据

通过驱动程序将栅格读入内存,并按照像素的实际大小,计算内存位置,读取数据。

驱动程序提供相应的计算接口。

3 方法

3.1 加载数据

通过驱动(默认GDAL(key=”gdal”)等),读入Raster数据(QgsRasterLayer)。然后读取数据的内存地址(QgsRasterDataProvider::block())(如果数据过大,则需要分块读取)。

3.2 读取数据

可以通过block()加载数据块,但是此块不能太大。对于大数据(实测超过1G大小,bValid=false,bEmpty=true),只能使用分块读取的方法。小数据(实测不超过1G,但并没有找到官方说明)可以直接取得全部范围并根据行列号取得像素值(QgsRasterDataProvider取得QgsRasterBlock)。

QgsRasterBlock提供value(row,col)取影像数据的行、列号数据。但分块时要重新计算范围,实际上就是QgsRasterDataProvider::Identify()的算法。小数据可以直接使用,方便。

对于经纬度,使用QgsRasterDataProvider::Identify(),会先将经纬度转换为行列号,然后计算读取1*1范围(单个像素)大小的像素值。

4 示例

/**************************************************************************

* @file QgsVectorAnalysis.cpp

* @brief analysis core funtion

*

* analysis core funtion.

* @author [email protected]

* @date 2014-10-20 16:19:16

**************************************************************************/

 

#include "qgsrasteranalysis.h"

#include <qgsrasterlayer.h>

#include <QDebug>

#include <qgsmapcanvas.h>

#include <qgsmapsettings.h>

#include <QgsRasterIdentifyResult.h>

using namespace gutang::qgsmaplib;

 

QgsRasterAnalysis::QgsRasterAnalysis()

{

}

 

/**

 * @briefQgsRasterAnalysis::lonLat2ColRow

 *

 * convertlon/lat to raster column number/row number.

 * @param pLayer

 * @param dLon

 * @param dLat

 * @param iCol

 * @param iRow

 * @return

 * @[email protected]

 * @date2014-10-31 10:36:25

 */

int QgsRasterAnalysis::lonLat2ColRow (QgsRasterLayer*pLayer, double dLon, double dLat,

                                      int&iCol, int &iRow)

{

    QgsPointptLeftTop;

    doubledXResolution, dYResolution;

    calculateRasterInfo(pLayer,ptLeftTop, dXResolution, dYResolution);

 

    iCol = qFloor((dLon - ptLeftTop.x ())/dXResolution);

    iRow = qFloor((dLat - ptLeftTop.y ())/dYResolution);

 

    return 0;

}

 

/**

 * @briefQgsRasterAnalysis::colRow2LonLat

 *

 * convert rastercolumn number/row number to lon/lat.

 * @param pLayer

 * @param iCol

 * @param iRow

 * @param dLon

 * @param dLat

 * @param bCentertrue = convert to pixel center lon/lat. false = convert to pixel lefttop cornerlon/lat.

 * @return

 * @[email protected]

 * @date2014-10-31 10:36:25

 */

int QgsRasterAnalysis::colRow2LonLat (QgsRasterLayer*pLayer, int iCol, int iRow,

                                      double&dLon, double &dLat, bool bCenter)

{

    QgsPointptLeftTop;

    doubledXResolution, dYResolution;

   calculateRasterInfo(pLayer, ptLeftTop, dXResolution, dYResolution);

 

    dLon =ptLeftTop.x () + dXResolution*iCol;

    dLat =ptLeftTop.y () + dYResolution*iRow;

 

    if(true ==bCenter)

    {

        dLon +=dXResolution/2;

        dLat +=dYResolution/2;

    }

 

    return 0;

}

 

/**

 * @briefQgsRasterAnalysis::calculateRasterInfo

 *

 * calculateraster layer info.

 * @param pLayer

 * @paramptLeftTop

 * @paramdXResolution

 * @paramdYResolution

 * @[email protected]

 * @date2014-10-31 10:36:25

 */

void QgsRasterAnalysis::calculateRasterInfo(QgsRasterLayer *pLayer, QgsPoint &ptLeftTop,

                                           double &dXResolution, double &dYResolution)

{

    int iRowCount= pLayer->height ();

    int iColCount = pLayer->width ();

    QgsRectanglerExtent = pLayer->extent ();

    QgsPointptLT(rExtent.xMinimum (),rExtent.yMaximum ());

    ptLeftTop =ptLT;

    dXResolution= rExtent.width ()/iColCount;

    dYResolution= rExtent.height ()/iRowCount;

    dYResolution*= -1;//reverse direction

}

 

/**

 * @briefQgsRasterAnalysis::getRasterValue

 *

 * get pixelvalue of raster.

 * @param pLayer

 * @param vPt

 * @paramiBandIndex start from 1

 * @parampFinished finished percent

 * @return

 * @author [email protected]

 * @date2014-10-31 10:36:25

 */

QVector<double> QgsRasterAnalysis::getRasterValue(QgsRasterLayer *pLayer,

                                       constQVector<QgsPoint> &vPt,

                                       intiBandIndex,

                                       int*pFinished)

{

   QgsRasterDataProvider *pProvider = pLayer->dataProvider ();

    if(NULL ==pProvider)

    {

      qDebug()<<"invalid layer.";

       returnQVector<double>();

    }

 

   QVector<double> vValue;

    for(inti=0;i<vPt.size ();++i)

    {

       QgsRasterIdentifyResult rst = pProvider->identify(vPt[i],QgsRaster::IdentifyFormatValue);

        doubledValue = rst.results ()[iBandIndex].toDouble ();

       vValue<<dValue;

       if(pFinished != NULL){

           *pFinished = i;

        }

    }

    returnvValue;

}

 

你可能感兴趣的:(开发,qgis,2.4.0)