834 changes: 590 additions & 244 deletions src/plugins/grass/qgsgrassmodule.cpp

Large diffs are not rendered by default.

75 changes: 59 additions & 16 deletions src/plugins/grass/qgsgrassmodule.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#include "qgis.h"
#include "qgsfield.h"
#include "qgscoordinatereferencesystem.h"

#include <QCheckBox>
#include <QGroupBox>
Expand All @@ -40,7 +41,6 @@ class QDomElement;
class QLineEdit;
class QValidator;


/*! \class QgsGrassModule
* \brief Interface to GRASS modules.
*
Expand All @@ -50,15 +50,30 @@ class QgsGrassModule: public QDialog, private Ui::QgsGrassModuleBase
Q_OBJECT

public:
class Description
{
public:
QString label;
// supported by GRASS Direct
bool direct;
Description(): direct( true ) {}
Description( QString lab, bool dir = false ): label( lab ), direct( dir ) { }
Description( const Description & desc ) { label = desc.label; direct = desc.direct; }
Description( Description & desc ) { label = desc.label; direct = desc.direct; }
};

//! Constructor
QgsGrassModule( QgsGrassTools *tools, QString moduleName, QgisInterface *iface,
QString path, QWidget *parent, Qt::WFlags f = 0 );
QString path, bool direct, QWidget *parent, Qt::WFlags f = 0 );

//! Destructor
~QgsGrassModule();

QString translate( QString string );

//! Returns module description (info from .qgs file) for module description path
static Description description( QString path );

//! Returns module label for module description path
static QString label( QString path );

Expand Down Expand Up @@ -93,6 +108,9 @@ class QgsGrassModule: public QDialog, private Ui::QgsGrassModuleBase
// Returns empty list if not found.
static QStringList execArguments( QString module );

//! Returns true if module is direct
bool isDirect() { return mDirect; }

signals:
// ! emitted when the module started
void moduleStarted();
Expand Down Expand Up @@ -122,6 +140,9 @@ class QgsGrassModule: public QDialog, private Ui::QgsGrassModuleBase
//! Read module's standard error
void readStderr();

//! Call on mapset change, i.e. also possible direct/indirect mode change
void mapsetChanged();

private:
//! Pointer to the QGIS interface object
QgisInterface *mIface;
Expand Down Expand Up @@ -161,6 +182,9 @@ class QgsGrassModule: public QDialog, private Ui::QgsGrassModuleBase

//! True if the module successfully finished
bool mSuccess;

//! Direct mode
bool mDirect;
};

/*! \class QgsGrassModuleOptions
Expand All @@ -170,10 +194,15 @@ class QgsGrassModule: public QDialog, private Ui::QgsGrassModuleBase
class QgsGrassModuleOptions
{
public:
enum RegionMode
{
RegionInput = 1, // intersection of input maps extent and highest input resolution
RegionCurrent = 0 // current map canvas extent and resolution
};
//! Constructor
QgsGrassModuleOptions(
QgsGrassTools *tools, QgsGrassModule *module,
QgisInterface *iface );
QgisInterface *iface, bool direct );

//! Destructor
virtual ~QgsGrassModuleOptions();
Expand Down Expand Up @@ -218,8 +247,8 @@ class QgsGrassModuleOptions
//! Get region covering all input maps
// \param all true all input maps
// \param all false only the mas which were switched on
virtual bool inputRegion( struct Cell_head *window, bool all )
{ Q_UNUSED( window ); Q_UNUSED( all ); return false; }
virtual bool inputRegion( struct Cell_head *window, QgsCoordinateReferenceSystem & crs, bool all )
{ Q_UNUSED( window ); Q_UNUSED( crs ); Q_UNUSED( all ); return false; }

// ! Flag names
virtual QStringList flagNames() { return QStringList() ; }
Expand All @@ -242,6 +271,12 @@ class QgsGrassModuleOptions

//! QGIS directory
QString mAppDir;

//! Region mode select box
QComboBox * mRegionModeComboBox;

//! Direct mode
bool mDirect;
};

/*! \class QgsGrassModuleStandardOptions
Expand All @@ -258,7 +293,7 @@ class QgsGrassModuleStandardOptions: QWidget, public QgsGrassModuleOptions
QgsGrassTools *tools, QgsGrassModule *module,
QgisInterface *iface,
QString xname, QDomElement docElem,
QWidget * parent = 0, Qt::WFlags f = 0 );
bool direct, QWidget * parent = 0, Qt::WFlags f = 0 );

//! Destructor
~QgsGrassModuleStandardOptions();
Expand All @@ -282,7 +317,7 @@ class QgsGrassModuleStandardOptions: QWidget, public QgsGrassModuleOptions
QStringList checkRegion();
bool usesRegion();
bool requestsRegion();
bool inputRegion( struct Cell_head *window, bool all );
bool inputRegion( struct Cell_head *window, QgsCoordinateReferenceSystem & crs, bool all );
QStringList flagNames() { return mFlagNames; }

public slots:
Expand Down Expand Up @@ -357,7 +392,7 @@ class QgsGrassModuleItem
* \param gnode option node in GRASS module XML description file
*/
QgsGrassModuleItem( QgsGrassModule *module, QString key,
QDomElement &qdesc, QDomElement &gdesc, QDomNode &gnode );
QDomElement &qdesc, QDomElement &gdesc, QDomNode &gnode, bool direct );

