📄 qgsgrassmapcalc.cpp
字号:
+ QgsGrass::getDefaultMapset(); QString mc = ms + "/mapcalc"; if ( !QFile::exists(mc) ) { QDir d(ms); if ( !d.mkdir("mapcalc" ) ) { QMessageBox::warning( 0, tr("Warning"), tr("Cannot create 'mapcalc' " "directory in current mapset." )); return; } } // Ask for file name QString name; while ( 1 ) { bool ok; name = QInputDialog::getText( tr("New mapcalc"), tr("Enter new mapcalc name:"), QLineEdit::Normal, mFileName, &ok); if ( !ok ) return; name = name.stripWhiteSpace(); if ( name.isEmpty() ) { QMessageBox::warning( 0, tr("Warning"), tr("Enter vector name" )); continue; } // check if exists if ( QFile::exists( mc+ "/" + name ) ) { QMessageBox::StandardButton ret = QMessageBox::question ( 0, tr("Warning"), tr("The file already exists. Overwrite? "), QMessageBox::Ok | QMessageBox::Cancel ); if ( ret == QMessageBox::Cancel ) continue; } break; } mFileName = name; mActionSave->setEnabled(true); save();}void QgsGrassMapcalc::save(){#ifdef QGISDEBUG std::cerr << "QgsGrassMapcalc::save()" << std::endl;#endif if ( mFileName.isEmpty() ) // Should not happen { QMessageBox::warning (this, tr("Save mapcalc"), tr("File name empty") ); return; } // TODO!!!: 'escape' < > & ... // Erase objects of Add* tools int tool = mTool; setTool(Select); // Open file QString path = QgsGrass::getDefaultGisdbase() + "/" + QgsGrass::getDefaultLocation() + "/" + QgsGrass::getDefaultMapset() + "/mapcalc/" + mFileName; QFile out ( path ); if ( !out.open( QIODevice::WriteOnly ) ) { QMessageBox::warning (this, tr("Save mapcalc"), tr("Cannot open mapcalc file") ); return; } QTextStream stream ( &out ); stream << "<mapcalc>\n"; stream << " <canvas width=\"" + QString::number(mCanvas->width()) + "\" height=\"" + QString::number(mCanvas->height()) + "\"/>\n"; Q3CanvasItemList l = mCanvas->allItems(); for ( Q3CanvasItemList::Iterator it=l.fromLast(); it!=l.end(); --it) { if (! (*it)->isActive() ) continue; if ( typeid (**it) == typeid (QgsGrassMapcalcObject) ) { QgsGrassMapcalcObject *obj = dynamic_cast <QgsGrassMapcalcObject *> (*it); QString type; if ( obj->type() == QgsGrassMapcalcObject::Map ) { type = "map"; } else if ( obj->type() == QgsGrassMapcalcObject::Constant ) { type = "constant"; } else if ( obj->type() == QgsGrassMapcalcObject::Function ) { if ( obj->function().type() == QgsGrassMapcalcFunction::Operator ) type = "operator"; else type = "function"; } else if ( obj->type() == QgsGrassMapcalcObject::Output ) { type = "output"; } QString val = obj->value(); if ( obj->type() == QgsGrassMapcalcObject::Function ) { val.replace ( "&", "&" ); val.replace ( "<", "<" ); val.replace ( ">", ">" ); } stream << " <object id=\"" + QString::number(obj->id()) + "\" x=\"" + QString::number(obj->center().x()) + "\" y=\"" + QString::number(obj->center().y()) + "\" type=\"" + type + "\" value=\"" + val + "\""; if ( obj->type() == QgsGrassMapcalcObject::Function ) { stream << " inputCount=\"" + QString::number(obj->function().inputCount()) + "\""; } if ( obj->type() == QgsGrassMapcalcObject::Map ) { stream << " label=\"" + obj->label() + "\""; } stream << "/>\n"; } else if ( typeid (**it) == typeid (QgsGrassMapcalcConnector) ) { QgsGrassMapcalcConnector *con = dynamic_cast <QgsGrassMapcalcConnector *> (*it); stream << " <connector id=\"" + QString::number(con->id()) + "\">\n"; for ( int i = 0; i < 2; i++ ) { stream << " <end x=\"" + QString::number(con->point(i).x()) + "\" y=\"" + QString::number(con->point(i).y()) + "\""; if ( con->object(i) ) { stream << " object=\"" + QString::number(con->object(i)->id()) + "\" socketType=\""; if ( con->socketDirection(i) == QgsGrassMapcalcObject::In ) { stream << "in"; } else { stream << "out"; } stream << "\" socket=\"" + QString::number(con->socket(i)) + "\""; } stream << "/>\n"; } stream << " </connector>\n"; } } stream << "</mapcalc>"; out.close(); setTool(tool);}void QgsGrassMapcalc::load(){#ifdef QGISDEBUG std::cerr << "QgsGrassMapcalc::load()" << std::endl;#endif QgsGrassSelect *sel = new QgsGrassSelect(QgsGrassSelect::MAPCALC ); if ( sel->exec() == QDialog::Rejected ) return; // Open file QString path = sel->gisdbase + "/" + sel->location + "/" + sel->mapset + "/mapcalc/" + sel->map; QFile file ( path ); if ( !file.exists() ) // should not happen { QMessageBox::warning( 0, tr("Warning"), tr("The mapcalc schema (") + path + tr(") not found." )); return; } if ( ! file.open( QIODevice::ReadOnly ) ) { QMessageBox::warning( 0, tr("Warning"), tr("Cannot open mapcalc schema (") + path + ")" ); return; } QDomDocument doc ( "mapcalc" ); QString err; int line, column; int parsed = doc.setContent( &file, &err, &line, &column ); file.close(); if ( !parsed ) { QString errmsg = tr("Cannot read mapcalc schema (") + path + "):\n" + err + tr("\nat line ") + QString::number(line) + tr(" column ") + QString::number(column); QMessageBox::warning( 0, tr("Warning"), errmsg ); return; } clear(); QDomElement docElem = doc.documentElement(); // Set canvas QDomNodeList canvasNodes = docElem.elementsByTagName ( "canvas" ); QDomElement canvasElement = canvasNodes.item(0).toElement(); int width = canvasElement.attribute("width","300").toInt(); int height = canvasElement.attribute("height","200").toInt(); resizeCanvas(width, height ); // Add objects std::vector<QgsGrassMapcalcObject *> objects; QDomNodeList objectNodes = docElem.elementsByTagName ( "object" ); std::cerr << "objectNodes.count() = " << objectNodes.count() << std::endl; for ( int n = 0; n < objectNodes.count(); n++ ) { QDomNode node = objectNodes.item(n); QDomElement e = node.toElement(); if( e.isNull() ) continue; std::cerr << "id = " << e.attribute("id","?").local8Bit().data() << std::endl; unsigned int id = e.attribute("id","0").toInt(); int x = e.attribute("x","0").toInt(); int y = e.attribute("y","0").toInt(); QString typeName = e.attribute("type","constant"); QString value = e.attribute("value","???"); if ( id >= mNextId ) mNextId = id+1; if ( id >= objects.size() ) { objects.resize(id + 1); } int type = -1; if ( typeName == "map" ) type = QgsGrassMapcalcObject::Map; else if ( typeName == "constant" ) type = QgsGrassMapcalcObject::Constant; else if ( typeName == "operator" ) type = QgsGrassMapcalcObject::Function; else if ( typeName == "function" ) type = QgsGrassMapcalcObject::Function; else if ( typeName == "output" ) type = QgsGrassMapcalcObject::Output; if ( type == -1 ) continue; QgsGrassMapcalcObject *obj = new QgsGrassMapcalcObject ( type ); objects[id] = obj; obj->setId ( id ); obj->setValue ( value ); obj->setCenter ( x, y ); obj->setCanvas ( mCanvas ); obj->show(); switch ( type ) { case QgsGrassMapcalcObject::Map: { QString label = e.attribute("label","???"); obj->setValue ( value, label ); break; } case QgsGrassMapcalcObject::Output : obj->setValue ( tr("Output") ); mOutput = obj; break; case QgsGrassMapcalcObject::Function : int inputCount = e.attribute("inputCount","1").toInt(); // Find function int fn = -1; for ( unsigned int i = 0; i < mFunctions.size(); i++ ) { if ( mFunctions[i].name() != value ) continue; if ( mFunctions[i].inputCount() != inputCount ) continue; fn = i; } if ( fn >= 0 ) { obj->setFunction ( mFunctions[fn] ); } // TODO: if not found break; } } // Add connectors QDomNodeList connectorNodes = docElem.elementsByTagName ( "connector" ); for ( int n = 0; n < connectorNodes.count(); n++ ) { QDomNode node = connectorNodes.item(n); QDomElement e = node.toElement(); if( e.isNull() ) continue; std::cerr << "id = " << e.attribute("id","?").local8Bit().data() << std::endl; unsigned int id = e.attribute("id","0").toInt(); if ( id >= mNextId ) mNextId = id+1; QgsGrassMapcalcConnector *con = new QgsGrassMapcalcConnector ( mCanvas ); con->setId ( id ); con->setCanvas ( mCanvas ); con->show(); QDomNodeList endNodes = e.elementsByTagName ( "end" ); std::cerr << "endNodes.count = " << endNodes.count() << std::endl; for ( int n2 = 0; n2 < endNodes.count() && n2 < 2; n2++ ) { QDomNode node2 = endNodes.item(n2); QDomElement e2 = node2.toElement(); if( e2.isNull() ) continue; int x = e2.attribute("x","0").toInt(); int y = e2.attribute("y","0").toInt(); con->setPoint ( n2, QPoint(x,y) ); std::cerr << "x = " << x << " y = " << y << std::endl; int objId = e2.attribute("object","-1").toInt(); std::cerr << "objId = " << objId << std::endl; if ( objId < 0 ) continue; // not connected if ( static_cast<uint>(objId) < objects.size() && objects[objId] ) { QString socketTypeName = e2.attribute("socketType","out"); int socketType; if ( socketTypeName == "in" ) socketType = QgsGrassMapcalcObject::In; else socketType = QgsGrassMapcalcObject::Out; int socket = e2.attribute("socket","0").toInt(); std::cerr << "end = " << n2 << " objId = " << objId << " socketType = " << socketType << " socket = " << socket << std::endl; con->setSocket ( n2, objects[objId], socketType, socket ); objects[objId]->setConnector ( socketType, socket, con, n2 ); } } } mFileName = sel->map; mActionSave->setEnabled(true); mCanvas->update();}void QgsGrassMapcalc::clear(){#ifdef QGISDEBUG std::cerr << "QgsGrassMapcalc::clear()" << std::endl;#endif setTool (Select); Q3CanvasItemList l = mCanvas->allItems(); for ( Q3CanvasItemList::Iterator it=l.fromLast(); it!=l.end(); --it) { if (! (*it)->isActive() ) continue; delete *it; } mNextId = 0;}/******************** CANVAS ITEMS ******************************/QgsGrassMapcalcItem::QgsGrassMapcalcItem(): mSelected(false){#ifdef QGISDEBUG std::cerr << "QgsGrassMapcalcItem::QgsGrassMapcalcItem()" << std::endl;#endif}QgsGrassMapcalcItem::~QgsGrassMapcalcItem(){}void QgsGrassMapcalcItem::setSelected(bool s){ mSelected = s;}bool QgsGrassMapcalcItem::selected(){ return mSelected;}/**************************** OBJECT ************************/QgsGrassMapcalcObject::QgsGrassMapcalcObject( int type ) :Q3CanvasRectangle(-1000,-1000,50,20,0), QgsGrassMapcalcItem(), mType(type),mCenter(-1000,-1000), mSelectionBoxSize(5), mOutputConnector(0){#ifdef QGISDEBUG std::cerr << "QgsGrassMapcalcObject::QgsGrassMapcalcObject()" << std::endl;#endif Q3CanvasRectangle::setZ(20); setActive(true); mInputCount = 0; mOutputCount = 1; if ( mType == Function ) mInputCount = 2; if ( mType == Output ) { mInputCount = 1; mOutputCount = 0; } mInputConnectors.resize( mInputCount ); mInputConnectorsEnd.resize( mInputCount );}QgsGrassMapcalcObject::~QgsGrassMapcalcObject(){ std::cerr << "QgsGrassMapcalcObject::~QgsGrassMapcalcObject()" << std::endl; // Delete connections for ( int i = 0; i < mInputCount; i++ ) { if ( mInputConnectors[i] ) { QgsGrassMapcalcConnector *con = mInputConnectors[i]; mInputConnectors[i]->setSocket ( mInputConnectorsEnd[i] ); con->repaint(); } } if ( mOutputConnector ) { QgsGrassMapcalcConnector *con = mOutputConnector; mOutputConnector->setSocket ( mOutputConnectorEnd ); con->repaint(); } std::cerr << "QgsGrassMapcalcObject::~QgsGrassMapcalcObject() end" << std::endl;}int QgsGrassMapcalcObject::type(){ return mType;}void QgsGrassMapcalcObject::draw( QPainter & painter ){ //QCanvasRectangle::draw(painter); painter.setPen ( QPen(QColor(0,0,0)) ); painter.setBrush ( QBrush(QColor(255,255,255)) ); int xRound = (int) ( 100 * mRound / mRect.width() ); int yRound = (int) ( 100 * mRound / mRect.height() ); painter.drawRoundRect ( mRect, xRound, yRound ); // Input sockets for ( int i = 0; i < mInputCount; i++ ) { if ( mInputConnectors[i] ) painter.setBrush ( QBrush(QColor(180,180,180)) ); else painter.setBrush ( QBrush(QColor(255,0,0)) ); painter.drawEllipse ( mInputPoints[i].x()-mSocketHalf, mInputPoints[i].y()-mSocketHalf, 2*mSocketHalf+1, 2*mSocketHalf+1 ); } // Output socket if ( mOutputCount > 0 ) { if ( mOutputConnector ) painter.setBrush ( QBrush(QColor(180,180,180)) ); else painter.setBrush ( QBrush(QColor(255,0,0)) ); painter.drawEllipse ( mOutputPoint.x()-mSocketHalf, mOutputPoint.y()-mSocketHalf, 2*mSocketHalf+1, 2*mSocketHalf+1 ); } // Input labels if ( mType == Function && mInputTextWidth > 0 ) { painter.setFont ( mFont ); QFontMetrics metrics ( mFont ); for ( int i = 0; i < mFunction.inputLabels().size(); i++ ) { /* QStringList::Iterator it = mFunction.inputLabels().at(i); QString l = *it; */ QString l = mFunction.inputLabels().at(i); int lx = mRect.x()+mSpace; int ly = mRect.y() +mSpace + i*(mTextHeight+mSpace); QRect lr ( lx, ly, metrics.width(l), mTextHeight ) ; painter.drawText ( lr, Qt::AlignCenter|Qt::TextSingleLine, l ); } } // Label if ( mType != Function || mFunction.drawlabel() ) { painter.drawText ( mLabelRect, Qt::AlignCenter|Qt::TextSingleLine, mLabel );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -