Skip to content

Commit aeb7519

Browse files
author
rblazek
committed
keep qgis.g.info process open and get values through stdin/stdout
git-svn-id: http://svn.osgeo.org/qgis/trunk@15711 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent c5a2126 commit aeb7519

File tree

5 files changed

+176
-69
lines changed

5 files changed

+176
-69
lines changed

src/providers/grass/qgis.g.info.c

+58-45
Original file line numberDiff line numberDiff line change
@@ -138,68 +138,81 @@ int main( int argc, char **argv )
138138
{
139139
double x, y;
140140
int row, col;
141-
x = atof( coor_opt->answers[0] );
142-
y = atof( coor_opt->answers[1] );
141+
//x = atof( coor_opt->answers[0] );
142+
//y = atof( coor_opt->answers[1] );
143143
if ( rast_opt->answer )
144144
{
145145
int fd;
146146
RASTER_MAP_TYPE rast_type;
147147
DCELL *dcell;
148148
CELL *cell;
149+
char buff[101];
149150
G_get_cellhd( rast_opt->answer, "", &window );
150151
G_set_window( &window );
151152
fd = G_open_cell_old( rast_opt->answer, "" );
152-
col = ( int ) G_easting_to_col( x, &window );
153-
row = ( int ) G_northing_to_row( y, &window );
154-
if ( col == window.cols ) col--;
155-
if ( row == window.rows ) row--;
156-
157-
if ( col < 0 || col > window.cols || row < 0 || row > window.rows )
158-
{
159-
fprintf( stdout, "value:null\n" );
160-
}
161-
else
153+
// wait for coors from stdin
154+
while ( G_getl2( buff, 100, stdin ) != 0 )
162155
{
163-
void *ptr;
164-
double val;
165-
166-
#if defined(GRASS_VERSION_MAJOR) && defined(GRASS_VERSION_MINOR) && \
167-
( ( GRASS_VERSION_MAJOR == 6 && GRASS_VERSION_MINOR > 2 ) || GRASS_VERSION_MAJOR > 6 )
168-
rast_type = G_get_raster_map_type( fd );
169-
#else
170-
rast_type = G_raster_map_type( rast_opt->answer, "" );
171-
#endif
172-
cell = G_allocate_c_raster_buf();
173-
dcell = G_allocate_d_raster_buf();
174-
175-
if ( rast_type == CELL_TYPE )
156+
if ( sscanf( buff, "%lf%lf", &x, &y ) != 2 )
176157
{
177-
if ( G_get_c_raster_row( fd, cell, row ) < 0 )
178-
{
179-
G_fatal_error(( "Unable to read raster map <%s> row %d" ),
180-
rast_opt->answer, row );
181-
}
182-
val = cell[col];
183-
ptr = &( cell[col] );
158+
fprintf( stdout, "value:error\n" );
184159
}
185160
else
186161
{
187-
if ( G_get_d_raster_row( fd, dcell, row ) < 0 )
162+
col = ( int ) G_easting_to_col( x, &window );
163+
row = ( int ) G_northing_to_row( y, &window );
164+
if ( col == window.cols ) col--;
165+
if ( row == window.rows ) row--;
166+
167+
if ( col < 0 || col > window.cols || row < 0 || row > window.rows )
188168
{
189-
G_fatal_error(( "Unable to read raster map <%s> row %d" ),
190-
rast_opt->answer, row );
169+
fprintf( stdout, "value:out\n" );
170+
}
171+
else
172+
{
173+
void *ptr;
174+
double val;
175+
176+
#if defined(GRASS_VERSION_MAJOR) && defined(GRASS_VERSION_MINOR) && \
177+
( ( GRASS_VERSION_MAJOR == 6 && GRASS_VERSION_MINOR > 2 ) || GRASS_VERSION_MAJOR > 6 )
178+
rast_type = G_get_raster_map_type( fd );
179+
#else
180+
rast_type = G_raster_map_type( rast_opt->answer, "" );
181+
#endif
182+
cell = G_allocate_c_raster_buf();
183+
dcell = G_allocate_d_raster_buf();
184+
185+
if ( rast_type == CELL_TYPE )
186+
{
187+
if ( G_get_c_raster_row( fd, cell, row ) < 0 )
188+
{
189+
G_fatal_error(( "Unable to read raster map <%s> row %d" ),
190+
rast_opt->answer, row );
191+
}
192+
val = cell[col];
193+
ptr = &( cell[col] );
194+
}
195+
else
196+
{
197+
if ( G_get_d_raster_row( fd, dcell, row ) < 0 )
198+
{
199+
G_fatal_error(( "Unable to read raster map <%s> row %d" ),
200+
rast_opt->answer, row );
201+
}
202+
val = dcell[col];
203+
ptr = &( dcell[col] );
204+
}
205+
if ( G_is_null_value( ptr, rast_type ) )
206+
{
207+
fprintf( stdout, "value:null\n" );
208+
}
209+
else
210+
{
211+
fprintf( stdout, "value:%f\n", val );
212+
}
191213
}
192-
val = dcell[col];
193-
ptr = &( dcell[col] );
194-
}
195-
if ( G_is_null_value( ptr, rast_type ) )
196-
{
197-
fprintf( stdout, "value:null\n" );
198-
}
199-
else
200-
{
201-
fprintf( stdout, "value:%f\n", val );
202214
}
215+
fflush( stdout );
203216
}
204217
G_close_cell( fd );
205218
}

src/providers/grass/qgsgrass.cpp

+32-23
Original file line numberDiff line numberDiff line change
@@ -1039,21 +1039,20 @@ bool GRASS_EXPORT QgsGrass::mapRegion( int type, QString gisbase,
10391039
return true;
10401040
}
10411041

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

10471048
#ifdef WIN32
10481049
module += ".exe";
10491050
#endif
10501051

10511052
// We have to set GISRC file, uff
1052-
QTemporaryFile gisrcFile;
10531053
if ( !gisrcFile.open() )
10541054
{
1055-
// TODO Exception
1056-
return QByteArray();
1055+
throw QgsGrass::Exception( QObject::tr( "Cannot open GISRC file" ) );
10571056
}
10581057

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

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

1069-
QProcess process;
1070-
process.setEnvironment( environment );
1069+
process->setEnvironment( environment );
10711070

10721071
QgsDebugMsg( module + " " + arguments.join( " " ) );
1073-
process.start( module, arguments );
1074-
if ( !process.waitForFinished()
1075-
|| ( process.exitCode() != 0 && process.exitCode() != 255 ) )
1072+
process->start( module, arguments );
1073+
if ( !process->waitForStarted() )
10761074
{
1077-
QgsDebugMsg( "process.exitCode() = " + QString::number( process.exitCode() ) );
1078-
/*
1079-
QMessageBox::warning( 0, QObject::tr( "Warning" ),
1080-
QObject::tr( "Cannot start module" )
1081-
+ QObject::tr( "<br>command: %1 %2<br>%3<br>%4" )
1082-
.arg( module ).arg( arguments.join( " " ) )
1083-
.arg( process.readAllStandardOutput().constData() )
1084-
.arg( process.readAllStandardError().constData() ) );
1085-
*/
10861075
throw QgsGrass::Exception( QObject::tr( "Cannot start module" ) + "\n"
1076+
+ QObject::tr( "command: %1 %2" )
1077+
.arg( module ).arg( arguments.join( " " ) ) );
1078+
}
1079+
return process;
1080+
}
1081+
1082+
QByteArray GRASS_EXPORT QgsGrass::runModule( QString gisdbase, QString location,
1083+
QString module, QStringList arguments )
1084+
{
1085+
QgsDebugMsg( QString( "gisdbase = %1 location = %2" ).arg( gisdbase ).arg( location ) );
1086+
1087+
QTemporaryFile gisrcFile;
1088+
QProcess *process = QgsGrass::startModule( gisdbase, location, module, arguments, gisrcFile );
1089+
1090+
if ( !process->waitForFinished()
1091+
|| ( process->exitCode() != 0 && process->exitCode() != 255 ) )
1092+
{
1093+
QgsDebugMsg( "process->exitCode() = " + QString::number( process->exitCode() ) );
1094+
1095+
throw QgsGrass::Exception( QObject::tr( "Cannot run module" ) + "\n"
10871096
+ QObject::tr( "command: %1 %2<br>%3<br>%4" )
10881097
.arg( module ).arg( arguments.join( " " ) )
1089-
.arg( process.readAllStandardOutput().constData() )
1090-
.arg( process.readAllStandardError().constData() ) );
1098+
.arg( process->readAllStandardOutput().constData() )
1099+
.arg( process->readAllStandardError().constData() ) );
10911100
}
1092-
QByteArray data = process.readAllStandardOutput();
1093-
1101+
QByteArray data = process->readAllStandardOutput();
1102+
delete process;
10941103
return data;
10951104
}
10961105

src/providers/grass/qgsgrass.h

+5
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,11 @@ extern "C"
2525

2626
#include <stdexcept>
2727
#include "qgsexception.h"
28+
#include <QProcess>
2829
#include <QString>
2930
#include <QMap>
3031
#include <QHash>
32+
#include <QTemporaryFile>
3133
class QgsCoordinateReferenceSystem;
3234
class QgsRectangle;
3335

@@ -181,6 +183,9 @@ class QgsGrass
181183
// ! Get current gisrc path
182184
static GRASS_EXPORT QString gisrcFilePath();
183185

186+
// ! Start a GRASS module in any gisdbase/location
187+
static GRASS_EXPORT QProcess *startModule( QString gisdbase, QString location, QString module, QStringList arguments, QTemporaryFile &gisrcFile );
188+
184189
// ! Run a GRASS module in any gisdbase/location
185190
static GRASS_EXPORT QByteArray runModule( QString gisdbase, QString location, QString module, QStringList arguments );
186191

src/providers/grass/qgsgrassrasterprovider.cpp

+58-1
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ QgsGrassRasterProvider::QgsGrassRasterProvider( QString const & uri )
7474
QgsDebugMsg( QString( "mapset: %1" ).arg( mMapset ) );
7575
QgsDebugMsg( QString( "mapName: %1" ).arg( mMapName ) );
7676