//! Destructor
virtual ~QgsGrassModuleItem();
Expand Down Expand Up @@ -404,6 +439,8 @@ class QgsGrassModuleItem
//! Is it required
bool mRequired;

bool mDirect;

private:

};
Expand All @@ -425,7 +462,7 @@ class QgsGrassModuleGroupBoxItem: public QGroupBox, public QgsGrassModuleItem
*/
QgsGrassModuleGroupBoxItem( QgsGrassModule *module, QString key,
QDomElement &qdesc, QDomElement &gdesc, QDomNode &gnode,
QWidget * parent = 0 );
bool direct, QWidget * parent = 0 );

//! Destructor
virtual ~QgsGrassModuleGroupBoxItem();
Expand Down Expand Up @@ -454,7 +491,7 @@ class QgsGrassModuleOption: public QgsGrassModuleGroupBoxItem
*/
QgsGrassModuleOption( QgsGrassModule *module, QString key,
QDomElement &qdesc, QDomElement &gdesc, QDomNode &gnode,
QWidget * parent = 0 );
bool direct, QWidget * parent = 0 );

//! Destructor
~QgsGrassModuleOption();
Expand Down Expand Up @@ -501,6 +538,9 @@ class QgsGrassModuleOption: public QgsGrassModuleGroupBoxItem
// Remove one line edit for multiple options
void removeLineEdit();

// Browse output
void browse( bool checked );

private:
//! Control type
ControlType mControlType;
Expand Down Expand Up @@ -557,7 +597,7 @@ class QgsGrassModuleFlag: public QgsGrassModuleCheckBox, public QgsGrassModuleIt
*/
QgsGrassModuleFlag( QgsGrassModule *module, QString key,
QDomElement &qdesc, QDomElement &gdesc, QDomNode &gnode,
QWidget * parent = 0 );
bool direct, QWidget * parent = 0 );

//! Destructor
~QgsGrassModuleFlag();
Expand All @@ -584,7 +624,7 @@ class QgsGrassModuleInput: public QgsGrassModuleGroupBoxItem
QgsGrassModuleInput( QgsGrassModule *module,
QgsGrassModuleStandardOptions *options, QString key,
QDomElement &qdesc, QDomElement &gdesc, QDomNode &gnode,
QWidget * parent = 0 );
bool direct, QWidget * parent = 0 );

