Esempio n. 1
0
int QgsGrassGisLib::G_get_cellhd( const char *name, const char *mapset, struct Cell_head *cellhd )
{
    Q_UNUSED( mapset );
    initCellHead( cellhd );
    Raster rast = raster( name );

    QgsRasterDataProvider *provider = rast.provider;

    cellhd->rows = provider->ySize();
    cellhd->cols = provider->xSize();
    cellhd->ew_res = provider->extent().width() / provider->xSize();
    cellhd->ns_res = provider->extent().height() / provider->ySize();
    cellhd->north = provider->extent().yMaximum();
    cellhd->south = provider->extent().yMinimum();
    cellhd->east = provider->extent().yMaximum();
    cellhd->west = provider->extent().xMinimum();

    return 0;
}
Esempio n. 2
0
bool QgsRasterChecker::runTest( QString theVerifiedKey, QString theVerifiedUri,
                                QString theExpectedKey, QString theExpectedUri )
{
  bool ok = true;
  mReport += "\n\n";

  //QgsRasterDataProvider* verifiedProvider = QgsRasterLayer::loadProvider( theVerifiedKey, theVerifiedUri );
  QgsRasterDataProvider* verifiedProvider = ( QgsRasterDataProvider* ) QgsProviderRegistry::instance()->provider( theVerifiedKey, theVerifiedUri );
  if ( !verifiedProvider || !verifiedProvider->isValid() )
  {
    error( QString( "Cannot load provider %1 with URI: %2" ).arg( theVerifiedKey ).arg( theVerifiedUri ), mReport );
    ok = false;
  }

  //QgsRasterDataProvider* expectedProvider = QgsRasterLayer::loadProvider( theExpectedKey, theExpectedUri );
  QgsRasterDataProvider* expectedProvider = ( QgsRasterDataProvider* ) QgsProviderRegistry::instance()->provider( theExpectedKey, theExpectedUri );
  if ( !expectedProvider || !expectedProvider->isValid() )
  {
    error( QString( "Cannot load provider %1 with URI: %2" ).arg( theExpectedKey ).arg( theExpectedUri ), mReport );
    ok = false;
  }

  if ( !ok ) return false;

  mReport += QString( "Verified URI: %1<br>" ).arg( theVerifiedUri.replace( "&", "&amp;" ) );
  mReport += QString( "Expected URI: %1<br>" ).arg( theExpectedUri.replace( "&", "&amp;" ) );

  mReport += "<br>";
  mReport += QString( "<table style='%1'>\n" ).arg( mTabStyle );
  mReport += compareHead();

  compare( "Band count", verifiedProvider->bandCount(), expectedProvider->bandCount(), mReport, ok );

  compare( "Width", verifiedProvider->xSize(), expectedProvider->xSize(), mReport, ok );
  compare( "Height", verifiedProvider->ySize(), expectedProvider->ySize(), mReport, ok );

  compareRow( "Extent", verifiedProvider->extent().toString(), expectedProvider->extent().toString(), mReport, verifiedProvider->extent() == expectedProvider->extent() );

  if ( verifiedProvider->extent() != expectedProvider->extent() ) ok = false;


  mReport += "</table>\n";

  if ( !ok ) return false;

  bool allOk = true;
  for ( int band = 1; band <= expectedProvider->bandCount(); band++ )
  {
    bool bandOk = true;
    mReport += QString( "<h3>Band %1</h3>\n" ).arg( band );
    mReport += QString( "<table style='%1'>\n" ).arg( mTabStyle );
    mReport += compareHead();

    // Data types may differ (?)
    bool typesOk = true;
    compare( "Source data type", verifiedProvider->srcDataType( band ), expectedProvider->srcDataType( band ), mReport, typesOk );
    compare( "Data type", verifiedProvider->dataType( band ), expectedProvider->dataType( band ), mReport, typesOk ) ;

    // TODO: not yet sure if noDataValue() should exist at all
    //compare( "No data (NULL) value", verifiedProvider->noDataValue( band ), expectedProvider->noDataValue( band ), mReport, typesOk );

    bool statsOk = true;
    QgsRasterBandStats verifiedStats =  verifiedProvider->bandStatistics( band );
    QgsRasterBandStats expectedStats =  expectedProvider->bandStatistics( band );

    // Min/max may 'slightly' differ, for big numbers however, the difference may
    // be quite big, for example for Float32 with max -3.332e+38, the difference is 1.47338e+24
    double tol = tolerance( expectedStats.minimumValue );
    compare( "Minimum value", verifiedStats.minimumValue, expectedStats.minimumValue, mReport, statsOk, tol );
    tol = tolerance( expectedStats.maximumValue );
    compare( "Maximum value", verifiedStats.maximumValue, expectedStats.maximumValue, mReport, statsOk, tol );

    // TODO: enable once fixed (WCS excludes nulls but GDAL does not)
    //compare( "Cells count", verifiedStats.elementCount, expectedStats.elementCount, mReport, statsOk );

    tol = tolerance( expectedStats.mean );
    compare( "Mean", verifiedStats.mean, expectedStats.mean, mReport, statsOk, tol );

    // stdDev usually differ significantly
    tol = tolerance( expectedStats.stdDev, 1 );
    compare( "Standard deviation", verifiedStats.stdDev, expectedStats.stdDev, mReport, statsOk, tol );

    mReport += "</table>";
    mReport += "<br>";

    if ( !bandOk )
    {
      allOk = false;
      continue;
    }

    if ( !statsOk || !typesOk )
    {
      allOk = false;
      // create values table anyway so that values are available
    }

    mReport += "<table><tr>";
    mReport += "<td>Data comparison</td>";
    mReport += QString( "<td style='%1 %2 border: 1px solid'>correct&nbsp;value</td>" ).arg( mCellStyle ).arg( mOkStyle );
    mReport += "<td></td>";
    mReport += QString( "<td style='%1 %2 border: 1px solid'>wrong&nbsp;value<br>expected value</td></tr>" ).arg( mCellStyle ).arg( mErrStyle );
    mReport += "</tr></table>";
    mReport += "<br>";

    int width = expectedProvider->xSize();
    int height = expectedProvider->ySize();
    QgsRasterBlock *expectedBlock = expectedProvider->block( band, expectedProvider->extent(), width, height );
    QgsRasterBlock *verifiedBlock = verifiedProvider->block( band, expectedProvider->extent(), width, height );

    if ( !expectedBlock || !expectedBlock->isValid() ||
         !verifiedBlock || !verifiedBlock->isValid() )
    {
      allOk = false;
      mReport += "cannot read raster block";
      continue;
    }

    // compare data values
    QString htmlTable = QString( "<table style='%1'>" ).arg( mTabStyle );
    for ( int row = 0; row < height; row ++ )
    {
      htmlTable += "<tr>";
      for ( int col = 0; col < width; col ++ )
      {
        bool cellOk = true;
        double verifiedVal = verifiedBlock->value( row, col );
        double expectedVal = expectedBlock->value( row, col );

        QString valStr;
        if ( compare( verifiedVal, expectedVal, 0 ) )
        {
          valStr = QString( "%1" ).arg( verifiedVal );
        }
        else
        {
          cellOk = false;
          allOk = false;
          valStr = QString( "%1<br>%2" ).arg( verifiedVal ).arg( expectedVal );
        }
        htmlTable += QString( "<td style='%1 %2'>%3</td>" ).arg( mCellStyle ).arg( cellOk ? mOkStyle : mErrStyle ).arg( valStr );
      }
      htmlTable += "</tr>";
    }
    htmlTable += "</table>";

    mReport += htmlTable;

    delete expectedBlock;
    delete verifiedBlock;
  }
  delete verifiedProvider;
  delete expectedProvider;
  return allOk;
}
ProjectorData::ProjectorData( const QgsRectangle &extent, int width, int height, QgsRasterInterface *input, const QgsCoordinateTransform &inverseCt, QgsRasterProjector::Precision precision )
  : mApproximate( false )
  , mInverseCt( inverseCt )
  , mDestExtent( extent )
  , mDestRows( height )
  , mDestCols( width )
  , mDestXRes( 0.0 )
  , mDestYRes( 0.0 )
  , mSrcRows( 0 )
  , mSrcCols( 0 )
  , mSrcXRes( 0.0 )
  , mSrcYRes( 0.0 )
  , mDestRowsPerMatrixRow( 0.0 )
  , mDestColsPerMatrixCol( 0.0 )
  , mHelperTopRow( 0 )
  , mCPCols( 0 )
  , mCPRows( 0 )
  , mSqrTolerance( 0.0 )
  , mMaxSrcXRes( 0 )
  , mMaxSrcYRes( 0 )
{
  QgsDebugMsgLevel( QStringLiteral( "Entered" ), 4 );

  // Get max source resolution and extent if possible
  if ( input )
  {
    QgsRasterDataProvider *provider = dynamic_cast<QgsRasterDataProvider *>( input->sourceInput() );
    if ( provider )
    {
      if ( provider->capabilities() & QgsRasterDataProvider::Size )
      {
        mMaxSrcXRes = provider->extent().width() / provider->xSize();
        mMaxSrcYRes = provider->extent().height() / provider->ySize();
      }
      // Get source extent
      if ( mExtent.isEmpty() )
      {
        mExtent = provider->extent();
      }
    }
  }

  mDestXRes = mDestExtent.width() / ( mDestCols );
  mDestYRes = mDestExtent.height() / ( mDestRows );

  // Calculate tolerance
  // TODO: Think it over better
  // Note: we are checking on matrix each even point, that means that the real error
  // in that moment is approximately half size
  double myDestRes = mDestXRes < mDestYRes ? mDestXRes : mDestYRes;
  mSqrTolerance = myDestRes * myDestRes;

  if ( precision == QgsRasterProjector::Approximate )
  {
    mApproximate = true;
  }
  else
  {
    mApproximate = false;
  }

  // Always try to calculate mCPMatrix, it is used in calcSrcExtent() for both Approximate and Exact
  // Initialize the matrix by corners and middle points
  mCPCols = mCPRows = 3;
  for ( int i = 0; i < mCPRows; i++ )
  {
    QList<QgsPointXY> myRow;
    myRow.append( QgsPointXY() );
    myRow.append( QgsPointXY() );
    myRow.append( QgsPointXY() );
    mCPMatrix.insert( i, myRow );
    // And the legal points
    QList<bool> myLegalRow;
    myLegalRow.append( bool( false ) );
    myLegalRow.append( bool( false ) );
    myLegalRow.append( bool( false ) );
    mCPLegalMatrix.insert( i, myLegalRow );
  }
  for ( int i = 0; i < mCPRows; i++ )
  {
    calcRow( i, inverseCt );
  }

  while ( true )
  {
    bool myColsOK = checkCols( inverseCt );
    if ( !myColsOK )
    {
      insertRows( inverseCt );
    }
    bool myRowsOK = checkRows( inverseCt );
    if ( !myRowsOK )
    {
      insertCols( inverseCt );
    }
    if ( myColsOK && myRowsOK )
    {
      QgsDebugMsgLevel( QStringLiteral( "CP matrix within tolerance" ), 4 );
      break;
    }
    // What is the maximum reasonable size of transformatio matrix?
    // TODO: consider better when to break - ratio
    if ( mCPRows * mCPCols > 0.25 * mDestRows * mDestCols )
      //if ( mCPRows * mCPCols > mDestRows * mDestCols )
    {
      QgsDebugMsgLevel( QStringLiteral( "Too large CP matrix" ), 4 );
      mApproximate = false;
      break;
    }
  }
  QgsDebugMsgLevel( QStringLiteral( "CPMatrix size: mCPRows = %1 mCPCols = %2" ).arg( mCPRows ).arg( mCPCols ), 4 );
  mDestRowsPerMatrixRow = static_cast< float >( mDestRows ) / ( mCPRows - 1 );
  mDestColsPerMatrixCol = static_cast< float >( mDestCols ) / ( mCPCols - 1 );

  QgsDebugMsgLevel( QStringLiteral( "CPMatrix:" ), 5 );
  QgsDebugMsgLevel( cpToString(), 5 );

  // init helper points
  pHelperTop = new QgsPointXY[mDestCols];
  pHelperBottom = new QgsPointXY[mDestCols];
  calcHelper( 0, pHelperTop );
  calcHelper( 1, pHelperBottom );
  mHelperTopRow = 0;

  // Calculate source dimensions
  calcSrcExtent();
  calcSrcRowsCols();
  mSrcYRes = mSrcExtent.height() / mSrcRows;
  mSrcXRes = mSrcExtent.width() / mSrcCols;
}
Esempio n. 4
0
void QgsRasterProjector::calc()
{
    QgsDebugMsg( "Entered" );
    mCPMatrix.clear();
    mCPLegalMatrix.clear();
    delete[] pHelperTop;
    pHelperTop = 0;
    delete[] pHelperBottom;
    pHelperBottom = 0;

    // Get max source resolution and extent if possible
    mMaxSrcXRes = 0;
    mMaxSrcYRes = 0;
    if ( mInput )
    {
        QgsRasterDataProvider *provider = dynamic_cast<QgsRasterDataProvider*>( mInput->srcInput() );
        if ( provider && ( provider->capabilities() & QgsRasterDataProvider::Size ) )
        {
            mMaxSrcXRes = provider->extent().width() / provider->xSize();
            mMaxSrcYRes = provider->extent().height() / provider->ySize();
        }
        // Get source extent
        if ( mExtent.isEmpty() )
        {
            mExtent = provider->extent();
        }
    }

    mDestXRes = mDestExtent.width() / ( mDestCols );
    mDestYRes = mDestExtent.height() / ( mDestRows );

    // Calculate tolerance
    // TODO: Think it over better
    // Note: we are checking on matrix each even point, that means that the real error
    // in that moment is approximately half size
    double myDestRes = mDestXRes < mDestYRes ? mDestXRes : mDestYRes;
    mSqrTolerance = myDestRes * myDestRes;

    const QgsCoordinateTransform* ct = QgsCoordinateTransformCache::instance()->transform( mDestCRS.authid(), mSrcCRS.authid(), mDestDatumTransform, mSrcDatumTransform );

    // Initialize the matrix by corners and middle points
    mCPCols = mCPRows = 3;
    for ( int i = 0; i < mCPRows; i++ )
    {
        QList<QgsPoint> myRow;
        myRow.append( QgsPoint() );
        myRow.append( QgsPoint() );
        myRow.append( QgsPoint() );
        mCPMatrix.insert( i,  myRow );
        // And the legal points
        QList<bool> myLegalRow;
        myLegalRow.append( bool( false ) );
        myLegalRow.append( bool( false ) );
        myLegalRow.append( bool( false ) );
        mCPLegalMatrix.insert( i,  myLegalRow );
    }
    for ( int i = 0; i < mCPRows; i++ )
    {
        calcRow( i, ct );
    }

    while ( true )
    {
        bool myColsOK = checkCols( ct );
        if ( !myColsOK )
        {
            insertRows( ct );
        }
        bool myRowsOK = checkRows( ct );
        if ( !myRowsOK )
        {
            insertCols( ct );
        }
        if ( myColsOK && myRowsOK )
        {
            QgsDebugMsg( "CP matrix within tolerance" );
            mApproximate = true;
            break;
        }
        // What is the maximum reasonable size of transformatio matrix?
        // TODO: consider better when to break - ratio
        if ( mCPRows * mCPCols > 0.25 * mDestRows * mDestCols )
        {
            QgsDebugMsg( "Too large CP matrix" );
            mApproximate = false;
            break;
        }
    }
    QgsDebugMsg( QString( "CPMatrix size: mCPRows = %1 mCPCols = %2" ).arg( mCPRows ).arg( mCPCols ) );
    mDestRowsPerMatrixRow = ( float )mDestRows / ( mCPRows - 1 );
    mDestColsPerMatrixCol = ( float )mDestCols / ( mCPCols - 1 );

    QgsDebugMsgLevel( "CPMatrix:", 5 );
    QgsDebugMsgLevel( cpToString(), 5 );

    // Calculate source dimensions
    calcSrcExtent();
    calcSrcRowsCols();
    mSrcYRes = mSrcExtent.height() / mSrcRows;
    mSrcXRes = mSrcExtent.width() / mSrcCols;

    // init helper points
    pHelperTop = new QgsPoint[mDestCols];
    pHelperBottom = new QgsPoint[mDestCols];
    calcHelper( 0, pHelperTop );
    calcHelper( 1, pHelperBottom );
    mHelperTopRow = 0;
}