<commit_before>#include "testfunctions.h"
#include <include/amici_hdf5.h>
#include "include/amici_interface_cpp.h"
#include <cstring>
#include <execinfo.h>
#include <cstdio>
#include <cmath>
#include <unistd.h>

ExpData *getTestExpData(const UserData *udata) {
    ExpData *edata = new ExpData(udata);
    return edata;
}

bool withinTolerance(double expected, double actual, double atol, double rtol, int index) {
    bool withinTol =  fabs(expected - actual) <= atol || fabs((expected - actual) / (rtol + expected)) <= rtol;

    if(!withinTol) {
        fprintf(stderr, "ERROR: Expected value %e, but was %e at index %d.\n",expected, actual, index);
        fprintf(stderr, "       Relative error: %e (tolerance was %e)\n", fabs((expected - actual) / (rtol + expected)), rtol);
        fprintf(stderr, "       Absolute error: %e (tolerance was %e)\n", fabs(expected - actual), atol);
        printBacktrace(12);
    }

    return withinTol;
}

void checkEqualArray(const double *expected, const double *actual, int length, double atol, double rtol) {
    for(int i = 0; i < length; ++i)
    {
        bool withinTol = withinTolerance(expected[i], actual[i], atol, rtol, i);
        CHECK_TRUE(withinTol);
    }
}

void checkEqualArrayStrided(const double *expected, const double *actual, int length, int strideExpected, int strideActual, double atol, double rtol) {
    for(int i = 0; i < length; ++i)
    {
        bool withinTol = withinTolerance(expected[i * strideExpected], actual[i * strideActual], atol, rtol, i);
        CHECK_TRUE(withinTol);
    }
}

void verifyReturnData(const char* resultPath, const ReturnData *rdata, const UserData *udata, double atol, double rtol) {
    CHECK_FALSE(udata == NULL);
    CHECK_FALSE(rdata == NULL);

    // compare to saved data in hdf file
    hid_t file_id = H5Fopen(HDFFILE, H5F_ACC_RDONLY, H5P_DEFAULT);

    hsize_t m, n, o;
    double *expected;

    double llhExp = AMI_HDF5_getDoubleScalarAttribute(file_id, resultPath, "llh");
    // TODO: ignores Inf and NaN results; need to check with format in HDF5
    if(! std::isinf(*rdata->llh) || std::isnan(*rdata->llh))
        CHECK_TRUE(withinTolerance(llhExp, *rdata->llh, atol, rtol, 1));

    AMI_HDF5_getDoubleArrayAttribute2D(file_id, resultPath, "x", &expected, &m, &n);
    checkEqualArray(expected, rdata->x, udata->nt * udata->nxtrue, atol, rtol);
    delete[] expected;

//    CHECK_EQUAL(AMICI_O2MODE_FULL, udata->o2mode);

    if(AMI_HDF5_attributeExists(file_id, resultPath, "J")) {
        AMI_HDF5_getDoubleArrayAttribute2D(file_id, resultPath, "J", &expected, &m, &n);
        checkEqualArray(expected, rdata->J, udata->nx * udata->nx, atol, rtol);
        delete[] expected;
    }

    AMI_HDF5_getDoubleArrayAttribute2D(file_id, resultPath, "y", &expected, &m, &n);
    checkEqualArray(expected, rdata->y, udata->nt * udata->nytrue, atol, rtol);
    delete[] expected;

    if(udata->nz>0) {
        AMI_HDF5_getDoubleArrayAttribute2D(file_id, resultPath, "z", &expected, &m, &n);
        checkEqualArray(expected, rdata->z, udata->nmaxevent * udata->nztrue, atol, rtol);
        delete[] expected;

        AMI_HDF5_getDoubleArrayAttribute2D(file_id, resultPath, "rz", &expected, &m, &n);
        checkEqualArray(expected, rdata->rz, udata->nmaxevent * udata->nztrue, atol, rtol);
        delete[] expected;

        AMI_HDF5_getDoubleArrayAttribute2D(file_id, resultPath, "sigmaz", &expected, &m, &n);
        checkEqualArray(expected, rdata->sigmaz, udata->nmaxevent * udata->nztrue, atol, rtol);
        delete[] expected;
    }

    AMI_HDF5_getDoubleArrayAttribute2D(file_id, resultPath, "xdot", &expected, &m, &n);
    checkEqualArray(expected, rdata->xdot, udata->nxtrue, atol, rtol);
    delete[] expected;

    if(udata->sensi >= AMICI_SENSI_ORDER_FIRST) {
        verifyReturnDataSensitivities(file_id, resultPath, rdata, udata, atol, rtol);
    } else {
        POINTERS_EQUAL(NULL, rdata->sllh);
        POINTERS_EQUAL(NULL, rdata->s2llh);
    }

    H5Fclose(file_id);
}

void verifyReturnDataSensitivities(hid_t file_id, const char* resultPath, const ReturnData *rdata, const UserData*udata, double atol, double rtol) {
    hsize_t m, n, o;
    double *expected;

    AMI_HDF5_getDoubleArrayAttribute2D(file_id, resultPath, "sllh", &expected, &m, &n);
    checkEqualArray(expected, rdata->sllh, udata->np, atol, rtol);
    delete[] expected;

    if(udata->sensi_meth == AMICI_SENSI_FSA) {
        AMI_HDF5_getDoubleArrayAttribute3D(file_id, resultPath, "sx", &expected, &m, &n, &o);
        for(int ip = 0; ip < udata->nplist; ++ip)
            checkEqualArray(&expected[ip * udata->nt * udata->nxtrue],
                    &rdata->sx[ip * udata->nt * udata->nx],
                    udata->nt * udata->nxtrue, atol, rtol);
        delete[] expected;

        AMI_HDF5_getDoubleArrayAttribute3D(file_id, resultPath, "sy", &expected, &m, &n, &o);
        for(int ip = 0; ip < udata->nplist; ++ip)
            checkEqualArray(&expected[ip * udata->nt * udata->nytrue],
                    &rdata->sy[ip * udata->nt * udata->ny],
                    udata->nt * udata->nytrue, atol, rtol);
        delete[] expected;

        if(udata->nz>0) {
            AMI_HDF5_getDoubleArrayAttribute3D(file_id, resultPath, "sz", &expected, &m, &n, &o);
            for(int ip = 0; ip < udata->nplist; ++ip)
                checkEqualArray(&expected[ip * udata->nmaxevent * udata->nztrue],
                                &rdata->sz[ip * udata->nmaxevent * udata->nz],
                                udata->nmaxevent * udata->nztrue, atol, rtol);
            delete[] expected;

            AMI_HDF5_getDoubleArrayAttribute3D(file_id, resultPath, "srz", &expected, &m, &n, &o);
            for(int ip = 0; ip < udata->nplist; ++ip)
                checkEqualArray(&expected[ip * udata->nmaxevent * udata->nztrue],
                                &rdata->srz[ip * udata->nmaxevent * udata->nz],
                                udata->nmaxevent * udata->nztrue, atol, rtol);
            delete[] expected;
        }
    }

    AMI_HDF5_getDoubleArrayAttribute3D(file_id, resultPath, "ssigmay", &expected, &m, &n, &o);
    for(int ip = 0; ip < udata->nplist; ++ip)
        checkEqualArray(&expected[ip * udata->nt * udata->nytrue],
                &rdata->ssigmay[ip * udata->nt * udata->ny],
                udata->nt * udata->nytrue, atol, rtol);
    delete[] expected;

    if(udata->nz>0) {
        AMI_HDF5_getDoubleArrayAttribute3D(file_id, resultPath, "ssigmaz", &expected, &m, &n, &o);
        for(int ip = 0; ip < udata->nplist; ++ip)
            checkEqualArray(&expected[ip * udata->nmaxevent * udata->nztrue],
                            &rdata->ssigmaz[ip * udata->nmaxevent * udata->nz],
                            udata->nmaxevent * udata->nztrue, atol, rtol);
        delete[] expected;
    }

    if(udata->sensi >= AMICI_SENSI_ORDER_SECOND) {
        AMI_HDF5_getDoubleArrayAttribute2D(file_id, resultPath, "s2llh", &expected, &m, &n);
        checkEqualArray(expected, rdata->s2llh, (udata->nJ-1) * udata->nplist, atol, rtol);
        delete[] expected;
    } else {
        POINTERS_EQUAL(NULL, rdata->s2llh);
        POINTERS_EQUAL(NULL, rdata->s2rz);
    }

}

void printBacktrace(int depth) {
    void *array[depth];
    size_t size;
    size = backtrace(array, depth);
    backtrace_symbols_fd(array, size, STDERR_FILENO);
}
<commit_msg>Properly compare Inf and NaN<commit_after>#include "testfunctions.h"
#include <include/amici_hdf5.h>
#include "include/amici_interface_cpp.h"
#include <cstring>
#include <execinfo.h>
#include <cstdio>
#include <cmath>
#include <unistd.h>

ExpData *getTestExpData(const UserData *udata) {
    ExpData *edata = new ExpData(udata);
    return edata;
}

bool withinTolerance(double expected, double actual, double atol, double rtol, int index) {
    bool withinTol =  fabs(expected - actual) <= atol || fabs((expected - actual) / (rtol + expected)) <= rtol;

    if(!withinTol && std::isnan(expected) && std::isnan(actual))
        withinTol = true;

    if(!withinTol && std::isinf(expected) && std::isinf(actual))
        withinTol = true;

    if(!withinTol) {
        fprintf(stderr, "ERROR: Expected value %e, but was %e at index %d.\n",expected, actual, index);
        fprintf(stderr, "       Relative error: %e (tolerance was %e)\n", fabs((expected - actual) / (rtol + expected)), rtol);
        fprintf(stderr, "       Absolute error: %e (tolerance was %e)\n", fabs(expected - actual), atol);
        printBacktrace(12);
    }

    return withinTol;
}

void checkEqualArray(const double *expected, const double *actual, int length, double atol, double rtol) {
    for(int i = 0; i < length; ++i)
    {
        bool withinTol = withinTolerance(expected[i], actual[i], atol, rtol, i);
        CHECK_TRUE(withinTol);
    }
}

void checkEqualArrayStrided(const double *expected, const double *actual, int length, int strideExpected, int strideActual, double atol, double rtol) {
    for(int i = 0; i < length; ++i)
    {
        bool withinTol = withinTolerance(expected[i * strideExpected], actual[i * strideActual], atol, rtol, i);
        CHECK_TRUE(withinTol);
    }
}