//! Destructor
~QgsGrassModuleInput();
Expand Down Expand Up @@ -664,6 +704,9 @@ class QgsGrassModuleInput: public QgsGrassModuleGroupBoxItem
//! Pointers to vector layers in combobox
std::vector<QgsMapLayer*> mMapLayers;

//! Vector of band numbers in combobox for rasters in direct mode
QList<int> mBands;

//! Attribute fields of layers in the combobox
std::vector< std::vector<QgsField> > mVectorFields;

Expand Down Expand Up @@ -693,7 +736,7 @@ class QgsGrassModuleGdalInput: public QgsGrassModuleGroupBoxItem
*/
QgsGrassModuleGdalInput( QgsGrassModule *module, int type, QString key,
QDomElement &qdesc, QDomElement &gdesc, QDomNode &gnode,
QWidget * parent = 0 );
bool direct, QWidget * parent = 0 );

//! Destructor
~QgsGrassModuleGdalInput();
Expand Down Expand Up @@ -757,7 +800,7 @@ class QgsGrassModuleField: public QgsGrassModuleGroupBoxItem
QgsGrassModuleStandardOptions *options,
QString key,
QDomElement &qdesc, QDomElement &gdesc, QDomNode &gnode,
QWidget * parent = 0 );
bool direct, QWidget * parent = 0 );

//! Destructor
~QgsGrassModuleField();
Expand Down Expand Up @@ -805,7 +848,7 @@ class QgsGrassModuleSelection: public QgsGrassModuleGroupBoxItem
QString key,
QDomElement &qdesc, QDomElement &gdesc,
QDomNode &gnode,
QWidget * parent = 0 );
bool direct, QWidget * parent = 0 );

//! Destructor
~QgsGrassModuleSelection();
Expand Down Expand Up @@ -855,7 +898,7 @@ class QgsGrassModuleFile: public QgsGrassModuleGroupBoxItem
QString key,
QDomElement &qdesc, QDomElement &gdesc,
QDomNode &gnode,
QWidget * parent = 0 );
bool direct, QWidget * parent = 0 );

//! Destructor
~QgsGrassModuleFile();
Expand Down
7 changes: 6 additions & 1 deletion src/plugins/grass/qgsgrassplugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,19 +221,21 @@ void QgsGrassPlugin::mapsetChanged()
{
if ( !QgsGrass::activeMode() )
{
mOpenToolsAction->setEnabled( false );
mOpenToolsAction->setEnabled( true );
mRegionAction->setEnabled( false );
mEditRegionAction->setEnabled( false );
mRegionBand->reset();
mCloseMapsetAction->setEnabled( false );
mNewVectorAction->setEnabled( false );

#if 0
if ( mTools )
{
mTools->hide();
delete mTools;
mTools = 0;
}
#endif
}
else
{
Expand All @@ -248,10 +250,12 @@ void QgsGrassPlugin::mapsetChanged()
mRegionAction->setChecked( on );
switchRegion( on );

#if 0
if ( mTools )
{
mTools->mapsetChanged();
}
#endif
QString gisdbase = QgsGrass::getDefaultGisdbase();
QString location = QgsGrass::getDefaultLocation();
try
Expand All @@ -268,6 +272,7 @@ void QgsGrassPlugin::mapsetChanged()
setTransform();
redrawRegion();
}
if ( mTools ) mTools->mapsetChanged();
}

void QgsGrassPlugin::saveMapset()
Expand Down
297 changes: 213 additions & 84 deletions src/plugins/grass/qgsgrasstools.cpp

Large diffs are not rendered by default.

26 changes: 17 additions & 9 deletions src/plugins/grass/qgsgrasstools.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,14 @@ class QgsGrassTools: public QDialog, private Ui::QgsGrassToolsBase

//! Recursively add sections and modules to the list view
// If parent is 0, the modules are added to mModulesListView root
void addModules( QTreeWidgetItem *parent, QDomElement &element );
void addModules( QTreeWidgetItem *parent, QDomElement &element, QTreeWidget *modulesTreeWidget, QStandardItemModel * modulesListModel, bool direct );

//! Returns application directory
QString appDir();

public slots:
//! Load configuration from file
bool loadConfig( QString filePath );
bool loadConfig( QString filePath, QTreeWidget *modulesTreeWidget, QStandardItemModel * modulesListModel, bool direct );

//! Close
void close( void );
Expand All @@ -73,6 +73,7 @@ class QgsGrassTools: public QDialog, private Ui::QgsGrassToolsBase

//! Module in list clicked
void moduleClicked( QTreeWidgetItem * item, int column );
void directModuleClicked( QTreeWidgetItem * item, int column );

//! Current mapset changed
void mapsetChanged();
Expand All @@ -85,10 +86,12 @@ class QgsGrassTools: public QDialog, private Ui::QgsGrassToolsBase

//! Update the regex used to filter the modules list (autoconnect to ui)
void on_mFilterInput_textChanged( QString theText );
void on_mDirectFilterInput_textChanged( QString theText );
//! Run a module when its entry is clicked in the list view
void listItemClicked( const QModelIndex &theIndex );
void directListItemClicked( const QModelIndex &theIndex );
//! Run a module given its module name e.g. r.in.gdal
void runModule( QString name );
void runModule( QString name, bool direct );
signals:
void regionChanged();

Expand All @@ -102,14 +105,19 @@ class QgsGrassTools: public QDialog, private Ui::QgsGrassToolsBase
//! Browser
QgsGrassBrowser *mBrowser;

//
// For experimental model & filtered model by Tim
//
QStandardItemModel * mModelTools;
// For model & filtered model by Tim
QStandardItemModel * mModulesListModel;
QSortFilterProxyModel * mModelProxy;
QListView * mListView2;
QDockWidget * mDockWidget;

// Direct modules model list
QStandardItemModel * mDirectModulesListModel;
QSortFilterProxyModel * mDirectModelProxy;

void removeEmptyItems( QTreeWidget *tree );
void removeEmptyItems( QTreeWidgetItem *item );

// Show (fill) / hide tabs according to direct/indirect mode
void showTabs();
};

#endif // QGSGRASSTOOLS_H
65 changes: 60 additions & 5 deletions src/plugins/grass/qgsgrasstoolsbase.ui
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>350</width>
<height>350</height>
<width>525</width>
<height>361</height>
</rect>
</property>
<property name="minimumSize">
Expand All @@ -23,9 +23,9 @@
<item row="0" column="0">
<widget class="QTabWidget" name="mTabWidget">
<property name="currentIndex">
<number>1</number>
<number>3</number>
</property>
<widget class="QWidget" name="modulesTree">
<widget class="QWidget" name="mModulesTreeTab">
<attribute name="title">
<string>Modules Tree</string>
</attribute>
Expand All @@ -50,7 +50,7 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="modulesList">
<widget class="QWidget" name="mModulesListTab">
<attribute name="title">
<string>Modules List</string>
</attribute>
Expand Down Expand Up @@ -80,6 +80,61 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="mDirectModulesTreeTab">
<attribute name="title">
<string>Direct Modules Tree</string>
</attribute>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QTreeWidget" name="mDirectModulesTree">
<property name="indentation">
<number>8</number>
</property>
<property name="rootIsDecorated">
<bool>false</bool>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<column>
<property name="text">
<string>1</string>
</property>
</column>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="mDirectModulesListTab">
<attribute name="title">
<string>Direct Modules List</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Filter</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="mDirectFilterInput"/>
</item>
<item row="1" column="0" colspan="2">
<widget class="QListView" name="mDirectListView">
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item row="1" column="0">
Expand Down
151 changes: 151 additions & 0 deletions src/providers/grass/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,153 @@ IF (APPLE)
SET_TARGET_PROPERTIES(qgisgrass PROPERTIES BUILD_WITH_INSTALL_RPATH TRUE)
ENDIF (APPLE)

