Skip to content

Commit 8993a4b

Browse files
committedOct 29, 2015
increased transformBoundingBox() accuracy
1 parent 1c22445 commit 8993a4b

File tree

1 file changed

+20
-13
lines changed

1 file changed

+20
-13
lines changed
 

‎src/core/qgscoordinatetransform.cpp

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -534,39 +534,46 @@ QgsRectangle QgsCoordinateTransform::transformBoundingBox( const QgsRectangle &r
534534
return QgsRectangle( p, p );
535535
}
536536

537-
static const int numP = 8;
537+
// 64 points (<=2.12) is not enough, see #13665, for EPSG:4326 -> EPSG:3574 (say that it is a hard one),
538+
// are decent result from about 500 points and more. This method is called quite often, but
539+
// even with 1000 points it takes < 1ms
540+
// TODO: how to effectively and precisely reproject bounding box?
541+
const int nPoints = 1000;
542+
double d = sqrt(( rect.width() * rect.height() ) / pow( sqrt( nPoints ) - 1, 2.0 ) );
543+
int nXPoints = ( int ) ceil( rect.width() / d ) + 1;
544+
int nYPoints = ( int ) ceil( rect.height() / d ) + 1;
538545

539546
QgsRectangle bb_rect;
540547
bb_rect.setMinimal();
541548

542549
// We're interfacing with C-style vectors in the
543550
// end, so let's do C-style vectors here too.
544551

545-
double x[numP * numP];
546-
double y[numP * numP];
547-
double z[numP * numP];
552+
double x[nXPoints * nYPoints];
553+
double y[nXPoints * nYPoints];
554+
double z[nXPoints * nYPoints];
548555

549556
QgsDebugMsg( "Entering transformBoundingBox..." );
550557

551558
// Populate the vectors
552559

553-
double dx = rect.width() / ( double )( numP - 1 );
554-
double dy = rect.height() / ( double )( numP - 1 );
560+
double dx = rect.width() / ( double )( nXPoints - 1 );
561+
double dy = rect.height() / ( double )( nYPoints - 1 );
555562

556563
double pointY = rect.yMinimum();
557564

558-
for ( int i = 0; i < numP ; i++ )
565+
for ( int i = 0; i < nYPoints ; i++ )
559566
{
560567

561568
// Start at right edge
562569
double pointX = rect.xMinimum();
563570

564-
for ( int j = 0; j < numP; j++ )
571+
for ( int j = 0; j < nXPoints; j++ )
565572
{
566-
x[( i*numP ) + j] = pointX;
567-
y[( i*numP ) + j] = pointY;
573+
x[( i*nXPoints ) + j] = pointX;
574+
y[( i*nXPoints ) + j] = pointY;
568575
// and the height...
569-
z[( i*numP ) + j] = 0.0;
576+
z[( i*nXPoints ) + j] = 0.0;
570577
// QgsDebugMsg(QString("BBox coord: (%1, %2)").arg(x[(i*numP) + j]).arg(y[(i*numP) + j]));
571578
pointX += dx;
572579
}
@@ -577,7 +584,7 @@ QgsRectangle QgsCoordinateTransform::transformBoundingBox( const QgsRectangle &r
577584
// be handled in above layers.
578585
try
579586
{
580-
transformCoords( numP * numP, x, y, z, direction );
587+
transformCoords( nXPoints * nYPoints, x, y, z, direction );
581588
}
582589
catch ( const QgsCsException & )
583590
{
@@ -588,7 +595,7 @@ QgsRectangle QgsCoordinateTransform::transformBoundingBox( const QgsRectangle &r
588595

589596
// Calculate the bounding box and use that for the extent
590597

591-
for ( int i = 0; i < numP * numP; i++ )
598+
for ( int i = 0; i < nXPoints * nYPoints; i++ )
592599
{
593600
if ( !qIsFinite( x[i] ) || !qIsFinite( y[i] ) )
594601
{

0 commit comments

Comments
 (0)
Please sign in to comment.