[QGIS Commit] r12880 - in trunk/qgis/src: plugins/grass
providers/grass
svn_qgis at osgeo.org
svn_qgis at osgeo.org
Thu Feb 4 16:25:36 EST 2010
Author: rblazek
Date: 2010-02-04 16:25:35 -0500 (Thu, 04 Feb 2010)
New Revision: 12880
Added:
trunk/qgis/src/providers/grass/qgis.d.rast.c
trunk/qgis/src/providers/grass/qgis.g.info.c
trunk/qgis/src/providers/grass/qgsgrassrasterprovider.cpp
trunk/qgis/src/providers/grass/qgsgrassrasterprovider.h
Modified:
trunk/qgis/src/plugins/grass/qgsgrassplugin.cpp
trunk/qgis/src/providers/grass/CMakeLists.txt
trunk/qgis/src/providers/grass/qgsgrass.cpp
trunk/qgis/src/providers/grass/qgsgrass.h
Log:
GRASS raster data provider
Modified: trunk/qgis/src/plugins/grass/qgsgrassplugin.cpp
===================================================================
--- trunk/qgis/src/plugins/grass/qgsgrassplugin.cpp 2010-02-04 21:23:12 UTC (rev 12879)
+++ trunk/qgis/src/plugins/grass/qgsgrassplugin.cpp 2010-02-04 21:25:35 UTC (rev 12880)
@@ -398,7 +398,9 @@
QString name = uri.right( uri.length() - pos - 1 );
name.replace( '/', ' ' );
- qGisInterface->addRasterLayer( uri, sel->map );
+ //qGisInterface->addRasterLayer( uri, sel->map );
+ qGisInterface->addRasterLayer( uri, sel->map, "grassraster", QStringList(), QStringList(),
+ QString(), QString() );
}
}
Modified: trunk/qgis/src/providers/grass/CMakeLists.txt
===================================================================
--- trunk/qgis/src/providers/grass/CMakeLists.txt 2010-02-04 21:23:12 UTC (rev 12879)
+++ trunk/qgis/src/providers/grass/CMakeLists.txt 2010-02-04 21:25:35 UTC (rev 12880)
@@ -5,8 +5,14 @@
SET(GRASS_PROVIDER_SRCS provider.cpp)
+SET(GRASS_RASTER_PROVIDER_SRCS qgsgrassrasterprovider.cpp)
+
SET(GRASS_LIB_SRCS qgsgrassprovider.cpp qgsgrass.cpp)
+SET(QGIS_D_RAST_SRCS qgis.d.rast.c)
+
+SET(QGIS_G_INFO_SRCS qgis.g.info.c)
+
########################################################
# Build
@@ -54,6 +60,32 @@
qgisgrass
)
+ADD_LIBRARY (grassrasterprovider MODULE ${GRASS_RASTER_PROVIDER_SRCS})
+
+IF (WIN32)
+ SET_TARGET_PROPERTIES(grassrasterprovider PROPERTIES COMPILE_FLAGS "\"-DGRASS_EXPORT=__declspec(dllimport)\"" )
+ELSE (WIN32)
+ SET_TARGET_PROPERTIES(grassrasterprovider PROPERTIES COMPILE_FLAGS "-DGRASS_EXPORT=" )
+ENDIF (WIN32)
+
+TARGET_LINK_LIBRARIES (grassrasterprovider
+ qgisgrass
+ qgis_core
+)
+
+ADD_EXECUTABLE(qgis.d.rast ${QGIS_D_RAST_SRCS})
+
+TARGET_LINK_LIBRARIES (qgis.d.rast
+ ${GRASS_LIBRARY_gis}
+)
+
+ADD_EXECUTABLE(qgis.g.info ${QGIS_G_INFO_SRCS})
+
+TARGET_LINK_LIBRARIES (qgis.g.info
+ ${GRASS_LIBRARY_gis}
+ ${GRASS_LIBRARY_gproj}
+)
+
########################################################
# Install
@@ -64,3 +96,12 @@
INSTALL(TARGETS grassprovider
RUNTIME DESTINATION ${QGIS_PLUGIN_DIR}
LIBRARY DESTINATION ${QGIS_PLUGIN_DIR})
+
+INSTALL(TARGETS grassrasterprovider
+ RUNTIME DESTINATION ${QGIS_PLUGIN_DIR}
+ LIBRARY DESTINATION ${QGIS_PLUGIN_DIR})
+
+INSTALL(TARGETS qgis.d.rast qgis.g.info
+ RUNTIME DESTINATION ${QGIS_DATA_DIR}/grass/modules
+ PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
+)
Added: trunk/qgis/src/providers/grass/qgis.d.rast.c
===================================================================
--- trunk/qgis/src/providers/grass/qgis.d.rast.c (rev 0)
+++ trunk/qgis/src/providers/grass/qgis.d.rast.c 2010-02-04 21:25:35 UTC (rev 12880)
@@ -0,0 +1,171 @@
+/****************************************************************************
+ *
+ * MODULE: qgis.d.rast
+ * AUTHOR(S): Radim Blazek <radim.blazek gmail.com>
+ * using d.rast from GRASS
+ * PURPOSE: display raster maps in active graphics display
+ * COPYRIGHT: (C) 2010 by Radim Blazek
+ *
+ * This program is free software under the GNU General Public
+ * License (>=v2).
+ *
+ *****************************************************************************/
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <grass/gis.h>
+#include <grass/raster.h>
+#include <grass/display.h>
+#include <grass/glocale.h>
+
+int display(char *name, char *mapset, RASTER_MAP_TYPE data_type);
+
+int main(int argc, char **argv)
+{
+ char *mapset;
+ char *name;
+ int fp;
+ int cols, rows;
+ struct GModule *module;
+ struct Option *map;
+ struct Option *win;
+ struct Flag *flag_o;
+ struct Flag *flag_i;
+ struct Flag *flag_x;
+ struct Cell_head window;
+
+ /* Initialize the GIS calls */
+ G_gisinit(argv[0]);
+
+ module = G_define_module();
+ module->keywords = _("display, raster");
+ module->description = _("Output raster map layers in a format suitable for display in QGIS");
+
+ map = G_define_standard_option(G_OPT_R_MAP);
+ map->description = _("Raster map to be displayed");
+
+ win = G_define_option();
+ win->key = "window";
+ win->type = TYPE_DOUBLE;
+ win->multiple = YES;
+ win->description = "xmin,ymin,xmax,ymax,ncols,nrows";
+
+ if (G_parser(argc, argv))
+ exit(EXIT_FAILURE);
+
+ name = map->answer;
+
+ G_get_window(&window);
+ window.west = atof(win->answers[0]);
+ window.south = atof(win->answers[1]);
+ window.east = atof(win->answers[2]);
+ window.north = atof(win->answers[3]);
+ window.cols = atoi(win->answers[4]);
+ window.rows = atoi(win->answers[5]);
+ G_adjust_Cell_head(&window,1,1);
+ G_set_window(&window);
+
+ /* Make sure map is available */
+ mapset = G_find_cell2(name, "");
+ if (mapset == NULL)
+ G_fatal_error(_("Raster map <%s> not found"), name);
+
+
+ fp = G_raster_map_is_fp(name, mapset);
+
+ /* use DCELL even if the map is FCELL */
+ if (fp)
+ display(name, mapset, DCELL_TYPE );
+ else
+ display(name, mapset, CELL_TYPE );
+
+ exit(EXIT_SUCCESS);
+}
+
+static int cell_draw(char *, char *, struct Colors *, RASTER_MAP_TYPE);
+
+int display(char *name,
+ char *mapset,
+ RASTER_MAP_TYPE data_type)
+{
+ struct Colors colors;
+ int r, g, b;
+
+ if (G_read_colors(name, mapset, &colors) == -1)
+ G_fatal_error(_("Color file for <%s> not available"), name);
+
+ //G_set_null_value_color(r, g, b, &colors);
+
+ /* Go draw the raster map */
+ cell_draw(name, mapset, &colors, data_type);
+
+ /* release the colors now */
+ G_free_colors(&colors);
+
+ return 0;
+}
+
+static int cell_draw(char *name,
+ char *mapset,
+ struct Colors *colors,
+ RASTER_MAP_TYPE data_type)
+{
+ int cellfile;
+ void *xarray;
+ int row;
+ int t, b, l, r;
+ int ncols, nrows;
+ static unsigned char *red, *grn, *blu, *set;
+ int i;
+ void *ptr;
+ int big_endian;
+ long one= 1;
+
+ big_endian = !(*((char *)(&one)));
+
+ ncols = G_window_cols();
+ nrows = G_window_rows();
+
+ /* Make sure map is available */
+ if ((cellfile = G_open_cell_old(name, mapset)) == -1)
+ G_fatal_error(_("Unable to open raster map <%s>"), name);
+
+ /* Allocate space for cell buffer */
+ xarray = G_allocate_raster_buf(data_type);
+ red = G_malloc(ncols);
+ grn = G_malloc(ncols);
+ blu = G_malloc(ncols);
+ set = G_malloc(ncols);
+
+ /* loop for array rows */
+ for ( row = 0; row < nrows; row++ ) {
+ G_get_raster_row(cellfile, xarray, row, data_type);
+ ptr = xarray;
+
+ G_lookup_raster_colors(xarray, red, grn, blu, set, ncols, colors,
+ data_type);
+
+ for (i = 0; i < ncols; i++) {
+ unsigned char alpha = 255;
+ if ( G_is_null_value(ptr, data_type) ) {
+ alpha = 0;
+ }
+ ptr = G_incr_void_ptr(ptr, G_raster_size(data_type));
+
+
+ // We need data suitable for QImage 32-bpp
+ // the data are stored in QImage as QRgb which is unsigned int.
+ // Because it depends on byte order of the platform we have to
+ // consider byte order (well, middle endian ignored)
+ if ( big_endian ) {
+ // I have never tested this
+ fprintf(stdout, "%c%c%c%c", alpha, red[i],grn[i],blu[i]);
+ } else {
+ fprintf(stdout, "%c%c%c%c", blu[i],grn[i],red[i],alpha);
+ }
+ }
+ }
+
+ G_close_cell(cellfile);
+ return (0);
+}
Added: trunk/qgis/src/providers/grass/qgis.g.info.c
===================================================================
--- trunk/qgis/src/providers/grass/qgis.g.info.c (rev 0)
+++ trunk/qgis/src/providers/grass/qgis.g.info.c 2010-02-04 21:25:35 UTC (rev 12880)
@@ -0,0 +1,135 @@
+/****************************************************************************
+ *
+ * MODULE: qgis.g.info
+ * AUTHOR(S): Radim Blazek <radim.blazek gmail.com>
+ * using various GRASS modules
+ * PURPOSE: get informations about locations,mapsets,maps
+ * COPYRIGHT: (C) 2010 by Radim Blazek
+ *
+ * This program is free software under the GNU General Public
+ * License (>=v2).
+ *
+ *****************************************************************************/
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <grass/gis.h>
+#include <grass/raster.h>
+#include <grass/display.h>
+#include <grass/glocale.h>
+#include <grass/gprojects.h>
+
+int main(int argc, char **argv)
+{
+ char *mapset;
+ char *name;
+ struct GModule *module;
+ struct Option *info_opt, *rast_opt, *vect_opt, *coor_opt;
+ struct Cell_head window;
+
+ /* Initialize the GIS calls */
+ G_gisinit(argv[0]);
+
+ module = G_define_module();
+ module->description = _("Get info about locations,mapsets,maps");
+
+ info_opt = G_define_option();
+ info_opt->key = "info";
+ info_opt->type = TYPE_STRING;
+ info_opt->description = "info key";
+ info_opt->options = "proj,window,query";
+
+ rast_opt = G_define_standard_option(G_OPT_R_INPUT);
+ rast_opt->key = "rast";
+ rast_opt->required = NO;
+
+ vect_opt = G_define_standard_option(G_OPT_V_INPUT);
+ vect_opt->key = "vect";
+ vect_opt->required = NO;
+
+ coor_opt = G_define_option();
+ coor_opt->key = "coor";
+ coor_opt->type = TYPE_DOUBLE;
+ coor_opt->multiple = YES;
+
+ if (G_parser(argc, argv))
+ exit(EXIT_FAILURE);
+
+
+ if ( strcmp("proj",info_opt->answer) == 0 )
+ {
+ G_get_window(&window);
+ /* code from g.proj */
+ if (window.proj != PROJECTION_XY) {
+ struct Key_Value *projinfo, *projunits;
+ char *wkt;
+ projinfo = G_get_projinfo();
+ projunits = G_get_projunits();
+ wkt = GPJ_grass_to_wkt( projinfo, projunits, 0, 0 );
+ fprintf (stdout, "%s", wkt);
+ }
+ }
+ else if ( strcmp("window",info_opt->answer) == 0 )
+ {
+ if ( rast_opt->answer )
+ {
+ G_get_cellhd( rast_opt->answer, "", &window);
+ fprintf (stdout, "%f,%f,%f,%f", window.west, window.south,window.east,window.north );
+ }
+ else if ( vect_opt->answer )
+ {
+ G_fatal_error ("Not yet supported");
+ }
+ }
+ else if ( strcmp("query",info_opt->answer) == 0 )
+ {
+ double x, y;
+ int row, col;
+ 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;
+ G_get_cellhd( rast_opt->answer, "", &window);
+ G_set_window(&window);
+ fd = G_open_cell_old( rast_opt->answer, "");
+ col = G_easting_to_col( x, &window);
+ row = G_northing_to_row( y, &window);
+ if (col == window.cols) col--;
+ if (row == window.rows) row--;
+
+ rast_type = G_get_raster_map_type(fd);
+ 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);
+ }
+ fprintf (stdout, "value:%d\n", 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);
+ }
+ fprintf (stdout, "value:%f\n", dcell[col] );
+ }
+ }
+ else if ( vect_opt->answer )
+ {
+ G_fatal_error ("Not yet supported");
+ }
+ }
+
+ exit(EXIT_SUCCESS);
+}
+
Modified: trunk/qgis/src/providers/grass/qgsgrass.cpp
===================================================================
--- trunk/qgis/src/providers/grass/qgsgrass.cpp 2010-02-04 21:23:12 UTC (rev 12879)
+++ trunk/qgis/src/providers/grass/qgsgrass.cpp 2010-02-04 21:25:35 UTC (rev 12880)
@@ -19,12 +19,15 @@
#include "qgslogger.h"
#include "qgsapplication.h"
+#include "qgscoordinatereferencesystem.h"
+#include "qgsrectangle.h"
#include <QFileDialog>
#include <QMessageBox>
#include <QProcess>
#include <QSettings>
#include <QTextStream>
+#include <QTemporaryFile>
#include <QTextCodec>
@@ -1029,6 +1032,157 @@
return true;
}
+QByteArray GRASS_EXPORT QgsGrass::runModule( QString gisdbase, QString location,
+ QString module, QStringList arguments )
+{
+ QgsDebugMsg( QString( "gisdbase = %1 location = %2" ).arg( gisdbase ).arg( location ) );
+
+#ifdef WIN32
+ module += ".exe";
+#endif
+
+ // We have to set GISRC file, uff
+ QTemporaryFile gisrcFile;
+ if ( !gisrcFile.open() )
+ {
+ // TODO Exception
+ return QByteArray();
+ }
+
+ QTextStream out(&gisrcFile);
+ out << "GISDBASE: " << gisdbase << "\n";
+ out << "LOCATION_NAME: " << location << "\n";
+ out << "MAPSET: PERMANENT\n";
+ out.flush ();
+ QgsDebugMsg( gisrcFile.fileName() );
+
+ QStringList environment = QProcess::systemEnvironment();
+ environment.append("GISRC=" + gisrcFile.fileName() );
+
+ QProcess process;
+ process.setEnvironment( environment );
+
+ QgsDebugMsg( module + " " + arguments.join (" ") );
+ process.start( module, arguments );
+ if ( !process.waitForFinished()
+ || ( process.exitCode() != 0 && process.exitCode() != 255 ) )
+ {
+ 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<br>%3<br>%4" )
+ .arg( module ).arg( arguments.join( " " ) )
+ .arg( process.readAllStandardOutput().constData() )
+ .arg( process.readAllStandardError().constData() ) );
+ }
+ QByteArray data = process.readAllStandardOutput();
+
+ return data;
+}
+
+QString GRASS_EXPORT QgsGrass::getInfo( QString info, QString gisdbase, QString location,
+ QString mapset, QString map, MapType type, double x, double y)
+{
+ QgsDebugMsg( QString( "gisdbase = %1 location = %2" ).arg( gisdbase ).arg( location ) );
+
+ QStringList arguments;
+
+ QString cmd = QgsApplication::pkgDataPath() + "/grass/modules/qgis.g.info";
+
+ arguments.append( "info=" + info );
+ if ( !map.isNull() )
+ {
+ QString opt;
+ switch (type)
+ {
+ case Raster:
+ opt = "rast";
+ break;
+ case Vector:
+ opt = "vect";
+ break;
+ }
+ arguments.append( opt + "=" + map + "@" + mapset );
+ }
+ if ( info == "query" )
+ {
+ arguments.append( QString("coor=%1,%2").arg(x).arg(y) );
+ }
+
+ QByteArray data = QgsGrass::runModule ( gisdbase, location, cmd, arguments );
+ QgsDebugMsg( data );
+ return QString( data );
+}
+
+QgsCoordinateReferenceSystem GRASS_EXPORT QgsGrass::crs( QString gisdbase, QString location )
+{
+ QgsDebugMsg( QString( "gisdbase = %1 location = %2" ).arg( gisdbase ).arg( location ) );
+ QgsCoordinateReferenceSystem crs = QgsCoordinateReferenceSystem();
+ try
+ {
+ QString wkt = QgsGrass::getInfo ( "proj", gisdbase, location );
+ crs.createFromWkt( wkt );
+
+ }
+ catch ( QgsException &e )
+ {
+ QMessageBox::warning( 0, QObject::tr( "Warning" ),
+ QObject::tr( "Cannot get projection " ) + "\n"+ e.what() );
+ }
+
+ return crs;
+}
+
+QgsRectangle GRASS_EXPORT QgsGrass::extent( QString gisdbase, QString location, QString mapset, QString map, MapType type )
+{
+ QgsDebugMsg( QString( "gisdbase = %1 location = %2" ).arg( gisdbase ).arg( location ) );
+
+ try
+ {
+ QString str = QgsGrass::getInfo ( "window", gisdbase, location, mapset, map, type );
+ QStringList list = str.split(",");
+ if ( list.size() != 4 ) {
+ throw QgsGrass::Exception( "Cannot parse GRASS map extent: " + str );
+ }
+ return QgsRectangle ( list[0].toDouble(), list[1].toDouble(), list[2].toDouble(), list[3].toDouble() ) ;
+ }
+ catch ( QgsException &e )
+ {
+ QMessageBox::warning( 0, QObject::tr( "Warning" ),
+ QObject::tr( "Cannot get raster extent" ) + "\n"+ e.what() );
+ }
+ return QgsRectangle( 0, 0, 0, 0 );
+}
+
+QMap<QString, QString> GRASS_EXPORT QgsGrass::query ( QString gisdbase, QString location, QString mapset, QString map, MapType type, double x, double y )
+{
+ QgsDebugMsg( QString( "gisdbase = %1 location = %2" ).arg( gisdbase ).arg( location ) );
+
+ QMap<QString, QString> result;
+ // TODO: multiple values (more rows)
+ try
+ {
+ QString str = QgsGrass::getInfo ( "query", gisdbase, location, mapset, map, type, x, y );
+ QStringList list = str.trimmed().split(":");
+ if ( list.size() == 2 ) {
+ result[list[0]] = list[1];
+ }
+ }
+ catch ( QgsException &e )
+ {
+ QMessageBox::warning( 0, QObject::tr( "Warning" ),
+ QObject::tr( "Cannot query raster " ) + "\n"+ e.what() );
+ }
+ return result;
+}
+
// GRASS version constants have been changed on 26.4.2007
// http://freegis.org/cgi-bin/viewcvs.cgi/grass6/include/version.h.in.diff?r1=1.4&r2=1.5
// The following lines workaround this change
Modified: trunk/qgis/src/providers/grass/qgsgrass.h
===================================================================
--- trunk/qgis/src/providers/grass/qgsgrass.h 2010-02-04 21:23:12 UTC (rev 12879)
+++ trunk/qgis/src/providers/grass/qgsgrass.h 2010-02-04 21:25:35 UTC (rev 12880)
@@ -25,6 +25,9 @@
#include "qgsexception.h"
#include <QString>
+#include <QMap>
+class QgsCoordinateReferenceSystem;
+class QgsRectangle;
/*!
Methods for C library initialization and error handling.
@@ -74,7 +77,7 @@
};
//! Map type
- enum MapType { Raster, Vector, Region };
+ enum MapType { None, Raster, Vector, Region };
//! Reset error code (to OK). Call this before a piece of code where an error is expected
static GRASS_EXPORT void resetError( void ); // reset error status
@@ -157,6 +160,24 @@
// ! Get the lock file
static GRASS_EXPORT QString lockFilePath();
+ // ! Run a GRASS module in any gisdbase/location
+ static GRASS_EXPORT QByteArray runModule( QString gisdbase, QString location, QString module, QStringList arguments );
+
+ // ! Get info string from qgis.g.info module
+ static GRASS_EXPORT QString getInfo( QString info, QString gisdbase,
+ QString location, QString mapset=0, QString map=0, MapType type = None, double x=0, double y=0 );
+
+ // ! Get location projection
+ static GRASS_EXPORT QgsCoordinateReferenceSystem crs( QString gisdbase, QString location);
+
+ // ! Get map extent
+ static GRASS_EXPORT QgsRectangle extent( QString gisdbase, QString location,
+ QString mapset, QString map, MapType type = None );
+
+ // ! Get map value / feautre info
+ static GRASS_EXPORT QMap<QString, QString> query( QString gisdbase, QString location,
+ QString mapset, QString map, MapType type, double x, double y);
+
//! Library version
static GRASS_EXPORT int versionMajor();
static GRASS_EXPORT int versionMinor();
Added: trunk/qgis/src/providers/grass/qgsgrassrasterprovider.cpp
===================================================================
--- trunk/qgis/src/providers/grass/qgsgrassrasterprovider.cpp (rev 0)
+++ trunk/qgis/src/providers/grass/qgsgrassrasterprovider.cpp 2010-02-04 21:25:35 UTC (rev 12880)
@@ -0,0 +1,215 @@
+/***************************************************************************
+ qgsgrassrasterprovider.cpp - QGIS Data provider for
+ GRASS rasters
+ -------------------
+ begin : 16 Jan, 2010
+ copyright : (C) 2010 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. *
+ * *
+ ***************************************************************************/
+
+/* $Id: qgsgrassrasterprovider.cpp 11522 2009-08-28 14:49:22Z jef $ */
+
+#include "qgslogger.h"
+#include "qgsgrass.h"
+#include "qgsgrassrasterprovider.h"
+
+#include <math.h>
+
+#include "qgsapplication.h"
+#include "qgscoordinatetransform.h"
+#include "qgsrectangle.h"
+#include "qgscoordinatereferencesystem.h"
+
+#include <QImage>
+#include <QSettings>
+#include <QColor>
+#include <QProcess>
+#include <QMessageBox>
+#include <QDir>
+#include <QFileInfo>
+#include <QFile>
+
+static QString PROVIDER_KEY = "grassraster";
+static QString PROVIDER_DESCRIPTION = "GRASS raster provider";
+
+QgsGrassRasterProvider::QgsGrassRasterProvider( QString const & uri )
+ : QgsRasterDataProvider( uri ), mValid(true)
+{
+ QgsDebugMsg( "QgsGrassRasterProvider: constructing with uri '" + uri + "'." );
+
+ // Parse URI, it is the same like using GDAL, i.e. path to raster cellhd, i.e.
+ // /path/to/gisdbase/location/mapset/cellhd/map
+ QFileInfo fileInfo ( uri );
+ mValid = fileInfo.exists(); // then we keep it valid forever
+ mMapName = fileInfo.fileName();
+ QDir dir = fileInfo.dir();
+ QString element = dir.dirName();
+ if ( element != "cellhd" )
+ {
+ QMessageBox::warning( 0, QObject::tr( "Warning" ),
+ QObject::tr( "Groups not yet supported" ) + " (GRASS " + uri + ")" );
+
+ mValid = false;
+ return;
+ }
+ dir.cdUp(); // skip cellhd
+ mMapset = dir.dirName();
+ dir.cdUp();
+ mLocation = dir.dirName();
+ dir.cdUp();
+ mGisdbase = dir.path();
+
+ QgsDebugMsg( QString( "gisdbase: %1" ).arg( mGisdbase ) );
+ QgsDebugMsg( QString( "location: %1" ).arg( mLocation ) );
+ QgsDebugMsg( QString( "mapset: %1" ).arg( mMapset ) );
+ QgsDebugMsg( QString( "mapName: %1" ).arg( mMapName ) );
+
+ mCrs = QgsGrass::crs ( mGisdbase, mLocation );
+}
+
+QgsGrassRasterProvider::~QgsGrassRasterProvider()
+{
+ QgsDebugMsg( "QgsGrassRasterProvider: deconstructing." );
+}
+
+QImage* QgsGrassRasterProvider::draw( QgsRectangle const & viewExtent, int pixelWidth, int pixelHeight )
+{
+ QgsDebugMsg( "pixelWidth = " + QString::number( pixelWidth ) );
+ QgsDebugMsg( "pixelHeight = " + QString::number( pixelHeight ) );
+ QgsDebugMsg( "viewExtent: " + viewExtent.toString() );
+
+ QImage *image = new QImage( pixelWidth, pixelHeight, QImage::Format_ARGB32 );
+ image->fill ( QColor(Qt::gray).rgb() );
+
+ QStringList arguments;
+ arguments.append( "map=" + mMapName + "@" + mMapset );
+
+ arguments.append( (QString("window=%1,%2,%3,%4,%5,%6")
+ .arg(viewExtent.xMinimum()).arg(viewExtent.yMinimum())
+ .arg(viewExtent.xMaximum()).arg(viewExtent.yMaximum())
+ .arg(pixelWidth).arg(pixelHeight)) );
+ QProcess process( this );
+ QString cmd = QgsApplication::pkgDataPath() + "/grass/modules/qgis.d.rast";
+ QByteArray data;
+ try
+ {
+ data = QgsGrass::runModule ( mGisdbase, mLocation, cmd, arguments );
+ }
+ //catch ( QgsGrass::Exception &e ) // does not work
+ catch ( QgsException &e )
+ {
+ QMessageBox::warning( 0, QObject::tr( "Warning" ), QObject::tr( "Cannot draw raster" ) + "\n"
+ + e.what() );
+
+ // We dont set mValid to false, because the raster can be recreated and work next time
+ return image;
+ }
+ QgsDebugMsg( QString("%1 bytes read from modules stdout").arg(data.size()) );
+ uchar * ptr = image->bits( ) ;
+ // byteCount() in Qt >= 4.6
+ //int size = image->byteCount() < data.size() ? image->byteCount() : data.size();
+ int size = pixelWidth*pixelHeight*4 < data.size() ? pixelWidth*pixelHeight*4 : data.size();
+ memcpy ( ptr, data.data(), size );
+
+ return image;
+}
+
+QgsCoordinateReferenceSystem QgsGrassRasterProvider::crs()
+{
+ QgsDebugMsg( "Entered" );
+ return mCrs;
+}
+
+QgsRectangle QgsGrassRasterProvider::extent()
+{
+ // The extend can change of course so we get always fresh, to avoid running always the module
+ // we should save mExtent and mLastModified and check if the map was modified
+
+ QgsRectangle rect;
+ rect = QgsGrass::extent ( mGisdbase, mLocation, mMapset, mMapName, QgsGrass::Raster );
+ return rect;
+}
+
+bool QgsGrassRasterProvider::identify( const QgsPoint& thePoint, QMap<QString, QString>& theResults )
+{
+ QgsDebugMsg( "Entered" );
+ //theResults["Error"] = tr( "Out of extent" );
+ theResults = QgsGrass::query ( mGisdbase, mLocation, mMapset, mMapName, QgsGrass::Raster, thePoint.x(), thePoint.y() );
+ return true;
+}
+
+int QgsGrassRasterProvider::capabilities() const
+{
+ int capability = QgsRasterDataProvider::Identify;
+ return capability;
+}
+
+bool QgsGrassRasterProvider::isValid()
+{
+ return mValid;
+}
+
+QString QgsGrassRasterProvider::identifyAsText( const QgsPoint& point )
+{
+ return QString ("Not implemented");
+}
+
+QString QgsGrassRasterProvider::lastErrorTitle()
+{
+ return QString ("Not implemented");
+}
+
+QString QgsGrassRasterProvider::lastError()
+{
+ return QString ("Not implemented");
+}
+
+QString QgsGrassRasterProvider::name() const
+{
+ return PROVIDER_KEY;
+}
+
+QString QgsGrassRasterProvider::description() const
+{
+ return PROVIDER_DESCRIPTION;
+}
+
+/**
+ * Class factory to return a pointer to a newly created
+ * QgsGrassRasterProvider object
+ */
+QGISEXTERN QgsGrassRasterProvider * classFactory( const QString *uri )
+{
+ return new QgsGrassRasterProvider( *uri );
+}
+/** Required key function (used to map the plugin to a data store type)
+*/
+QGISEXTERN QString providerKey()
+{
+ return PROVIDER_KEY;
+}
+/**
+ * Required description function
+ */
+QGISEXTERN QString description()
+{
+ return PROVIDER_DESCRIPTION;
+}
+/**
+ * Required isProvider function. Used to determine if this shared library
+ * is a data provider plugin
+ */
+QGISEXTERN bool isProvider()
+{
+ return true;
+}
+
Added: trunk/qgis/src/providers/grass/qgsgrassrasterprovider.h
===================================================================
--- trunk/qgis/src/providers/grass/qgsgrassrasterprovider.h (rev 0)
+++ trunk/qgis/src/providers/grass/qgsgrassrasterprovider.h 2010-02-04 21:25:35 UTC (rev 12880)
@@ -0,0 +1,186 @@
+/***************************************************************************
+ qgsgrassrasterprovider.h - QGIS Data provider for
+ GRASS rasters
+ -------------------
+ begin : 16 Jan, 2010
+ copyright : (C) 2010 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. *
+ * *
+ ***************************************************************************/
+
+/* $Id: qgsgrassrasterprovider.h 12528 2009-12-20 12:29:07Z jef $ */
+
+#ifndef QGSWMSPROVIDER_H
+#define QGSWMSPROVIDER_H
+
+#include "qgscoordinatereferencesystem.h"
+#include "qgsrasterdataprovider.h"
+#include "qgsrectangle.h"
+
+#include <QString>
+#include <QStringList>
+#include <QDomElement>
+#include <QMap>
+#include <QVector>
+
+class QgsCoordinateTransform;
+
+/**
+
+ \brief Data provider for OGC WMS layers.
+
+ This provider implements the
+ interface defined in the QgsDataProvider class to provide access to spatial
+ data residing in a OGC Web Map Service.
+
+*/
+class QgsGrassRasterProvider : public QgsRasterDataProvider
+{
+ //Q_OBJECT
+
+ public:
+ /**
+ * Constructor for the provider.
+ *
+ * \param uri HTTP URL of the Web Server. If needed a proxy will be used
+ * otherwise we contact the host directly.
+ *
+ */
+ QgsGrassRasterProvider( QString const & uri = 0 );
+
+ //! Destructor
+ ~QgsGrassRasterProvider();
+
+ /** \brief Renders the layer as an image
+ */
+ QImage* draw( QgsRectangle const & viewExtent, int pixelWidth, int pixelHeight );
+
+ /** return a provider name
+
+ Essentially just returns the provider key. Should be used to build file
+ dialogs so that providers can be shown with their supported types. Thus
+ if more than one provider supports a given format, the user is able to
+ select a specific provider to open that file.
+
+ @note
+
+ Instead of being pure virtual, might be better to generalize this
+ behavior and presume that none of the sub-classes are going to do
+ anything strange with regards to their name or description?
+
+ */
+ QString name() const;
+
+
+ /** return description
+
+ Return a terse string describing what the provider is.
+
+ @note
+
+ Instead of being pure virtual, might be better to generalize this
+ behavior and presume that none of the sub-classes are going to do
+ anything strange with regards to their name or description?
+
+ */
+ QString description() const;
+
+ /*! Get the QgsCoordinateReferenceSystem for this layer
+ * @note Must be reimplemented by each provider.
+ * If the provider isn't capable of returning
+ * its projection an empty srs will be return, ti will return 0
+ */
+ virtual QgsCoordinateReferenceSystem crs();
+
+ /** Return the extent for this data layer
+ */
+ virtual QgsRectangle extent();
+
+ /**Returns true if layer is valid
+ */
+ bool isValid();
+
+ /** \brief Identify raster value(s) found on the point position */
+ bool identify( const QgsPoint & point, QMap<QString, QString>& results );
+
+ /**
+ * \brief Identify details from a WMS Server from the last screen update
+ *
+ * \param point[in] The pixel coordinate (as it was displayed locally on screen)
+ *
+ * \return A text document containing the return from the WMS server
+ *
+ * \note WMS Servers prefer to receive coordinates in image space, therefore
+ * this function expects coordinates in that format.
+ *
+ * \note The arbitraryness of the returned document is enforced by WMS standards
+ * up to at least v1.3.0
+ */
+ QString identifyAsText( const QgsPoint& point );
+
+ /**
+ * \brief Returns the caption error text for the last error in this provider
+ *
+ * If an operation returns 0 (e.g. draw()), this function
+ * returns the text of the error associated with the failure.
+ * Interactive users of this provider can then, for example,
+ * call a QMessageBox to display the contents.
+ */
+ QString lastErrorTitle();
+
+ /**
+ * \brief Returns the verbose error text for the last error in this provider
+ *
+ * If an operation returns 0 (e.g. draw()), this function
+ * returns the text of the error associated with the failure.
+ * Interactive users of this provider can then, for example,
+ * call a QMessageBox to display the contents.
+ */
+
+ QString lastError();
+
+ /** Returns a bitmask containing the supported capabilities
+ Note, some capabilities may change depending on which
+ sublayers are visible on this provider, so it may
+ be prudent to check this value per intended operation.
+ */
+ int capabilities() const;
+
+ /**
+ * Get metadata in a format suitable for feeding directly
+ * into a subset of the GUI raster properties "Metadata" tab.
+ */
+ QString metadata() { return QString(); }
+
+ // Following methods specific for WMS are not used at all in this provider and should be removed IMO from qgsdataprovider.h
+ void addLayers( QStringList const & layers, QStringList const & styles = QStringList() ) {}
+ QStringList supportedImageEncodings() { return QStringList();}
+ QString imageEncoding() const { return QString(); }
+ void setImageEncoding( QString const & mimeType ) {}
+ void setImageCrs( QString const & crs ) {}
+
+ private:
+
+ /**
+ * Flag indicating if the layer data source is a valid WMS layer
+ */
+ bool mValid;
+
+ QString mGisdbase; // map gisdabase
+ QString mLocation; // map location name (not path!)
+ QString mMapset; // map mapset
+ QString mMapName; // map name
+
+ QgsCoordinateReferenceSystem mCrs;
+};
+
+#endif
+
More information about the QGIS-commit
mailing list