mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-13 00:03:09 -04:00
raster creation moved from QgsGdalProvider::create() to GDAL provider extern C function
This commit is contained in:
parent
c2aca4f268
commit
d58d3476c0
@ -249,7 +249,9 @@ class QgsRasterDataProvider : QgsDataProvider, QgsRasterInterface
|
||||
|
||||
/** Creates a new dataset with mDataSourceURI
|
||||
@return true in case of success*/
|
||||
virtual bool create( const QString& format, int nBands,
|
||||
static QgsRasterDataProvider* create( const QString &providerKey,
|
||||
const QString &uri,
|
||||
const QString& format, int nBands,
|
||||
QGis::DataType type,
|
||||
int width, int height, double* geoTransform,
|
||||
const QgsCoordinateReferenceSystem& crs,
|
||||
|
@ -15,6 +15,7 @@
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgsproviderregistry.h"
|
||||
#include "qgsrasterdataprovider.h"
|
||||
#include "qgsrasterprojector.h"
|
||||
#include "qgslogger.h"
|
||||
@ -475,4 +476,30 @@ void QgsRasterDataProvider::setUserNoDataValue( int bandNo, QList<QgsRasterBlock
|
||||
}
|
||||
}
|
||||
|
||||
typedef QgsRasterDataProvider * createFunction_t( const QString&,
|
||||
const QString&, int,
|
||||
QGis::DataType,
|
||||
int, int, double*,
|
||||
const QgsCoordinateReferenceSystem&,
|
||||
QStringList );
|
||||
|
||||
QgsRasterDataProvider* QgsRasterDataProvider::create( const QString &providerKey,
|
||||
const QString &uri,
|
||||
const QString& format, int nBands,
|
||||
QGis::DataType type,
|
||||
int width, int height, double* geoTransform,
|
||||
const QgsCoordinateReferenceSystem& crs,
|
||||
QStringList createOptions )
|
||||
{
|
||||
createFunction_t *createFn = ( createFunction_t* ) cast_to_fptr( QgsProviderRegistry::instance()->function( providerKey, "create" ) );
|
||||
if ( !createFn )
|
||||
{
|
||||
QgsDebugMsg( "Cannot resolve 'create' function in " + providerKey + " provider" );
|
||||
// TODO: it would be good to return invalid QgsRasterDataProvider
|
||||
// with QgsError set, but QgsRasterDataProvider has pure virtual methods
|
||||
return 0;
|
||||
}
|
||||
return createFn( uri, format, nBands, type, width, height, geoTransform, crs, createOptions );
|
||||
}
|
||||
|
||||
// ENDS
|
||||
|
@ -403,6 +403,7 @@ class CORE_EXPORT QgsRasterDataProvider : public QgsDataProvider, public QgsRast
|
||||
|
||||
/** Creates a new dataset with mDataSourceURI
|
||||
@return true in case of success*/
|
||||
#if 0
|
||||
virtual bool create( const QString& format, int nBands,
|
||||
QGis::DataType type,
|
||||
int width, int height, double* geoTransform,
|
||||
@ -419,6 +420,16 @@ class CORE_EXPORT QgsRasterDataProvider : public QgsDataProvider, public QgsRast
|
||||
Q_UNUSED( createOptions );
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
static QgsRasterDataProvider* create( const QString &providerKey,
|
||||
const QString &uri,
|
||||
const QString& format, int nBands,
|
||||
QGis::DataType type,
|
||||
int width, int height, double* geoTransform,
|
||||
const QgsCoordinateReferenceSystem& crs,
|
||||
QStringList createOptions = QStringList() );
|
||||
|
||||
|
||||
/** Set no data value on created dataset
|
||||
* @param bandNo band number
|
||||
|
@ -873,11 +873,11 @@ QgsRasterDataProvider* QgsRasterFileWriter::createPartProvider( const QgsRectang
|
||||
|
||||
QString outputFile = outputUrl + "/" + partFileName( fileIndex );
|
||||
//QgsRasterDataProvider* destProvider = QgsRasterLayer::loadProvider( mOutputProviderKey, outputFile );
|
||||
QgsRasterDataProvider* destProvider = ( QgsRasterDataProvider* ) QgsProviderRegistry::instance()->provider( mOutputProviderKey, outputFile );
|
||||
if ( !destProvider )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
//QgsRasterDataProvider* destProvider = ( QgsRasterDataProvider* ) QgsProviderRegistry::instance()->provider( mOutputProviderKey, outputFile );
|
||||
//if ( !destProvider )
|
||||
//{
|
||||
// return 0;
|
||||
//}
|
||||
|
||||
//geotransform
|
||||
double geoTransform[6];
|
||||
@ -889,12 +889,29 @@ QgsRasterDataProvider* QgsRasterFileWriter::createPartProvider( const QgsRectang
|
||||
geoTransform[5] = -mup;
|
||||
|
||||
// perhaps we need a separate createOptions for tiles ?
|
||||
if ( !destProvider->create( mOutputFormat, nBands, type, iterCols, iterRows, geoTransform,
|
||||
crs ) )
|
||||
/*
|
||||
if ( !destProvider->create( mOutputFormat, nBands, type, iterCols, iterRows, geoTransform,
|
||||
crs ) )
|
||||
{
|
||||
delete destProvider;
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
QgsRasterDataProvider* destProvider = QgsRasterDataProvider::create( mOutputProviderKey, mOutputUrl, mOutputFormat, nBands, type, iterCols, iterRows, geoTransform, crs, mCreateOptions ) ;
|
||||
|
||||
if ( !destProvider )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// TODO: return provider and report error
|
||||
if ( !destProvider->isValid() )
|
||||
{
|
||||
delete destProvider;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return destProvider;
|
||||
}
|
||||
|
||||
@ -909,24 +926,35 @@ QgsRasterDataProvider* QgsRasterFileWriter::initOutput( int nCols, int nRows, co
|
||||
}
|
||||
else
|
||||
{
|
||||
//QgsRasterDataProvider* destProvider = QgsRasterLayer::loadProvider( mOutputProviderKey, mOutputUrl );
|
||||
QgsRasterDataProvider* destProvider = ( QgsRasterDataProvider* ) QgsProviderRegistry::instance()->provider( mOutputProviderKey, mOutputUrl );
|
||||
if ( !destProvider )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// TODO enable "use existing", has no effect for now, because using Create() in gdal provider
|
||||
// should this belong in provider? should also test that source provider is gdal
|
||||
// if ( mBuildPyramidsFlag == -4 && mOutputProviderKey == "gdal" && mOutputFormat.toLower() == "gtiff" )
|
||||
// mCreateOptions << "COPY_SRC_OVERVIEWS=YES";
|
||||
|
||||
if ( !destProvider->create( mOutputFormat, nBands, type, nCols, nRows, geoTransform,
|
||||
crs, mCreateOptions ) )
|
||||
//QgsRasterDataProvider* destProvider = QgsRasterLayer::loadProvider( mOutputProviderKey, mOutputUrl );
|
||||
//QgsRasterDataProvider* destProvider = ( QgsRasterDataProvider* ) QgsProviderRegistry::instance()->provider( mOutputProviderKey, mOutputUrl );
|
||||
QgsRasterDataProvider* destProvider = QgsRasterDataProvider::create( mOutputProviderKey, mOutputUrl, mOutputFormat, nBands, type, nCols, nRows, geoTransform, crs, mCreateOptions ) ;
|
||||
|
||||
if ( !destProvider )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// TODO: return provider and report error
|
||||
if ( !destProvider->isValid() )
|
||||
{
|
||||
delete destProvider;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
if ( !destProvider->create( mOutputFormat, nBands, type, nCols, nRows, geoTransform,
|
||||
crs, mCreateOptions ) )
|
||||
{
|
||||
delete destProvider;
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
return destProvider;
|
||||
}
|
||||
}
|
||||
|
@ -92,10 +92,17 @@ int CPL_STDCALL progressCallback( double dfComplete,
|
||||
return true;
|
||||
}
|
||||
|
||||
QgsGdalProvider::QgsGdalProvider( QString const & uri, QgsError error )
|
||||
: QgsRasterDataProvider( uri )
|
||||
, mValid( false )
|
||||
{
|
||||
setError( error );
|
||||
}
|
||||
|
||||
QgsGdalProvider::QgsGdalProvider( QString const & uri )
|
||||
QgsGdalProvider::QgsGdalProvider( QString const & uri, bool update )
|
||||
: QgsRasterDataProvider( uri )
|
||||
, QgsGdalProviderBase()
|
||||
, mUpdate( update )
|
||||
, mValid( true )
|
||||
{
|
||||
QgsDebugMsg( "QgsGdalProvider: constructing with uri '" + uri + "'." );
|
||||
@ -126,28 +133,11 @@ QgsGdalProvider::QgsGdalProvider( QString const & uri )
|
||||
setDataSourceUri( vsiPrefix + uri );
|
||||
QgsDebugMsg( QString( "Trying %1 syntax, uri= %2" ).arg( vsiPrefix ).arg( dataSourceUri() ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: this constructor is also called for new rasters, in that case GDAL prints error:
|
||||
// "ERROR 4: `pok.tif' does not exist in the file system, and is not recognised as a supported dataset name."
|
||||
// To avoid this message, we test first if the file exists at all.
|
||||
// This should be done better adding static create() method or something like that
|
||||
// TODO: Cannot test for file existence, for example NetCDF with sublayers
|
||||
// is using URI: NETCDF:"/path/to/file.cdf":layer1
|
||||
/*
|
||||
if ( !QFile::exists( uri ) )
|
||||
{
|
||||
QString msg = QString( "File does not exist: %1" ).arg( dataSourceUri() );
|
||||
appendError( ERR( msg ) );
|
||||
return;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
QString gdalUri = dataSourceUri();
|
||||
|
||||
CPLErrorReset();
|
||||
mGdalBaseDataset = GDALOpen( TO8F( gdalUri ), GA_ReadOnly );
|
||||
mGdalBaseDataset = GDALOpen( TO8F( gdalUri ), mUpdate ? GA_Update : GA_ReadOnly );
|
||||
|
||||
if ( !mGdalBaseDataset )
|
||||
{
|
||||
@ -1481,7 +1471,7 @@ QString QgsGdalProvider::buildPyramids( QList<QgsRasterPyramid> const & theRaste
|
||||
//something bad happenend
|
||||
//QString myString = QString (CPLGetLastError());
|
||||
GDALClose( mGdalBaseDataset );
|
||||
mGdalBaseDataset = GDALOpen( TO8F( dataSourceUri() ), GA_ReadOnly );
|
||||
mGdalBaseDataset = GDALOpen( TO8F( dataSourceUri() ), mUpdate ? GA_Update : GA_ReadOnly );
|
||||
//Since we are not a virtual warped dataset, mGdalDataSet and mGdalBaseDataset are supposed to be the same
|
||||
mGdalDataset = mGdalBaseDataset;
|
||||
|
||||
@ -1523,7 +1513,7 @@ QString QgsGdalProvider::buildPyramids( QList<QgsRasterPyramid> const & theRaste
|
||||
QgsDebugMsg( "Reopening dataset ..." );
|
||||
//close the gdal dataset and reopen it in read only mode
|
||||
GDALClose( mGdalBaseDataset );
|
||||
mGdalBaseDataset = GDALOpen( TO8F( dataSourceUri() ), GA_ReadOnly );
|
||||
mGdalBaseDataset = GDALOpen( TO8F( dataSourceUri() ), mUpdate ? GA_Update : GA_ReadOnly );
|
||||
//Since we are not a virtual warped dataset, mGdalDataSet and mGdalBaseDataset are supposed to be the same
|
||||
mGdalDataset = mGdalBaseDataset;
|
||||
}
|
||||
@ -2401,17 +2391,27 @@ char** papszFromStringList( const QStringList& list )
|
||||
return papszRetList;
|
||||
}
|
||||
|
||||
#if 0
|
||||
bool QgsGdalProvider::create( const QString& format, int nBands,
|
||||
QGis::DataType type,
|
||||
int width, int height, double* geoTransform,
|
||||
const QgsCoordinateReferenceSystem& crs,
|
||||
QStringList createOptions )
|
||||
#endif
|
||||
QGISEXTERN QgsGdalProvider * create(
|
||||
const QString &uri,
|
||||
const QString& format, int nBands,
|
||||
QGis::DataType type,
|
||||
int width, int height, double* geoTransform,
|
||||
const QgsCoordinateReferenceSystem& crs,
|
||||
QStringList createOptions )
|
||||
{
|
||||
//get driver
|
||||
GDALDriverH driver = GDALGetDriverByName( format.toLocal8Bit().data() );
|
||||
if ( !driver )
|
||||
{
|
||||
return false;
|
||||
QgsError error( "Cannot load GDAL driver " + format, "GDAL provider" );
|
||||
return new QgsGdalProvider( uri, error );
|
||||
}
|
||||
|
||||
QString tmpStr = "create options:";
|
||||
@ -2420,27 +2420,21 @@ bool QgsGdalProvider::create( const QString& format, int nBands,
|
||||
QgsDebugMsg( tmpStr );
|
||||
|
||||
//create dataset
|
||||
CPLErrorReset();
|
||||
char **papszOptions = papszFromStringList( createOptions );
|
||||
GDALDatasetH dataset = GDALCreate( driver, dataSourceUri().toLocal8Bit().data(), width, height, nBands, ( GDALDataType )type, papszOptions );
|
||||
GDALDatasetH dataset = GDALCreate( driver, uri.toLocal8Bit().data(), width, height, nBands, ( GDALDataType )type, papszOptions );
|
||||
CSLDestroy( papszOptions );
|
||||
if ( dataset == NULL )
|
||||
{
|
||||
return false;
|
||||
QgsError error( QString( "Cannot create new dataset %1:\n%2" ).arg( uri ).arg( QString::fromUtf8( CPLGetLastErrorMsg() ) ), "GDAL provider" );
|
||||
return new QgsGdalProvider( uri, error );
|
||||
}
|
||||
|
||||
mGeoTransform[0] = geoTransform[0];
|
||||
mGeoTransform[1] = geoTransform[1];
|
||||
mGeoTransform[2] = geoTransform[2];
|
||||
mGeoTransform[3] = geoTransform[3];
|
||||
mGeoTransform[4] = geoTransform[4];
|
||||
mGeoTransform[5] = geoTransform[5];
|
||||
|
||||
GDALSetGeoTransform( dataset, mGeoTransform );
|
||||
GDALSetGeoTransform( dataset, geoTransform );
|
||||
GDALSetProjection( dataset, crs.toWkt().toLocal8Bit().data() );
|
||||
GDALClose( dataset );
|
||||
|
||||
mGdalBaseDataset = dataset;
|
||||
initBaseDataset();
|
||||
return mValid;
|
||||
return new QgsGdalProvider( uri, true );
|
||||
}
|
||||
|
||||
bool QgsGdalProvider::write( void* data, int band, int width, int height, int xOffset, int yOffset )
|
||||
|
@ -65,7 +65,10 @@ class QgsGdalProvider : public QgsRasterDataProvider, QgsGdalProviderBase
|
||||
* otherwise we contact the host directly.
|
||||
*
|
||||
*/
|
||||
QgsGdalProvider( QString const & uri = 0 );
|
||||
QgsGdalProvider( QString const & uri = 0, bool update = false );
|
||||
|
||||
/** Create invalid provider with error */
|
||||
QgsGdalProvider( QString const & uri, QgsError error );
|
||||
|
||||
//! Destructor
|
||||
~QgsGdalProvider();
|
||||
@ -234,11 +237,13 @@ class QgsGdalProvider : public QgsRasterDataProvider, QgsGdalProviderBase
|
||||
|
||||
/** Creates a new dataset with mDataSourceURI
|
||||
@return true in case of success*/
|
||||
/*
|
||||
bool create( const QString& format, int nBands,
|
||||
QGis::DataType type,
|
||||
int width, int height, double* geoTransform,
|
||||
const QgsCoordinateReferenceSystem& crs,
|
||||
QStringList createOptions = QStringList() );
|
||||
*/
|
||||
|
||||
/**Writes into the provider datasource*/
|
||||
bool write( void* data, int band, int width, int height, int xOffset, int yOffset );
|
||||
@ -257,6 +262,9 @@ class QgsGdalProvider : public QgsRasterDataProvider, QgsGdalProviderBase
|
||||
void statusChanged( QString );
|
||||
|
||||
private:
|
||||
// update mode
|
||||
bool mUpdate;
|
||||
|
||||
// initialize CRS from wkt
|
||||
bool crsFromWkt( const char *wkt );
|
||||
|
||||
|
@ -573,12 +573,6 @@ int QgsGrassGisLib::G_open_raster_new( const char *name, RASTER_MAP_TYPE wr_type
|
||||
raster.name = name;
|
||||
//raster.writer = new QgsRasterFileWriter( dataSource );
|
||||
|
||||
raster.provider = ( QgsRasterDataProvider* )QgsProviderRegistry::instance()->provider( providerKey, dataSource );
|
||||
if ( !raster.provider )
|
||||
{
|
||||
fatal( "Cannot load raster provider with data source: " + dataSource );
|
||||
}
|
||||
|
||||
QString outputFormat = "GTiff";
|
||||
int nBands = 1;
|
||||
QGis::DataType type = qgisRasterType( wr_type );
|
||||
@ -591,11 +585,13 @@ int QgsGrassGisLib::G_open_raster_new( const char *name, RASTER_MAP_TYPE wr_type
|
||||
geoTransform[4] = 0.0;
|
||||
geoTransform[5] = -1. * mExtent.height() / mRows;
|
||||
|
||||
if ( !raster.provider->create( outputFormat, nBands, type, mColumns, mRows, geoTransform, mCrs ) )
|
||||
raster.provider = QgsRasterDataProvider::create( providerKey, dataSource, outputFormat, nBands, type, mColumns, mRows, geoTransform, mCrs );
|
||||
if ( !raster.provider || !raster.provider->isValid() )
|
||||
{
|
||||
delete raster.provider;
|
||||
if ( raster.provider ) delete raster.provider;
|
||||
fatal( "Cannot create output data source: " + dataSource );
|
||||
}
|
||||
|
||||
raster.band = 1;
|
||||
double noDataValue = std::numeric_limits<double>::quiet_NaN();
|
||||
switch ( wr_type )
|
||||
|
Loading…
x
Reference in New Issue
Block a user