[QGIS Commit] r15711 - trunk/qgis/src/providers/grass

svn_qgis at osgeo.org svn_qgis at osgeo.org
Fri Apr 15 13:09:46 EDT 2011


Author: rblazek
Date: 2011-04-15 10:09:46 -0700 (Fri, 15 Apr 2011)
New Revision: 15711

Modified:
   trunk/qgis/src/providers/grass/qgis.g.info.c
   trunk/qgis/src/providers/grass/qgsgrass.cpp
   trunk/qgis/src/providers/grass/qgsgrass.h
   trunk/qgis/src/providers/grass/qgsgrassrasterprovider.cpp
   trunk/qgis/src/providers/grass/qgsgrassrasterprovider.h
Log:
keep qgis.g.info process open and get values through stdin/stdout

Modified: trunk/qgis/src/providers/grass/qgis.g.info.c
===================================================================
--- trunk/qgis/src/providers/grass/qgis.g.info.c	2011-04-15 17:04:36 UTC (rev 15710)
+++ trunk/qgis/src/providers/grass/qgis.g.info.c	2011-04-15 17:09:46 UTC (rev 15711)
@@ -138,68 +138,81 @@
   {
     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 )
+      // wait for coors from stdin
+      while ( G_getl2( buff, 100, stdin ) != 0 )
       {
-        fprintf( stdout, "value:null\n" );
-      }
-      else
-      {
-        void *ptr;
-        double val;
+        if ( sscanf( buff, "%lf%lf", &x, &y ) != 2 )
+        {
+          fprintf( stdout, "value:error\n" );
+        }
+        else
+        {
+          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: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 );
+            rast_type = G_get_raster_map_type( fd );
 #else
-        rast_type = G_raster_map_type( rast_opt->answer, "" );
+            rast_type = G_raster_map_type( rast_opt->answer, "" );
 #endif
-        cell = G_allocate_c_raster_buf();
-        dcell = G_allocate_d_raster_buf();
+            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 );
+            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 = 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 );
-        }
+        fflush( stdout );
       }
       G_close_cell( fd );
     }

Modified: trunk/qgis/src/providers/grass/qgsgrass.cpp
===================================================================
--- trunk/qgis/src/providers/grass/qgsgrass.cpp	2011-04-15 17:04:36 UTC (rev 15710)
+++ trunk/qgis/src/providers/grass/qgsgrass.cpp	2011-04-15 17:09:46 UTC (rev 15711)
@@ -1039,21 +1039,20 @@
   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 );
@@ -1062,35 +1061,45 @@
   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;
 }
 

Modified: trunk/qgis/src/providers/grass/qgsgrass.h
===================================================================
--- trunk/qgis/src/providers/grass/qgsgrass.h	2011-04-15 17:04:36 UTC (rev 15710)
+++ trunk/qgis/src/providers/grass/qgsgrass.h	2011-04-15 17:09:46 UTC (rev 15711)
@@ -25,9 +25,11 @@
 
 #include <stdexcept>
 #include "qgsexception.h"
+#include <QProcess>
 #include <QString>
 #include <QMap>
 #include <QHash>
+#include <QTemporaryFile>
 class QgsCoordinateReferenceSystem;
 class QgsRectangle;
 
@@ -181,6 +183,9 @@
     // ! 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 );
 

Modified: trunk/qgis/src/providers/grass/qgsgrassrasterprovider.cpp
===================================================================
--- trunk/qgis/src/providers/grass/qgsgrassrasterprovider.cpp	2011-04-15 17:04:36 UTC (rev 15710)
+++ trunk/qgis/src/providers/grass/qgsgrassrasterprovider.cpp	2011-04-15 17:09:46 UTC (rev 15711)
@@ -74,6 +74,7 @@
   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 );
@@ -337,7 +338,20 @@
 {
   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;
 }
 
@@ -504,4 +518,47 @@
   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;
+}
+
+

Modified: trunk/qgis/src/providers/grass/qgsgrassrasterprovider.h
===================================================================
--- trunk/qgis/src/providers/grass/qgsgrassrasterprovider.h	2011-04-15 17:04:36 UTC (rev 15710)
+++ trunk/qgis/src/providers/grass/qgsgrassrasterprovider.h	2011-04-15 17:09:46 UTC (rev 15711)
@@ -40,7 +40,29 @@
 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.
 
   This provider implements the
@@ -245,6 +267,7 @@
 
     QgsCoordinateReferenceSystem mCrs;
 
+    QgsGrassRasterValue mRasterValue;
 };
 
 #endif



More information about the QGIS-commit mailing list