Exemplo n.º 1
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;
}
Exemplo n.º 2
0
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;
}
QgsRasterProjector::QgsRasterProjector(
  QgsCoordinateReferenceSystem theSrcCRS,
  QgsCoordinateReferenceSystem theDestCRS,
  QgsRectangle theDestExtent,
  int theDestRows, int theDestCols,
  double theMaxSrcXRes, double theMaxSrcYRes,
  QgsRectangle theExtent )
    : mSrcCRS( theSrcCRS )
    , mDestCRS( theDestCRS )
    , mCoordinateTransform( theDestCRS, theSrcCRS )
    , mDestExtent( theDestExtent )
    , mExtent( theExtent )
    , mDestRows( theDestRows ), mDestCols( theDestCols )
    , mMaxSrcXRes( theMaxSrcXRes ), mMaxSrcYRes( theMaxSrcYRes )
{
  QgsDebugMsg( "Entered" );
  QgsDebugMsg( "theDestExtent = " + theDestExtent.toString() );

  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 taht the real error
  // in that moment is approximately half size
  double myDestRes = mDestXRes < mDestYRes ? mDestXRes : mDestYRes;
  mSqrTolerance = myDestRes * myDestRes;

  // 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 );
  }
  for ( int i = 0; i < mCPRows; i++ )
  {
    calcRow( i );
  }

  while ( true )
  {
    bool myColsOK = checkCols();
    if ( !myColsOK )
    {
      insertRows();
    }
    bool myRowsOK = checkRows();
    if ( !myRowsOK )
    {
      insertCols();
    }
    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.0625 * 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 );

  //QgsDebugMsg( "CPMatrix:\n" + cpToString() );

  // 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;
}