/*
    Add all workflow output fields for an operation to the json document. This happens both
    for internal connections and actual output nodes.

 */
QJsonArray WorkflowJSONConnector::createJSONOperationOutputList(const SPWorkFlowNode& node) {
    QJsonArray outputs;

    IOperationMetaData op = node->operation();
    if (op.isValid()) {

        int index = 0;
        std::vector<SPOperationParameter> params = op->getOutputParameters();
        foreach (SPOperationParameter opParam, params) {
            QJsonObject output;
            QString baseName("");
            output["local"] = baseName;
            output["url"] = baseName;
            output["value"] = baseName;
            output["name"] = opParam->name();
            output["id"] = index;
            output["optional"] = opParam->isOptional();
            output["description"] = opParam->description();

            bool isNum = hasType(opParam->type(), itNUMBER);
            bool isMap = hasType(opParam->type(), itRASTER );    // or should this be itCOVERAGE?
            if (isNum || isMap) output["show"] = true;
            if (isNum) output["type"] = QString("number");
            if (isMap) output["type"] = QString("map");

            index++;

            outputs.append(output);
        }
/**
 * Executes an operation (or workflow) and generates output
 * @param parameters the input and output parameters that the user filled in
 */
QString OperationCatalogModel::executeoperation(quint64 operationid, const QString& parameters, QVariant runparams) {

    try {
        IOperationMetaData metadata;
        metadata.prepare(operationid);
        auto opExpr = OperationExpression::createExpression(operationid, parameters);
        if ( metadata.isValid() && opExpr.isValid()){
            if ( metadata->resource().hasProperty("runinmainthread")){ // some operations may not run in a different thread. particular operations that invoke methods from the qml which must run in the mainthread
                OperationWorker::run(opExpr);
            }else {
                QThread* thread = new QThread;
                thread->setProperty("runparameters",runparams);
                OperationWorker* worker = new OperationWorker(opExpr);
                worker->moveToThread(thread);
                thread->setProperty("workingcatalog", qVariantFromValue(context()->workingCatalog()));
                thread->connect(thread, &QThread::started, worker, &OperationWorker::process);
                thread->connect(worker, &OperationWorker::finished, thread, &QThread::quit);
                thread->connect(worker, &OperationWorker::finished, worker, &OperationWorker::deleteLater);
                thread->connect(thread, &QThread::finished, thread, &QThread::deleteLater);
                thread->connect(worker, &OperationWorker::finished, this, &OperationCatalogModel::workerFinished);
                thread->start();

                return "TODO";

            }
        }
        return sUNDEF;
    } catch (const ErrorObject& err){
        emit error(err.message());
    }

    return sUNDEF;
}
Example #3
0
void WorkflowModel::selectOperation(const QString& id)
{
    IOperationMetaData op;
    op.prepare(id.toULongLong());
    if ( op.isValid()){
        _selectedOperation.clear();
        _selectedOperation.append(new IlwisObjectModel(op->resource(),this));
    }
    emit selectionChanged();

}
Example #4
0
void WorkflowModel::setFixedValues(qint32 nodeid, const QString &formValues)
{
    try {
        SPWorkFlowNode node = _workflow->nodeById(nodeid);
        if (!node)
            return;

        IOperationMetaData op = node->operation();

        QStringList inputParameters = formValues.split('|');
        for (int i = 0; i < inputParameters.length(); ++i) {
            QString value = inputParameters[i].trimmed();
            WorkFlowParameter& parm = node->inputRef(i);
            parm.value(value, op->getInputParameters()[i]->type(), WorkFlowParameter::pkFIXED);
        }
    }catch(ErrorObject&){}

}
QJsonObject WorkflowJSONConnector::createJSONOperationMetadata(const SPWorkFlowNode& node, const std::vector<SPWorkFlowNode>& outNodes) {
    QJsonObject jsonMeta;
    jsonMeta["longname"] = node->name();
    jsonMeta["label"] = node->label();
    jsonMeta["description"] = node->description();

    quint64 nid = node->id();
    std::vector<SPWorkFlowNode>::const_iterator p = std::find_if(
                outNodes.begin(),
                outNodes.end(),
                [nid] (const SPWorkFlowNode& nod) { return nod->id() == nid; }
    );
    if (p != outNodes.end())
        jsonMeta["final"] = true;
    else
        jsonMeta["final"] = false;

    IOperationMetaData op = node->operation();
    if (op.isValid()){
        QString provider = op->resource()["namespace"].toString();
        jsonMeta["resource"] = provider;
        jsonMeta["syntax"] = op->resource()["syntax"].toString();
        QString keywords = op->resource()["keyword"].toString();
        jsonMeta["keywords"] = keywords;

        jsonMeta["outputparametercount"] = (int) op->outputParameterCount();

    }

    jsonMeta["inputparametercount"] = node->inputCount();

    return jsonMeta;
}
QStringList WorkflowModel::addOperation(const QString &id)
{
    QStringList* parameterEntrySet = new QStringList();
    bool ok;
    quint64 opid = id.toULongLong(&ok);
    Resource res = mastercatalog()->id2Resource(opid);

    if ( ok && res.isValid()){
        OVertex v = _workflow->addOperation({res});
        IOperationMetaData meta = _workflow->getOperationMetadata(v);
        std::vector<SPOperationParameter> inputs = meta->getInputParameters();
        for (int i = 0 ; i < inputs.size() ; i++) {
            _workflow->assignInputData(v, i);
            ++_inputParameterCount;
            int parameterIndex = _workflow->getWorkflowParameterIndex(v, i);
            parameterEntrySet->push_back(QString::number(parameterIndex) + "|insert");
        }
    }else {
       kernel()->issues()->log(QString(TR("Invalid operation id used in workflow %1")).arg(name()));
    }
    return *parameterEntrySet;
}
/*
    Add all workflow input fields for an operation to the json document. This happens both
    for internal connections and actual input nodes.

    Pre-assigned inputs (fixed values) are taken as is (it is assumed they point to actual existing objects)

    External inputs that are not specified remain empty (this should be avoided, because that
    invalidates the output Json file!).

    Internal inputs get a name (auto-generated) based on the name of the operation
    that provides the input and its corresponding output edge number. The user input folder
    is used to create an actual local file location.

    Every input is also added into a local file list. The list links the WMS layername
    with the local filename. This is necessary to find the correct local file, when the
    Json file is interpreted as a workflow.
 */
QJsonArray WorkflowJSONConnector::createJSONOperationInputList(const SPWorkFlowNode& node) {
    QJsonArray inputs;

    for (int i = 0; i < node->inputCount(); i++) {
        QJsonObject input;

        WorkFlowParameter& wfp = node->inputRef(i);
        input["url"] = QString("");
        input["local"] = QString("");
        input["value"] = QString("");
        input["name"] = wfp.label();
        input["id"] = wfp.order();
        input["description"] = wfp.description();

        input["change"] = false;
        input["show"] = false;
        input["type"] = QString("");
        if (wfp.state() == WorkFlowParameter::pkFIXED)
            input["value"] = wfp.value();

        IOperationMetaData op = node->operation();
        if (op.isValid()) {
            SPOperationParameter parm = op->getInputParameters()[i];
            input["optional"] = parm->isOptional();
            bool isExp = hasType(parm->type(), itSTRING) && wfp.value().contains('@');
            bool isNum = hasType(parm->type(), itNUMBER);
            bool isMap = hasType(parm->type(), itRASTER );    // or should this be itCOVERAGE?
            if (isNum || isMap) input["show"] = true;
            if (isNum) input["type"] = QString("number");
            if (isMap) input["type"] = QString("map");
            if (isExp) input["type"] = QString("expression");
        }
        inputs.append(input);
    }

    return inputs;
}
Example #8
0
std::vector<QString> GenerateScriptNode::executeOperation(const OperationExpression &expression, const std::map<quint64, int> &idmap, QStringList& script, const QString& whitespace)
{
    auto getValue = [&](const WorkFlowParameter& parm, const OperationExpression& expression, const std::map<quint64, int>& idmap)-> QVariant{
        auto iter = idmap.find(parm.id());
        if  ( iter != idmap.end())       {
            int idx = (*iter).second;
            QString value =  expression.parm(idx).value();
            if ( hasType(parm.valueType(), itILWISOBJECT)){
                if ( value.indexOf("?input") != 0){
                    if ( value.indexOf("://") != -1){
                        value = "'"     + value + "'";
                    }
                }
            }
            return value;
        }
        return parameterValue(parm.order());
    };
    int inputCount = _node->inputCount();
    for(int i=0; i < inputCount; ++i){
        WorkFlowParameter& parameter = _node->inputRef(i);
        if ( parameterValue(i) == sUNDEF){
            if (parameter.inputLink()) {
                GenerateScriptNode exNode(parameter.inputLink());
                auto outs = exNode.execute(expression, idmap, script,whitespace);
                if ( parameter.outputParameterIndex() < outs.size())
                    _parameterValues[i] = outs[parameter.outputParameterIndex()];
            }
        }
    }

    SPOperationNode opNode = std::static_pointer_cast<OperationNode>(_node);
    IOperationMetaData metadata = opNode->operation();
    QString expr = "ilwis.Engine.do('"+ metadata->name()  + "',";
    QString parms;
    for(int i=0; i < inputCount; ++i){
        WorkFlowParameter& inParam = _node->inputRef(i);
        if ( parms != "")
            parms += ",";
        if ( hasType(inParam.valueType(),itILWISOBJECT)){
            parms += getValue(inParam, expression, idmap).toString();
        }else if ( hasType(inParam.valueType(), itINTEGER | itFLOAT | itDOUBLE )) {
            QString val = getValue(inParam,expression, idmap).toString();
            bool ok;
            val.toDouble(&ok); // some parms can be strings or numbers; we test what it actually is
            if (!ok)
                val = "\'" + val + "\'";
            parms += val;
        } else if (hasType(inParam.valueType(),itSTRING)){
            parms += "\'" + getValue(inParam,expression, idmap).toString() + "\'";
        }else
            parms += getValue(inParam,expression, idmap).toString();
    }
    std::vector<QString> names;
    QString nameslist;
    for(int i=0; i < opNode->operation()->outputParameterCount(); ++i){
        QString name = opNode->operation()->name() + "_" + QString::number(_node->id()) + "_" + QString::number(i);
        names.push_back(name);
        nameslist = nameslist + (i==0 ? "" : ",") + name;
    }
    expr = nameslist + (nameslist!="" ? "=" : "") + expr;
    expr = expr + parms + ")";
    if(!script.contains(expr)){

        script.append(whitespace + expr);
    }

    return names;

}
Example #9
0
QVariantMap WorkflowModel::getNode(int nodeId){
    QVariantMap data;
    try {
    if (_workflow.isValid()){
        SPWorkFlowNode node = _workflow->nodeById(nodeId)    ;
        if (!node)
            return data;
        IOperationMetaData op = node->operation();
        quint64 oid = op.isValid() ? op->id() : i64UNDEF;
        quint64 nid = node->id();
        BoundingBox box = node->box();
        data["name"] = node->name();
        data["label"] = node->label();
        data["description"]= node->description();
        data["operationid"] = QString::number(oid);
        data["nodeid"] = QString::number(nid);
        data["type"] = nodetype2string(node->type());
        data["x"] = box.min_corner().x;
        data["y"] = box.min_corner().y;
        data["w"] = box.xlength();
        data["h"] = box.ylength();
        if ( node->type()== WorkFlowNode::ntOPERATION){
            QVariantList parameters;
            for(int i=0; i < node->inputCount(); ++i){
                parameters.push_back(getParameter(node, i));
            }
            data["parameters"] = parameters;
        }else if ( hasType(node->type(), WorkFlowNode::ntCONDITION)){
            QVariantList test, operations, junctions;
            std::shared_ptr<WorkFlowCondition> condition = std::static_pointer_cast<WorkFlowCondition>(node);
            for(int i=0; i < condition->testCount(); ++i){
                WorkFlowCondition::Test tst = condition->test(i);
                QVariantMap t;
                t["pre"] = MathHelper::logicalOperator2string(tst._pre);
                t["post"] = MathHelper::logicalOperator2string(tst._post);
                t["operation"] = getNode(tst._operation->id());
                test.push_back(t);
            }
            std::vector<SPWorkFlowNode> subnodes = node->subnodes("operations");
            for(int i=0; i < subnodes.size(); ++i){
                operations.push_back(getNode(subnodes[i]->id()));
            }
            data["ownedoperations"] = operations;
            subnodes = node->subnodes("junctions");
            for(int i=0; i < subnodes.size(); ++i){
                junctions.push_back(getNode(subnodes[i]->id()));
            }
            data["ownedjunctions"] = junctions;
            data["tests"] = test;
        }if ( hasType(node->type(), WorkFlowNode::ntRANGE)){
              QVariantList operations, junctions, parameters;

              std::shared_ptr<RangeNode> range = std::static_pointer_cast<RangeNode>(node);
              QString def =  range->rangeDefinition();
              data["rangedefinition"] = def;
              parameters.push_back(getParameter(node, 0));
              data["parameters"] = parameters;
              std::vector<SPWorkFlowNode> subnodes = node->subnodes("operations");
              for(int i=0; i < subnodes.size(); ++i){
                  operations.push_back(getNode(subnodes[i]->id()));
              }
              subnodes = node->subnodes("junctions");
              for(int i=0; i < subnodes.size(); ++i){
                  junctions.push_back(getNode(subnodes[i]->id()));
              }
              data["ownedoperations"] = operations;
              data["ownedjunctions"] = junctions;
        }else if ( node->type() == WorkFlowNode::ntRANGEJUNCTION){
            QVariantList parameters;
            std::shared_ptr<RangeJunctionNode> junction = std::static_pointer_cast<RangeJunctionNode>(node);
            for(int i=0; i <4; ++i){
                parameters.push_back(getParameter(junction, i));
            }
            data["parameters"] = parameters;

        }else if ( node->type() == WorkFlowNode::ntJUNCTION){
            std::shared_ptr<JunctionNode> junction = std::static_pointer_cast<JunctionNode>(node);
            SPWorkFlowNode testNode =  junction->inputRef(WorkFlowCondition::cpTEST).inputLink();
            data["linkedcondition"] = testNode ? testNode->id() : i64UNDEF;
            data["linkedtrueoperation"] = getParameter(junction,WorkFlowCondition::cpTRUECASE);
            data["linkedfalseoperation"] = getParameter(junction,WorkFlowCondition::cpFALSECASE);
        }
    }
    } catch(ErrorObject&){}
    return data;
}