void verifyReturnData(const char* resultPath, const ReturnData *rdata, const UserData *udata, double atol, double rtol) {
    CHECK_FALSE(udata == NULL);
    CHECK_FALSE(rdata == NULL);

    // compare to saved data in hdf file
    hid_t file_id = H5Fopen(HDFFILE, H5F_ACC_RDONLY, H5P_DEFAULT);

    hsize_t m, n, o;
    double *expected;

    double llhExp = AMI_HDF5_getDoubleScalarAttribute(file_id, resultPath, "llh");
    CHECK_TRUE(withinTolerance(llhExp, *rdata->llh, atol, rtol, 1));

    AMI_HDF5_getDoubleArrayAttribute2D(file_id, resultPath, "x", &expected, &m, &n);
    checkEqualArray(expected, rdata->x, udata->nt * udata->nxtrue, atol, rtol);
    delete[] expected;

//    CHECK_EQUAL(AMICI_O2MODE_FULL, udata->o2mode);

    if(AMI_HDF5_attributeExists(file_id, resultPath, "J")) {
        AMI_HDF5_getDoubleArrayAttribute2D(file_id, resultPath, "J", &expected, &m, &n);
        checkEqualArray(expected, rdata->J, udata->nx * udata->nx, atol, rtol);
        delete[] expected;
    }

    AMI_HDF5_getDoubleArrayAttribute2D(file_id, resultPath, "y", &expected, &m, &n);
    checkEqualArray(expected, rdata->y, udata->nt * udata->nytrue, atol, rtol);
    delete[] expected;

    if(udata->nz>0) {
        AMI_HDF5_getDoubleArrayAttribute2D(file_id, resultPath, "z", &expected, &m, &n);
        checkEqualArray(expected, rdata->z, udata->nmaxevent * udata->nztrue, atol, rtol);
        delete[] expected;

        AMI_HDF5_getDoubleArrayAttribute2D(file_id, resultPath, "rz", &expected, &m, &n);
        checkEqualArray(expected, rdata->rz, udata->nmaxevent * udata->nztrue, atol, rtol);
        delete[] expected;

        AMI_HDF5_getDoubleArrayAttribute2D(file_id, resultPath, "sigmaz", &expected, &m, &n);
        checkEqualArray(expected, rdata->sigmaz, udata->nmaxevent * udata->nztrue, atol, rtol);
        delete[] expected;
    }

    AMI_HDF5_getDoubleArrayAttribute2D(file_id, resultPath, "xdot", &expected, &m, &n);
    checkEqualArray(expected, rdata->xdot, udata->nxtrue, atol, rtol);
    delete[] expected;

    if(udata->sensi >= AMICI_SENSI_ORDER_FIRST) {
        verifyReturnDataSensitivities(file_id, resultPath, rdata, udata, atol, rtol);
    } else {
        POINTERS_EQUAL(NULL, rdata->sllh);
        POINTERS_EQUAL(NULL, rdata->s2llh);
    }

    H5Fclose(file_id);
}

void verifyReturnDataSensitivities(hid_t file_id, const char* resultPath, const ReturnData *rdata, const UserData*udata, double atol, double rtol) {
    hsize_t m, n, o;
    double *expected;

    AMI_HDF5_getDoubleArrayAttribute2D(file_id, resultPath, "sllh", &expected, &m, &n);
    checkEqualArray(expected, rdata->sllh, udata->np, atol, rtol);
    delete[] expected;

    if(udata->sensi_meth == AMICI_SENSI_FSA) {
        AMI_HDF5_getDoubleArrayAttribute3D(file_id, resultPath, "sx", &expected, &m, &n, &o);
        for(int ip = 0; ip < udata->nplist; ++ip)
            checkEqualArray(&expected[ip * udata->nt * udata->nxtrue],
                    &rdata->sx[ip * udata->nt * udata->nx],
                    udata->nt * udata->nxtrue, atol, rtol);
        delete[] expected;

        AMI_HDF5_getDoubleArrayAttribute3D(file_id, resultPath, "sy", &expected, &m, &n, &o);
        for(int ip = 0; ip < udata->nplist; ++ip)
            checkEqualArray(&expected[ip * udata->nt * udata->nytrue],
                    &rdata->sy[ip * udata->nt * udata->ny],
                    udata->nt * udata->nytrue, atol, rtol);
        delete[] expected;

        if(udata->nz>0) {
            AMI_HDF5_getDoubleArrayAttribute3D(file_id, resultPath, "sz", &expected, &m, &n, &o);
            for(int ip = 0; ip < udata->nplist; ++ip)
                checkEqualArray(&expected[ip * udata->nmaxevent * udata->nztrue],
                                &rdata->sz[ip * udata->nmaxevent * udata->nz],
                                udata->nmaxevent * udata->nztrue, atol, rtol);
            delete[] expected;

            AMI_HDF5_getDoubleArrayAttribute3D(file_id, resultPath, "srz", &expected, &m, &n, &o);
            for(int ip = 0; ip < udata->nplist; ++ip)
                checkEqualArray(&expected[ip * udata->nmaxevent * udata->nztrue],
                                &rdata->srz[ip * udata->nmaxevent * udata->nz],
                                udata->nmaxevent * udata->nztrue, atol, rtol);
            delete[] expected;
        }
    }

    AMI_HDF5_getDoubleArrayAttribute3D(file_id, resultPath, "ssigmay", &expected, &m, &n, &o);
    for(int ip = 0; ip < udata->nplist; ++ip)
        checkEqualArray(&expected[ip * udata->nt * udata->nytrue],
                &rdata->ssigmay[ip * udata->nt * udata->ny],
                udata->nt * udata->nytrue, atol, rtol);
    delete[] expected;

    if(udata->nz>0) {
        AMI_HDF5_getDoubleArrayAttribute3D(file_id, resultPath, "ssigmaz", &expected, &m, &n, &o);
        for(int ip = 0; ip < udata->nplist; ++ip)
            checkEqualArray(&expected[ip * udata->nmaxevent * udata->nztrue],
                            &rdata->ssigmaz[ip * udata->nmaxevent * udata->nz],
                            udata->nmaxevent * udata->nztrue, atol, rtol);
        delete[] expected;
    }

    if(udata->sensi >= AMICI_SENSI_ORDER_SECOND) {
        AMI_HDF5_getDoubleArrayAttribute2D(file_id, resultPath, "s2llh", &expected, &m, &n);
        checkEqualArray(expected, rdata->s2llh, (udata->nJ-1) * udata->nplist, atol, rtol);
        delete[] expected;
    } else {
        POINTERS_EQUAL(NULL, rdata->s2llh);
        POINTERS_EQUAL(NULL, rdata->s2rz);
    }

}

void printBacktrace(int depth) {
    void *array[depth];
    size_t size;
    size = backtrace(array, depth);
    backtrace_symbols_fd(array, size, STDERR_FILENO);
}
<|endoftext|>


<commit_before>#include "dfs.hh"
using namespace std;
using namespace eclipse;

namespace eclipse{
  void DFS::load_settings () {
    Context con;
    BLOCK_SIZE = con.settings.get<int>("filesystem.block");
    NUM_SERVERS = con.settings.get<vector<string>>("network.nodes").size();
    path = con.settings.get<string>("path.scratch");
    replica = con.settings.get<int>("filesystem.replica");
    port = con.settings.get<int> ("network.port_mapreduce");
    nodes = con.settings.get<vector<string>>("network.nodes");
  }

  unique_ptr<tcp::socket> DFS::connect (uint32_t hash_value) {
		auto socket = make_unique<tcp::socket>(iosvc);
    string host = nodes[ hash_value % nodes.size() ];
    tcp::resolver resolver (iosvc);
    tcp::resolver::query query (host, to_string(port));
    tcp::resolver::iterator it (resolver.resolve(query));
    auto ep = make_unique<tcp::endpoint>(*it);
    socket->connect(*ep);
    return socket;
  }

  void DFS::send_message (tcp::socket* socket, eclipse::messages::Message* msg) {
    string out = save_message(msg);
    stringstream ss;
    ss << setfill('0') << setw(16) << out.length() << out;

    socket->send(boost::asio::buffer(ss.str()));
  }

  template <typename T>
    unique_ptr<T> DFS::read_reply(tcp::socket* socket) {
      char header[17] = {0};
      header[16] = '\0';
      socket->receive(boost::asio::buffer(header, 16));
      size_t size_of_msg = atoi(header);
			vector<char> body(size_of_msg);
      socket->receive(boost::asio::buffer(body.data(), size_of_msg));
      string recv_msg(body.data(), size_of_msg);
      eclipse::messages::Message* m = load_message(recv_msg);
      return unique_ptr<T>(dynamic_cast<T*>(m));
    }

  int DFS::put(int argc, char* argv[])
  {
    Context con;
    if(argc < 3)
    {
      cout << "[INFO] dfs put file_1 file_2 ..." << endl;
      return -1;
    }
    else
    {
			vector<char> chunk(BLOCK_SIZE);
      Histogram boundaries(NUM_SERVERS, 0);
      boundaries.initialize();

      for(int i=2; i<argc; i++)
      {
        string file_name = argv[i];
        FileExist fe;
        fe.file_name = file_name;
        uint32_t file_hash_key = h(file_name);
        auto socket = connect(file_hash_key);
        send_message(socket.get(), &fe);
        auto rep = read_reply<Reply> (socket.get());

        if (rep->message == "TRUE")
        {
          cerr << "[ERR] " << file_name << " already exists." << endl;
          continue;
        }
        cout << "[INFO] " << argv[i] << " is uploaded." << endl;

        int which_server = rand()%NUM_SERVERS;
        ifstream myfile (file_name);
        uint64_t start = 0;
        uint64_t end = start + BLOCK_SIZE - 1;
        uint32_t block_size = 0;
        unsigned int block_seq = 0;

        FileInfo file_info;
        file_info.file_name = file_name;
        file_info.file_hash_key = file_hash_key;
        file_info.replica = replica;
        myfile.seekg(0, myfile.end);
        file_info.file_size = myfile.tellg();
        BlockInfo block_info;

        while(1)
        {
          if(end < file_info.file_size)
          {
            myfile.seekg(start+BLOCK_SIZE-1, myfile.beg);
            while(1)
            {
              if(myfile.peek() =='\n')
              {
                break;
              }
              else
              {
                myfile.seekg(-1, myfile.cur);
                end--;
              }
            }
          }
          block_size = (uint32_t) end - start;
          bzero(chunk.data(), BLOCK_SIZE);
          myfile.seekg(start, myfile.beg);
          block_info.content.reserve(block_size);
          myfile.read(chunk.data(), block_size);
          block_info.content = chunk.data();

          block_info.block_name = file_name + "_" + to_string(block_seq);
          block_info.file_name = file_name;
          block_info.block_seq = block_seq++;
          block_info.block_hash_key = boundaries.random_within_boundaries(which_server);
          block_info.block_size = block_size;
          block_info.is_inter = 0;
          block_info.node = "1.1.1.1";
          block_info.l_node = "1.1.1.0";
          block_info.r_node = "1.1.1.2";
          block_info.is_committed = 1;
          //block_info.node = remote_server.ip_address;
          //Node l_node = lookup((block_hash_key-1+NUM_SERVERS)%NUM_SERVERS);
          //Node r_node = lookup((block_hash_key+1+NUM_SERVERS)%NUM_SERVERS);
          //block_info.l_node = l_node.ip_address;
          //block_info.r_node = r_node.ip_address;

          send_message(socket.get(), &block_info);
          auto reply = read_reply<Reply> (socket.get());

          if (reply->message != "OK") {
            cerr << "[ERR] Failed to upload file. Details: " << reply->details << endl;
            return EXIT_FAILURE;
          }

          if(end >= file_info.file_size)
          {
            break;
          }
          start = end;
          end = start + BLOCK_SIZE - 1;
          which_server = (which_server + 1) % NUM_SERVERS;
        }

        file_info.num_block = block_seq;
        send_message(socket.get(), &file_info);
        auto reply = read_reply<Reply> (socket.get());

        if (reply->message != "OK") {
          cerr << "[ERR] Failed to upload file. Details: " << reply->details << endl;
          return EXIT_FAILURE;
        }
        myfile.close();
      }
    }
    return 0;
  }