#
# Fake GRASS gis library
#

# Generate functions mapping for funcions used in original version
# Create list of functions to be mapped
SET ( FUNCTIONS
"G_add_color_rule"
"G_adjust_Cell_head"
"G_align_window"
"G_allocate_cell_buf"
"G_allocate_raster_buf"
"G__calloc"
"G_col_to_easting"
"G_define_flag"
"G_define_module"
"G_define_option"
"G_define_standard_option"
"G_free"
"G_get_fp_range_min_max"
"G_get_range_min_max"
"G_get_window"
"G_get_set_window"
"G__init_null_patterns"
"G_incr_void_ptr"
"G_init_colors"
"G_init_fp_range"
"G_init_raster_cats"
"G_init_range"
"G_is_c_null_value"
"G_is_d_null_value"
"G__malloc"
"G_percent"
"G_program_name"
"G_projection"
"G_quant_add_rule"
"G_quant_free"
"G_quant_get_limits"
"G_quant_init"
"G__realloc"
"G_raster_size"
"G_row_to_northing"
"G_set_c_null_value"
"G_set_d_null_value"
"G_set_d_raster_cat"
"G_set_gisrc_mode"
"G_set_null_value"
"G_set_raster_cats_title"
"G_set_raster_value_d"
"G_set_window"
"G_setenv"
"G_strip"
"G_suppress_masking"
"G_trim_decimal"
"G_update_fp_range"
"G_update_range"
"G_window_cols"
"G_window_rows"
"G_zero"
)

# Read GRASS header file and create functions mapping
FILE(READ "${GRASS_INCLUDE_DIR}/grass/gisdefs.h" HEADER_FILE)

# Function definitions in gisdefs.h may spread over more lines -> remove comments
# and split by ';'
# Remove comments and directives (some macros are lost)
STRING(REGEX REPLACE "(/\\*([^*]|[\r\n]|(\\*+([^*/]|[\r\n])))*\\*+/)" "" HEADER_FILE "${HEADER_FILE}")
STRING(REGEX REPLACE "#[^\r\n]*" "" HEADER_FILE "${HEADER_FILE}")

SET ( FUNCTIONS_MAP "// Auto generated by cmake, do not edit\n" )
LIST ( APPEND FUNCTIONS_MAP "#include \"qgsgrassgislib.h\"\n" )
LIST ( APPEND FUNCTIONS_MAP "#include \"qgslogger.h\"\n" )
LIST ( APPEND FUNCTIONS_MAP "#include \"qgis.h\"\n" )
FOREACH( ROW ${HEADER_FILE} )
STRING(REGEX REPLACE "\n" " " ROW "${ROW}")
STRING(REGEX REPLACE "__attribute__.*" "" ROW "${ROW}")
#MESSAGE (STATUS, "ROW: ${ROW}")
# Parse function declaration
STRING( REGEX REPLACE ".*(G_[^\\(]*)\\(.*" "\\1" FUNCTION_NAME "${ROW}" )
FOREACH( FN ${FUNCTIONS} )
IF ( "${FN}" STREQUAL "${FUNCTION_NAME}" )
LIST ( APPEND FUNCTIONS_MAP "// ${ROW}\n" )
# \\*? and \\** patterns do not work, why?
STRING( REGEX REPLACE "(.*)G_.*" "\\1" FUNCTION_TYPE "${ROW}" )
STRING( REGEX REPLACE "\\*" "" FUNCTION_TYPE "${FUNCTION_TYPE}" )
STRING( REGEX REPLACE ".*(\\*+) *G_.*" "\\1" POINTER "${ROW}" )
IF ( NOT "${POINTER}" STREQUAL "*" )
SET ( POINTER "" )
ENDIF ( NOT "${POINTER}" STREQUAL "*" )
STRING( REGEX REPLACE ".*G_[^\\(]*\\((.*)\\).*" "\\1" PARAM_TYPES "${ROW}" )
SET ( PARAM_NAMES "" )
SET ( PARAMS "" )
IF ( NOT "${PARAM_TYPES}" STREQUAL "void" )
STRING ( REGEX MATCHALL "[^,]+" PARAM_TYPE_LIST ${PARAM_TYPES} )
SET ( I 0 )
FOREACH( PARAM_TYPE ${PARAM_TYPE_LIST} )
LIST ( APPEND PARAM_NAMES "p${I}" )
LIST ( APPEND PARAMS "${PARAM_TYPE} p${I}" )
MATH(EXPR I "${I} + 1")
ENDFOREACH ( PARAM_TYPE )
ENDIF ( NOT "${PARAM_TYPES}" STREQUAL "void" )