77+
mRasterValue.start( mGisdbase, mLocation, mMapset, mMapName );
7778
mValidNoDataValue = true;
7879

7980
mCrs = QgsGrass::crs( mGisdbase, mLocation );
@@ -337,7 +338,20 @@ bool QgsGrassRasterProvider::identify( const QgsPoint& thePoint, QMap<QString, Q
337338
{
338339
QgsDebugMsg( "Entered" );
339340
//theResults["Error"] = tr( "Out of extent" );
340-
theResults = QgsGrass::query( mGisdbase, mLocation, mMapset, mMapName, QgsGrass::Raster, thePoint.x(), thePoint.y() );
341+
//theResults = QgsGrass::query( mGisdbase, mLocation, mMapset, mMapName, QgsGrass::Raster, thePoint.x(), thePoint.y() );
342+
QString value = mRasterValue.value( thePoint.x(), thePoint.y() );
343+
theResults.clear();
344+
// attention, value tool does his own tricks with grass identify() so it stops to refresh values outside extent or null values e.g.
345+
if ( value == "out" )
346+
{
347+
value = tr( "Out of extent" );
348+
}
349+
if ( value == "null" )
350+
{
351+
value = tr( "null (no data)" );
352+
}
353+
theResults["value"] = value;
354+
QgsDebugMsg( "value = " + value );
341355
return true;
342356
}
343357

@@ -504,4 +518,47 @@ QGISEXTERN bool isProvider()
504518
return true;
505519
}
506520

521+
QgsGrassRasterValue::QgsGrassRasterValue() : mProcess( 0 )
522+
{
523+
}
524+
525+
void QgsGrassRasterValue::start( QString gisdbase, QString location,
526+
QString mapset, QString map )
527+
{
528+
mGisdbase = gisdbase;
529+
mLocation = location;
530+
mMapset = mapset;
531+
mMapName = map;
532+
// TODO: catch exceptions
533+
QString module = QgsApplication::prefixPath() + "/" QGIS_LIBEXEC_SUBDIR "/grass/modules/qgis.g.info";
534+
QStringList arguments;
535+
536+
arguments.append( "info=query" );
537+
arguments.append( "rast=" + mMapName + "@" + mMapset );
538+
mProcess = QgsGrass::startModule( mGisdbase, mLocation, module, arguments, mGisrcFile );
539+
}
540+
QgsGrassRasterValue::~QgsGrassRasterValue()
541+
{
542+
if ( mProcess ) delete mProcess;
543+
}
544+
545+
QString QgsGrassRasterValue::value( double x, double y )
546+
{
547+
QString value = "error";
548+
if ( !mProcess ) return value; // throw some exception?
549+
QString coor = QString( "%1 %2\n" ).arg( x ).arg( y );
550+
QgsDebugMsg( "coor : " + coor );
551+
mProcess->write( coor.toAscii() ); // how to flush, necessary?
552+
mProcess->waitForReadyRead();
553+
QString str = mProcess->readLine().trimmed();
554+
QgsDebugMsg( "read from stdout : " + str );
555+
556+
QStringList list = str.trimmed().split( ":" );
557+
if ( list.size() == 2 )
558+
{
559+
value = list[1];
560+
}
561+
return value;
562+
}
563+
507564

src/providers/grass/qgsgrassrasterprovider.h

+23
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,28 @@ extern "C"
3939

4040
class QgsCoordinateTransform;
4141

42+
/**
43+
\brief Read raster value for given coordinates
44+
45+
Executes qgis.g.info and keeps it open comunicating through pipe. Restarts the command if raster was updated.
46+
*/
47+
48+
class QgsGrassRasterValue
49+
{
50+
public:
51+
QgsGrassRasterValue( );
52+
~QgsGrassRasterValue();
53+
void start( QString gisdbase, QString location, QString mapset, QString map );
54+
// returns raster value as string or "null" or "error"
55+
QString value( double x, double y );
56+
private:
57+
QString mGisdbase; // map gisdabase
58+
QString mLocation; // map location name (not path!)
59+
QString mMapset; // map mapset
60+
QString mMapName; // map name
61+
QTemporaryFile mGisrcFile;
62+
QProcess *mProcess;
63+
};
4264
/**
4365
4466
\brief Data provider for OGC WMS layers.
@@ -245,6 +267,7 @@ class QgsGrassRasterProvider : public QgsRasterDataProvider
245267

246268
QgsCoordinateReferenceSystem mCrs;
247269

270+
QgsGrassRasterValue mRasterValue;
248271
};
249272

250273
#endif

0 commit comments

Comments
 (0)