Permalink
Show file tree
Hide file tree
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Merge pull request #9549 from wonder-sk/online-3d-terrain
[3d] Add option to use terrain data from online service
- Loading branch information
Showing
16 changed files
with
872 additions
and
83 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
/*************************************************************************** | ||
qgsonlineterraingenerator.cpp | ||
-------------------------------------- | ||
Date : March 2019 | ||
Copyright : (C) 2019 by Martin Dobias | ||
Email : wonder dot sk at gmail dot com | ||
*************************************************************************** | ||
* * | ||
* This program is free software; you can redistribute it and/or modify * | ||
* it under the terms of the GNU General Public License as published by * | ||
* the Free Software Foundation; either version 2 of the License, or * | ||
* (at your option) any later version. * | ||
* * | ||
***************************************************************************/ | ||
|
||
#include "qgsonlineterraingenerator.h" | ||
|
||
#include "qgsdemterraintileloader_p.h" | ||
|
||
|
||
QgsOnlineTerrainGenerator::QgsOnlineTerrainGenerator() = default; | ||
|
||
QgsOnlineTerrainGenerator::~QgsOnlineTerrainGenerator() = default; | ||
|
||
QgsChunkLoader *QgsOnlineTerrainGenerator::createChunkLoader( QgsChunkNode *node ) const | ||
{ | ||
return new QgsDemTerrainTileLoader( mTerrain, node ); | ||
} | ||
|
||
QgsTerrainGenerator *QgsOnlineTerrainGenerator::clone() const | ||
{ | ||
QgsOnlineTerrainGenerator *cloned = new QgsOnlineTerrainGenerator; | ||
cloned->mCrs = mCrs; | ||
cloned->mExtent = mExtent; | ||
cloned->mResolution = mResolution; | ||
cloned->mSkirtHeight = mSkirtHeight; | ||
cloned->updateGenerator(); | ||
return cloned; | ||
} | ||
|
||
QgsTerrainGenerator::Type QgsOnlineTerrainGenerator::type() const | ||
{ | ||
return QgsTerrainGenerator::Online; | ||
} | ||
|
||
QgsRectangle QgsOnlineTerrainGenerator::extent() const | ||
{ | ||
return mTerrainTilingScheme.tileToExtent( 0, 0, 0 ); | ||
} | ||
|
||
float QgsOnlineTerrainGenerator::heightAt( double x, double y, const Qgs3DMapSettings &map ) const | ||
{ | ||
Q_UNUSED( map ); | ||
if ( mHeightMapGenerator ) | ||
return mHeightMapGenerator->heightAt( x, y ); | ||
else | ||
return 0; | ||
} | ||
|
||
void QgsOnlineTerrainGenerator::writeXml( QDomElement &elem ) const | ||
{ | ||
QgsRectangle r = mExtent; | ||
QDomElement elemExtent = elem.ownerDocument().createElement( QStringLiteral( "extent" ) ); | ||
elemExtent.setAttribute( QStringLiteral( "xmin" ), QString::number( r.xMinimum() ) ); | ||
elemExtent.setAttribute( QStringLiteral( "xmax" ), QString::number( r.xMaximum() ) ); | ||
elemExtent.setAttribute( QStringLiteral( "ymin" ), QString::number( r.yMinimum() ) ); | ||
elemExtent.setAttribute( QStringLiteral( "ymax" ), QString::number( r.yMaximum() ) ); | ||
|
||
elem.setAttribute( QStringLiteral( "resolution" ), mResolution ); | ||
elem.setAttribute( QStringLiteral( "skirt-height" ), mSkirtHeight ); | ||
|
||
// crs is not read/written - it should be the same as destination crs of the map | ||
} | ||
|
||
void QgsOnlineTerrainGenerator::readXml( const QDomElement &elem ) | ||
{ | ||
QDomElement elemExtent = elem.firstChildElement( QStringLiteral( "extent" ) ); | ||
double xmin = elemExtent.attribute( QStringLiteral( "xmin" ) ).toDouble(); | ||
double xmax = elemExtent.attribute( QStringLiteral( "xmax" ) ).toDouble(); | ||
double ymin = elemExtent.attribute( QStringLiteral( "ymin" ) ).toDouble(); | ||
double ymax = elemExtent.attribute( QStringLiteral( "ymax" ) ).toDouble(); | ||
|
||
setExtent( QgsRectangle( xmin, ymin, xmax, ymax ) ); | ||
|
||
mResolution = elem.attribute( QStringLiteral( "resolution" ) ).toInt(); | ||
mSkirtHeight = elem.attribute( QStringLiteral( "skirt-height" ) ).toFloat(); | ||
|
||
// crs is not read/written - it should be the same as destination crs of the map | ||
} | ||
|
||
void QgsOnlineTerrainGenerator::setCrs( const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context ) | ||
{ | ||
mCrs = crs; | ||
mTransformContext = context; | ||
updateGenerator(); | ||
} | ||
|
||
void QgsOnlineTerrainGenerator::setExtent( const QgsRectangle &extent ) | ||
{ | ||
mExtent = extent; | ||
updateGenerator(); | ||
} | ||
|
||
void QgsOnlineTerrainGenerator::updateGenerator() | ||
{ | ||
if ( mExtent.isNull() ) | ||
{ | ||
mTerrainTilingScheme = QgsTilingScheme(); | ||
} | ||
else | ||
{ | ||
// the real extent will be a square where the given extent fully fits | ||
mTerrainTilingScheme = QgsTilingScheme( mExtent, mCrs ); | ||
} | ||
|
||
mHeightMapGenerator.reset( new QgsDemHeightMapGenerator( nullptr, mTerrainTilingScheme, mResolution ) ); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
/*************************************************************************** | ||
qgsonlineterraingenerator.h | ||
-------------------------------------- | ||
Date : March 2019 | ||
Copyright : (C) 2019 by Martin Dobias | ||
Email : wonder dot sk at gmail dot com | ||
*************************************************************************** | ||
* * | ||
* This program is free software; you can redistribute it and/or modify * | ||
* it under the terms of the GNU General Public License as published by * | ||
* the Free Software Foundation; either version 2 of the License, or * | ||
* (at your option) any later version. * | ||
* * | ||
***************************************************************************/ | ||
|
||
#ifndef QGSONLINETERRAINGENERATOR_H | ||
#define QGSONLINETERRAINGENERATOR_H | ||
|
||
#include "qgis_3d.h" | ||
|
||
#include "qgsterraingenerator.h" | ||
|
||
#include "qgscoordinatetransformcontext.h" | ||
|
||
class QgsDemHeightMapGenerator; | ||
|
||
/** | ||
* \ingroup 3d | ||
* Implementation of terrain generator that uses online resources to download heightmaps. | ||
* \since QGIS 3.8 | ||
*/ | ||
class _3D_EXPORT QgsOnlineTerrainGenerator : public QgsTerrainGenerator | ||
{ | ||
public: | ||
//! Constructor for QgsOnlineTerrainGenerator | ||
QgsOnlineTerrainGenerator(); | ||
~QgsOnlineTerrainGenerator() override; | ||
|
||
//! Sets extent of the terrain | ||
void setExtent( const QgsRectangle &extent ); | ||
|
||
//! Sets CRS of the terrain | ||
void setCrs( const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context ); | ||
//! Returns CRS of the terrain | ||
QgsCoordinateReferenceSystem crs() const { return mCrs; } | ||
|
||
//! Sets resolution of the generator (how many elevation samples on one side of a terrain tile) | ||
void setResolution( int resolution ) { mResolution = resolution; updateGenerator(); } | ||
//! Returns resolution of the generator (how many elevation samples on one side of a terrain tile) | ||
int resolution() const { return mResolution; } | ||
|
||
//! Sets skirt height (in world units). Skirts at the edges of terrain tiles help hide cracks between adjacent tiles. | ||
void setSkirtHeight( float skirtHeight ) { mSkirtHeight = skirtHeight; } | ||
//! Returns skirt height (in world units). Skirts at the edges of terrain tiles help hide cracks between adjacent tiles. | ||
float skirtHeight() const { return mSkirtHeight; } | ||
|
||
//! Returns height map generator object - takes care of extraction of elevations from the layer) | ||
QgsDemHeightMapGenerator *heightMapGenerator() { return mHeightMapGenerator.get(); } | ||
|
||
QgsTerrainGenerator *clone() const override SIP_FACTORY; | ||
Type type() const override; | ||
QgsRectangle extent() const override; | ||
float heightAt( double x, double y, const Qgs3DMapSettings &map ) const override; | ||
void writeXml( QDomElement &elem ) const override; | ||
void readXml( const QDomElement &elem ) override; | ||
//void resolveReferences( const QgsProject &project ) override; | ||
|
||
QgsChunkLoader *createChunkLoader( QgsChunkNode *node ) const override SIP_FACTORY; | ||
|
||
private: | ||
|
||
void updateGenerator(); | ||
|
||
QgsRectangle mExtent; | ||
QgsCoordinateReferenceSystem mCrs; | ||
QgsCoordinateTransformContext mTransformContext; | ||
|
||
//! how many vertices to place on one side of the tile | ||
int mResolution = 16; | ||
//! height of the "skirts" at the edges of tiles to hide cracks between adjacent cracks | ||
float mSkirtHeight = 10.f; | ||
|
||
std::unique_ptr<QgsDemHeightMapGenerator> mHeightMapGenerator; | ||
}; | ||
|
||
#endif // QGSONLINETERRAINGENERATOR_H |
Oops, something went wrong.