  int DFS::get(int argc, char* argv[])
  {
    if (argc < 3) {
      cout << "[INFO] dfs get file_1 file_2 ..." << endl;
      return -1;

    } else {
      Histogram boundaries(NUM_SERVERS, 0);
      boundaries.initialize();

      for (int i=2; i<argc; i++) {
        string file_name = argv[i];
        uint32_t file_hash_key = h(file_name);
        auto socket = connect (file_hash_key % NUM_SERVERS);
        FileRequest fr;
        fr.file_name = file_name;

        send_message (socket.get(), &fr);
        auto fd = read_reply<FileDescription> (socket.get());

        ofstream f (file_name);
        int block_seq = 0;
        for (auto block_name : fd->blocks) {
          uint32_t hash_key = fd->hash_keys[block_seq++];
          auto tmp_socket = connect(boundaries.get_index(hash_key));
          BlockRequest br;
          br.block_name = block_name;
          br.hash_key   = hash_key;
          send_message(tmp_socket.get(), &br);
          auto msg = read_reply<BlockInfo>(tmp_socket.get());
          f << msg->content;
        }

        cout << "[INFO] " << file_name << " is downloaded." << endl;
        f.close();
      }
    }
    return 0;
  }

  int DFS::ls(int argc, char* argv[])
  {
    vector<FileInfo> total;

    for(unsigned int net_id=0; net_id<NUM_SERVERS; net_id++)
    {
      FileList file_list;
      auto socket = connect(net_id);
      send_message(socket.get(), &file_list);
      auto file_list_reply = read_reply<FileList>(socket.get());

      std::copy(file_list_reply->data.begin(), file_list_reply->data.end(), back_inserter(total));
    }

    std::sort(total.begin(), total.end(), [] (const FileInfo& a, const FileInfo& b) {
        return (a.file_name < b.file_name);
        });

    cout
      << setw(25) << "FileName"
      << setw(14) << "Hash Key"
      << setw(14) << "Size"
      << setw(8)  << "Blocks"
      << setw(14) << "Host"
      << setw(5)  << "Repl"
      << endl << string(80,'-') << endl;

    for (auto& fl: total) {
      cout
        << setw(25) << fl.file_name
        << setw(14) << fl.file_hash_key
        << setw(14) << fl.file_size
        << setw(8) << fl.num_block
        << setw(14) << nodes[h(fl.file_name) % NUM_SERVERS]
        << setw(5) << fl.replica
        << endl;
    }
    return 0;
  }

  int DFS::rm(int argc, char* argv[])
  {
    if(argc < 3)
    {
      cout << "[INFO] dfs rm file_1 file_2 ..." << endl;
      return -1;
    }
    else
    {
      Histogram boundaries(NUM_SERVERS, 0);
      boundaries.initialize();

      for(int i=2; i<argc; i++)
      {
        string file_name = argv[i];
        uint32_t file_hash_key = h(file_name);
        auto socket = connect(file_hash_key);
        FileRequest fr;
        fr.file_name = file_name;

        send_message(socket.get(), &fr);
        auto fd = read_reply<FileDescription>(socket.get());

        unsigned int block_seq = 0;
        for (auto block_name : fd->blocks) {
          auto tmp_socket = connect(boundaries.get_index(fd->hash_keys[block_seq]));
          BlockDel bd;
          bd.block_name = block_name;
          bd.file_name = file_name;
          bd.block_seq = block_seq++;
          send_message(tmp_socket.get(), &bd);
          auto msg = read_reply<Reply>(tmp_socket.get());
          if (msg->message != "OK") {
            cerr << "[ERR] " << block_name << "doesn't exist." << endl;
            return EXIT_FAILURE;
          }

        }

        FileDel file_del;
        file_del.file_name = file_name;
        socket = connect(file_hash_key);
        send_message(socket.get(), &file_del);
        auto reply = read_reply<Reply>(socket.get());
        if (reply->message != "OK") {
          cerr << "[ERR] " << file_name << " doesn't exist." << endl;
          return EXIT_FAILURE;
        }
        cout << "[INFO] " << file_name << " is removed." << endl;
      }
      return 0;
    }
  }

  int DFS::format(int argc, char* argv[]) {
    vector<FileInfo> total;

    for (unsigned int net_id = 0; net_id < NUM_SERVERS; net_id++) {
      FormatRequest fr;
      auto socket = connect(net_id);
      send_message(socket.get(), &fr);
      auto reply = read_reply<Reply>(socket.get());

      if (reply->message != "OK") {
        cerr << "[ERR] Failed to upload file. Details: " << reply->details << endl;
        return -1;
      }

    }
    cout << "[INFO] dfs format is done." << endl;
    return 0;
  }
}
<commit_msg>Fixed dfsget<commit_after>#include "dfs.hh"
using namespace std;
using namespace eclipse;

namespace eclipse{
  void DFS::load_settings () {
    Context con;
    BLOCK_SIZE = con.settings.get<int>("filesystem.block");
    NUM_SERVERS = con.settings.get<vector<string>>("network.nodes").size();
    path = con.settings.get<string>("path.scratch");
    replica = con.settings.get<int>("filesystem.replica");
    port = con.settings.get<int> ("network.port_mapreduce");
    nodes = con.settings.get<vector<string>>("network.nodes");
  }

  unique_ptr<tcp::socket> DFS::connect (uint32_t hash_value) {
		auto socket = make_unique<tcp::socket>(iosvc);
    string host = nodes[ hash_value % nodes.size() ];
    tcp::resolver resolver (iosvc);
    tcp::resolver::query query (host, to_string(port));
    tcp::resolver::iterator it (resolver.resolve(query));
    auto ep = make_unique<tcp::endpoint>(*it);
    socket->connect(*ep);
    return socket;
  }

  void DFS::send_message (tcp::socket* socket, eclipse::messages::Message* msg) {
    string out = save_message(msg);
    stringstream ss;
    ss << setfill('0') << setw(16) << out.length() << out;

    socket->send(boost::asio::buffer(ss.str()));
  }

  template <typename T>
    unique_ptr<T> DFS::read_reply(tcp::socket* socket) {
      using namespace boost::asio;
      char header[17] = {0};
      header[16] = '\0';
      socket->receive(boost::asio::buffer(header, 16));
      size_t size_of_msg = atoi(header);
      char* body = new char[size_of_msg];

//      size_t current_size = 0;
 //     while (current_size < size_of_msg) {
  //      current_size += socket->receive(boost::asio::buffer(&body[current_size], size_of_msg - current_size));
   //   }
      boost::system::error_code ec;
      read(*socket, buffer(body, size_of_msg), transfer_exactly(size_of_msg), ec);

      string recv_msg(body);
      delete[] body;
      eclipse::messages::Message* m = load_message(recv_msg);
      return unique_ptr<T>(dynamic_cast<T*>(m));
    }

  int DFS::put(int argc, char* argv[])
  {
    Context con;
    if(argc < 3)
    {
      cout << "[INFO] dfs put file_1 file_2 ..." << endl;
      return -1;
    }
    else
    {
			vector<char> chunk(BLOCK_SIZE);
      Histogram boundaries(NUM_SERVERS, 0);
      boundaries.initialize();

      for(int i=2; i<argc; i++)
      {
        string file_name = argv[i];
        FileExist fe;
        fe.file_name = file_name;
        uint32_t file_hash_key = h(file_name);
        auto socket = connect(file_hash_key);
        send_message(socket.get(), &fe);
        auto rep = read_reply<Reply> (socket.get());

        if (rep->message == "TRUE")
        {
          cerr << "[ERR] " << file_name << " already exists." << endl;
          continue;
        }
        cout << "[INFO] " << argv[i] << " is uploaded." << endl;

        int which_server = rand()%NUM_SERVERS;
        ifstream myfile (file_name);
        uint64_t start = 0;
        uint64_t end = start + BLOCK_SIZE - 1;
        uint32_t block_size = 0;
        unsigned int block_seq = 0;

        FileInfo file_info;
        file_info.file_name = file_name;
        file_info.file_hash_key = file_hash_key;
        file_info.replica = replica;
        myfile.seekg(0, myfile.end);
        file_info.file_size = myfile.tellg();
        BlockInfo block_info;

        while(1)
        {
          if(end < file_info.file_size)
          {
            myfile.seekg(start+BLOCK_SIZE-1, myfile.beg);
            while(1)
            {
              if(myfile.peek() =='\n')
              {
                break;
              }
              else
              {
                myfile.seekg(-1, myfile.cur);
                end--;
              }
            }
          }
          block_size = (uint32_t) end - start;
          bzero(chunk.data(), BLOCK_SIZE);
          myfile.seekg(start, myfile.beg);
          block_info.content.reserve(block_size);
          myfile.read(chunk.data(), block_size);
          block_info.content = chunk.data();

          block_info.block_name = file_name + "_" + to_string(block_seq);
          block_info.file_name = file_name;
          block_info.block_seq = block_seq++;
          block_info.block_hash_key = boundaries.random_within_boundaries(which_server);
          block_info.block_size = block_size;
          block_info.is_inter = 0;
          block_info.node = "1.1.1.1";
          block_info.l_node = "1.1.1.0";
          block_info.r_node = "1.1.1.2";
          block_info.is_committed = 1;
          //block_info.node = remote_server.ip_address;
          //Node l_node = lookup((block_hash_key-1+NUM_SERVERS)%NUM_SERVERS);
          //Node r_node = lookup((block_hash_key+1+NUM_SERVERS)%NUM_SERVERS);
          //block_info.l_node = l_node.ip_address;
          //block_info.r_node = r_node.ip_address;

          send_message(socket.get(), &block_info);
          auto reply = read_reply<Reply> (socket.get());

          if (reply->message != "OK") {
            cerr << "[ERR] Failed to upload file. Details: " << reply->details << endl;
            return EXIT_FAILURE;
          }

          if(end >= file_info.file_size)
          {
            break;
          }
          start = end;
          end = start + BLOCK_SIZE - 1;
          which_server = (which_server + 1) % NUM_SERVERS;
        }

        file_info.num_block = block_seq;
        send_message(socket.get(), &file_info);
        auto reply = read_reply<Reply> (socket.get());

        if (reply->message != "OK") {
          cerr << "[ERR] Failed to upload file. Details: " << reply->details << endl;
          return EXIT_FAILURE;
        }
        myfile.close();
      }
    }
    return 0;
  }

  int DFS::get(int argc, char* argv[])
  {
    if (argc < 3) {
      cout << "[INFO] dfs get file_1 file_2 ..." << endl;
      return -1;

    } else {
      Histogram boundaries(NUM_SERVERS, 0);
      boundaries.initialize();

      for (int i=2; i<argc; i++) {
        string file_name = argv[i];
        uint32_t file_hash_key = h(file_name);
        auto socket = connect (file_hash_key % NUM_SERVERS);
        FileRequest fr;
        fr.file_name = file_name;

        send_message (socket.get(), &fr);
        auto fd = read_reply<FileDescription> (socket.get());

        ofstream f (file_name);
        int block_seq = 0;
        for (auto block_name : fd->blocks) {
          uint32_t hash_key = fd->hash_keys[block_seq++];
          auto tmp_socket = connect(boundaries.get_index(hash_key));
          BlockRequest br;
          br.block_name = block_name;
          br.hash_key   = hash_key;
          send_message(tmp_socket.get(), &br);
          auto msg = read_reply<BlockInfo>(tmp_socket.get());
          f << msg->content;
        }

        cout << "[INFO] " << file_name << " is downloaded." << endl;
        f.close();
      }
    }
    return 0;
  }