STRING( REPLACE ";" ", " PARAM_NAMES "${PARAM_NAMES}" )
STRING( REPLACE ";" ", " PARAMS "${PARAMS}" )

# Declare function type
LIST ( APPEND FUNCTIONS_MAP "typedef ${FUNCTION_TYPE} ${POINTER} ${FUNCTION_NAME}_type(${PARAM_TYPES})\;\n\n" )
LIST ( APPEND FUNCTIONS_MAP "${FUNCTION_TYPE} GRASS_LIB_EXPORT ${POINTER} ${FUNCTION_NAME} ( ${PARAMS} ) {\n" )
#LIST ( APPEND FUNCTIONS_MAP " QgsDebugMsg( \"Entered\" )\;\n" )

LIST ( APPEND FUNCTIONS_MAP " ${FUNCTION_NAME}_type* fn = (${FUNCTION_NAME}_type*) cast_to_fptr (QgsGrassGisLib::instance()->resolve( \"${FUNCTION_NAME}\" ))\;\n" )
LIST ( APPEND FUNCTIONS_MAP " return fn( ${PARAM_NAMES} )\;\n")
LIST ( APPEND FUNCTIONS_MAP "}\n\n" )
ENDIF ( "${FN}" STREQUAL "${FUNCTION_NAME}" )
ENDFOREACH ( FN )
ENDFOREACH( ROW )

This comment has been minimized.

Copy link
@dakcarto

dakcarto Feb 10, 2013

Member

Hi,

Recently, I've noticed a considerable slow down in CMake configuring the QGIS build if WITH_GRASS is TRUE (about 3x longer config time than without). I've traced it to this file and think the cause may be this nested foreach loop. Is there a way to optimize this, maybe have the resultant file 'qgsgrassgislibfunctions.cpp' created off of a git push hook instead of always during configure, or have the file built by an external (possibly faster) script?

Not a big deal for me, just curious.


FILE(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qgsgrassgislibfunctions.cpp" ${FUNCTIONS_MAP})


# Build fake library
SET (FAKE_LIB_GRASS_GIS "grass_gis.${GRASS_VERSION}")
ADD_LIBRARY( ${FAKE_LIB_GRASS_GIS} MODULE qgsgrassgislib.cpp qgsgrassgislibfunctions.cpp )

SET_TARGET_PROPERTIES(${FAKE_LIB_GRASS_GIS} PROPERTIES
CLEAN_DIRECT_OUTPUT 1
FRAMEWORK 1
FRAMEWORK_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}"
MACOSX_FRAMEWORK_INFO_PLIST "${CMAKE_SOURCE_DIR}/mac/framework.info.plist.in"
MACOSX_FRAMEWORK_SHORT_VERSION_STRING ${COMPLETE_VERSION}
MACOSX_FRAMEWORK_IDENTIFIER org.qgis.qgisgrassgislib
COMPILE_FLAGS "\"-DGRASS_LIB_EXPORT=${DLLEXPORT}\" \"-DGRASS_EXPORT=${DLLIMPORT}\" -DGRASS_LIBRARY_GIS=\\\"${GRASS_LIBRARY_gis}\\\" \"-I${CMAKE_CURRENT_SOURCE_DIR}\" ")

