Skip to content

Commit

Permalink
[GRASS] various import fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
blazek committed May 27, 2015
1 parent f0eeef7 commit bfabb85
Show file tree
Hide file tree
Showing 10 changed files with 136 additions and 78 deletions.
1 change: 1 addition & 0 deletions src/core/qgsdataitem.cpp
Expand Up @@ -644,6 +644,7 @@ void QgsDataItem::setState( State state )
{
if ( !mPopulatingIcon )
{
// TODO: ensure that QgsAnimatedIcon is created on UI thread only
mPopulatingIcon = new QgsAnimatedIcon( QgsApplication::iconPath( "/mIconLoading.gif" ) );
}
mPopulatingIcon->connectFrameChanged( this, SLOT( emitDataChanged() ) );
Expand Down
2 changes: 1 addition & 1 deletion src/core/qgsdataitem.h
Expand Up @@ -38,7 +38,7 @@ class QgsDataItem;
typedef QgsDataItem * dataItem_t( QString, QgsDataItem* );

/** Animated icon is keeping an animation running if there are listeners connected to frameChanged */
class QgsAnimatedIcon : public QObject
class CORE_EXPORT QgsAnimatedIcon : public QObject
{
Q_OBJECT
public:
Expand Down
11 changes: 9 additions & 2 deletions src/providers/grass/qgis.r.in.cpp
Expand Up @@ -38,6 +38,7 @@ extern "C"
#include <QDataStream>
#include <QFile>
#include <QIODevice>
#include <QTextStream>

#include "qgsrectangle.h"
#include "qgsrasterblock.h"
Expand Down Expand Up @@ -80,10 +81,13 @@ int main( int argc, char **argv )
name = map->answer;

QFile stdinFile;
stdinFile.open( 0, QIODevice::ReadOnly );

stdinFile.open( stdin, QIODevice::ReadOnly );
QDataStream stdinStream( &stdinFile );

QFile stdoutFile;
stdoutFile.open( stdout, QIODevice::WriteOnly );
QDataStream stdoutStream( &stdoutFile );

QgsRectangle extent;
qint32 rows, cols;
stdinStream >> extent >> cols >> rows;
Expand Down Expand Up @@ -167,6 +171,9 @@ int main( int argc, char **argv )
ptr = G_incr_void_ptr( ptr, G_raster_size( grass_type ) );
}
G_put_raster_row( cf, buf, grass_type );

stdoutStream << ( bool )true; // row written
stdoutFile.flush();
}

if ( isCanceled )
Expand Down
32 changes: 30 additions & 2 deletions src/providers/grass/qgis.v.in.cpp
Expand Up @@ -105,11 +105,11 @@ int main( int argc, char **argv )
exit( EXIT_FAILURE );

QFile stdinFile;
stdinFile.open( 0, QIODevice::ReadOnly );
stdinFile.open( stdin, QIODevice::ReadOnly );
QDataStream stdinStream( &stdinFile );

QFile stdoutFile;
stdoutFile.open( 0, QIODevice::ReadOnly );
stdoutFile.open( stdout, QIODevice::WriteOnly );
QDataStream stdoutStream( &stdoutFile );

qint32 typeQint32;
Expand Down Expand Up @@ -178,6 +178,8 @@ int main( int argc, char **argv )
{
exitIfCanceled( stdinStream, isPolygon, tmpName, &tmpMap, finalName, &finalMap );
stdinStream >> feature;
stdoutStream << ( bool )true; // feature received
stdoutFile.flush();
if ( !feature.isValid() )
{
break;
Expand Down Expand Up @@ -278,6 +280,29 @@ int main( int argc, char **argv )
break;
}
}
// TODO: review if necessary and if there is GRASS function
// remove zero length
int nlines = Vect_get_num_lines( map );
struct line_pnts *line = Vect_new_line_struct();
for ( int i = 1; i <= nlines; i++ )
{
if ( !Vect_line_alive( map, i ) )
{
continue;
}

int type = Vect_read_line( map, line, NULL, i );
if ( !( type & GV_BOUNDARY ) )
{
continue;
}

if ( Vect_line_length( line ) == 0 )
{
Vect_delete_line( map, i );
}
}