  int DFS::ls(int argc, char* argv[])
  {
    vector<FileInfo> total;

    for(unsigned int net_id=0; net_id<NUM_SERVERS; net_id++)
    {
      FileList file_list;
      auto socket = connect(net_id);
      send_message(socket.get(), &file_list);
      auto file_list_reply = read_reply<FileList>(socket.get());

      std::copy(file_list_reply->data.begin(), file_list_reply->data.end(), back_inserter(total));
    }

    std::sort(total.begin(), total.end(), [] (const FileInfo& a, const FileInfo& b) {
        return (a.file_name < b.file_name);
        });

    cout
      << setw(25) << "FileName"
      << setw(14) << "Hash Key"
      << setw(14) << "Size"
      << setw(8)  << "Blocks"
      << setw(14) << "Host"
      << setw(5)  << "Repl"
      << endl << string(80,'-') << endl;

    for (auto& fl: total) {
      cout
        << setw(25) << fl.file_name
        << setw(14) << fl.file_hash_key
        << setw(14) << fl.file_size
        << setw(8) << fl.num_block
        << setw(14) << nodes[h(fl.file_name) % NUM_SERVERS]
        << setw(5) << fl.replica
        << endl;
    }
    return 0;
  }

  int DFS::rm(int argc, char* argv[])
  {
    if(argc < 3)
    {
      cout << "[INFO] dfs rm file_1 file_2 ..." << endl;
      return -1;
    }
    else
    {
      Histogram boundaries(NUM_SERVERS, 0);
      boundaries.initialize();

      for(int i=2; i<argc; i++)
      {
        string file_name = argv[i];
        uint32_t file_hash_key = h(file_name);
        auto socket = connect(file_hash_key);
        FileRequest fr;
        fr.file_name = file_name;

        send_message(socket.get(), &fr);
        auto fd = read_reply<FileDescription>(socket.get());

        unsigned int block_seq = 0;
        for (auto block_name : fd->blocks) {
          auto tmp_socket = connect(boundaries.get_index(fd->hash_keys[block_seq]));
          BlockDel bd;
          bd.block_name = block_name;
          bd.file_name = file_name;
          bd.block_seq = block_seq++;
          send_message(tmp_socket.get(), &bd);
          auto msg = read_reply<Reply>(tmp_socket.get());
          if (msg->message != "OK") {
            cerr << "[ERR] " << block_name << "doesn't exist." << endl;
            return EXIT_FAILURE;
          }

        }

        FileDel file_del;
        file_del.file_name = file_name;
        socket = connect(file_hash_key);
        send_message(socket.get(), &file_del);
        auto reply = read_reply<Reply>(socket.get());
        if (reply->message != "OK") {
          cerr << "[ERR] " << file_name << " doesn't exist." << endl;
          return EXIT_FAILURE;
        }
        cout << "[INFO] " << file_name << " is removed." << endl;
      }
      return 0;
    }
  }

  int DFS::format(int argc, char* argv[]) {
    vector<FileInfo> total;

    for (unsigned int net_id = 0; net_id < NUM_SERVERS; net_id++) {
      FormatRequest fr;
      auto socket = connect(net_id);
      send_message(socket.get(), &fr);
      auto reply = read_reply<Reply>(socket.get());

      if (reply->message != "OK") {
        cerr << "[ERR] Failed to upload file. Details: " << reply->details << endl;
        return -1;
      }

    }
    cout << "[INFO] dfs format is done." << endl;
    return 0;
  }
}
<|endoftext|>


<commit_before>/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                        Intel License Agreement
//                For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//   * The name of Intel Corporation may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/

#include <iostream>
#include <string>
#include <iosfwd>
#include "gputest.hpp"
using namespace cv;
using namespace cv::gpu;
using namespace std;

struct CV_GpuMeanShiftSegmentationTest : public CvTest {
    CV_GpuMeanShiftSegmentationTest() : CvTest( "GPU-MeanShiftSegmentation", "MeanShiftSegmentation" ) {}

    void run(int)
    {
        try
        {
            Mat img_rgb = imread(string(ts->get_data_path()) + "meanshift/cones.png");
            if (img_rgb.empty())
            {
                ts->set_failed_test_info(CvTS::FAIL_MISSING_TEST_DATA);
                return;
            }

            Mat img;
            cvtColor(img_rgb, img, CV_BGR2BGRA);

            for (int minsize = 0; minsize < 2000; minsize = (minsize + 1) * 4)
            {
                stringstream path;
                path << ts->get_data_path() << "meanshift/cones_segmented_sp10_sr10_minsize" << minsize;
                if (TargetArchs::builtWith(COMPUTE_20) && DeviceInfo().supports(COMPUTE_20))
                    path << ".png";
                else
                    path << "_CC1X.png";

                Mat dst;
                meanShiftSegmentation((GpuMat)img, dst, 10, 10, minsize);
                Mat dst_rgb;
                cvtColor(dst, dst_rgb, CV_BGRA2BGR);

                //imwrite(path.str(), dst_rgb);
                Mat dst_ref = imread(path.str());
                if (dst_ref.empty())
                {
                    ts->set_failed_test_info(CvTS::FAIL_MISSING_TEST_DATA);
                    return;
                }
                if (abs(cv::norm(dst_rgb - dst_ref, NORM_INF)) > 1e-3)
                {
                    ts->printf(CvTS::LOG, "\ndiffers from image *minsize%d.png\n", minsize);
                    ts->set_failed_test_info(CvTS::FAIL_BAD_ACCURACY);
                    return;
                }
            }
        }
        catch (const cv::Exception& e)
        {
            if (!check_and_treat_gpu_exception(e, ts))
                throw;
            return;
        }

        ts->set_failed_test_info(CvTS::OK);
    }
} ms_segm_test;
<commit_msg>fixed GPU meanshift segmentation test under Ubuntu<commit_after>/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                        Intel License Agreement
//                For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//   * The name of Intel Corporation may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/

#include <iostream>
#include <string>
#include <iosfwd>
#include "gputest.hpp"
using namespace cv;
using namespace cv::gpu;
using namespace std;

struct CV_GpuMeanShiftSegmentationTest : public CvTest {
    CV_GpuMeanShiftSegmentationTest() : CvTest( "GPU-MeanShiftSegmentation", "MeanShiftSegmentation" ) {}

    void run(int)
    {
        try
        {
            Mat img_rgb = imread(string(ts->get_data_path()) + "meanshift/cones.png");
            if (img_rgb.empty())
            {
                ts->set_failed_test_info(CvTS::FAIL_MISSING_TEST_DATA);
                return;
            }

            Mat img;
            cvtColor(img_rgb, img, CV_BGR2BGRA);

            for (int minsize = 0; minsize < 2000; minsize = (minsize + 1) * 4)
            {
                stringstream path;
                path << ts->get_data_path() << "meanshift/cones_segmented_sp10_sr10_minsize" << minsize;
                if (TargetArchs::builtWith(COMPUTE_20) && DeviceInfo().supports(COMPUTE_20))
                    path << ".png";
                else
                    path << "_CC1X.png";

                Mat dst;
                meanShiftSegmentation((GpuMat)img, dst, 10, 10, minsize);
                Mat dst_rgb;
                cvtColor(dst, dst_rgb, CV_BGRA2BGR);

                //imwrite(path.str(), dst_rgb);
                Mat dst_ref = imread(path.str());
                if (dst_ref.empty())
                {
                    ts->set_failed_test_info(CvTS::FAIL_MISSING_TEST_DATA);
                    return;
                }
                if (CheckSimilarity(dst_rgb, dst_ref, 1e-3f) != CvTS::OK)
                {
                    ts->printf(CvTS::LOG, "\ndiffers from image *minsize%d.png\n", minsize);
                    ts->set_failed_test_info(CvTS::FAIL_BAD_ACCURACY);
                }
            }
        }
        catch (const cv::Exception& e)
        {
            if (!check_and_treat_gpu_exception(e, ts))
                throw;
            return;
        }

        ts->set_failed_test_info(CvTS::OK);
    }

    int CheckSimilarity(const Mat& m1, const Mat& m2, float max_err)
    {
        Mat diff;
        cv::matchTemplate(m1, m2, diff, CV_TM_CCORR_NORMED);

        float err = abs(diff.at<float>(0, 0) - 1.f);

        if (err > max_err)
            return CvTS::FAIL_INVALID_OUTPUT;

        return CvTS::OK;
    }

} ms_segm_test;
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "mapswidget.h"
#include "marker.h"

#include <QGraphicsSceneMouseEvent>
#include <QGraphicsSceneWheelEvent>
#include <QPropertyAnimation>
#include <QParallelAnimationGroup>
#include <QTimer>

#include "qgeocoordinate.h"

GeoMap::GeoMap(QGeoMappingManager *manager, MapsWidget *mapsWidget) :
    QGraphicsGeoMap(manager), mapsWidget(mapsWidget)
{
    this->setFocus();
}

GeoMap::~GeoMap()
{
}

double GeoMap::centerLatitude() const
{
    return center().latitude();
}

double GeoMap::centerLongitude() const
{
    return center().longitude();
}

void GeoMap::setCenterLatitude(double lat)
{
    QGeoCoordinate c = center();
    c.setLatitude(lat);
    setCenter(c);
}

void GeoMap::setCenterLongitude(double lon)
{
    QGeoCoordinate c = center();
    c.setLongitude(lon);
    setCenter(c);
}

void GeoMap::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    panActive = true;
    markerPressed = false;
    QList<QGeoMapObject*> objects = mapObjectsAtScreenPosition(event->pos());
    if (objects.size() > 0) {
        pressed = objects.first();
        markerPressed = true;
    }

    this->setFocus();
    event->accept();
}

void GeoMap::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
    panActive = false;

    if (markerPressed) {
        // check if we're still over the object
        QList<QGeoMapObject*> objects = mapObjectsAtScreenPosition(event->pos());
        if (objects.contains(pressed)) {
            Marker *m = dynamic_cast<Marker*>(pressed);
            if (m)
                emit clicked(m);
        }

        markerPressed = false;
    }

    this->setFocus();
    event->accept();
}

void GeoMap::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    if (panActive) {
        QPointF delta = event->lastPos() - event->pos();
        pan(delta.x(), delta.y());
        emit panned();
    }
    this->setFocus();
    event->accept();
}

void GeoMap::wheelEvent(QGraphicsSceneWheelEvent *event)
{
    // pan our current point to the centre, zoom, then pan back

    qreal panx = event->pos().x() - size().width() / 2.0;
    qreal pany = event->pos().y() - size().height() / 2.0;
    pan(panx, pany);
    if (event->delta() > 0) {   // zoom in
        if (zoomLevel() < maximumZoomLevel()) {
            setZoomLevel(zoomLevel() + 1);
        }
    } else {                    // zoom out
        if (zoomLevel() > minimumZoomLevel()) {
            setZoomLevel(zoomLevel() - 1);
        }
    }
    pan(-panx, -pany);
    this->setFocus();
    event->accept();
}

void GeoMap::keyPressEvent(QKeyEvent *event)
{
    QGeoCoordinate center;
    QPropertyAnimation *anim;
    const qreal width = size().width();
    const qreal height = size().height();

    switch (event->key()) {
    case Qt::Key_4:
    case Qt::Key_Left:
        center = screenPositionToCoordinate(
                    QPointF(width/2 - width/5, height/2));
        anim = new QPropertyAnimation(this, "centerLongitude");
        anim->setEndValue(center.longitude());
        anim->setDuration(200);
        anim->start(QAbstractAnimation::DeleteWhenStopped);
        break;
    case Qt::Key_6:
    case Qt::Key_Right:
        center = screenPositionToCoordinate(
                    QPointF(width/2 + width/5, height/2));
        anim = new QPropertyAnimation(this, "centerLongitude");
        anim->setEndValue(center.longitude());
        anim->setDuration(200);
        anim->start(QAbstractAnimation::DeleteWhenStopped);
        break;
    case Qt::Key_2:
    case Qt::Key_Up:
        center = screenPositionToCoordinate(
                    QPointF(width/2, height/2 - height/5));
        anim = new QPropertyAnimation(this, "centerLatitude");
        anim->setEndValue(center.latitude());
        anim->setDuration(200);
        anim->start(QAbstractAnimation::DeleteWhenStopped);
        break;
    case Qt::Key_8:
    case Qt::Key_Down:
        center = screenPositionToCoordinate(
                    QPointF(width/2, height/2 + height/5));
        anim = new QPropertyAnimation(this, "centerLatitude");
        anim->setEndValue(center.latitude());
        anim->setDuration(200);
        anim->start(QAbstractAnimation::DeleteWhenStopped);
        break;
    case Qt::Key_1:
        if (zoomLevel() > minimumZoomLevel()) {
            setZoomLevel(zoomLevel() - 1);
        }
        break;
    case Qt::Key_3:
        if (zoomLevel() < maximumZoomLevel()) {
            setZoomLevel(zoomLevel() + 1);
        }
        break;
    }
    this->setFocus();
    event->accept();
}

class ZoomButtonItemPrivate
{
public:
    GeoMap *map;

    QGraphicsSimpleTextItem *plusText;
    QGraphicsSimpleTextItem *minusText;

    bool pressedOverTopHalf;
    bool pressedOverBottomHalf;
};

ZoomButtonItem::ZoomButtonItem(GeoMap *map) :
    d(new ZoomButtonItemPrivate)
{
    d->map = map;
    d->pressedOverBottomHalf = false;
    d->pressedOverTopHalf = false;

    setPen(QPen(QBrush(), 0));
    setBrush(QBrush(QColor(0,0,0,150)));

    d->plusText = new QGraphicsSimpleTextItem(this);
    d->plusText->setText("+");
    d->plusText->setBrush(QBrush(Qt::white));

    d->minusText = new QGraphicsSimpleTextItem(this);
    d->minusText->setText("-");
    d->minusText->setBrush(QBrush(Qt::white));
}

void ZoomButtonItem::setRect(qreal x, qreal y, qreal w, qreal h)
{
    QGraphicsRectItem::setRect(x, y, w, h);

    QFont f;
    f.setFixedPitch(true);
    f.setPixelSize(h/3.0);
    d->plusText->setFont(f);
    d->minusText->setFont(f);

    QRectF plusBound = d->plusText->boundingRect();
    QPointF plusCenter(x+w/2.0, y+h/4.0);
    QPointF plusDelta = plusCenter - plusBound.center();
    d->plusText->setPos(plusDelta);

    QRectF minusBound = d->minusText->boundingRect();
    QPointF minusCenter(x+w/2.0, y+3.0*h/4.0);
    QPointF minusDelta = minusCenter - minusBound.center();
    d->minusText->setPos(minusDelta);
}

void ZoomButtonItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    const QPointF pos = event->pos();
    if (!d->pressedOverTopHalf && !d->pressedOverBottomHalf) {
        if (isTopHalf(pos)) {
            d->pressedOverTopHalf = true;
        } else if (isBottomHalf(pos)) {
            d->pressedOverBottomHalf = true;
        }
    }
    d->map->setFocus();
    event->accept();
}

bool ZoomButtonItem::isTopHalf(const QPointF &point)
{
    return QRectF(rect().x(), rect().y(),
                  rect().width(), rect().height()/2).contains(point);
}

bool ZoomButtonItem::isBottomHalf(const QPointF &point)
{
    return QRectF(rect().x(), rect().y() + rect().height()/2,
                  rect().width(), rect().height()/2).contains(point);
}

void ZoomButtonItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
    const QPointF pos = event->pos();
    if (isTopHalf(pos) && d->pressedOverTopHalf) {
        d->map->setZoomLevel(d->map->zoomLevel() + 1.0);
    } else if (isBottomHalf(pos) && d->pressedOverBottomHalf) {
        d->map->setZoomLevel(d->map->zoomLevel() - 1.0);
    }
    d->pressedOverBottomHalf = false;
    d->pressedOverTopHalf = false;
    d->map->setFocus();
    event->accept();
}

void ZoomButtonItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    event->accept();
}

class StatusBarItemPrivate
{
public:
    int offset;
    QGraphicsSimpleTextItem *textItem;
};

StatusBarItem::StatusBarItem() :
    d(new StatusBarItemPrivate)
{
    d->offset = 0;

    setPen(QPen(QBrush(), 0));
    setBrush(QBrush(QColor(0,0,0,120)));

    d->textItem = new QGraphicsSimpleTextItem(this);
    d->textItem->setBrush(QBrush(Qt::white));

    setText("");
}

StatusBarItem::~StatusBarItem()
{
}

void StatusBarItem::setText(QString text)
{
    d->textItem->setText(text);
    QRectF rect = d->textItem->boundingRect();
    QPointF delta = this->rect().center() - rect.center();
    d->textItem->setPos(delta.x(), delta.y());
}

int StatusBarItem::offset() const
{
    return d->offset;
}

void StatusBarItem::setRect(qreal x, qreal y, qreal w, qreal h)
{
    QGraphicsRectItem::setRect(x, y + d->offset, w, h);
    setText(d->textItem->text());
}

void StatusBarItem::setOffset(int offset)
{
    this->setY(this->y() - d->offset + offset);
    d->offset = offset;
}

void StatusBarItem::showText(QString text, quint32 timeout)
{
    setText(text);
    show();
    QTimer::singleShot(timeout, this, SLOT(hide()));
}

void StatusBarItem::show()
{
    QPropertyAnimation *anim = new QPropertyAnimation(this, "offset");
    anim->setStartValue(0);
    anim->setEndValue(-1 * rect().height());
    anim->setDuration(500);
    anim->start(QAbstractAnimation::DeleteWhenStopped);
}

void StatusBarItem::hide()
{
    QPropertyAnimation *anim = new QPropertyAnimation(this, "offset");
    anim->setStartValue(d->offset);
    anim->setEndValue(0);
    anim->setDuration(500);
    anim->start(QAbstractAnimation::DeleteWhenStopped);
}

FixedGraphicsView::FixedGraphicsView(QWidget *parent) :
    QGraphicsView(parent)
{
}

void FixedGraphicsView::scrollContentsBy(int dx, int dy)
{
    Q_UNUSED(dx)
    Q_UNUSED(dy)
}

class MapsWidgetPrivate
{
public:
    GeoMap *map;
    QGraphicsView *view;
    MarkerManager *markerManager;
    StatusBarItem *statusBarItem;
    ZoomButtonItem *zoomButtonItem;
};

MapsWidget::MapsWidget(QWidget *parent) :
    QWidget(parent),
    d(new MapsWidgetPrivate)
{
    d->map = 0;
    d->view = 0;
    d->markerManager = 0;
}

MapsWidget::~MapsWidget()
{
}

void MapsWidget::initialize(QGeoMappingManager *manager)
{
    d->map = new GeoMap(manager, this);
    if (d->markerManager)
        d->markerManager->setMap(d->map);

    connect(d->map, SIGNAL(clicked(Marker*)),
            this, SIGNAL(markerClicked(Marker*)));
    connect(d->map, SIGNAL(panned()),
            this, SIGNAL(mapPanned()));

    QGraphicsScene *sc = new QGraphicsScene;
    sc->addItem(d->map);

    d->map->setPos(0, 0);
    d->map->resize(this->size());
    d->view = new FixedGraphicsView(this);
    d->view->setVisible(true);
    d->view->setInteractive(true);
    d->view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    d->view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    d->view->setScene(sc);

    d->statusBarItem = new StatusBarItem;
    sc->addItem(d->statusBarItem);

    d->zoomButtonItem = new ZoomButtonItem(d->map);
    sc->addItem(d->zoomButtonItem);

    d->view->resize(this->size());
    d->view->centerOn(d->map);
    resizeEvent(0);
    d->map->setCenter(QGeoCoordinate(-27.5796, 153.1));
    d->map->setZoomLevel(15);
}

void MapsWidget::setMyLocation(QGeoCoordinate location, bool center)
{
    if (d->markerManager)
        d->markerManager->setMyLocation(location);
    if (d->map && center)
        d->map->setCenter(location);
}

QGraphicsGeoMap *MapsWidget::map() const
{
    return d->map;
}

StatusBarItem *MapsWidget::statusBar() const
{
    return d->statusBarItem;
}

void MapsWidget::resizeEvent(QResizeEvent *event)
{
    Q_UNUSED(event)

    if (d->view && d->map) {
        d->view->resize(size());
        d->map->resize(width()-2, height()-2);
        d->view->centerOn(d->map);
        d->statusBarItem->setRect(0, height()-2, width()-2, 20);
        d->zoomButtonItem->setRect((width()-2)-(width()-2)/10.0,
                                   (height()-2)/2.0 - (height()-2)/6.0,
                                   (width()-2)/10.0,
                                   (height()-2)/3.0);
    }
}

void MapsWidget::animatedPanTo(QGeoCoordinate center)
{
    if (!d->map)
        return;

    QPropertyAnimation *latAnim = new QPropertyAnimation(d->map, "centerLatitude");
    latAnim->setEndValue(center.latitude());
    latAnim->setDuration(200);
    QPropertyAnimation *lonAnim = new QPropertyAnimation(d->map, "centerLongitude");
    lonAnim->setEndValue(center.longitude());
    lonAnim->setDuration(200);

    QParallelAnimationGroup *group = new QParallelAnimationGroup;
    group->addAnimation(latAnim);
    group->addAnimation(lonAnim);
    group->start(QAbstractAnimation::DeleteWhenStopped);
}

void MapsWidget::showEvent(QShowEvent *event)
{
    Q_UNUSED(event)
    resizeEvent(0);
}

MarkerManager *MapsWidget::markerManager() const
{
    return d->markerManager;
}