SET_TARGET_PROPERTIES(${FAKE_LIB_GRASS_GIS} PROPERTIES
VERSION ${COMPLETE_VERSION}
SOVERSION ${COMPLETE_VERSION}
)

TARGET_LINK_LIBRARIES(${FAKE_LIB_GRASS_GIS}
qgis_core
)

IF (APPLE)
SET_TARGET_PROPERTIES(${FAKE_LIB_GRASS_GIS} PROPERTIES BUILD_WITH_INSTALL_RPATH TRUE)
ENDIF (APPLE)

#
# GRASS vector provider
#
Expand Down Expand Up @@ -103,6 +250,10 @@ INSTALL(TARGETS qgisgrass
RUNTIME DESTINATION ${QGIS_BIN_DIR}
LIBRARY DESTINATION ${QGIS_LIB_DIR}
FRAMEWORK DESTINATION ${QGIS_FW_SUBDIR})

INSTALL(TARGETS ${FAKE_LIB_GRASS_GIS}
RUNTIME DESTINATION ${QGIS_PLUGIN_DIR}
LIBRARY DESTINATION ${QGIS_PLUGIN_DIR})

INSTALL(TARGETS grassprovider
RUNTIME DESTINATION ${QGIS_PLUGIN_DIR}
Expand Down
34 changes: 34 additions & 0 deletions src/providers/grass/qgsgrass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1071,6 +1071,40 @@ void GRASS_LIB_EXPORT QgsGrass::extendRegion( struct Cell_head *source,
target->bottom = source->bottom;
}

void GRASS_LIB_EXPORT QgsGrass::initRegion( struct Cell_head *window )
{
window->format = 0;
window->rows = 0;
window->rows3 = 0;
window->cols = 0;
window->cols3 = 0;
window->depths = 1;
window->proj = -1;
window->zone = -1;
window->compressed = -1;
window->ew_res = 0.0;
window->ew_res3 = 1.0;
window->ns_res = 0.0;
window->ns_res3 = 1.0;
window->tb_res = 1.0;
window->top = 1.0;
window->bottom = 0.0;
window->west = 0;
window->south = 0;
window->east = 1;
window->north = 1;
window->rows = 1;
window->cols = 1;
}

void GRASS_LIB_EXPORT QgsGrass::setRegion( struct Cell_head *window, QgsRectangle rect )
{
window->west = rect.xMinimum();
window->south = rect.yMinimum();
window->east = rect.xMaximum();
window->north = rect.yMaximum();
}

bool GRASS_LIB_EXPORT QgsGrass::mapRegion( int type, QString gisbase,
QString location, QString mapset, QString map,
struct Cell_head *window )
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 @@ -148,6 +148,11 @@ class QgsGrass
QString mapsetName, QString element );
static GRASS_LIB_EXPORT QStringList elements( QString mapsetPath, QString element );

//! Initialize GRASS region
static GRASS_LIB_EXPORT void initRegion( struct Cell_head *window );
//! Set region extent
static GRASS_LIB_EXPORT void setRegion( struct Cell_head *window, QgsRectangle rect );