Vect_merge_lines( map, GV_BOUNDARY, NULL, NULL );
#if GRASS_VERSION_MAJOR < 7
Vect_remove_bridges( map, NULL );
Expand Down Expand Up @@ -310,6 +335,8 @@ int main( int argc, char **argv )
{
exitIfCanceled( stdinStream, isPolygon, tmpName, &tmpMap, finalName, &finalMap );
stdinStream >> feature;
stdoutStream << ( bool )true; // feature received
stdoutFile.flush();
if ( !feature.isValid() )
{
break;
Expand Down Expand Up @@ -357,6 +384,7 @@ int main( int argc, char **argv )
Vect_close( &finalMap );

stdoutStream << ( bool )true; // to keep caller waiting until finished
stdoutFile.flush();
// TODO history

exit( EXIT_SUCCESS );
Expand Down
6 changes: 6 additions & 0 deletions src/providers/grass/qgsgrass.cpp
Expand Up @@ -212,6 +212,12 @@ QRegExp GRASS_LIB_EXPORT QgsGrassObject::newNameRegExp( Type type )
return rx;
}

bool QgsGrassObject::operator==( const QgsGrassObject& other ) const
{
return mGisdbase == other.mGisdbase && mLocation == other.mLocation && mMapset == other.mMapset
&& mName == other.mName && mType == other.mType;
}

#ifdef Q_OS_WIN
#include <windows.h>
QString GRASS_LIB_EXPORT QgsGrass::shortPath( const QString &path )
Expand Down
2 changes: 2 additions & 0 deletions src/providers/grass/qgsgrass.h
Expand Up @@ -107,6 +107,8 @@ class GRASS_LIB_EXPORT QgsGrassObject
bool mapsetIdentical( const QgsGrassObject &other ) const;
// get regexp patter for new names, e.g. vectors should not start with number
static QRegExp newNameRegExp( Type type );

bool operator==( const QgsGrassObject& other ) const;
private:
QString mGisdbase;
QString mLocation;
Expand Down
34 changes: 32 additions & 2 deletions src/providers/grass/qgsgrassimport.cpp
Expand Up @@ -91,6 +91,17 @@ QStringList QgsGrassImport::names() const
return list;
}

bool QgsGrassImport::isCanceled() const
{
return mCanceled;
}

void QgsGrassImport::cancel()
{
QgsDebugMsg( "entered" );
mCanceled = true;
}

//------------------------------ QgsGrassRasterImport ------------------------------------
QgsGrassRasterImport::QgsGrassRasterImport( QgsRasterPipe* pipe, const QgsGrassObject& grassObject,
const QgsRectangle &extent, int xSize, int ySize )
Expand Down Expand Up @@ -214,6 +225,11 @@ bool QgsGrassRasterImport::import()
// calculate reasonable block size (5MB)
int maximumTileHeight = 5000000 / mXSize;
maximumTileHeight = std::max( 1, maximumTileHeight );
// smaller if reprojecting so that it can be canceled quickly
if ( mPipe->projector() )
{
maximumTileHeight = std::max( 1, 100000 / mXSize );
}

QgsRasterIterator iter( mPipe->last() );
iter.setMaximumTileWidth( mXSize );
Expand All @@ -226,6 +242,7 @@ bool QgsGrassRasterImport::import()
int iterCols = 0;
int iterRows = 0;
QgsRasterBlock* block = 0;
process->setReadChannel( QProcess::StandardOutput );
while ( iter.readNextRasterPart( band, iterCols, iterRows, &block, iterLeft, iterTop ) )
{
for ( int row = 0; row < iterRows; row++ )
Expand All @@ -246,6 +263,11 @@ bool QgsGrassRasterImport::import()
}
outStream << false; // not canceled
outStream << byteArray;

// wait until the row is written to allow quick cancel (don't send data to buffer)
process->waitForReadyRead();
bool result;
outStream >> result;
}
delete block;
if ( isCanceled() )
Expand Down Expand Up @@ -450,17 +472,25 @@ bool QgsGrassVectorImport::import()
}
outStream << false; // not canceled
outStream << feature;

// wait until the feature is written to allow quick cancel (don't send data to buffer)
process->waitForReadyRead();
bool result;
outStream >> result;
}
feature = QgsFeature(); // indicate end by invalid feature
outStream << false; // not canceled
outStream << feature;
QgsDebugMsg( "features sent" );

process->waitForReadyRead();
bool result;
outStream >> result;
}
iterator.close();

process->setReadChannel( QProcess::StandardOutput );

bool result;
process->waitForReadyRead();
outStream >> result;
QgsDebugMsg( QString( "result = %1" ).arg( result ) );

Expand Down
4 changes: 2 additions & 2 deletions src/providers/grass/qgsgrassimport.h
Expand Up @@ -39,15 +39,15 @@ class GRASS_LIB_EXPORT QgsGrassImport : public QObject
// get error if import failed
QString error();
virtual QStringList names() const;
bool isCanceled() const { return mCanceled; }
bool isCanceled() const;
public slots:
void onFinished();
// TODO: this is not completely kosher, because QgsGrassImport exist on the main thread
// but import is running in another thread, to do it right, we should have an import object
// created on another thread, send cancel signal to that object which regularly processes events
// and thus recieves the signal.
// Most probably however, it will work correctly, even if read/write the bool wasn't atomic
void cancel() { mCanceled = true; }
void cancel();

signals:
// sent when process finished
Expand Down

0 comments on commit bfabb85

Please sign in to comment.