void MapsWidget::setMarkerManager(MarkerManager *markerManager)
{
    d->markerManager = markerManager;
    if (d->map)
        d->markerManager->setMap(d->map);
    d->markerManager->setStatusBar(d->statusBarItem);
}
<commit_msg>Mapsdemo zoom '+' to fit zoombox in common screen sizes.<commit_after>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "mapswidget.h"
#include "marker.h"

#include <QGraphicsSceneMouseEvent>
#include <QGraphicsSceneWheelEvent>
#include <QPropertyAnimation>
#include <QParallelAnimationGroup>
#include <QTimer>

#include "qgeocoordinate.h"

GeoMap::GeoMap(QGeoMappingManager *manager, MapsWidget *mapsWidget) :
    QGraphicsGeoMap(manager), mapsWidget(mapsWidget)
{
    this->setFocus();
}

GeoMap::~GeoMap()
{
}

double GeoMap::centerLatitude() const
{
    return center().latitude();
}

double GeoMap::centerLongitude() const
{
    return center().longitude();
}

void GeoMap::setCenterLatitude(double lat)
{
    QGeoCoordinate c = center();
    c.setLatitude(lat);
    setCenter(c);
}

void GeoMap::setCenterLongitude(double lon)
{
    QGeoCoordinate c = center();
    c.setLongitude(lon);
    setCenter(c);
}

void GeoMap::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    panActive = true;
    markerPressed = false;
    QList<QGeoMapObject*> objects = mapObjectsAtScreenPosition(event->pos());
    if (objects.size() > 0) {
        pressed = objects.first();
        markerPressed = true;
    }

    this->setFocus();
    event->accept();
}

void GeoMap::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
    panActive = false;

    if (markerPressed) {
        // check if we're still over the object
        QList<QGeoMapObject*> objects = mapObjectsAtScreenPosition(event->pos());
        if (objects.contains(pressed)) {
            Marker *m = dynamic_cast<Marker*>(pressed);
            if (m)
                emit clicked(m);
        }

        markerPressed = false;
    }

    this->setFocus();
    event->accept();
}

void GeoMap::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    if (panActive) {
        QPointF delta = event->lastPos() - event->pos();
        pan(delta.x(), delta.y());
        emit panned();
    }
    this->setFocus();
    event->accept();
}

void GeoMap::wheelEvent(QGraphicsSceneWheelEvent *event)
{
    // pan our current point to the centre, zoom, then pan back

    qreal panx = event->pos().x() - size().width() / 2.0;
    qreal pany = event->pos().y() - size().height() / 2.0;
    pan(panx, pany);
    if (event->delta() > 0) {   // zoom in
        if (zoomLevel() < maximumZoomLevel()) {
            setZoomLevel(zoomLevel() + 1);
        }
    } else {                    // zoom out
        if (zoomLevel() > minimumZoomLevel()) {
            setZoomLevel(zoomLevel() - 1);
        }
    }
    pan(-panx, -pany);
    this->setFocus();
    event->accept();
}

void GeoMap::keyPressEvent(QKeyEvent *event)
{
    QGeoCoordinate center;
    QPropertyAnimation *anim;
    const qreal width = size().width();
    const qreal height = size().height();

    switch (event->key()) {
    case Qt::Key_4:
    case Qt::Key_Left:
        center = screenPositionToCoordinate(
                    QPointF(width/2 - width/5, height/2));
        anim = new QPropertyAnimation(this, "centerLongitude");
        anim->setEndValue(center.longitude());
        anim->setDuration(200);
        anim->start(QAbstractAnimation::DeleteWhenStopped);
        break;
    case Qt::Key_6:
    case Qt::Key_Right:
        center = screenPositionToCoordinate(
                    QPointF(width/2 + width/5, height/2));
        anim = new QPropertyAnimation(this, "centerLongitude");
        anim->setEndValue(center.longitude());
        anim->setDuration(200);
        anim->start(QAbstractAnimation::DeleteWhenStopped);
        break;
    case Qt::Key_2:
    case Qt::Key_Up:
        center = screenPositionToCoordinate(
                    QPointF(width/2, height/2 - height/5));
        anim = new QPropertyAnimation(this, "centerLatitude");
        anim->setEndValue(center.latitude());
        anim->setDuration(200);
        anim->start(QAbstractAnimation::DeleteWhenStopped);
        break;
    case Qt::Key_8:
    case Qt::Key_Down:
        center = screenPositionToCoordinate(
                    QPointF(width/2, height/2 + height/5));
        anim = new QPropertyAnimation(this, "centerLatitude");
        anim->setEndValue(center.latitude());
        anim->setDuration(200);
        anim->start(QAbstractAnimation::DeleteWhenStopped);
        break;
    case Qt::Key_1:
        if (zoomLevel() > minimumZoomLevel()) {
            setZoomLevel(zoomLevel() - 1);
        }
        break;
    case Qt::Key_3:
        if (zoomLevel() < maximumZoomLevel()) {
            setZoomLevel(zoomLevel() + 1);
        }
        break;
    }
    this->setFocus();
    event->accept();
}

class ZoomButtonItemPrivate
{
public:
    GeoMap *map;

    QGraphicsSimpleTextItem *plusText;
    QGraphicsSimpleTextItem *minusText;

    bool pressedOverTopHalf;
    bool pressedOverBottomHalf;
};

ZoomButtonItem::ZoomButtonItem(GeoMap *map) :
    d(new ZoomButtonItemPrivate)
{
    d->map = map;
    d->pressedOverBottomHalf = false;
    d->pressedOverTopHalf = false;

    setPen(QPen(QBrush(), 0));
    setBrush(QBrush(QColor(0,0,0,150)));

    d->plusText = new QGraphicsSimpleTextItem(this);
    d->plusText->setText("+");
    d->plusText->setBrush(QBrush(Qt::white));

    d->minusText = new QGraphicsSimpleTextItem(this);
    d->minusText->setText("-");
    d->minusText->setBrush(QBrush(Qt::white));
}

void ZoomButtonItem::setRect(qreal x, qreal y, qreal w, qreal h)
{
    QGraphicsRectItem::setRect(x, y, w, h);

    QFont f;
    f.setFixedPitch(true);
    f.setPixelSize(h/5.0);
    d->plusText->setFont(f);
    d->minusText->setFont(f);

    QRectF plusBound = d->plusText->boundingRect();
    QPointF plusCenter(x+w/2.0, y+h/4.0);
    QPointF plusDelta = plusCenter - plusBound.center();
    d->plusText->setPos(plusDelta);

    QRectF minusBound = d->minusText->boundingRect();
    QPointF minusCenter(x+w/2.0, y+3.0*h/4.0);
    QPointF minusDelta = minusCenter - minusBound.center();
    d->minusText->setPos(minusDelta);
}

void ZoomButtonItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    const QPointF pos = event->pos();
    if (!d->pressedOverTopHalf && !d->pressedOverBottomHalf) {
        if (isTopHalf(pos)) {
            d->pressedOverTopHalf = true;
        } else if (isBottomHalf(pos)) {
            d->pressedOverBottomHalf = true;
        }
    }
    d->map->setFocus();
    event->accept();
}

bool ZoomButtonItem::isTopHalf(const QPointF &point)
{
    return QRectF(rect().x(), rect().y(),
                  rect().width(), rect().height()/2).contains(point);
}

bool ZoomButtonItem::isBottomHalf(const QPointF &point)
{
    return QRectF(rect().x(), rect().y() + rect().height()/2,
                  rect().width(), rect().height()/2).contains(point);
}

void ZoomButtonItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
    const QPointF pos = event->pos();
    if (isTopHalf(pos) && d->pressedOverTopHalf) {
        d->map->setZoomLevel(d->map->zoomLevel() + 1.0);
    } else if (isBottomHalf(pos) && d->pressedOverBottomHalf) {
        d->map->setZoomLevel(d->map->zoomLevel() - 1.0);
    }
    d->pressedOverBottomHalf = false;
    d->pressedOverTopHalf = false;
    d->map->setFocus();
    event->accept();
}

void ZoomButtonItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    event->accept();
}

class StatusBarItemPrivate
{
public:
    int offset;
    QGraphicsSimpleTextItem *textItem;
};

StatusBarItem::StatusBarItem() :
    d(new StatusBarItemPrivate)
{
    d->offset = 0;

    setPen(QPen(QBrush(), 0));
    setBrush(QBrush(QColor(0,0,0,120)));

    d->textItem = new QGraphicsSimpleTextItem(this);
    d->textItem->setBrush(QBrush(Qt::white));

    setText("");
}

StatusBarItem::~StatusBarItem()
{
}

void StatusBarItem::setText(QString text)
{
    d->textItem->setText(text);
    QRectF rect = d->textItem->boundingRect();
    QPointF delta = this->rect().center() - rect.center();
    d->textItem->setPos(delta.x(), delta.y());
}

int StatusBarItem::offset() const
{
    return d->offset;
}

void StatusBarItem::setRect(qreal x, qreal y, qreal w, qreal h)
{
    QGraphicsRectItem::setRect(x, y + d->offset, w, h);
    setText(d->textItem->text());
}

void StatusBarItem::setOffset(int offset)
{
    this->setY(this->y() - d->offset + offset);
    d->offset = offset;
}

void StatusBarItem::showText(QString text, quint32 timeout)
{
    setText(text);
    show();
    QTimer::singleShot(timeout, this, SLOT(hide()));
}

void StatusBarItem::show()
{
    QPropertyAnimation *anim = new QPropertyAnimation(this, "offset");
    anim->setStartValue(0);
    anim->setEndValue(-1 * rect().height());
    anim->setDuration(500);
    anim->start(QAbstractAnimation::DeleteWhenStopped);
}

void StatusBarItem::hide()
{
    QPropertyAnimation *anim = new QPropertyAnimation(this, "offset");
    anim->setStartValue(d->offset);
    anim->setEndValue(0);
    anim->setDuration(500);
    anim->start(QAbstractAnimation::DeleteWhenStopped);
}

FixedGraphicsView::FixedGraphicsView(QWidget *parent) :
    QGraphicsView(parent)
{
}

void FixedGraphicsView::scrollContentsBy(int dx, int dy)
{
    Q_UNUSED(dx)
    Q_UNUSED(dy)
}

class MapsWidgetPrivate
{
public:
    GeoMap *map;
    QGraphicsView *view;
    MarkerManager *markerManager;
    StatusBarItem *statusBarItem;
    ZoomButtonItem *zoomButtonItem;
};

MapsWidget::MapsWidget(QWidget *parent) :
    QWidget(parent),
    d(new MapsWidgetPrivate)
{
    d->map = 0;
    d->view = 0;
    d->markerManager = 0;
}

MapsWidget::~MapsWidget()
{
}

void MapsWidget::initialize(QGeoMappingManager *manager)
{
    d->map = new GeoMap(manager, this);
    if (d->markerManager)
        d->markerManager->setMap(d->map);

    connect(d->map, SIGNAL(clicked(Marker*)),
            this, SIGNAL(markerClicked(Marker*)));
    connect(d->map, SIGNAL(panned()),
            this, SIGNAL(mapPanned()));

    QGraphicsScene *sc = new QGraphicsScene;
    sc->addItem(d->map);

    d->map->setPos(0, 0);
    d->map->resize(this->size());
    d->view = new FixedGraphicsView(this);
    d->view->setVisible(true);
    d->view->setInteractive(true);
    d->view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    d->view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    d->view->setScene(sc);

    d->statusBarItem = new StatusBarItem;
    sc->addItem(d->statusBarItem);

    d->zoomButtonItem = new ZoomButtonItem(d->map);
    sc->addItem(d->zoomButtonItem);

    d->view->resize(this->size());
    d->view->centerOn(d->map);
    resizeEvent(0);
    d->map->setCenter(QGeoCoordinate(-27.5796, 153.1));
    d->map->setZoomLevel(15);
}

