24
24
#include " qgscsexception.h"
25
25
26
26
27
-
28
27
QgsRasterProjector::QgsRasterProjector ()
29
28
: QgsRasterInterface( nullptr )
30
29
, mSrcDatumTransform( -1 )
31
30
, mDestDatumTransform( -1 )
32
31
, mPrecision( Approximate )
33
- , mApproximate( false )
34
- , mDestRows( 0 )
35
- , mDestCols( 0 )
36
- , mDestXRes( 0.0 )
37
- , mDestYRes( 0.0 )
38
- , mSrcRows( 0 )
39
- , mSrcCols( 0 )
40
- , mSrcXRes( 0.0 )
41
- , mSrcYRes( 0.0 )
42
- , mDestRowsPerMatrixRow( 0.0 )
43
- , mDestColsPerMatrixCol( 0.0 )
44
- , pHelperTop( nullptr )
45
- , pHelperBottom( nullptr )
46
- , mHelperTopRow( 0 )
47
- , mCPCols( 0 )
48
- , mCPRows( 0 )
49
- , mSqrTolerance( 0.0 )
50
- , mMaxSrcXRes( 0 )
51
- , mMaxSrcYRes( 0 )
52
32
{
53
33
QgsDebugMsgLevel ( " Entered" , 4 );
54
34
}
@@ -62,17 +42,12 @@ QgsRasterProjector* QgsRasterProjector::clone() const
62
42
projector->mDestCRS = mDestCRS ;
63
43
projector->mSrcDatumTransform = mSrcDatumTransform ;
64
44
projector->mDestDatumTransform = mDestDatumTransform ;
65
- projector->mMaxSrcXRes = mMaxSrcXRes ;
66
- projector->mMaxSrcYRes = mMaxSrcYRes ;
67
- projector->mExtent = mExtent ;
68
45
projector->mPrecision = mPrecision ;
69
46
return projector;
70
47
}
71
48
72
49
QgsRasterProjector::~QgsRasterProjector ()
73
50
{
74
- delete[] pHelperTop;
75
- delete[] pHelperBottom;
76
51
}
77
52
78
53
int QgsRasterProjector::bandCount () const
@@ -97,22 +72,36 @@ void QgsRasterProjector::setCrs( const QgsCoordinateReferenceSystem & theSrcCRS,
97
72
mDestDatumTransform = destDatumTransform;
98
73
}
99
74
100
- void QgsRasterProjector::calc ()
75
+
76
+ ProjectorData::ProjectorData ( const QgsRectangle& extent, int width, int height, QgsRasterInterface* input, const QgsCoordinateTransform& inverseCt, QgsRasterProjector::Precision precision )
77
+ : mApproximate( false )
78
+ , mInverseCt( new QgsCoordinateTransform( inverseCt ) )
79
+ , mDestExtent( extent )
80
+ , mDestRows( height )
81
+ , mDestCols( width )
82
+ , mDestXRes( 0.0 )
83
+ , mDestYRes( 0.0 )
84
+ , mSrcRows( 0 )
85
+ , mSrcCols( 0 )
86
+ , mSrcXRes( 0.0 )
87
+ , mSrcYRes( 0.0 )
88
+ , mDestRowsPerMatrixRow( 0.0 )
89
+ , mDestColsPerMatrixCol( 0.0 )
90
+ , pHelperTop( nullptr )
91
+ , pHelperBottom( nullptr )
92
+ , mHelperTopRow( 0 )
93
+ , mCPCols( 0 )
94
+ , mCPRows( 0 )
95
+ , mSqrTolerance( 0.0 )
96
+ , mMaxSrcXRes( 0 )
97
+ , mMaxSrcYRes( 0 )
101
98
{
102
99
QgsDebugMsgLevel ( " Entered" , 4 );
103
- mCPMatrix .clear ();
104
- mCPLegalMatrix .clear ();
105
- delete[] pHelperTop;
106
- pHelperTop = nullptr ;
107
- delete[] pHelperBottom;
108
- pHelperBottom = nullptr ;
109
100
110
101
// Get max source resolution and extent if possible
111
- mMaxSrcXRes = 0 ;
112
- mMaxSrcYRes = 0 ;
113
- if ( mInput )
102
+ if ( input )
114
103
{
115
- QgsRasterDataProvider *provider = dynamic_cast <QgsRasterDataProvider*>( mInput ->sourceInput () );
104
+ QgsRasterDataProvider *provider = dynamic_cast <QgsRasterDataProvider*>( input ->sourceInput () );
116
105
if ( provider )
117
106
{
118
107
if ( provider->capabilities () & QgsRasterDataProvider::Size )
@@ -138,9 +127,7 @@ void QgsRasterProjector::calc()
138
127
double myDestRes = mDestXRes < mDestYRes ? mDestXRes : mDestYRes ;
139
128
mSqrTolerance = myDestRes * myDestRes;
140
129
141
- QgsCoordinateTransform inverseCt = QgsCoordinateTransformCache::instance ()->transform ( mDestCRS .authid (), mSrcCRS .authid (), mDestDatumTransform , mSrcDatumTransform );
142
-
143
- if ( mPrecision == Approximate )
130
+ if ( precision == QgsRasterProjector::Approximate )
144
131
{
145
132
mApproximate = true ;
146
133
}
@@ -219,7 +206,15 @@ void QgsRasterProjector::calc()
219
206
mSrcXRes = mSrcExtent .width () / mSrcCols ;
220
207
}
221
208
222
- void QgsRasterProjector::calcSrcExtent ()
209
+ ProjectorData::~ProjectorData ()
210
+ {
211
+ delete[] pHelperTop;
212
+ delete[] pHelperBottom;
213
+ delete mInverseCt ;
214
+ }
215
+
216
+
217
+ void ProjectorData::calcSrcExtent ()
223
218
{
224
219
/* Run around the mCPMatrix and find source extent */
225
220
// Attention, source limits are not necessarily on destination edges, e.g.
@@ -283,7 +278,7 @@ void QgsRasterProjector::calcSrcExtent()
283
278
QgsDebugMsgLevel ( " mSrcExtent = " + mSrcExtent .toString (), 4 );
284
279
}
285
280
286
- QString QgsRasterProjector ::cpToString ()
281
+ QString ProjectorData ::cpToString ()
287
282
{
288
283
QString myString;
289
284
for ( int i = 0 ; i < mCPRows ; i++ )
@@ -308,7 +303,7 @@ QString QgsRasterProjector::cpToString()
308
303
return myString;
309
304
}
310
305
311
- void QgsRasterProjector ::calcSrcRowsCols ()
306
+ void ProjectorData ::calcSrcRowsCols ()
312
307
{
313
308
// Wee need to calculate minimum cell size in the source
314
309
// TODO: Think it over better, what is the right source resolution?
@@ -347,11 +342,10 @@ void QgsRasterProjector::calcSrcRowsCols()
347
342
else
348
343
{
349
344
// take highest from corners, points in in the middle of corners and center (3 x 3 )
350
- QgsCoordinateTransform inverseCt = QgsCoordinateTransformCache::instance ()->transform ( mDestCRS .authid (), mSrcCRS .authid (), mDestDatumTransform , mSrcDatumTransform );
351
345
// double
352
346
QgsRectangle srcExtent;
353
347
int srcXSize, srcYSize;
354
- if ( extentSize ( inverseCt , mDestExtent , mDestCols , mDestRows , srcExtent, srcXSize, srcYSize ) )
348
+ if ( QgsRasterProjector:: extentSize ( * mInverseCt , mDestExtent , mDestCols , mDestRows , srcExtent, srcXSize, srcYSize ) )
355
349
{
356
350
double srcXRes = srcExtent.width () / srcXSize;
357
351
double srcYRes = srcExtent.height () / srcYSize;
@@ -383,29 +377,22 @@ void QgsRasterProjector::calcSrcRowsCols()
383
377
}
384
378
385
379
386
- inline void QgsRasterProjector ::destPointOnCPMatrix ( int theRow, int theCol, double *theX, double *theY )
380
+ inline void ProjectorData ::destPointOnCPMatrix ( int theRow, int theCol, double *theX, double *theY )
387
381
{
388
382
*theX = mDestExtent .xMinimum () + theCol * mDestExtent .width () / ( mCPCols - 1 );
389
383
*theY = mDestExtent .yMaximum () - theRow * mDestExtent .height () / ( mCPRows - 1 );
390
384
}
391
385
392
- inline int QgsRasterProjector ::matrixRow ( int theDestRow )
386
+ inline int ProjectorData ::matrixRow ( int theDestRow )
393
387
{
394
388
return static_cast < int >( floor (( theDestRow + 0.5 ) / mDestRowsPerMatrixRow ) );
395
389
}
396
- inline int QgsRasterProjector ::matrixCol ( int theDestCol )
390
+ inline int ProjectorData ::matrixCol ( int theDestCol )
397
391
{
398
392
return static_cast < int >( floor (( theDestCol + 0.5 ) / mDestColsPerMatrixCol ) );
399
393
}
400
394
401
- QgsPoint QgsRasterProjector::srcPoint ( int theDestRow, int theCol )
402
- {
403
- Q_UNUSED ( theDestRow );
404
- Q_UNUSED ( theCol );
405
- return QgsPoint ();
406
- }
407
-
408
- void QgsRasterProjector::calcHelper ( int theMatrixRow, QgsPoint *thePoints )
395
+ void ProjectorData::calcHelper ( int theMatrixRow, QgsPoint *thePoints )
409
396
{
410
397
// TODO?: should we also precalc dest cell center coordinates for x and y?
411
398
for ( int myDestCol = 0 ; myDestCol < mDestCols ; myDestCol++ )
@@ -430,7 +417,8 @@ void QgsRasterProjector::calcHelper( int theMatrixRow, QgsPoint *thePoints )
430
417
thePoints[myDestCol].setY ( t );
431
418
}
432
419
}
433
- void QgsRasterProjector::nextHelper ()
420
+
421
+ void ProjectorData::nextHelper ()
434
422
{
435
423
// We just switch pHelperTop and pHelperBottom, memory is not lost
436
424
QgsPoint *tmp;
@@ -441,19 +429,19 @@ void QgsRasterProjector::nextHelper()
441
429
mHelperTopRow ++;
442
430
}
443
431
444
- bool QgsRasterProjector ::srcRowCol ( int theDestRow, int theDestCol, int *theSrcRow, int *theSrcCol, const QgsCoordinateTransform& ct )
432
+ bool ProjectorData ::srcRowCol ( int theDestRow, int theDestCol, int *theSrcRow, int *theSrcCol )
445
433
{
446
434
if ( mApproximate )
447
435
{
448
436
return approximateSrcRowCol ( theDestRow, theDestCol, theSrcRow, theSrcCol );
449
437
}
450
438
else
451
439
{
452
- return preciseSrcRowCol ( theDestRow, theDestCol, theSrcRow, theSrcCol, ct );
440
+ return preciseSrcRowCol ( theDestRow, theDestCol, theSrcRow, theSrcCol );
453
441
}
454
442
}
455
443
456
- bool QgsRasterProjector ::preciseSrcRowCol ( int theDestRow, int theDestCol, int *theSrcRow, int *theSrcCol, const QgsCoordinateTransform& ct )
444
+ bool ProjectorData ::preciseSrcRowCol ( int theDestRow, int theDestCol, int *theSrcRow, int *theSrcCol )
457
445
{
458
446
#ifdef QGISDEBUG
459
447
QgsDebugMsgLevel ( QString ( " theDestRow = %1" ).arg ( theDestRow ), 5 );
@@ -469,9 +457,9 @@ bool QgsRasterProjector::preciseSrcRowCol( int theDestRow, int theDestCol, int *
469
457
QgsDebugMsgLevel ( QString ( " x = %1 y = %2" ).arg ( x ).arg ( y ), 5 );
470
458
#endif
471
459
472
- if ( ct. isValid () )
460
+ if ( mInverseCt -> isValid () )
473
461
{
474
- ct. transformInPlace ( x, y, z );
462
+ mInverseCt -> transformInPlace ( x, y, z );
475
463
}
476
464
477
465
#ifdef QGISDEBUG
@@ -502,7 +490,7 @@ bool QgsRasterProjector::preciseSrcRowCol( int theDestRow, int theDestCol, int *
502
490
return true ;
503
491
}
504
492
505
- bool QgsRasterProjector ::approximateSrcRowCol ( int theDestRow, int theDestCol, int *theSrcRow, int *theSrcCol )
493
+ bool ProjectorData ::approximateSrcRowCol ( int theDestRow, int theDestCol, int *theSrcRow, int *theSrcCol )
506
494
{
507
495
int myMatrixRow = matrixRow ( theDestRow );
508
496
int myMatrixCol = matrixCol ( theDestCol );
@@ -559,7 +547,7 @@ bool QgsRasterProjector::approximateSrcRowCol( int theDestRow, int theDestCol, i
559
547
return true ;
560
548
}
561
549
562
- void QgsRasterProjector ::insertRows ( const QgsCoordinateTransform& ct )
550
+ void ProjectorData ::insertRows ( const QgsCoordinateTransform& ct )
563
551
{
564
552
for ( int r = 0 ; r < mCPRows - 1 ; r++ )
565
553
{
@@ -583,7 +571,7 @@ void QgsRasterProjector::insertRows( const QgsCoordinateTransform& ct )
583
571
}
584
572
}
585
573
586
- void QgsRasterProjector ::insertCols ( const QgsCoordinateTransform& ct )
574
+ void ProjectorData ::insertCols ( const QgsCoordinateTransform& ct )
587
575
{
588
576
for ( int r = 0 ; r < mCPRows ; r++ )
589
577
{
@@ -601,7 +589,7 @@ void QgsRasterProjector::insertCols( const QgsCoordinateTransform& ct )
601
589
602
590
}
603
591
604
- void QgsRasterProjector ::calcCP ( int theRow, int theCol, const QgsCoordinateTransform& ct )
592
+ void ProjectorData ::calcCP ( int theRow, int theCol, const QgsCoordinateTransform& ct )
605
593
{
606
594
double myDestX, myDestY;
607
595
destPointOnCPMatrix ( theRow, theCol, &myDestX, &myDestY );
@@ -626,7 +614,7 @@ void QgsRasterProjector::calcCP( int theRow, int theCol, const QgsCoordinateTran
626
614
}
627
615
}
628
616
629
- bool QgsRasterProjector ::calcRow ( int theRow, const QgsCoordinateTransform& ct )
617
+ bool ProjectorData ::calcRow ( int theRow, const QgsCoordinateTransform& ct )
630
618
{
631
619
QgsDebugMsgLevel ( QString ( " theRow = %1" ).arg ( theRow ), 3 );
632
620
for ( int i = 0 ; i < mCPCols ; i++ )
@@ -637,7 +625,7 @@ bool QgsRasterProjector::calcRow( int theRow, const QgsCoordinateTransform& ct )
637
625
return true ;
638
626
}
639
627
640
- bool QgsRasterProjector ::calcCol ( int theCol, const QgsCoordinateTransform& ct )
628
+ bool ProjectorData ::calcCol ( int theCol, const QgsCoordinateTransform& ct )
641
629
{
642
630
QgsDebugMsgLevel ( QString ( " theCol = %1" ).arg ( theCol ), 3 );
643
631
for ( int i = 0 ; i < mCPRows ; i++ )
@@ -648,7 +636,7 @@ bool QgsRasterProjector::calcCol( int theCol, const QgsCoordinateTransform& ct )
648
636
return true ;
649
637
}
650
638
651
- bool QgsRasterProjector ::checkCols ( const QgsCoordinateTransform& ct )
639
+ bool ProjectorData ::checkCols ( const QgsCoordinateTransform& ct )
652
640
{
653
641
if ( !ct.isValid () )
654
642
{
@@ -693,7 +681,7 @@ bool QgsRasterProjector::checkCols( const QgsCoordinateTransform& ct )
693
681
return true ;
694
682
}
695
683
696
- bool QgsRasterProjector ::checkRows ( const QgsCoordinateTransform& ct )
684
+ bool ProjectorData ::checkRows ( const QgsCoordinateTransform& ct )
697
685
{
698
686
if ( !ct.isValid () )
699
687
{
@@ -766,22 +754,21 @@ QgsRasterBlock * QgsRasterProjector::block( int bandNo, QgsRectangle const & ex
766
754
return mInput ->block ( bandNo, extent, width, height, feedback );
767
755
}
768
756
769
- mDestExtent = extent;
770
- mDestRows = height;
771
- mDestCols = width;
772
- calc ();
757
+ QgsCoordinateTransform inverseCt = QgsCoordinateTransformCache::instance ()->transform ( mDestCRS .authid (), mSrcCRS .authid (), mDestDatumTransform , mSrcDatumTransform );
758
+
759
+ ProjectorData pd ( extent, width, height, mInput , inverseCt, mPrecision );
773
760
774
- QgsDebugMsgLevel ( QString ( " srcExtent:\n %1" ).arg ( mSrcExtent .toString () ), 4 );
775
- QgsDebugMsgLevel ( QString ( " srcCols = %1 srcRows = %2" ).arg ( mSrcCols ).arg ( mSrcRows ), 4 );
761
+ QgsDebugMsgLevel ( QString ( " srcExtent:\n %1" ).arg ( pd. srcExtent () .toString () ), 4 );
762
+ QgsDebugMsgLevel ( QString ( " srcCols = %1 srcRows = %2" ).arg ( pd. srcCols () ).arg ( pd. srcRows () ), 4 );
776
763
777
764
// If we zoom out too much, projector srcRows / srcCols maybe 0, which can cause problems in providers
778
- if ( mSrcRows <= 0 || mSrcCols <= 0 )
765
+ if ( pd. srcRows () <= 0 || pd. srcCols () <= 0 )
779
766
{
780
767
QgsDebugMsgLevel ( " Zero srcRows or srcCols" , 4 );
781
768
return new QgsRasterBlock ();
782
769
}
783
770
784
- QgsRasterBlock *inputBlock = mInput ->block ( bandNo, mSrcExtent , mSrcCols , mSrcRows , feedback );
771
+ QgsRasterBlock *inputBlock = mInput ->block ( bandNo, pd. srcExtent (), pd. srcCols (), pd. srcRows () , feedback );
785
772
if ( !inputBlock || inputBlock->isEmpty () )
786
773
{
787
774
QgsDebugMsg ( " No raster data!" );
@@ -822,23 +809,17 @@ QgsRasterBlock * QgsRasterProjector::block( int bandNo, QgsRectangle const & ex
822
809
// we cannot fill output block with no data because we use memcpy for data, not setValue().
823
810
bool doNoData = !QgsRasterBlock::typeIsNumeric ( inputBlock->dataType () ) && inputBlock->hasNoData () && !inputBlock->hasNoDataValue ();
824
811
825
- QgsCoordinateTransform inverseCt;
826
- if ( !mApproximate )
827
- {
828
- inverseCt = QgsCoordinateTransformCache::instance ()->transform ( mDestCRS .authid (), mSrcCRS .authid (), mDestDatumTransform , mSrcDatumTransform );
829
- }
830
-
831
812
outputBlock->setIsNoData ();
832
813
833
814
int srcRow, srcCol;
834
815
for ( int i = 0 ; i < height; ++i )
835
816
{
836
817
for ( int j = 0 ; j < width; ++j )
837
818
{
838
- bool inside = srcRowCol ( i, j, &srcRow, &srcCol, inverseCt );
819
+ bool inside = pd. srcRowCol ( i, j, &srcRow, &srcCol );
839
820
if ( !inside ) continue ; // we have everything set to no data
840
821
841
- qgssize srcIndex = static_cast < qgssize >( srcRow ) * mSrcCols + srcCol;
822
+ qgssize srcIndex = static_cast < qgssize >( srcRow ) * pd. srcCols () + srcCol;
842
823
QgsDebugMsgLevel ( QString ( " row = %1 col = %2 srcRow = %3 srcCol = %4" ).arg ( i ).arg ( j ).arg ( srcRow ).arg ( srcCol ), 5 );
843
824
844
825
// isNoData() may be slow so we check doNoData first
0 commit comments