Exemple #1
0
void Map::saveOtbm(const std::string &fileName)
{
    FileStreamPtr fin = g_resources.createFile(fileName);
    if(!fin)
        stdext::throw_exception(stdext::format("failed to open file '%s' for write", fileName));

    std::string dir;
    if(fileName.find_last_of('/') == std::string::npos)
        dir = g_resources.getWorkDir();
    else
        dir = fileName.substr(0, fileName.find_last_of('/'));

    uint32 version = 0;
    /// Support old versions (< 810 or 860 IIRC)
    /// TODO: Use constants?
    if(g_things.getOtbMajorVersion() < 10)
        version = 1;
    else
        version = 2;

    /// Usually when a map has empty house/spawn file it means the map is new.
    /// TODO: Ask the user for a map name instead of those ugly uses of substr
    std::string::size_type sep_pos;
    std::string houseFile = getHouseFile();
    std::string spawnFile = getSpawnFile();
    std::string cpyf;

    if((sep_pos = fileName.rfind('.')) != std::string::npos && stdext::ends_with(fileName, ".otbm"))
        cpyf = fileName.substr(0, sep_pos);

    if(houseFile.empty())
        houseFile = cpyf + "-houses.xml";

    if(spawnFile.empty())
        spawnFile = cpyf + "-spawns.xml";

    /// we only need the filename to save to, the directory should be resolved by the OTBM loader not here
    if((sep_pos = spawnFile.rfind('/')) != std::string::npos)
        spawnFile = spawnFile.substr(sep_pos + 1);

    if((sep_pos = houseFile.rfind('/')) != std::string::npos)
        houseFile = houseFile.substr(sep_pos + 1);
#if 0
    if(version > 1)
        m_houses->save(dir + "/" + houseFile);

    saveSpawns(dir + "/" + spawnFile);
#endif

    fin->addU32(0); // file version
    BinaryWriteTreePtr root(new BinaryWriteTree(fin));
    root->startNode(0);
    {
        root->writeU32(version);

        Size mapSize = getSize();
        root->writeU16(mapSize.width());
        root->writeU16(mapSize.height());

        root->writeU32(g_things.getOtbMajorVersion());
        root->writeU32(g_things.getOtbMinorVersion());

        root->startNode(OTBM_MAP_DATA);
        {
            // own description.
            for(const auto& desc : getDescriptions()) {
                root->writeU8(OTBM_ATTR_DESCRIPTION);
                root->writeString(desc);
            }

            // special one
            root->writeU8(OTBM_ATTR_DESCRIPTION);
            root->writeString(stdext::format("Saved with %s v%s", g_app.getName(), g_app.getVersion()));

            // spawn file.
            root->writeU8(OTBM_ATTR_SPAWN_FILE);
            root->writeString(spawnFile);

            // house file.
            if(version > 1) {
                root->writeU8(OTBM_ATTR_HOUSE_FILE);
                root->writeString(houseFile);
            }

            Position base(-1, -1, -1);
            bool firstNode = true;

            for(uint8_t z = 0; z < Otc::MAX_Z + 1; ++z) {
                for(const auto& it : m_tileBlocks[z]) {
                    const TileBlock& block = it.second;
                    for(const TilePtr& tile : block.getTiles()) {
                        if(!tile)
                            continue;

                        const Position& pos = tile->getPosition();
                        if(!pos.isValid())
                            continue;

                        if(pos.x < base.x || pos.x >= base.x + 256 || pos.y < base.y|| pos.y >= base.y + 256 ||
                                pos.z != base.z) {
                            if(!firstNode)
                                root->endNode(); /// OTBM_TILE_AREA

                            root->startNode(OTBM_TILE_AREA);
                            firstNode = false;
                            root->writePos(base = pos & 0xFF00);
                        }

                        uint32 flags = tile->getFlags();

                        root->startNode((flags & TILESTATE_HOUSE) == TILESTATE_HOUSE ? OTBM_HOUSETILE : OTBM_TILE);
                        root->writePoint(Point(pos.x, pos.y) & 0xFF);
//                      if(tileNode->getType() == OTBM_HOUSETILE)
//                          tileNode->writeU32(tile->getHouseId());

                        if(flags) {
                            root->writeU8(OTBM_ATTR_TILE_FLAGS);
                            root->writeU32(flags);
                        }

                        for(const ItemPtr& item : tile->getItems()) {
                            if(item->isGround()) {
                                root->writeU8(OTBM_ATTR_ITEM);
                                root->writeU16(item->getId());
                                continue;
                            }

                            item->serializeItem(root); 
                        }

                        root->endNode(); // OTBM_TILE
                    }
                }
            }

            if(!firstNode)
                root->endNode();  // OTBM_TILE_AREA

            root->startNode(OTBM_TOWNS);
            for(const TownPtr& town : m_towns.getTowns()) {
                root->writeU32(town->getId());
                root->writeString(town->getName());
                root->writePos(town->getPos());
            }
            root->endNode();

            if(version > 1) {
                root->startNode(OTBM_WAYPOINTS);
                for(const auto& it : m_waypoints) {
                    root->writeString(it.second);
                    root->writePos(it.first);
                }
                root->endNode();
            }
        }
        root->endNode(); // OTBM_MAP_DATA
    }
    root->endNode(); // 0 (root)
}
Exemple #2
0
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    //Command line arguments
    TCLAP::CmdLine cmd("GOBLET (c) 2012, International Livestock Research Institute (ILRI) \n Developed by Carlos Quiros ([email protected])", ' ', "1.0 (Beta 1)");
    //Required arguments
    TCLAP::ValueArg<std::string> databaseArg("d","database","Database name",true,"","string");
    TCLAP::ValueArg<std::string> calculationArg("c","calculation","Calculation to perform. For example: 'sum(DatasetA),sum(DatasetB)' ",true,"","string");
    TCLAP::ValueArg<std::string> ouputArg("o","output","Output type: (h)uman readable or (c)omputer readable",true,"","string");


    //Non required arguments
    TCLAP::ValueArg<std::string> pathArg("a","path","Path to database. Default .",false,".","string");
    TCLAP::ValueArg<std::string> hostArg("H","host","Connect to host. Default localhost",false,"localhost","string");
    TCLAP::ValueArg<std::string> portArg("P","port","Port number to use. Default 3306",false,"3306","string");
    TCLAP::ValueArg<std::string> userArg("u","user","User. Default empty",false,"","string");
    TCLAP::ValueArg<std::string> passArg("p","password","Passwork. Default no password",false,"","string");
    TCLAP::ValueArg<std::string> descArg("s","descriptions","Descriptions for the calculations separated by coma. Default value is the calculation string",false,"","string");
    //Switches
    TCLAP::SwitchArg remoteSwitch("r","remote","Connect to remote host", cmd, false);
    cmd.add(databaseArg);
    cmd.add(calculationArg);
    cmd.add(ouputArg);


    cmd.add(pathArg);
    cmd.add(hostArg);
    cmd.add(portArg);
    cmd.add(userArg);
    cmd.add(passArg);
    cmd.add(descArg);


    //Parsing the command lines
    cmd.parse( argc, argv );

    //Getting the variables from the command
    bool remote = remoteSwitch.getValue();
    QString path = QString::fromUtf8(pathArg.getValue().c_str());
    QString dbName = QString::fromUtf8(databaseArg.getValue().c_str());
    QString host = QString::fromUtf8(hostArg.getValue().c_str());
    QString port = QString::fromUtf8(portArg.getValue().c_str());
    QString userName = QString::fromUtf8(userArg.getValue().c_str());
    QString password = QString::fromUtf8(passArg.getValue().c_str());
    QString calculation = QString::fromUtf8(calculationArg.getValue().c_str());
    QString format = QString::fromUtf8(ouputArg.getValue().c_str());
    QString description = QString::fromUtf8(descArg.getValue().c_str());

    myDBConn con;
    QSqlDatabase mydb;
    if (!remote)
    {
        QDir dir;
        dir.setPath(path);
        if (con.connectToDB(dir.absolutePath()) == 1)
        {
            if (!dir.cd(dbName))
            {
                gbtLog(QObject::tr("The database does not exists"));
                con.closeConnection();
                return 1;
            }
            mydb = QSqlDatabase::addDatabase(con.getDriver(),"connection1");
        }
    }
    else
    {
        mydb = QSqlDatabase::addDatabase("QMYSQL","connection1");
        mydb.setHostName(host);
        mydb.setPort(port.toInt());
        if (!userName.isEmpty())
           mydb.setUserName(userName);
        if (!password.isEmpty())
           mydb.setPassword(password);
    }

    mydb.setDatabaseName(dbName);

    if (!mydb.open())
    {
        gbtLog(QObject::tr("Cannot open database"));
        con.closeConnection();
        return 1;
    }
    else
    {
        QTime procTime;
        procTime.start();

        QString sql;
        QSqlQuery qry(mydb);

        QList <TdatasetInfo> datasets;

        if (constructSQL(calculation,sql,mydb,datasets))
        {
            gbtLog(QObject::tr("Error in calculation."));
            gbtLog(qry.lastError().databaseText());
            mydb.close();
            con.closeConnection();
            return 1;
        }


        QDomDocument doc;
        QDomElement root;

        doc = QDomDocument("GOBLETXML");

        root = doc.createElement("CalcXML");
        root.setAttribute("version", "1.0");
        doc.appendChild(root);

        QDomElement varName;
        QDomText varValue;

        QList<TfieldDef> fields;
        int ncols;
        ncols = 0;

        if (!qry.exec(sql))
        {
            gbtLog(QObject::tr("Cannot reset dataset."));
            gbtLog(qry.lastError().databaseText());
            mydb.close();
            con.closeConnection();
            return 1;
        }
        int nfields;
        nfields = qry.record().count();
        QString nfield;

        int pos;
        QStringList descriptions;
        descriptions = getDescriptions(description);

        if (descriptions.count() != nfields)
        {
            descriptions.clear();
            descriptions.append("Class code");
            for (pos = 1; pos <= nfields-1; pos++)
            {
                descriptions.append(qry.record().field(pos).name());
            }
        }


        for (pos = 0; pos <= nfields-1;pos++)
        {
            ncols++;
            nfield = descriptions[pos];
            nfield.replace("T" + datasets[pos].code + ".",datasets[pos].name + ".");
            nfield.replace(".cellvalue","");
            TfieldDef field;
            field.fieldName = nfield;
            field.fieldDesc = nfield; //Change for description

            if (pos == 0)
            {
                field.fieldType = "CHAR";
            }
            else
                field.fieldType = "DEC";
            fields.append(field);
        }

        QDomElement shapevars;
        shapevars = doc.createElement("Values");
        root.appendChild(shapevars);


        for (pos = 0; pos <= fields.count()-1;pos++)
        {
            varName = doc.createElement("Field");
            shapevars.appendChild(varName);
            varValue = doc.createTextNode(fields[pos].fieldDesc);
            varName.appendChild(varValue);
        }

        int nrows;

        nrows = 0;
        while (qry.next())
        {
            nrows++;
        }
        nrows++;

        QVector<QVector<QString> >  grid;
        grid.resize(nrows);
        int r;
        for(r=0; r<nrows; r++)
        {
            grid[r].resize(ncols);
        }

        for (pos = 0; pos <= fields.count()-1;pos++)
            grid[0][pos] = fields[pos].fieldDesc;
        r = 1;
        qry.first();
        QString value;
        while (qry.isValid())
        {
            for (pos = 0; pos <= fields.count()-1;pos++)
            {
                if (fields[pos].fieldType == "DEC")
                    value = QString::number(qry.value(pos).toDouble(),'f',3);
                else
                    value = qry.value(pos).toString();
                grid[r][pos] = value;
            }
            r++;
            qry.next();
        }


        if (format == "h")
        {
            QVector< int> colSizes;
            colSizes.resize(ncols);
            for (pos = 0; pos <= ncols-1;pos++)
                colSizes[pos] = 0;
            //Get the maximum size of each column
            for (pos = 0; pos <= ncols-1;pos++)
            {
                for(r=0; r<nrows; r++)
                {
                    if (grid[r][pos].length() +2 > colSizes[pos])
                    {
                        colSizes[pos] = grid[r][pos].length() +2;
                    }
                }
            }
            //Print the table
            printf("\n");
            //Print top line
            for (pos=0;pos<= ncols-1;pos++)
            {
                printf("+");
                printf(fixLine("-",colSizes[pos]).toLocal8Bit().data());
            }
            printf("+");
            printf("\n");
            //Print the columns headings

            for (pos=0;pos<= ncols-1;pos++)
            {
                printf("+");
                printf(fixString(" " + grid[0][pos] + " ",colSizes[pos]).toLocal8Bit().data());

            }
            printf("+");
            printf("\n");

            //Print separation
            for (pos=0;pos<= ncols-1;pos++)
            {
                printf("+");
                printf(fixLine("-",colSizes[pos]).toLocal8Bit().data());
            }
            printf("+");
            printf("\n");

            //Print the values
            for (r=1;r<=nrows-1;r++)
            {
                printf("|");
                for (pos=0;pos<= ncols-1;pos++)
                {
                    printf(fixString(" " + grid[r][pos] + " ",colSizes[pos]).toLocal8Bit().data());
                    printf("|");
                }
                printf("\n");
            }

            //Print the end
            //Print separation
            for (pos=0;pos<= ncols-1;pos++)
            {
                printf("+");
                printf(fixLine("-",colSizes[pos]).toLocal8Bit().data());
            }
            printf("+");
            printf("\n");
        }
        else
        {
            QDomElement shapeData;
            shapeData = doc.createElement("CalcData");
            root.appendChild(shapeData);

            QDomElement rowData;
            QDomElement fieldData;
            QDomText fieldValue;

            for (r=1;r<=nrows-1;r++)
            {
                rowData = doc.createElement("Row");
                shapeData.appendChild(rowData);
                for (pos=0;pos<= ncols-1;pos++)
                {
                    fieldData = doc.createElement("Field");
                    fieldData.setAttribute("Name",fields[pos].fieldDesc);
                    rowData.appendChild(fieldData);
                    fieldValue = doc.createTextNode(grid[r][pos]);
                    fieldData.appendChild(fieldValue);
                }

            }

            QTextStream out(stdout);
            out.setCodec("UTF-8");
            doc.save(out,1,QDomNode::EncodingFromTextStream);
        }

        int Hours;
        int Minutes;
        int Seconds;
        int Milliseconds;

        Milliseconds = procTime.elapsed();

        Hours = Milliseconds / (1000*60*60);
        Minutes = (Milliseconds % (1000*60*60)) / (1000*60);
        Seconds = ((Milliseconds % (1000*60*60)) % (1000*60)) / 1000;

        if (format == "h")
            gbtLog("Finished in " + QString::number(Hours) + " Hours," + QString::number(Minutes) + " Minutes and " + QString::number(Seconds) + " Seconds.");

        mydb.close();
        con.closeConnection();

        return 0;
    }

    return 0;

}
Exemple #3
0
MatrixOpDataRcPtr MatrixOpData::compose(ConstMatrixOpDataRcPtr & B) const
{
    if (getOutputBitDepth() != B->getInputBitDepth())
    {
        std::ostringstream oss;
        oss << "Matrix bit-depth missmatch between '";
        oss << getID();
        oss << "' and '";
        oss << B->getID();
        oss << "'. ";

        throw Exception(oss.str().c_str());
    }

    // Ensure that both matrices will have the right dimension (ie. 4x4).
    if (m_array.getLength() != 4 || B->m_array.getLength() != 4)
    {
        // Note: By design, only 4x4 matrices are instantiated.
        // The CLF 3x3 (and 3x4) matrices are automatically converted
        // to 4x4 matrices, and a Matrix Transform only expects 4x4 matrices.
        throw Exception("MatrixOpData: array content issue.");
    }

    Descriptions newDesc = getDescriptions();
    newDesc += B->getDescriptions();
    MatrixOpDataRcPtr out = std::make_shared<MatrixOpData>(
        getInputBitDepth(),
        B->getOutputBitDepth());
    out->setID(getID() + B->getID());
    out->getDescriptions() = newDesc;

    // TODO: May want to revisit how the metadata is set.

    // By definition, A.compose(B) implies that op A precedes op B
    // in the opList. The LUT format coefficients follow matrix math:
    // vec2 = A x vec1 where A is 3x3 and vec is 3x1.
    // So the composite operation in matrix form is vec2 = B x A x vec1.
    // Hence we compute B x A rather than A x B.

    MatrixArrayPtr outPtr = B->m_array.inner(this->m_array);

    out->getArray() = *outPtr.get();

    // Compute matrix B times offsets from A.

    Offsets offs;

    B->m_array.inner(getOffsets(), offs);

    const unsigned long dim = this->m_array.getLength();

    // Determine overall scaling of the offsets prior to any catastrophic
    // cancellation that may occur during the add.
    double val, max_val = 0.;
    for (unsigned long i = 0; i<dim; ++i)
    {
        val = fabs(offs[i]);
        max_val = max_val > val ? max_val : val;
        val = fabs(B->getOffsets()[i]);
        max_val = max_val > val ? max_val : val;
    }

    // Add offsets from B.
    for (unsigned long i = 0; i<dim; ++i)
    {
        offs[i] += B->getOffsets()[i];
    }

    out->setOffsets(offs);

    // To enable use of strict float comparisons above, we adjust the
    // result so that values very near integers become exactly integers.
    out->cleanUp(max_val);

    return out;
}
Exemple #4
0
void Map::saveOtbm(const std::string& fileName, const UIWidgetPtr&/* pbar*/)
{
    FileStreamPtr fin = g_resources.createFile(fileName);
    if(!fin)
        stdext::throw_exception(stdext::format("failed to open file '%s' for write", fileName));

    fin->cache();
    std::string dir;
    if(fileName.find_last_of('/') == std::string::npos)
        dir = g_resources.getWorkDir();
    else
        dir = fileName.substr(0, fileName.find_last_of('/'));

    uint32 version = 0;
    if(g_things.getOtbMajorVersion() < ClientVersion820)
        version = 1;
    else
        version = 2;

    /// Usually when a map has empty house/spawn file it means the map is new.
    /// TODO: Ask the user for a map name instead of those ugly uses of substr
    std::string::size_type sep_pos;
    std::string houseFile = getHouseFile();
    std::string spawnFile = getSpawnFile();
    std::string cpyf;

    if((sep_pos = fileName.rfind('.')) != std::string::npos && stdext::ends_with(fileName, ".otbm"))
        cpyf = fileName.substr(0, sep_pos);

    if(houseFile.empty())
        houseFile = cpyf + "-houses.xml";

    if(spawnFile.empty())
        spawnFile = cpyf + "-spawns.xml";

    /// we only need the filename to save to, the directory should be resolved by the OTBM loader not here
    if((sep_pos = spawnFile.rfind('/')) != std::string::npos)
        spawnFile = spawnFile.substr(sep_pos + 1);

    if((sep_pos = houseFile.rfind('/')) != std::string::npos)
        houseFile = houseFile.substr(sep_pos + 1);

    fin->addU32(0); // file version
    OutputBinaryTreePtr root(new OutputBinaryTree(fin));
    {
        root->addU32(version);

        Size mapSize = getSize();
        root->addU16(mapSize.width());
        root->addU16(mapSize.height());

        root->addU32(g_things.getOtbMajorVersion());
        root->addU32(g_things.getOtbMinorVersion());

        root->startNode(OTBM_MAP_DATA);
        {
            // own description.
            for(const auto& desc : getDescriptions()) {
                root->addU8(OTBM_ATTR_DESCRIPTION);
                root->addString(desc);
            }

            // special one
            root->addU8(OTBM_ATTR_DESCRIPTION);
            root->addString(stdext::format("Saved with %s v%s", g_app.getName(), g_app.getVersion()));

            // spawn file.
            root->addU8(OTBM_ATTR_SPAWN_FILE);
            root->addString(spawnFile);

            // house file.
            if(version > 1) {
                root->addU8(OTBM_ATTR_HOUSE_FILE);
                root->addString(houseFile);
            }

            int px = -1, py = -1, pz =-1;
            bool firstNode = true;

            for(uint8_t z = 0; z <= Otc::MAX_Z; ++z) {
                for(const auto& it : m_tileBlocks[z]) {
                    const TileBlock& block = it.second;
                    for(const TilePtr& tile : block.getTiles()) {
                        if(!tile || tile->isEmpty())
                            continue;

                        const Position& pos = tile->getPosition();
                        if(!pos.isValid())
                            continue;

                        if(pos.x < px || pos.x >= px + 256
                                || pos.y < py || pos.y >= py + 256
                                || pos.z != pz) {
                            if(!firstNode)
                                root->endNode(); /// OTBM_TILE_AREA

                            firstNode = false;
                            root->startNode(OTBM_TILE_AREA);

                            px = pos.x & 0xFF00;
                            py = pos.y & 0xFF00;
                            pz = pos.z;
                            root->addPos(Position(px, py, pz));
                        }

                        root->startNode(tile->isHouseTile() ? OTBM_HOUSETILE : OTBM_TILE);
                        root->addPoint(Point(pos.x, pos.y) & 0xFF);
                        if(tile->isHouseTile())
                            root->addU32(tile->getHouseId());

                        if(tile->getFlags()) {
                            root->addU8(OTBM_ATTR_TILE_FLAGS);
                            root->addU32(tile->getFlags());
                        }

                        const auto& itemList = tile->getItems();
                        const ItemPtr& ground = tile->getGround();
                        if(ground) {
                            // Those types are called "complex" needs other stuff to be written.
                            // For containers, there is container items, for depot, depot it and so on.
                            if(!ground->isContainer() && !ground->isDepot()
                                    && !ground->isDoor() && !ground->isTeleport()) {
                                root->addU8(OTBM_ATTR_ITEM);
                                root->addU16(ground->getServerId());
                            } else
                                ground->serializeItem(root);
                        }
                        for(const ItemPtr& item : itemList)
                            if(!item->isGround())
                                item->serializeItem(root);

                        root->endNode(); // OTBM_TILE
                    }
                }
            }

            if(!firstNode)
                root->endNode();  // OTBM_TILE_AREA

            root->startNode(OTBM_TOWNS);
            for(const TownPtr& town : g_towns.getTowns()) {
                root->addU32(town->getId());
                root->addString(town->getName());
                root->addPos(town->getPos());
            }
            root->endNode();

            if(version > 1) {
                root->startNode(OTBM_WAYPOINTS);
                for(const auto& it : m_waypoints) {
                    root->addString(it.second);
                    root->addPos(it.first);
                }
                root->endNode();
            }
        }
        root->endNode(); // OTBM_MAP_DATA
    }
    root->endNode();

    fin->flush();
    fin->close();
}