void MapsWidget::setMyLocation(QGeoCoordinate location, bool center)
{
    if (d->markerManager)
        d->markerManager->setMyLocation(location);
    if (d->map && center)
        d->map->setCenter(location);
}

QGraphicsGeoMap *MapsWidget::map() const
{
    return d->map;
}

StatusBarItem *MapsWidget::statusBar() const
{
    return d->statusBarItem;
}

void MapsWidget::resizeEvent(QResizeEvent *event)
{
    Q_UNUSED(event)

    if (d->view && d->map) {
        d->view->resize(size());
        d->map->resize(width()-2, height()-2);
        d->view->centerOn(d->map);
        d->statusBarItem->setRect(0, height()-2, width()-2, 20);
        d->zoomButtonItem->setRect((width()-2)-(width()-2)/10.0,
                                   (height()-2)/2.0 - (height()-2)/6.0,
                                   (width()-2)/10.0,
                                   (height()-2)/3.0);
    }
}

void MapsWidget::animatedPanTo(QGeoCoordinate center)
{
    if (!d->map)
        return;

    QPropertyAnimation *latAnim = new QPropertyAnimation(d->map, "centerLatitude");
    latAnim->setEndValue(center.latitude());
    latAnim->setDuration(200);
    QPropertyAnimation *lonAnim = new QPropertyAnimation(d->map, "centerLongitude");
    lonAnim->setEndValue(center.longitude());
    lonAnim->setDuration(200);

    QParallelAnimationGroup *group = new QParallelAnimationGroup;
    group->addAnimation(latAnim);
    group->addAnimation(lonAnim);
    group->start(QAbstractAnimation::DeleteWhenStopped);
}

void MapsWidget::showEvent(QShowEvent *event)
{
    Q_UNUSED(event)
    resizeEvent(0);
}

MarkerManager *MapsWidget::markerManager() const
{
    return d->markerManager;
}

void MapsWidget::setMarkerManager(MarkerManager *markerManager)
{
    d->markerManager = markerManager;
    if (d->map)
        d->markerManager->setMap(d->map);
    d->markerManager->setStatusBar(d->statusBarItem);
}
<|endoftext|>


<commit_before>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_GDT_MAPPER_DEFAULT_PRODUCT_HH
#define DUNE_GDT_MAPPER_DEFAULT_PRODUCT_HH

#include <dune/common/dynvector.hh>

#include <dune/stuff/common/debug.hh>
#include <dune/stuff/common/type_utils.hh>

#include <dune/gdt/basefunctionset/default/product.hh>

#include "../../mapper/interface.hh"

namespace Dune {
namespace GDT {
namespace Mapper {

// forward
template <class GridViewImp, class... MapperTypes>
class DefaultProductMapper;

namespace internal {

template <size_t I = 0>
struct DynamicTupleGetter
{
  template <class EntityType, typename... TupleArgs>
  static typename std::enable_if<I == sizeof...(TupleArgs), size_t>::type
  numDofs(const std::tuple<TupleArgs...>& /*tuple*/, const size_t /*factor_index*/, const EntityType& /*entity*/)
  {
    return 0;
  }

  template <class EntityType, typename... TupleArgs>
      static typename std::enable_if
      < I<sizeof...(TupleArgs), size_t>::type numDofs(const std::tuple<TupleArgs...>& tuple, const size_t factor_index,
                                                      const EntityType& entity)
  {
    if (factor_index == 0)
      return std::get<I>(tuple).numDofs(entity);
    return DynamicTupleGetter<I + 1>::numDofs(tuple, factor_index - 1, entity);
  }

  template <typename... TupleArgs>
  static typename std::enable_if<I == sizeof...(TupleArgs), size_t>::type
  maxNumDofs(const std::tuple<TupleArgs...>& /*tuple*/, const size_t /*factor_index*/)
  {
    return 0;
  }

  template <typename... TupleArgs>
      static typename std::enable_if < I<sizeof...(TupleArgs), size_t>::type
                                       maxNumDofs(const std::tuple<TupleArgs...>& tuple, const size_t factor_index)
  {
    if (factor_index == 0)
      return std::get<I>(tuple).maxNumDofs();
    return DynamicTupleGetter<I + 1>::maxNumDofs(tuple, factor_index - 1);
  }

  template <typename... TupleArgs>
  static typename std::enable_if<I == sizeof...(TupleArgs), size_t>::type
  size(const std::tuple<TupleArgs...>& /*tuple*/, const size_t /*factor_index*/)
  {
    return 0;
  }

  template <typename... TupleArgs>
      static typename std::enable_if
      < I<sizeof...(TupleArgs), size_t>::type size(const std::tuple<TupleArgs...>& tuple, const size_t factor_index)
  {
    if (factor_index == 0)
      return std::get<I>(tuple).size();
    return DynamicTupleGetter<I + 1>::size(tuple, factor_index - 1);
  }

  template <class EntityType, typename... TupleArgs>
  static typename std::enable_if<I == sizeof...(TupleArgs), size_t>::type
  mapToGlobal(const std::tuple<TupleArgs...>& /*tuple*/, const size_t /*factor_index*/, const EntityType& /*entity*/,
              const size_t& /*local_index_in_factor*/)
  {
    return 0;
  }

  template <class EntityType, typename... TupleArgs>
      static typename std::enable_if
      < I<sizeof...(TupleArgs), size_t>::type mapToGlobal(const std::tuple<TupleArgs...>& tuple,
                                                          const size_t factor_index, const EntityType& entity,
                                                          const size_t& local_index_in_factor)
  {
    if (factor_index == 0)
      return std::get<I>(tuple).mapToGlobal(entity, local_index_in_factor);
    return DynamicTupleGetter<I + 1>::mapToGlobal(tuple, factor_index - 1, entity, local_index_in_factor);
  }
};

template <class GridViewImp, class... MapperTypes>
class DefaultProductMapperTraits
{
public:
  typedef GridViewImp GridViewType;
  typedef DefaultProductMapper<GridViewType, MapperTypes...> derived_type;
  static const size_t dimRange = GDT::BaseFunctionSet::internal::SumDimRange<MapperTypes...>::dimRange;
  typedef typename GridViewType::IndexSet BackendType;
  typedef typename GridViewType::template Codim<0>::Entity EntityType;
};

} // namespace internal

template <class GridViewImp, class TupleType>
struct DefaultProductMapperFromTuple;

template <class GridViewImp, class... MapperTypes>
struct DefaultProductMapperFromTuple<GridViewImp, std::tuple<MapperTypes...>>
{
  typedef DefaultProductMapper<GridViewImp, MapperTypes...> type;
};

template <class GridViewImp, class... MapperTypes>
class DefaultProductMapper
    : public ProductMapperInterface<internal::DefaultProductMapperTraits<GridViewImp, MapperTypes...>>
{
  typedef ProductMapperInterface<internal::DefaultProductMapperTraits<GridViewImp, MapperTypes...>> BaseType;

public:
  typedef internal::DefaultProductMapperTraits<GridViewImp, MapperTypes...> Traits;
  typedef typename Traits::GridViewType GridViewType;
  static const size_t dimRange = Traits::dimRange;
  using typename BaseType::EntityType;
  using typename BaseType::BackendType;

  DefaultProductMapper(const GridViewType& grid_view, const MapperTypes&... mappers)
    : mappers_(mappers...)
    , grid_view_(grid_view)
  {
  }

  DefaultProductMapper(const GridViewType& grid_view, const std::tuple<MapperTypes...>& mappers)
    : mappers_(mappers)
    , grid_view_(grid_view)
  {
  }

  template <class FirstSpaceType, class... SpaceTypes>
  DefaultProductMapper(const FirstSpaceType& first_space, const SpaceTypes&... spaces)
    : DefaultProductMapper(first_space.grid_view(), first_space.mapper(), spaces.mapper()...)
  {
  }

  // These methods are required by the ProductMapperInterface
  size_t numDofs(const size_t factor_index, const EntityType& entity) const
  {
    return internal::DynamicTupleGetter<0>::numDofs(mappers_, factor_index, entity);
  }

  size_t maxNumDofs(const size_t factor_index) const
  {
    return internal::DynamicTupleGetter<0>::maxNumDofs(mappers_, factor_index);
  }

  void globalIndices(const size_t factor_index, const EntityType& entity, Dune::DynamicVector<size_t>& ret) const
  {
    const size_t num_dofs_entity = numDofs(factor_index, entity);
    if (ret.size() != num_dofs_entity)
      ret.resize(num_dofs_entity);
    for (size_t ii = 0; ii < num_dofs_entity; ++ii)
      ret[ii] = mapToGlobal(factor_index, entity, ii);
  }

  size_t mapToGlobal(const size_t factor_index, const EntityType& entity, const size_t& local_index_in_factor) const
  {
    size_t first_global_index_of_factor = 0;
    for (size_t ii = 0; ii < factor_index; ++ii)
      first_global_index_of_factor += size(ii);
    return first_global_index_of_factor
           + internal::DynamicTupleGetter<0>::mapToGlobal(mappers_, factor_index, entity, local_index_in_factor);
  }

  size_t mapToLocal(const size_t factor_index, const EntityType& entity, const size_t& local_index_in_factor) const
  {
    size_t first_local_index_of_factor = 0;
    for (size_t ii = 0; ii < factor_index; ++ii)
      first_local_index_of_factor += numDofs(ii, entity);
    return first_local_index_of_factor + local_index_in_factor;
  }

  const BackendType& backend() const
  {
    return BackendType();
  }

  size_t size(const size_t factor_index) const
  {
    return internal::DynamicTupleGetter<0>::size(mappers_, factor_index);
  }

  size_t size() const
  {
    size_t ret = 0;
    for (size_t ii = 0; ii < sizeof...(MapperTypes); ++ii)
      ret += size(ii);
    return ret;
  }

  size_t numDofs(const EntityType& entity) const
  {
    size_t ret = 0;
    for (size_t ii = 0; ii < sizeof...(MapperTypes); ++ii)
      ret += numDofs(ii, entity);
    return ret;
  }

  size_t maxNumDofs() const
  {
    size_t max_num_dofs = 0;
    const auto it_end = grid_view_.template end<0>();
    for (auto it = grid_view_.template begin<0>(); it != it_end; ++it) {
      const auto& entity = *it;
      if (max_num_dofs < numDofs(entity))
        max_num_dofs = numDofs(entity);
    }
    return max_num_dofs;
  }

  void globalIndices(const EntityType& entity, Dune::DynamicVector<size_t>& ret) const
  {
    const size_t num_dofs_entity = numDofs(entity);
    if (ret.size() != num_dofs_entity)
      ret.resize(num_dofs_entity);
    for (size_t ii = 0; ii < num_dofs_entity; ++ii)
      ret[ii] = mapToGlobal(entity, ii);
  } // ... globalIndices(...)

  using BaseType::globalIndices;

  size_t mapToGlobal(const EntityType& entity, const size_t& localIndex) const
  {
    size_t factor_index          = 0;
    size_t local_index_in_factor = localIndex;
    while (local_index_in_factor >= numDofs(factor_index, entity)) {
      local_index_in_factor -= numDofs(factor_index, entity);
      ++factor_index;
    }
    return mapToGlobal(factor_index, entity, local_index_in_factor);
  }

private:
  const std::tuple<MapperTypes...> mappers_;
  const GridViewType& grid_view_;
}; // class DefaultProductMapper

} // namespace Mapper
} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_MAPPER_DEFAULT_PRODUCT_HH
<commit_msg>[mapper.default.product] add possibility to create from tuple of Spaces<commit_after>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_GDT_MAPPER_DEFAULT_PRODUCT_HH
#define DUNE_GDT_MAPPER_DEFAULT_PRODUCT_HH

#include <dune/common/dynvector.hh>

#include <dune/stuff/common/debug.hh>
#include <dune/stuff/common/type_utils.hh>

#include <dune/gdt/basefunctionset/default/product.hh>

#include "../../mapper/interface.hh"

namespace Dune {
namespace GDT {
namespace Mapper {

// forward
template <class GridViewImp, class... MapperTypes>
class DefaultProductMapper;

namespace internal {

template <size_t I = 0>
struct DynamicTupleGetter
{
  template <class EntityType, typename... TupleArgs>
  static typename std::enable_if<I == sizeof...(TupleArgs), size_t>::type
  numDofs(const std::tuple<TupleArgs...>& /*tuple*/, const size_t /*factor_index*/, const EntityType& /*entity*/)
  {
    return 0;
  }