// ! Get map region
static GRASS_LIB_EXPORT bool mapRegion( int type, QString gisbase,
QString location, QString mapset, QString map,
Expand Down
1,038 changes: 1,038 additions & 0 deletions src/providers/grass/qgsgrassgislib.cpp

Large diffs are not rendered by default.

140 changes: 140 additions & 0 deletions src/providers/grass/qgsgrassgislib.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
/***************************************************************************
qgsgrassgislib.h - Fake GRASS gis lib
-------------------
begin : Nov 2012
copyright : (C) 2012 by Radim Blazek
email : radim dot blazek at gmail dot com
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSGRASSGISLIB_H
#define QGSGRASSGISLIB_H

// GRASS header files
extern "C"
{
#include <grass/gis.h>
#include <grass/form.h>
}

#include <stdexcept>
#include <qgscoordinatereferencesystem.h>
#include <qgsdistancearea.h>
#include <qgsexception.h>
#include <qgsproviderregistry.h>
#include <qgsrectangle.h>
#include <qgsrasterdataprovider.h>
#include <qgsrasterprojector.h>

#include <QLibrary>
#include <QProcess>
#include <QString>
#include <QMap>
#include <QHash>
#include <QTemporaryFile>
class QgsCoordinateReferenceSystem;
class QgsRectangle;

class GRASS_LIB_EXPORT QgsGrassGisLib
{
public:
// Region term is used in modules (g.region), internaly it is hold in structure
// Cell_head, but variables keeping that struture are usually called window
/*
class Region
{
QgsRectangle extent;
double ewRes; // east-west resolution
double nsRes; // north south resolution
};
*/

class Raster
{
public:
int fd; // fake file descriptor
QString name; // name passed from grass module, uri
QgsRasterDataProvider *provider;
QgsRasterProjector *projector;
// Input points to provider or projector
QgsRasterInterface *input;
int band;
int row; // next row to be written
Raster(): provider( 0 ), projector( 0 ), input( 0 ), band( 1 ), row( 0 ) {}

};

static GRASS_LIB_EXPORT QgsGrassGisLib* instance();

QgsGrassGisLib();

int G__gisinit( const char * version, const char * programName );
char *G_find_cell2( const char * name, const char * mapset );
int G_open_cell_old( const char *name, const char *mapset );
int G_open_raster_new( const char *name, RASTER_MAP_TYPE wr_type );
int G_close_cell( int fd );
RASTER_MAP_TYPE G_raster_map_type( const char *name, const char *mapset );
RASTER_MAP_TYPE G_get_raster_map_type( int fd );
//int G_raster_map_is_fp( const char *name, const char *mapset );
int G_read_fp_range( const char *name, const char *mapset, struct FPRange *drange );

int readRasterRow( int fd, void * buf, int row, RASTER_MAP_TYPE data_type, bool noDataAsZero = false );
int G_put_raster_row( int fd, const void *buf, RASTER_MAP_TYPE data_type );
int G_get_cellhd( const char *name, const char *mapset, struct Cell_head *cellhd );

double G_database_units_to_meters_factor( void );
double G_distance( double e1, double n1, double e2, double n2 );

/** Get QGIS raster type for GRASS raster type */
QgsRasterBlock::DataType qgisRasterType( RASTER_MAP_TYPE grassType );

/** Get GRASS raster type for QGIS raster type */
RASTER_MAP_TYPE grassRasterType( QgsRasterBlock::DataType qgisType );

/** Grass does not seem to have any function to init Cell_head,
* initialisation is done in G__read_Cell_head_array */
void initCellHead( struct Cell_head *cellhd );

/** Get raster from map of opened rasters, open it if it is not yet open */
Raster raster( QString name );

void * resolve( const char * symbol );

// Print error function set to be called by GRASS lib
static GRASS_LIB_EXPORT int errorRoutine( const char *msg, int fatal );

// Error called by fake lib
void fatal( QString msg );
void warning( QString msg );

private:
/** pointer to canonical Singleton object */
static QgsGrassGisLib* _instance;

/** Original GRASS library handle */
QLibrary mLibrary;

/** Raster maps, key is fake file descriptor */
QMap<int, Raster> mRasters;

/** Region to be used for data processing and output */
struct Cell_head mWindow;

/** Current region extent */
QgsRectangle mExtent;
/** Current region rows */
int mRows;
/** Current region columns */
int mColumns;
/** Current coordinate reference system */
QgsCoordinateReferenceSystem mCrs;
QgsDistanceArea mDistanceArea;
};

#endif // QGSGRASSGISLIB_H