Skip to content

Commit ebde3be

Browse files
committedNov 29, 2017
[3d] Reproject DEM for terrain if the DEM has different CRS (fixes #17514)
1 parent 62543eb commit ebde3be

File tree

5 files changed

+38
-5
lines changed

5 files changed

+38
-5
lines changed
 

‎src/3d/qgs3dmapsettings.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,9 @@ void Qgs3DMapSettings::readXml( const QDomElement &elem, const QgsReadWriteConte
8484
QString terrainGenType = elemTerrainGenerator.attribute( "type" );
8585
if ( terrainGenType == "dem" )
8686
{
87-
mTerrainGenerator.reset( new QgsDemTerrainGenerator );
87+
QgsDemTerrainGenerator *demTerrainGenerator = new QgsDemTerrainGenerator;
88+
demTerrainGenerator->setCrs( mCrs );
89+
mTerrainGenerator.reset( demTerrainGenerator );
8890
}
8991
else if ( terrainGenType == "quantized-mesh" )
9092
{

‎src/3d/terrain/qgsdemterraingenerator.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,16 @@ QgsRasterLayer *QgsDemTerrainGenerator::layer() const
3535
return qobject_cast<QgsRasterLayer *>( mLayer.layer.data() );
3636
}
3737

38+
void QgsDemTerrainGenerator::setCrs( const QgsCoordinateReferenceSystem &crs )
39+
{
40+
mCrs = crs;
41+
updateGenerator();
42+
}
43+
3844
QgsTerrainGenerator *QgsDemTerrainGenerator::clone() const
3945
{
4046
QgsDemTerrainGenerator *cloned = new QgsDemTerrainGenerator;
47+
cloned->mCrs = mCrs;
4148
cloned->mLayer = mLayer;
4249
cloned->mResolution = mResolution;
4350
cloned->mSkirtHeight = mSkirtHeight;
@@ -66,13 +73,17 @@ void QgsDemTerrainGenerator::writeXml( QDomElement &elem ) const
6673
elem.setAttribute( "layer", mLayer.layerId );
6774
elem.setAttribute( "resolution", mResolution );
6875
elem.setAttribute( "skirt-height", mSkirtHeight );
76+
77+
// crs is not read/written - it should be the same as destination crs of the map
6978
}
7079

7180
void QgsDemTerrainGenerator::readXml( const QDomElement &elem )
7281
{
7382
mLayer = QgsMapLayerRef( elem.attribute( "layer" ) );
7483
mResolution = elem.attribute( "resolution" ).toInt();
7584
mSkirtHeight = elem.attribute( "skirt-height" ).toFloat();
85+
86+
// crs is not read/written - it should be the same as destination crs of the map
7687
}
7788

7889
void QgsDemTerrainGenerator::resolveReferences( const QgsProject &project )
@@ -91,7 +102,11 @@ void QgsDemTerrainGenerator::updateGenerator()
91102
QgsRasterLayer *dem = layer();
92103
if ( dem )
93104
{
94-
mTerrainTilingScheme = QgsTilingScheme( dem->extent(), dem->crs() );
105+
QgsRectangle te = dem->extent();
106+
QgsCoordinateTransform terrainToMapTransform( dem->crs(), mCrs );
107+
te = terrainToMapTransform.transformBoundingBox( te );
108+
109+
mTerrainTilingScheme = QgsTilingScheme( te, mCrs );
95110
delete mHeightMapGenerator;
96111
mHeightMapGenerator = new QgsDemHeightMapGenerator( dem, mTerrainTilingScheme, mResolution );
97112
}

‎src/3d/terrain/qgsdemterraingenerator.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ class _3D_EXPORT QgsDemTerrainGenerator : public QgsTerrainGenerator
4545
//! Returns raster layer with elevation model to be used for terrain generation
4646
QgsRasterLayer *layer() const;
4747

48+
//! Sets CRS of the terrain
49+
void setCrs( const QgsCoordinateReferenceSystem &crs );
50+
4851
//! Sets resolution of the generator (how many elevation samples on one side of a terrain tile)
4952
void setResolution( int resolution ) { mResolution = resolution; updateGenerator(); }
5053
//! Returns resolution of the generator (how many elevation samples on one side of a terrain tile)
@@ -73,6 +76,7 @@ class _3D_EXPORT QgsDemTerrainGenerator : public QgsTerrainGenerator
7376

7477
QgsDemHeightMapGenerator *mHeightMapGenerator = nullptr;
7578

79+
QgsCoordinateReferenceSystem mCrs;
7680
//! source layer for heights
7781
QgsMapLayerRef mLayer;
7882
//! how many vertices to place on one side of the tile

‎src/3d/terrain/qgsdemterraintileloader_p.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ void QgsDemTerrainTileLoader::onHeightMapReady( int jobId, const QByteArray &hei
113113
// ---------------------
114114

115115
#include <qgsrasterlayer.h>
116+
#include <qgsrasterprojector.h>
116117
#include <QtConcurrent/QtConcurrentRun>
117118
#include <QFutureWatcher>
118119

@@ -132,13 +133,22 @@ QgsDemHeightMapGenerator::~QgsDemHeightMapGenerator()
132133

133134
#include <QElapsedTimer>
134135

135-
static QByteArray _readDtmData( QgsRasterDataProvider *provider, const QgsRectangle &extent, int res )
136+
static QByteArray _readDtmData( QgsRasterDataProvider *provider, const QgsRectangle &extent, int res, const QgsCoordinateReferenceSystem &destCrs )
136137
{
137138
QElapsedTimer t;
138139
t.start();
139140

140141
// TODO: use feedback object? (but GDAL currently does not support cancelation anyway)
141-
QgsRasterBlock *block = provider->block( 1, extent, res, res );
142+
QgsRasterInterface *input = provider;
143+
std::unique_ptr<QgsRasterProjector> projector;
144+
if ( provider->crs() != destCrs )
145+
{
146+
projector.reset( new QgsRasterProjector );
147+
projector->setCrs( provider->crs(), destCrs );
148+
projector->setInput( provider );
149+
input = projector.get();
150+
}
151+
QgsRasterBlock *block = input->block( 1, extent, res, res );
142152

143153
QByteArray data;
144154
if ( block )
@@ -168,7 +178,7 @@ int QgsDemHeightMapGenerator::render( int x, int y, int z )
168178
jd.extent = extent;
169179
jd.timer.start();
170180
// make a clone of the data provider so it is safe to use in worker thread
171-
jd.future = QtConcurrent::run( _readDtmData, mClonedProvider, extent, mResolution );
181+
jd.future = QtConcurrent::run( _readDtmData, mClonedProvider, extent, mResolution, mTilingScheme.crs() );
172182

173183
QFutureWatcher<QByteArray> *fw = new QFutureWatcher<QByteArray>;
174184
fw->setFuture( jd.future );

‎src/app/3d/qgs3dmapconfigwidget.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ void Qgs3DMapConfigWidget::apply()
9090
if ( tGenNeedsUpdate )
9191
{
9292
QgsDemTerrainGenerator *demTerrainGen = new QgsDemTerrainGenerator;
93+
demTerrainGen->setCrs( mMap->crs() );
9394
demTerrainGen->setLayer( demLayer );
9495
demTerrainGen->setResolution( spinTerrainResolution->value() );
9596
demTerrainGen->setSkirtHeight( spinTerrainSkirtHeight->value() );
@@ -139,6 +140,7 @@ void Qgs3DMapConfigWidget::updateMaxZoomLevel()
139140
if ( demLayer )
140141
{
141142
QgsDemTerrainGenerator *demTerrainGen = new QgsDemTerrainGenerator;
143+
demTerrainGen->setCrs( mMap->crs() );
142144
demTerrainGen->setLayer( demLayer );
143145
demTerrainGen->setResolution( spinTerrainResolution->value() );
144146
tGen.reset( demTerrainGen );

0 commit comments

Comments
 (0)
Please sign in to comment.