Skip to content

Commit

Permalink
keep qgis.g.info process open and get values through stdin/stdout
Browse files Browse the repository at this point in the history
git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@15711 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
rblazek committed Apr 15, 2011
1 parent 6042fd3 commit 63a2222
Show file tree
Hide file tree
Showing 5 changed files with 176 additions and 69 deletions.
103 changes: 58 additions & 45 deletions src/providers/grass/qgis.g.info.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,68 +138,81 @@ int main( int argc, char **argv )
{
double x, y;
int row, col;
x = atof( coor_opt->answers[0] );
y = atof( coor_opt->answers[1] );
//x = atof( coor_opt->answers[0] );
//y = atof( coor_opt->answers[1] );
if ( rast_opt->answer )
{
int fd;
RASTER_MAP_TYPE rast_type;
DCELL *dcell;
CELL *cell;
char buff[101];
G_get_cellhd( rast_opt->answer, "", &window );
G_set_window( &window );
fd = G_open_cell_old( rast_opt->answer, "" );
col = ( int ) G_easting_to_col( x, &window );
row = ( int ) G_northing_to_row( y, &window );
if ( col == window.cols ) col--;
if ( row == window.rows ) row--;

if ( col < 0 || col > window.cols || row < 0 || row > window.rows )
{
fprintf( stdout, "value:null\n" );
}
else
// wait for coors from stdin
while ( G_getl2( buff, 100, stdin ) != 0 )
{
void *ptr;
double val;

#if defined(GRASS_VERSION_MAJOR) && defined(GRASS_VERSION_MINOR) && \
( ( GRASS_VERSION_MAJOR == 6 && GRASS_VERSION_MINOR > 2 ) || GRASS_VERSION_MAJOR > 6 )
rast_type = G_get_raster_map_type( fd );
#else
rast_type = G_raster_map_type( rast_opt->answer, "" );
#endif
cell = G_allocate_c_raster_buf();
dcell = G_allocate_d_raster_buf();

if ( rast_type == CELL_TYPE )
if ( sscanf( buff, "%lf%lf", &x, &y ) != 2 )
{
if ( G_get_c_raster_row( fd, cell, row ) < 0 )
{
G_fatal_error(( "Unable to read raster map <%s> row %d" ),
rast_opt->answer, row );
}
val = cell[col];
ptr = &( cell[col] );
fprintf( stdout, "value:error\n" );
}
else
{
if ( G_get_d_raster_row( fd, dcell, row ) < 0 )
col = ( int ) G_easting_to_col( x, &window );
row = ( int ) G_northing_to_row( y, &window );
if ( col == window.cols ) col--;
if ( row == window.rows ) row--;

if ( col < 0 || col > window.cols || row < 0 || row > window.rows )
{
G_fatal_error(( "Unable to read raster map <%s> row %d" ),
rast_opt->answer, row );
fprintf( stdout, "value:out\n" );
}
else
{
void *ptr;
double val;

#if defined(GRASS_VERSION_MAJOR) && defined(GRASS_VERSION_MINOR) && \
( ( GRASS_VERSION_MAJOR == 6 && GRASS_VERSION_MINOR > 2 ) || GRASS_VERSION_MAJOR > 6 )
rast_type = G_get_raster_map_type( fd );
#else
rast_type = G_raster_map_type( rast_opt->answer, "" );
#endif
cell = G_allocate_c_raster_buf();
dcell = G_allocate_d_raster_buf();

if ( rast_type == CELL_TYPE )
{
if ( G_get_c_raster_row( fd, cell, row ) < 0 )
{
G_fatal_error(( "Unable to read raster map <%s> row %d" ),
rast_opt->answer, row );
}
val = cell[col];
ptr = &( cell[col] );
}
else
{
if ( G_get_d_raster_row( fd, dcell, row ) < 0 )
{
G_fatal_error(( "Unable to read raster map <%s> row %d" ),
rast_opt->answer, row );
}
val = dcell[col];
ptr = &( dcell[col] );
}
if ( G_is_null_value( ptr, rast_type ) )
{
fprintf( stdout, "value:null\n" );
}
else
{
fprintf( stdout, "value:%f\n", val );
}
}
val = dcell[col];
ptr = &( dcell[col] );
}
if ( G_is_null_value( ptr, rast_type ) )
{
fprintf( stdout, "value:null\n" );
}
else
{
fprintf( stdout, "value:%f\n", val );
}
fflush( stdout );
}
G_close_cell( fd );
}
Expand Down
55 changes: 32 additions & 23 deletions src/providers/grass/qgsgrass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1039,21 +1039,20 @@ bool GRASS_EXPORT QgsGrass::mapRegion( int type, QString gisbase,
return true;
}

QByteArray GRASS_EXPORT QgsGrass::runModule( QString gisdbase, QString location,
QString module, QStringList arguments )
QProcess * GRASS_EXPORT QgsGrass::startModule( QString gisdbase, QString location,
QString module, QStringList arguments, QTemporaryFile &gisrcFile )
{
QgsDebugMsg( QString( "gisdbase = %1 location = %2" ).arg( gisdbase ).arg( location ) );
QProcess *process = new QProcess();

#ifdef WIN32
module += ".exe";
#endif

// We have to set GISRC file, uff
QTemporaryFile gisrcFile;
if ( !gisrcFile.open() )
{
// TODO Exception
return QByteArray();
throw QgsGrass::Exception( QObject::tr( "Cannot open GISRC file" ) );
}

QTextStream out( &gisrcFile );
Expand All @@ -1062,35 +1061,45 @@ QByteArray GRASS_EXPORT QgsGrass::runModule( QString gisdbase, QString location,
out << "MAPSET: PERMANENT\n";
out.flush();
QgsDebugMsg( gisrcFile.fileName() );
gisrcFile.close();

QStringList environment = QProcess::systemEnvironment();
environment.append( "GISRC=" + gisrcFile.fileName() );

QProcess process;
process.setEnvironment( environment );
process->setEnvironment( environment );

QgsDebugMsg( module + " " + arguments.join( " " ) );
process.start( module, arguments );
if ( !process.waitForFinished()
|| ( process.exitCode() != 0 && process.exitCode() != 255 ) )
process->start( module, arguments );
if ( !process->waitForStarted() )
{
QgsDebugMsg( "process.exitCode() = " + QString::number( process.exitCode() ) );
/*
QMessageBox::warning( 0, QObject::tr( "Warning" ),
QObject::tr( "Cannot start module" )
+ QObject::tr( "<br>command: %1 %2<br>%3<br>%4" )
.arg( module ).arg( arguments.join( " " ) )
.arg( process.readAllStandardOutput().constData() )
.arg( process.readAllStandardError().constData() ) );
*/
throw QgsGrass::Exception( QObject::tr( "Cannot start module" ) + "\n"
+ QObject::tr( "command: %1 %2" )
.arg( module ).arg( arguments.join( " " ) ) );
}
return process;
}

QByteArray GRASS_EXPORT QgsGrass::runModule( QString gisdbase, QString location,
QString module, QStringList arguments )
{
QgsDebugMsg( QString( "gisdbase = %1 location = %2" ).arg( gisdbase ).arg( location ) );

QTemporaryFile gisrcFile;
QProcess *process = QgsGrass::startModule( gisdbase, location, module, arguments, gisrcFile );

if ( !process->waitForFinished()
|| ( process->exitCode() != 0 && process->exitCode() != 255 ) )
{
QgsDebugMsg( "process->exitCode() = " + QString::number( process->exitCode() ) );

throw QgsGrass::Exception( QObject::tr( "Cannot run module" ) + "\n"
+ QObject::tr( "command: %1 %2<br>%3<br>%4" )
.arg( module ).arg( arguments.join( " " ) )
.arg( process.readAllStandardOutput().constData() )
.arg( process.readAllStandardError().constData() ) );
.arg( process->readAllStandardOutput().constData() )
.arg( process->readAllStandardError().constData() ) );
}
QByteArray data = process.readAllStandardOutput();

QByteArray data = process->readAllStandardOutput();
delete process;
return data;
}

Expand Down
5 changes: 5 additions & 0 deletions src/providers/grass/qgsgrass.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@ extern "C"

#include <stdexcept>
#include "qgsexception.h"
#include <QProcess>
#include <QString>
#include <QMap>
#include <QHash>
#include <QTemporaryFile>
class QgsCoordinateReferenceSystem;
class QgsRectangle;

Expand Down Expand Up @@ -181,6 +183,9 @@ class QgsGrass
// ! Get current gisrc path
static GRASS_EXPORT QString gisrcFilePath();

// ! Start a GRASS module in any gisdbase/location
static GRASS_EXPORT QProcess *startModule( QString gisdbase, QString location, QString module, QStringList arguments, QTemporaryFile &gisrcFile );

// ! Run a GRASS module in any gisdbase/location
static GRASS_EXPORT QByteArray runModule( QString gisdbase, QString location, QString module, QStringList arguments );

Expand Down
59 changes: 58 additions & 1 deletion src/providers/grass/qgsgrassrasterprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ QgsGrassRasterProvider::QgsGrassRasterProvider( QString const & uri )
QgsDebugMsg( QString( "mapset: %1" ).arg( mMapset ) );
QgsDebugMsg( QString( "mapName: %1" ).arg( mMapName ) );

mRasterValue.start( mGisdbase, mLocation, mMapset, mMapName );
mValidNoDataValue = true;

mCrs = QgsGrass::crs( mGisdbase, mLocation );
Expand Down Expand Up @@ -337,7 +338,20 @@ bool QgsGrassRasterProvider::identify( const QgsPoint& thePoint, QMap<QString, Q
{
QgsDebugMsg( "Entered" );
//theResults["Error"] = tr( "Out of extent" );
theResults = QgsGrass::query( mGisdbase, mLocation, mMapset, mMapName, QgsGrass::Raster, thePoint.x(), thePoint.y() );
//theResults = QgsGrass::query( mGisdbase, mLocation, mMapset, mMapName, QgsGrass::Raster, thePoint.x(), thePoint.y() );
QString value = mRasterValue.value( thePoint.x(), thePoint.y() );
theResults.clear();
// attention, value tool does his own tricks with grass identify() so it stops to refresh values outside extent or null values e.g.
if ( value == "out" )
{
value = tr( "Out of extent" );
}
if ( value == "null" )
{
value = tr( "null (no data)" );
}
theResults["value"] = value;
QgsDebugMsg( "value = " + value );
return true;
}

Expand Down Expand Up @@ -504,4 +518,47 @@ QGISEXTERN bool isProvider()
return true;
}

QgsGrassRasterValue::QgsGrassRasterValue() : mProcess( 0 )
{
}

void QgsGrassRasterValue::start( QString gisdbase, QString location,
QString mapset, QString map )
{
mGisdbase = gisdbase;
mLocation = location;
mMapset = mapset;
mMapName = map;
// TODO: catch exceptions
QString module = QgsApplication::prefixPath() + "/" QGIS_LIBEXEC_SUBDIR "/grass/modules/qgis.g.info";
QStringList arguments;

arguments.append( "info=query" );
arguments.append( "rast=" + mMapName + "@" + mMapset );
mProcess = QgsGrass::startModule( mGisdbase, mLocation, module, arguments, mGisrcFile );
}
QgsGrassRasterValue::~QgsGrassRasterValue()
{
if ( mProcess ) delete mProcess;
}

QString QgsGrassRasterValue::value( double x, double y )
{
QString value = "error";
if ( !mProcess ) return value; // throw some exception?
QString coor = QString( "%1 %2\n" ).arg( x ).arg( y );
QgsDebugMsg( "coor : " + coor );
mProcess->write( coor.toAscii() ); // how to flush, necessary?
mProcess->waitForReadyRead();
QString str = mProcess->readLine().trimmed();
QgsDebugMsg( "read from stdout : " + str );

QStringList list = str.trimmed().split( ":" );
if ( list.size() == 2 )
{
value = list[1];
}
return value;
}


23 changes: 23 additions & 0 deletions src/providers/grass/qgsgrassrasterprovider.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,28 @@ extern "C"

class QgsCoordinateTransform;

/**
\brief Read raster value for given coordinates
Executes qgis.g.info and keeps it open comunicating through pipe. Restarts the command if raster was updated.
*/

class QgsGrassRasterValue
{
public:
QgsGrassRasterValue( );
~QgsGrassRasterValue();
void start( QString gisdbase, QString location, QString mapset, QString map );
// returns raster value as string or "null" or "error"
QString value( double x, double y );
private:
QString mGisdbase; // map gisdabase
QString mLocation; // map location name (not path!)
QString mMapset; // map mapset
QString mMapName; // map name
QTemporaryFile mGisrcFile;
QProcess *mProcess;
};
/**
\brief Data provider for OGC WMS layers.
Expand Down Expand Up @@ -245,6 +267,7 @@ class QgsGrassRasterProvider : public QgsRasterDataProvider

QgsCoordinateReferenceSystem mCrs;

QgsGrassRasterValue mRasterValue;
};

#endif
Expand Down

0 comments on commit 63a2222

Please sign in to comment.