  template <class EntityType, typename... TupleArgs>
      static typename std::enable_if
      < I<sizeof...(TupleArgs), size_t>::type numDofs(const std::tuple<TupleArgs...>& tuple, const size_t factor_index,
                                                      const EntityType& entity)
  {
    if (factor_index == 0)
      return std::get<I>(tuple).numDofs(entity);
    return DynamicTupleGetter<I + 1>::numDofs(tuple, factor_index - 1, entity);
  }

  template <typename... TupleArgs>
  static typename std::enable_if<I == sizeof...(TupleArgs), size_t>::type
  maxNumDofs(const std::tuple<TupleArgs...>& /*tuple*/, const size_t /*factor_index*/)
  {
    return 0;
  }

  template <typename... TupleArgs>
      static typename std::enable_if < I<sizeof...(TupleArgs), size_t>::type
                                       maxNumDofs(const std::tuple<TupleArgs...>& tuple, const size_t factor_index)
  {
    if (factor_index == 0)
      return std::get<I>(tuple).maxNumDofs();
    return DynamicTupleGetter<I + 1>::maxNumDofs(tuple, factor_index - 1);
  }

  template <typename... TupleArgs>
  static typename std::enable_if<I == sizeof...(TupleArgs), size_t>::type
  size(const std::tuple<TupleArgs...>& /*tuple*/, const size_t /*factor_index*/)
  {
    return 0;
  }

  template <typename... TupleArgs>
      static typename std::enable_if
      < I<sizeof...(TupleArgs), size_t>::type size(const std::tuple<TupleArgs...>& tuple, const size_t factor_index)
  {
    if (factor_index == 0)
      return std::get<I>(tuple).size();
    return DynamicTupleGetter<I + 1>::size(tuple, factor_index - 1);
  }

  template <class EntityType, typename... TupleArgs>
  static typename std::enable_if<I == sizeof...(TupleArgs), size_t>::type
  mapToGlobal(const std::tuple<TupleArgs...>& /*tuple*/, const size_t /*factor_index*/, const EntityType& /*entity*/,
              const size_t& /*local_index_in_factor*/)
  {
    return 0;
  }

  template <class EntityType, typename... TupleArgs>
      static typename std::enable_if
      < I<sizeof...(TupleArgs), size_t>::type mapToGlobal(const std::tuple<TupleArgs...>& tuple,
                                                          const size_t factor_index, const EntityType& entity,
                                                          const size_t& local_index_in_factor)
  {
    if (factor_index == 0)
      return std::get<I>(tuple).mapToGlobal(entity, local_index_in_factor);
    return DynamicTupleGetter<I + 1>::mapToGlobal(tuple, factor_index - 1, entity, local_index_in_factor);
  }
};

template <size_t I, class... SpaceTypes>
struct MapperTuplefromSpaceTupleCreator
{
  template <class... MapperTypes>
  static typename std::enable_if<sizeof...(MapperTypes) == sizeof...(SpaceTypes),
                                 typename std::tuple<MapperTypes...>>::type
  create(const std::tuple<SpaceTypes...>& /*spaces*/, const std::tuple<MapperTypes...>& mappers)
  {
    return mappers;
  }

  template <class... MapperTypes>
  static typename std::enable_if<sizeof...(MapperTypes) < sizeof...(SpaceTypes),
                                 typename std::tuple<typename SpaceTypes::MapperType...>>::type
  create(const std::tuple<SpaceTypes...>& spaces, const std::tuple<MapperTypes...>& mappers)
  {
    const auto new_mappers = std::tuple_cat(mappers, std::make_tuple(std::get<I>(spaces).mapper()));
    return MapperTuplefromSpaceTupleCreator<I + 1, SpaceTypes...>::create(spaces, new_mappers);
  }
};

template <class GridViewImp, class... MapperTypes>
class DefaultProductMapperTraits
{
public:
  typedef GridViewImp GridViewType;
  typedef DefaultProductMapper<GridViewType, MapperTypes...> derived_type;
  static const size_t dimRange = GDT::BaseFunctionSet::internal::SumDimRange<MapperTypes...>::dimRange;
  typedef typename GridViewType::IndexSet BackendType;
  typedef typename GridViewType::template Codim<0>::Entity EntityType;
};

} // namespace internal

template <class GridViewImp, class TupleType>
struct DefaultProductMapperFromTuple;

template <class GridViewImp, class... MapperTypes>
struct DefaultProductMapperFromTuple<GridViewImp, std::tuple<MapperTypes...>>
{
  typedef DefaultProductMapper<GridViewImp, MapperTypes...> type;
};

template <class GridViewImp, class... MapperTypes>
class DefaultProductMapper
    : public ProductMapperInterface<internal::DefaultProductMapperTraits<GridViewImp, MapperTypes...>>
{
  typedef ProductMapperInterface<internal::DefaultProductMapperTraits<GridViewImp, MapperTypes...>> BaseType;

public:
  typedef internal::DefaultProductMapperTraits<GridViewImp, MapperTypes...> Traits;
  typedef typename Traits::GridViewType GridViewType;
  static const size_t dimRange = Traits::dimRange;
  using typename BaseType::EntityType;
  using typename BaseType::BackendType;

  DefaultProductMapper(const GridViewType& grid_view, const MapperTypes&... mappers)
    : mappers_(std::make_tuple(mappers...))
    , grid_view_(grid_view)
  {
  }

  DefaultProductMapper(const GridViewType& grid_view, const std::tuple<MapperTypes...>& mappers)
    : mappers_(mappers)
    , grid_view_(grid_view)
  {
  }

  template <class... SpaceTypes>
  DefaultProductMapper(const std::tuple<SpaceTypes...>& spaces)
    : DefaultProductMapper(std::get<0>(spaces).grid_view(),
                           internal::MapperTuplefromSpaceTupleCreator<0, SpaceTypes...>::create(spaces, std::tuple<>()))
  {
  }

  // These methods are required by the ProductMapperInterface
  size_t numDofs(const size_t factor_index, const EntityType& entity) const
  {
    return internal::DynamicTupleGetter<0>::numDofs(mappers_, factor_index, entity);
  }

  size_t maxNumDofs(const size_t factor_index) const
  {
    return internal::DynamicTupleGetter<0>::maxNumDofs(mappers_, factor_index);
  }

  void globalIndices(const size_t factor_index, const EntityType& entity, Dune::DynamicVector<size_t>& ret) const
  {
    const size_t num_dofs_entity = numDofs(factor_index, entity);
    if (ret.size() != num_dofs_entity)
      ret.resize(num_dofs_entity);
    for (size_t ii = 0; ii < num_dofs_entity; ++ii)
      ret[ii] = mapToGlobal(factor_index, entity, ii);
  }

  size_t mapToGlobal(const size_t factor_index, const EntityType& entity, const size_t& local_index_in_factor) const
  {
    size_t first_global_index_of_factor = 0;
    for (size_t ii = 0; ii < factor_index; ++ii)
      first_global_index_of_factor += size(ii);
    return first_global_index_of_factor
           + internal::DynamicTupleGetter<0>::mapToGlobal(mappers_, factor_index, entity, local_index_in_factor);
  }

  size_t mapToLocal(const size_t factor_index, const EntityType& entity, const size_t& local_index_in_factor) const
  {
    size_t first_local_index_of_factor = 0;
    for (size_t ii = 0; ii < factor_index; ++ii)
      first_local_index_of_factor += numDofs(ii, entity);
    return first_local_index_of_factor + local_index_in_factor;
  }

  const BackendType& backend() const
  {
    return BackendType();
  }

  size_t size(const size_t factor_index) const
  {
    return internal::DynamicTupleGetter<0>::size(mappers_, factor_index);
  }

  size_t size() const
  {
    size_t ret = 0;
    for (size_t ii = 0; ii < sizeof...(MapperTypes); ++ii)
      ret += size(ii);
    return ret;
  }

  size_t numDofs(const EntityType& entity) const
  {
    size_t ret = 0;
    for (size_t ii = 0; ii < sizeof...(MapperTypes); ++ii)
      ret += numDofs(ii, entity);
    return ret;
  }

  size_t maxNumDofs() const
  {
    size_t max_num_dofs = 0;
    const auto it_end = grid_view_.template end<0>();
    for (auto it = grid_view_.template begin<0>(); it != it_end; ++it) {
      const auto& entity = *it;
      if (max_num_dofs < numDofs(entity))
        max_num_dofs = numDofs(entity);
    }
    return max_num_dofs;
  }

  void globalIndices(const EntityType& entity, Dune::DynamicVector<size_t>& ret) const
  {
    const size_t num_dofs_entity = numDofs(entity);
    if (ret.size() != num_dofs_entity)
      ret.resize(num_dofs_entity);
    for (size_t ii = 0; ii < num_dofs_entity; ++ii)
      ret[ii] = mapToGlobal(entity, ii);
  } // ... globalIndices(...)

  using BaseType::globalIndices;

  size_t mapToGlobal(const EntityType& entity, const size_t& localIndex) const
  {
    size_t factor_index          = 0;
    size_t local_index_in_factor = localIndex;
    while (local_index_in_factor >= numDofs(factor_index, entity)) {
      local_index_in_factor -= numDofs(factor_index, entity);
      ++factor_index;
    }
    return mapToGlobal(factor_index, entity, local_index_in_factor);
  }

private:
  const std::tuple<MapperTypes...> mappers_;
  const GridViewType& grid_view_;
}; // class DefaultProductMapper

} // namespace Mapper
} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_MAPPER_DEFAULT_PRODUCT_HH
<|endoftext|>