📄 qgsgrassmapcalc.cpp
字号:
/********************************************************************** qgsgrassmapcalc.cpp ------------------- begin : September, 2005 copyright : (C) 2005 by Radim Blazek email : radim.blazek@gmail.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. * * * *************************************************************************/#include <iostream>#include <typeinfo>#include <qapplication.h>#include <qstringlist.h>#include <qlabel.h>#include <QComboBox>#include <qpushbutton.h>#include <qmessagebox.h>#include <qpen.h>#include <q3pointarray.h>#include <qcursor.h>#include <qevent.h>#include <qpoint.h>#include <qsize.h>#include <qlayout.h>#include <qlineedit.h>#include <q3groupbox.h>#include <qpainter.h>#include <qpixmap.h>#include <q3picture.h>#include <q3canvas.h>#include <qstatusbar.h>#include <qinputdialog.h>#include <qdom.h>#include <QMouseEvent>#include <QKeyEvent>#include <QGridLayout>#include <QTextStream>#include <QActionGroup>#include <QToolBar>#include "qgis.h"#include "qgisinterface.h"#include "qgsapplication.h"#include "qgsmapcanvas.h"#include "qgsmaplayer.h"#include "qgsvectorlayer.h"#include "qgsdataprovider.h"#include "qgsfield.h"extern "C" {#include <grass/gis.h>#include <grass/Vect.h>}#include "../../src/providers/grass/qgsgrass.h"#include "../../src/providers/grass/qgsgrassprovider.h"#include "qgsgrassattributes.h"#include "qgsgrassmodule.h"#include "qgsgrasstools.h"#include "qgsgrassmapcalc.h"#include "qgsgrassselect.h"QgsGrassMapcalc::QgsGrassMapcalc ( QgsGrassTools *tools, QgsGrassModule *module, QgisInterface *iface, QWidget * parent, const char * name, Qt::WFlags f ) : QMainWindow(0,Qt::WType_Dialog), QgsGrassMapcalcBase ( ), QgsGrassModuleOptions( tools, module, iface), mTool(-1), mObject(0), mConnector(0){#ifdef QGISDEBUG std::cerr << "QgsGrassMapcalc()" << std::endl;#endif setupUi(this); mStartMoveConnectorPoints.resize(2); mNextId = 0; // Set frame fixed (but for current desktop font/theme) mInputFrame->setMinimumHeight( mInputFrame->height() ); mInputFrame->setMaximumHeight( mInputFrame->height() ); mView = new QgsGrassMapcalcView ( this, mViewFrame); QGridLayout *layout = new QGridLayout( mViewFrame, 1, 1 ); layout->addWidget( mView, 0, 0 ); mCanvas = new Q3Canvas ( 400, 300 ); mCanvas->setBackgroundColor( QColor(180,180,180) ); mPaper = new Q3CanvasRectangle ( mCanvas ); mPaper->setBrush ( QBrush(QColor(255,255,255)) ); mPaper->setActive(false); mPaper->show(); resizeCanvas( 400, 300 ); mView->setCanvas ( mCanvas ); QString myIconPath = QgsApplication::themePath() + "/grass/"; QActionGroup *ag = new QActionGroup ( this ); QToolBar *tb = addToolBar(tr("Mapcalc tools")); mActionAddMap = new QAction( QIcon(myIconPath+"mapcalc_add_map.png"), tr("Add map"), this); mActionAddMap->setCheckable ( true ); ag->addAction ( mActionAddMap ); tb->addAction ( mActionAddMap ); connect ( mActionAddMap, SIGNAL(triggered()), this, SLOT(addMap()) ); mActionAddConstant = new QAction( QIcon(myIconPath+"mapcalc_add_constant.png"), tr("Add constant value"), this); mActionAddConstant->setCheckable ( true ); ag->addAction ( mActionAddConstant ); tb->addAction ( mActionAddConstant ); connect ( mActionAddConstant, SIGNAL(triggered()), this, SLOT(addConstant()) ); mActionAddFunction = new QAction( QIcon(myIconPath+"mapcalc_add_function.png"), tr("Add operator or function"), this); mActionAddFunction->setCheckable ( true ); ag->addAction ( mActionAddFunction ); tb->addAction ( mActionAddFunction ); connect ( mActionAddFunction, SIGNAL(triggered()), this, SLOT(addFunction()) ); mActionAddConnection = new QAction( QIcon(myIconPath+"mapcalc_add_connection.png"), tr("Add connection"), this); mActionAddConnection->setCheckable ( true ); ag->addAction ( mActionAddConnection ); tb->addAction ( mActionAddConnection ); connect ( mActionAddConnection, SIGNAL(triggered()), this, SLOT(addConnection()) ); mActionSelectItem = new QAction( QIcon(myIconPath+"mapcalc_select.png"), tr("Select item"), this); mActionSelectItem->setCheckable ( true ); ag->addAction ( mActionSelectItem ); tb->addAction ( mActionSelectItem ); connect ( mActionSelectItem, SIGNAL(triggered()), this, SLOT(selectItem()) ); mActionDeleteItem = new QAction( QIcon(myIconPath+"mapcalc_delete.png"), tr("Delete selected item"), this); mActionDeleteItem->setCheckable ( true ); mActionDeleteItem->setEnabled ( false ); ag->addAction ( mActionDeleteItem ); tb->addAction ( mActionDeleteItem ); connect ( mActionDeleteItem, SIGNAL(triggered()), this, SLOT(deleteItem()) ); mActionAddMap->setOn(true); mActionLoad = new QAction( QIcon(myIconPath+"mapcalc_open.png"), tr("Open"), this); tb->addAction ( mActionLoad ); connect ( mActionLoad, SIGNAL(triggered()), this, SLOT(load()) ); mActionSave = new QAction( QIcon(myIconPath+"mapcalc_save.png"), tr("Save"), this); tb->addAction ( mActionSave ); connect ( mActionSave, SIGNAL(triggered()), this, SLOT(save()) ); mActionSave->setEnabled(false); mActionSaveAs = new QAction( QIcon(myIconPath+"mapcalc_save_as.png"), tr("Save as"), this); tb->addAction ( mActionSaveAs ); connect ( mActionSaveAs, SIGNAL(triggered()), this, SLOT(saveAs()) ); /* Create functions */ int t = QgsGrassMapcalcFunction::Operator; //mFunctions.push_back(QgsGrassMapcalcFunction("-",2, "Odcitani", "in1,in2" )); // Arithmetical mFunctions.push_back(QgsGrassMapcalcFunction( t, "+", 2, tr("Addition" ))); mFunctions.push_back(QgsGrassMapcalcFunction( t, "-", 2, tr("Subtraction"))); mFunctions.push_back(QgsGrassMapcalcFunction( t, "*", 2, tr("Multiplication" ))); mFunctions.push_back(QgsGrassMapcalcFunction( t, "/", 2, tr("Division" ))); mFunctions.push_back(QgsGrassMapcalcFunction( t, "%", 2, tr("Modulus" ))); mFunctions.push_back(QgsGrassMapcalcFunction( t, "^", 2, tr("Exponentiation" ))); // Logical mFunctions.push_back(QgsGrassMapcalcFunction( t, "==", 2, tr("Equal" ))); mFunctions.push_back(QgsGrassMapcalcFunction( t, "!=", 2, tr("Not equal" ))); mFunctions.push_back(QgsGrassMapcalcFunction( t, ">", 2, tr("Greater than" ))); mFunctions.push_back(QgsGrassMapcalcFunction( t, ">=", 2, tr("Greater than or equal" ))); mFunctions.push_back(QgsGrassMapcalcFunction( t, "<", 2, tr("Less than" ))); mFunctions.push_back(QgsGrassMapcalcFunction( t, "<=", 2, tr("Less than or equal" ))); mFunctions.push_back(QgsGrassMapcalcFunction( t, "&&", 2, tr("And" ))); mFunctions.push_back(QgsGrassMapcalcFunction( t, "||", 2, tr("Or" ))); t = QgsGrassMapcalcFunction::Function; mFunctions.push_back(QgsGrassMapcalcFunction( t, "abs", 1, tr("Absolute value of x"), "abs(x)" )); mFunctions.push_back(QgsGrassMapcalcFunction( t, "atan", 1, tr("Inverse tangent of x (result is in degrees)"), "atan(x)" )); mFunctions.push_back(QgsGrassMapcalcFunction( t, "atan", 2, tr("Inverse tangent of y/x (result is in degrees)"), "atan(x,y)" )); mFunctions.push_back(QgsGrassMapcalcFunction( t, "col", 0, tr("Current column of moving window (starts with 1)") )); mFunctions.push_back(QgsGrassMapcalcFunction( t, "cos", 1, tr("Cosine of x (x is in degrees)"), "cos(x)" )); mFunctions.push_back(QgsGrassMapcalcFunction( t, "double", 1, tr("Convert x to double-precision floating point"), "double(x)" )); mFunctions.push_back(QgsGrassMapcalcFunction( t, "ewres", 0, tr("Current east-west resolution" ))); mFunctions.push_back(QgsGrassMapcalcFunction( t, "exp", 1, tr("Exponential function of x"), "exp(x)" )); mFunctions.push_back(QgsGrassMapcalcFunction( t, "exp", 2, tr("x to the power y"), "exp(x,y)" )); mFunctions.push_back(QgsGrassMapcalcFunction( t, "float", 2, tr("Convert x to single-precision floating point"), "float(x)" )); mFunctions.push_back(QgsGrassMapcalcFunction( t, "if", 1, tr("Decision: 1 if x not zero, 0 otherwise"), "if(x)" )); mFunctions.push_back(QgsGrassMapcalcFunction( t, "if", 2, tr("Decision: a if x not zero, 0 otherwise"), "if(x,a)" )); mFunctions.push_back(QgsGrassMapcalcFunction( t, "if", 3, tr("Decision: a if x not zero, b otherwise"), "if(x,a,b)", "if,then,else", false )); mFunctions.push_back(QgsGrassMapcalcFunction( t, "if", 4, tr("Decision: a if x > 0, b if x is zero, c if x < 0"), "if(x,a,b,c)" )); mFunctions.push_back(QgsGrassMapcalcFunction( t, "int", 1, tr("Convert x to integer [ truncates ]"), "int(x)" )); mFunctions.push_back(QgsGrassMapcalcFunction( t, "isnull", 1, tr("Check if x = NULL"), "isnull(x)" )); mFunctions.push_back(QgsGrassMapcalcFunction( t, "log", 1, tr("Natural log of x"), "log(x)" )); mFunctions.push_back(QgsGrassMapcalcFunction( t, "log", 2, tr("Log of x base b"), "log(x,b)" )); mFunctions.push_back(QgsGrassMapcalcFunction( t, "max", 2, tr("Largest value"), "max(a,b)" )); mFunctions.push_back(QgsGrassMapcalcFunction( t, "max", 3, tr("Largest value"), "max(a,b,c)" )); mFunctions.push_back(QgsGrassMapcalcFunction( t, "median", 2, tr("Median value"), "median(a,b)" )); mFunctions.push_back(QgsGrassMapcalcFunction( t, "median", 3, tr("Median value"), "median(a,b,c)" )); mFunctions.push_back(QgsGrassMapcalcFunction( t, "min", 2, tr("Smallest value"), "min(a,b)" )); mFunctions.push_back(QgsGrassMapcalcFunction( t, "min", 3, tr("Smallest value"), "min(a,b,c)" )); mFunctions.push_back(QgsGrassMapcalcFunction( t, "mode", 2, tr("Mode value"), "mode(a,b)" )); mFunctions.push_back(QgsGrassMapcalcFunction( t, "mode", 3, tr("Mode value"), "mode(a,b,c)" )); mFunctions.push_back(QgsGrassMapcalcFunction( t, "not", 1, tr("1 if x is zero, 0 otherwise"), "not(x)" )); mFunctions.push_back(QgsGrassMapcalcFunction( t, "nsres", 0, tr("Current north-south resolution" ))); mFunctions.push_back(QgsGrassMapcalcFunction( t, "null", 0, tr("NULL value" ))); mFunctions.push_back(QgsGrassMapcalcFunction( t, "rand", 2, tr("Random value between a and b"), "rand(a,b)" )); mFunctions.push_back(QgsGrassMapcalcFunction( t, "round", 1, tr("Round x to nearest integer"), "round(x)" )); mFunctions.push_back(QgsGrassMapcalcFunction( t, "row", 0, tr("Current row of moving window (Starts with 1)" ))); mFunctions.push_back(QgsGrassMapcalcFunction( t, "sin", 1, tr("Sine of x (x is in degrees)", "sin(x)" ))); mFunctions.push_back(QgsGrassMapcalcFunction( t, "sqrt", 1, tr("Square root of x", "sqrt(x)" ))); mFunctions.push_back(QgsGrassMapcalcFunction( t, "tan", 1, tr("Tangent of x (x is in degrees)", "tan(x)" ))); mFunctions.push_back(QgsGrassMapcalcFunction( t, "x", 0, tr("Current x-coordinate of moving window" ))); mFunctions.push_back(QgsGrassMapcalcFunction( t, "y", 0, tr("Current y-coordinate of moving window" ))); for ( unsigned int i =0; i < mFunctions.size(); i++ ) { mFunctionComboBox->insertItem( mFunctions[i].label() + " " + mFunctions[i].description() ); } // Add output object mOutput = new QgsGrassMapcalcObject( QgsGrassMapcalcObject::Output); mOutput->setId ( nextId() ); mOutput->setValue ( tr("Output") ); mOutput->setCanvas(mCanvas); mOutput->setCenter ( (int)(mCanvas->width()-mOutput->width()), (int)(mCanvas->height()/2) ), mCanvas->update(); mOutput->Q3CanvasRectangle::show(); // Set default tool updateMaps(); if ( mMaps.size() > 0 ) { setTool ( AddMap ); } else { setTool ( AddConstant ); }}void QgsGrassMapcalc::contentsMousePressEvent(QMouseEvent* e){#ifdef QGISDEBUG std::cerr << "QgsGrassMapcalc::contentsMousePressEvent mTool = " << mTool << " mToolStep = " << mToolStep << std::endl;#endif QPoint p = mView->inverseWorldMatrix().map(e->pos()); limit(&p); switch ( mTool ) { case AddMap: case AddConstant: case AddFunction: mObject->setCenter ( p.x(), p.y() ); mObject = 0; //addMap(); // restart setTool ( mTool ); // restart break; case AddConnector: if ( mToolStep == 0 ) { mConnector->setPoint ( 0, p ); mConnector->setPoint ( 1, p ); // Try to connect mConnector->tryConnectEnd ( 0 ); mToolStep = 1; } break; case Select: // Cleare previous if ( mObject ) { mObject->setSelected ( false ); mObject = 0; } if ( mConnector ) { mConnector->setSelected ( false ); mConnector = 0; } showOptions(Select); QRect r ( p.x()-5, p.y()-5, 10, 10 ); Q3CanvasItemList l = mCanvas->collisions(r); // Connector precedence (reverse order - connectors are under objects) for ( Q3CanvasItemList::Iterator it=l.fromLast(); it!=l.end(); --it) { if (! (*it)->isActive() ) continue; if ( typeid (**it) == typeid (QgsGrassMapcalcConnector) ) { mConnector = dynamic_cast <QgsGrassMapcalcConnector *> (*it); mConnector->setSelected ( true ); mConnector->selectEnd ( p ); mStartMoveConnectorPoints[0] = mConnector->point(0); mStartMoveConnectorPoints[1] = mConnector->point(1); break; } else if ( typeid (**it) == typeid (QgsGrassMapcalcObject) ) { mObject = dynamic_cast <QgsGrassMapcalcObject *> (*it); mObject->setSelected ( true ); int tool = Select; if ( mObject->type() == QgsGrassMapcalcObject::Map ) tool = AddMap; else if ( mObject->type() == QgsGrassMapcalcObject::Constant ) tool = AddConstant; else if ( mObject->type() == QgsGrassMapcalcObject::Function ) tool = AddFunction; showOptions(tool); break; } } if ( (mConnector && mConnector->selectedEnd() == -1) || mObject ) { mView->setCursor ( QCursor(Qt::SizeAllCursor) ); } else if ( mConnector ) { mView->setCursor ( QCursor(Qt::CrossCursor) ); } if ( mConnector || ( mObject && mObject->type() != QgsGrassMapcalcObject::Output ) ) { mActionDeleteItem->setEnabled(true); } else { mActionDeleteItem->setEnabled(false); } setOption(); break; } mCanvas->update(); mLastPoint = p; mStartMovePoint = p;}void QgsGrassMapcalc::contentsMouseMoveEvent(QMouseEvent* e){#ifdef QGISDEBUG // std::cerr << "QgsGrassMapcalc::contentsMouseMoveEvent mTool = " // << mTool << " mToolStep = " << mToolStep << std::endl;#endif QPoint p = mView->inverseWorldMatrix().map(e->pos()); limit(&p); switch ( mTool ) { case AddMap: case AddConstant: case AddFunction: mObject->setCenter ( p.x(), p.y() ); break; case AddConnector: if ( mToolStep == 1 ) { mConnector->setPoint ( 1, p ); mConnector->setSocket ( 1 ); // disconnect mConnector->tryConnectEnd ( 1 ); // try to connect } break; case Select: if ( mObject ) { int dx = p.x() - mLastPoint.x(); int dy = p.y() - mLastPoint.y(); QPoint c = mObject->center(); mObject->setCenter ( c.x()+dx, c.y()+dy ); } if ( mConnector ) { int end = mConnector->selectedEnd(); int dx = p.x() - mStartMovePoint.x(); int dy = p.y() - mStartMovePoint.y(); if ( end == -1 ) { for ( int i = 0; i < 2; i++ ) { //QPoint pe = mConnector->point( i ); mConnector->setSocket ( i ); // disconnect mConnector->setPoint ( i, QPoint( mStartMoveConnectorPoints[i].x()+dx, mStartMoveConnectorPoints[i].y()+dy) ); mConnector->tryConnectEnd ( i ); // try to connect } } else { mConnector->setSocket ( end ); // disconnect mConnector->setPoint ( end, QPoint(p.x(),p.y()) ); mConnector->tryConnectEnd ( end ); // try to connect } } break; } mCanvas->update(); mLastPoint = p;}void QgsGrassMapcalc::contentsMouseReleaseEvent(QMouseEvent* e){#ifdef QGISDEBUG std::cerr << "QgsGrassMapcalc::contentsMouseReleaseEvent mTool = " << mTool << " mToolStep = " << mToolStep << std::endl;#endif QPoint p = mView->inverseWorldMatrix().map(e->pos()); limit(&p); switch ( mTool ) { case AddConnector: if ( mToolStep == 1 ) { QPoint p0 = mConnector->point(0); double d = sqrt ( pow( (double)(p.x()-p0.x()), 2.0 ) + pow( (double)(p.y()-p0.y()), 2.0 ) ); std::cerr << "d = " << d << std::endl; if ( d < 5 ) // filter 'single' clicks { mConnector->setSocket ( 0 ); // disconnect delete mConnector; } mConnector = 0; setTool ( mTool ); // restart } break; case Select: mView->setCursor ( QCursor(Qt::ArrowCursor) ); break; } autoGrow(); mCanvas->update(); mLastPoint = p;}QStringList QgsGrassMapcalc::arguments(){ QString cmd = ""; //cmd.append("'"); cmd.append( mOutputLineEdit->text() ); cmd.append("="); cmd.append ( mOutput->expression() ); //cmd.append("'"); //cmd = "\"pok=1\""; //cmd = mOutputLineEdit->text(); return QStringList ( cmd );}QStringList QgsGrassMapcalc::checkOutput(){#ifdef QGISDEBUG std::cerr << "QgsGrassMapcalc::checkOutput()" << std::endl;#endif QStringList list; QString value = mOutputLineEdit->text().trimmed(); if ( value.length() == 0 ) return QStringList(); QString path = QgsGrass::getDefaultGisdbase() + "/" + QgsGrass::getDefaultLocation() + "/" + QgsGrass::getDefaultMapset() + "/cell/" + value; QFileInfo fi(path); if ( fi.exists() ) { return ( QStringList(value) ); } return QStringList();}QStringList QgsGrassMapcalc::checkRegion(){#ifdef QGISDEBUG std::cerr << "QgsGrassMapcalc::checkRegion()" << std::endl;#endif QStringList list; Q3CanvasItemList l = mCanvas->allItems(); struct Cell_head currentWindow; if ( !QgsGrass::region ( QgsGrass::getDefaultGisdbase(), QgsGrass::getDefaultLocation(), QgsGrass::getDefaultMapset(), ¤tWindow ) ) { QMessageBox::warning( 0, tr("Warning"), tr("Cannot get current region" )); return list; } for ( Q3CanvasItemList::Iterator it=l.fromLast(); it!=l.end(); --it) { if (! (*it)->isActive() ) continue; if ( typeid (**it) != typeid (QgsGrassMapcalcObject) ) continue; QgsGrassMapcalcObject *obj = dynamic_cast <QgsGrassMapcalcObject *> (*it); if ( obj->type() != QgsGrassMapcalcObject::Map ) continue;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -