void ProjectorData::calcHelper( int matrixRow, QgsPointXY *points ) { // TODO?: should we also precalc dest cell center coordinates for x and y? for ( int myDestCol = 0; myDestCol < mDestCols; myDestCol++ ) { double myDestX = mDestExtent.xMinimum() + ( myDestCol + 0.5 ) * mDestXRes; int myMatrixCol = matrixCol( myDestCol ); double myDestXMin, myDestYMin, myDestXMax, myDestYMax; destPointOnCPMatrix( matrixRow, myMatrixCol, &myDestXMin, &myDestYMin ); destPointOnCPMatrix( matrixRow, myMatrixCol + 1, &myDestXMax, &myDestYMax ); double xfrac = ( myDestX - myDestXMin ) / ( myDestXMax - myDestXMin ); QgsPointXY &mySrcPoint0 = mCPMatrix[matrixRow][myMatrixCol]; QgsPointXY &mySrcPoint1 = mCPMatrix[matrixRow][myMatrixCol + 1]; double s = mySrcPoint0.x() + ( mySrcPoint1.x() - mySrcPoint0.x() ) * xfrac; double t = mySrcPoint0.y() + ( mySrcPoint1.y() - mySrcPoint0.y() ) * xfrac; points[myDestCol].setX( s ); points[myDestCol].setY( t ); } }
bool ProjectorData::approximateSrcRowCol( int destRow, int destCol, int *srcRow, int *srcCol ) { int myMatrixRow = matrixRow( destRow ); int myMatrixCol = matrixCol( destCol ); if ( myMatrixRow > mHelperTopRow ) { // TODO: make it more robust (for random, not sequential reading) nextHelper(); } double myDestY = mDestExtent.yMaximum() - ( destRow + 0.5 ) * mDestYRes; // See the schema in javax.media.jai.WarpGrid doc (but up side down) // TODO: use some kind of cache of values which can be reused double myDestXMin, myDestYMin, myDestXMax, myDestYMax; destPointOnCPMatrix( myMatrixRow + 1, myMatrixCol, &myDestXMin, &myDestYMin ); destPointOnCPMatrix( myMatrixRow, myMatrixCol + 1, &myDestXMax, &myDestYMax ); double yfrac = ( myDestY - myDestYMin ) / ( myDestYMax - myDestYMin ); QgsPointXY &myTop = pHelperTop[destCol]; QgsPointXY &myBot = pHelperBottom[destCol]; // Warning: this is very SLOW compared to the following code!: //double mySrcX = myBot.x() + (myTop.x() - myBot.x()) * yfrac; //double mySrcY = myBot.y() + (myTop.y() - myBot.y()) * yfrac; double tx = myTop.x(); double ty = myTop.y(); double bx = myBot.x(); double by = myBot.y(); double mySrcX = bx + ( tx - bx ) * yfrac; double mySrcY = by + ( ty - by ) * yfrac; if ( !mExtent.contains( QgsPointXY( mySrcX, mySrcY ) ) ) { return false; } // TODO: check again cell selection (coor is in the middle) *srcRow = static_cast< int >( std::floor( ( mSrcExtent.yMaximum() - mySrcY ) / mSrcYRes ) ); *srcCol = static_cast< int >( std::floor( ( mySrcX - mSrcExtent.xMinimum() ) / mSrcXRes ) ); // For now silently correct limits to avoid crashes // TODO: review // should not happen if ( *srcRow >= mSrcRows ) return false; if ( *srcRow < 0 ) return false; if ( *srcCol >= mSrcCols ) return false; if ( *srcCol < 0 ) return false; return true; }
void QgsRasterProjector::approximateSrcRowCol( int theDestRow, int theDestCol, int *theSrcRow, int *theSrcCol ) { int myMatrixRow = matrixRow( theDestRow ); int myMatrixCol = matrixCol( theDestCol ); if ( myMatrixRow > mHelperTopRow ) { // TODO: make it more robust (for random, not sequential reading) nextHelper(); } double myDestY = mDestExtent.yMaximum() - ( theDestRow + 0.5 ) * mDestYRes; // See the schema in javax.media.jai.WarpGrid doc (but up side down) // TODO: use some kind of cache of values which can be reused double myDestXMin, myDestYMin, myDestXMax, myDestYMax; destPointOnCPMatrix( myMatrixRow + 1, myMatrixCol, &myDestXMin, &myDestYMin ); destPointOnCPMatrix( myMatrixRow, myMatrixCol + 1, &myDestXMax, &myDestYMax ); double yfrac = ( myDestY - myDestYMin ) / ( myDestYMax - myDestYMin ); QgsPoint &myTop = pHelperTop[theDestCol]; QgsPoint &myBot = pHelperBottom[theDestCol]; // Warning: this is very SLOW compared to the following code!: //double mySrcX = myBot.x() + (myTop.x() - myBot.x()) * yfrac; //double mySrcY = myBot.y() + (myTop.y() - myBot.y()) * yfrac; double tx = myTop.x(); double ty = myTop.y(); double bx = myBot.x(); double by = myBot.y(); double mySrcX = bx + ( tx - bx ) * yfrac; double mySrcY = by + ( ty - by ) * yfrac; // TODO: check again cell selection (coor is in the middle) *theSrcRow = ( int ) floor(( mSrcExtent.yMaximum() - mySrcY ) / mSrcYRes ); *theSrcCol = ( int ) floor(( mySrcX - mSrcExtent.xMinimum() ) / mSrcXRes ); // For now silently correct limits to avoid crashes // TODO: review if ( *theSrcRow >= mSrcRows ) *theSrcRow = mSrcRows - 1; if ( *theSrcRow < 0 ) *theSrcRow = 0; if ( *theSrcCol >= mSrcCols ) *theSrcCol = mSrcCols - 1; if ( *theSrcCol < 0 ) *theSrcCol = 0; Q_ASSERT( *theSrcRow < mSrcRows ); Q_ASSERT( *theSrcCol < mSrcCols ); }
bool QgsRasterProjector::checkRows() { for ( int r = 0; r < mCPRows; r++ ) { for ( int c = 1; c < mCPCols - 1; c += 2 ) { double myDestX, myDestY; destPointOnCPMatrix( r, c, &myDestX, &myDestY ); QgsPoint myDestPoint( myDestX, myDestY ); QgsPoint mySrcPoint1 = mCPMatrix[r][c-1]; QgsPoint mySrcPoint2 = mCPMatrix[r][c]; QgsPoint mySrcPoint3 = mCPMatrix[r][c+1]; QgsPoint mySrcApprox(( mySrcPoint1.x() + mySrcPoint3.x() ) / 2, ( mySrcPoint1.y() + mySrcPoint3.y() ) / 2 ); try { QgsPoint myDestApprox = mCoordinateTransform.transform( mySrcApprox, QgsCoordinateTransform::ReverseTransform ); double mySqrDist = myDestApprox.sqrDist( myDestPoint ); if ( mySqrDist > mSqrTolerance ) { return false; } } catch ( QgsCsException &e ) { Q_UNUSED( e ); // Caught an error in transform return false; } } } return true; }
void QgsRasterProjector::calcCP( int theRow, int theCol ) { double myDestX, myDestY; destPointOnCPMatrix( theRow, theCol, &myDestX, &myDestY ); QgsPoint myDestPoint( myDestX, myDestY ); mCPMatrix[theRow][theCol] = mCoordinateTransform.transform( myDestPoint ); }
void QgsRasterProjector::calcCP( int theRow, int theCol ) { double myDestX, myDestY; destPointOnCPMatrix( theRow, theCol, &myDestX, &myDestY ); QgsPoint myDestPoint( myDestX, myDestY ); try { mCPMatrix[theRow][theCol] = mCoordinateTransform.transform( myDestPoint ); mCPLegalMatrix[theRow][theCol] = true; } catch ( QgsCsException &e ) { Q_UNUSED( e ); // Caught an error in transform mCPLegalMatrix[theRow][theCol] = true; } }
bool ProjectorData::checkRows( const QgsCoordinateTransform &ct ) { if ( !ct.isValid() ) { return false; } for ( int r = 0; r < mCPRows; r++ ) { for ( int c = 1; c < mCPCols - 1; c += 2 ) { double myDestX, myDestY; destPointOnCPMatrix( r, c, &myDestX, &myDestY ); QgsPointXY myDestPoint( myDestX, myDestY ); QgsPointXY mySrcPoint1 = mCPMatrix[r][c - 1]; QgsPointXY mySrcPoint2 = mCPMatrix[r][c]; QgsPointXY mySrcPoint3 = mCPMatrix[r][c + 1]; QgsPointXY mySrcApprox( ( mySrcPoint1.x() + mySrcPoint3.x() ) / 2, ( mySrcPoint1.y() + mySrcPoint3.y() ) / 2 ); if ( !mCPLegalMatrix[r][c - 1] || !mCPLegalMatrix[r][c] || !mCPLegalMatrix[r][c + 1] ) { // There was an error earlier in transform, just abort return false; } try { QgsPointXY myDestApprox = ct.transform( mySrcApprox, QgsCoordinateTransform::ReverseTransform ); double mySqrDist = myDestApprox.sqrDist( myDestPoint ); if ( mySqrDist > mSqrTolerance ) { return false; } } catch ( QgsCsException &e ) { Q_UNUSED( e ); // Caught an error in transform return false; } } } return true; }
bool QgsRasterProjector::checkCols() { for ( int c = 0; c < mCPCols; c++ ) { for ( int r = 1; r < mCPRows - 1; r += 2 ) { double myDestX, myDestY; destPointOnCPMatrix( r, c, &myDestX, &myDestY ); QgsPoint myDestPoint( myDestX, myDestY ); QgsPoint mySrcPoint1 = mCPMatrix[r-1][c]; QgsPoint mySrcPoint2 = mCPMatrix[r][c]; QgsPoint mySrcPoint3 = mCPMatrix[r+1][c]; QgsPoint mySrcApprox(( mySrcPoint1.x() + mySrcPoint3.x() ) / 2, ( mySrcPoint1.y() + mySrcPoint3.y() ) / 2 ); if ( !mCPLegalMatrix[r-1][c] || !mCPLegalMatrix[r][c] || !mCPLegalMatrix[r+1][c] ) { // There was an error earlier in transform, just abort return false; } try { QgsPoint myDestApprox = mCoordinateTransform.transform( mySrcApprox, QgsCoordinateTransform::ReverseTransform ); double mySqrDist = myDestApprox.sqrDist( myDestPoint ); if ( mySqrDist > mSqrTolerance ) { return false; } } catch ( QgsCsException &e ) { Q_UNUSED( e ); // Caught an error in transform return false; } } } return true; }
bool QgsRasterProjector::checkCols() { for ( int c = 0; c < mCPCols; c++ ) { for ( int r = 1; r < mCPRows - 1; r += 2 ) { double myDestX, myDestY; destPointOnCPMatrix( r, c, &myDestX, &myDestY ); QgsPoint myDestPoint( myDestX, myDestY ); QgsPoint mySrcPoint1 = mCPMatrix[r-1][c]; QgsPoint mySrcPoint2 = mCPMatrix[r][c]; QgsPoint mySrcPoint3 = mCPMatrix[r+1][c]; QgsPoint mySrcApprox(( mySrcPoint1.x() + mySrcPoint3.x() ) / 2, ( mySrcPoint1.y() + mySrcPoint3.y() ) / 2 ); QgsPoint myDestApprox = mCoordinateTransform.transform( mySrcApprox, QgsCoordinateTransform::ReverseTransform ); double mySqrDist = myDestApprox.sqrDist( myDestPoint ); if ( mySqrDist > mSqrTolerance ) return false; } } return true; }
void ProjectorData::calcCP( int row, int col, const QgsCoordinateTransform &ct ) { double myDestX, myDestY; destPointOnCPMatrix( row, col, &myDestX, &myDestY ); QgsPointXY myDestPoint( myDestX, myDestY ); try { if ( ct.isValid() ) { mCPMatrix[row][col] = ct.transform( myDestPoint ); mCPLegalMatrix[row][col] = true; } else { mCPLegalMatrix[row][col] = false; } } catch ( QgsCsException &e ) { Q_UNUSED( e ); // Caught an error in transform mCPLegalMatrix[row][col] = false; } }