QGeoCoordinate OpenstreetmapMapProvider::pixelToCoord(const QPoint& point,
    int zoomLevel) const
{
    return QGeoCoordinate(tiley2lat(point.y() / (double)TILE_DIMENSION,
               zoomLevel),
               tilex2long(point.x() / (double)TILE_DIMENSION, zoomLevel));
}
int main(int argc, char* argv[])
{
  std::string   map;
  std::string   style;
  double        latTop,latBottom,lonLeft,lonRight;
  unsigned long xTileStart,xTileEnd,xTileCount,yTileStart,yTileEnd,yTileCount;
  unsigned long startZoom;
  unsigned long endZoom;
  unsigned long tileWidth;
  unsigned long tileHeight;
  std::string   driver;

  if (argc!=12) {
    std::cerr << "DrawMap ";
    std::cerr << "<map directory> <style-file> ";
    std::cerr << "<lat_top> <lon_left> <lat_bottom> <lon_right> ";
    std::cerr << "<start zoom>" << std::endl;
    std::cerr << "<end zoom>" << std::endl;
    std::cerr << "<tile width>" << std::endl;
    std::cerr << "<tile height>" << std::endl;
    std::cerr << "<driver>" << std::endl;
    return 1;
  }

  map=argv[1];
  style=argv[2];

  if (sscanf(argv[3],"%lf",&latTop)!=1) {
    std::cerr << "lon is not numeric!" << std::endl;
    return 1;
  }

  if (sscanf(argv[4],"%lf",&lonLeft)!=1) {
    std::cerr << "lat is not numeric!" << std::endl;
    return 1;
  }

  if (sscanf(argv[5],"%lf",&latBottom)!=1) {
    std::cerr << "lon is not numeric!" << std::endl;
    return 1;
  }

  if (sscanf(argv[6],"%lf",&lonRight)!=1) {
    std::cerr << "lat is not numeric!" << std::endl;
    return 1;
  }

  if (sscanf(argv[7],"%lu",&startZoom)!=1) {
    std::cerr << "start zoom is not numeric!" << std::endl;
    return 1;
  }

  if (sscanf(argv[8],"%lu",&endZoom)!=1) {
    std::cerr << "end zoom is not numeric!" << std::endl;
    return 1;
  }

  if (sscanf(argv[9],"%lu",&tileWidth)!=1) {
    std::cerr << "tile width is not numeric!" << std::endl;
    return 1;
  }

  if (sscanf(argv[10],"%lu",&tileHeight)!=1) {
    std::cerr << "tile height is not numeric!" << std::endl;
    return 1;
  }

  driver=argv[11];

#if defined(HAVE_LIB_OSMSCOUTMAPCAIRO)
  cairo_surface_t *surface=NULL;
  cairo_t         *cairo=NULL;
#endif

  if (driver=="cairo") {
    std::cout << "Using driver 'cairo'..." << std::endl;
#if defined(HAVE_LIB_OSMSCOUTMAPCAIRO)
    surface=cairo_image_surface_create(CAIRO_FORMAT_RGB24,tileWidth,tileHeight);

    if (surface==NULL) {
      std::cerr << "Cannot create cairo image surface" << std::endl;
      return 1;
    }

    cairo=cairo_create(surface);

    if (cairo==NULL) {
      std::cerr << "Cannot create cairo_t for image surface" << std::endl;
      return 1;
    }
#else
    std::cerr << "Driver 'cairo' is not enabled" << std::endl;
    return 1;
#endif
  }
  else {
    std::cerr << "Unsupported driver '" << driver << "'" << std::endl;
    return 1;
  }

  osmscout::DatabaseParameter databaseParameter;

  //databaseParameter.SetDebugPerformance(true);

  osmscout::Database          database(databaseParameter);

  if (!database.Open(map.c_str())) {
    std::cerr << "Cannot open database" << std::endl;
    return 1;
  }

  osmscout::StyleConfig styleConfig(database.GetTypeConfig());

  if (!osmscout::LoadStyleConfig(style.c_str(),styleConfig)) {
    std::cerr << "Cannot open style" << std::endl;
    return 1;
  }

  osmscout::MercatorProjection  projection;
  osmscout::MapParameter        drawParameter;
  osmscout::AreaSearchParameter searchParameter;

  for (size_t zoom=std::min(startZoom,endZoom);
       zoom<=std::max(startZoom,endZoom);
       zoom++) {
    xTileStart=long2tilex(std::min(lonLeft,lonRight),zoom);
    xTileEnd=long2tilex(std::max(lonLeft,lonRight),zoom);
    xTileCount=xTileEnd-xTileStart+1;

    yTileStart=lat2tiley(std::max(latTop,latBottom),zoom);
    yTileEnd=lat2tiley(std::min(latTop,latBottom),zoom);
    yTileCount=yTileEnd-yTileStart+1;

    std::cout << "Drawing zoom " << zoom;
    //<< ", " << (xTileCount)*(yTileCount) << " tiles [" << xTileStart << "," << yTileStart << " - " <<  xTileEnd << "," << yTileEnd << "]";
    std::cout << std::endl;

#if defined(HAVE_LIB_OSMSCOUTMAPCAIRO)
    osmscout::MapPainterCairo cairoPainter;
#endif

    osmscout::Magnification   magnification;

    magnification.SetLevel(zoom);

    double dbMinTime=std::numeric_limits<double>::max();
    double dbMaxTime=0.0;
    double dbTotalTime=0.0;

    double drawMinTime=std::numeric_limits<double>::max();
    double drawMaxTime=0.0;
    double drawTotalTime=0.0;

    for (size_t y=yTileStart; y<=yTileEnd; y++) {
      for (size_t x=xTileStart; x<=xTileEnd; x++) {
        double                         lat,lon;
        osmscout::TypeSet              nodeTypes;
        std::vector<osmscout::TypeSet> wayTypes;
        osmscout::TypeSet              areaTypes;
        osmscout::MapData              data;

        lat=(tiley2lat(y,zoom)+tiley2lat(y+1,zoom))/2;
        lon=(tilex2long(x,zoom)+tilex2long(x+1,zoom))/2;

        //std::cout << "Drawing tile at " << lat << "," << lon << "/";
        //std::cout << x << "," << y << "/";
        //std::cout << x-xTileStart << "," << y-yTileStart << std::endl;

        projection.Set(lon,
                       lat,
                       magnification,
                       tileWidth,
                       tileHeight);

        styleConfig.GetNodeTypesWithMaxMag(projection.GetMagnification(),
                                           nodeTypes);

        styleConfig.GetWayTypesByPrioWithMaxMag(projection.GetMagnification(),
                                                wayTypes);

        styleConfig.GetAreaTypesWithMaxMag(projection.GetMagnification(),
                                           areaTypes);

        osmscout::StopClock dbTimer;

        database.GetObjects(nodeTypes,
                            wayTypes,
                            areaTypes,
                            projection.GetLonMin(),
                            projection.GetLatMin(),
                            projection.GetLonMax(),
                            projection.GetLatMax(),
                            projection.GetMagnification(),
                            searchParameter,
                            data.nodes,
                            data.ways,
                            data.areas);

        dbTimer.Stop();

        double dbTime=dbTimer.GetMilliseconds();

        dbMinTime=std::min(dbMinTime,dbTime);
        dbMaxTime=std::max(dbMaxTime,dbTime);
        dbTotalTime+=dbTime;

        osmscout::StopClock drawTimer;

#if defined(HAVE_LIB_OSMSCOUTMAPCAIRO)
        if (driver=="cairo") {
          //std::cout << data.nodes.size() << " " << data.ways.size() << " " << data.areas.size() << std::endl;
          cairoPainter.DrawMap(styleConfig,
                               projection,
                               drawParameter,
                               data,
                               cairo);
        }
#endif

        drawTimer.Stop();

        double drawTime=drawTimer.GetMilliseconds();

        drawMinTime=std::min(drawMinTime,drawTime);
        drawMaxTime=std::max(drawMaxTime,drawTime);
        drawTotalTime+=drawTime;
      }
    }

    std::cout << "GetObjects: ";
    std::cout << "total: " << dbTotalTime << " msec ";
    std::cout << "min: " << dbMinTime << " msec ";
    std::cout << "avg: " << dbTotalTime/(xTileCount*yTileCount) << " msec ";
    std::cout << "max: " << dbMaxTime << " msec" << std::endl;

    std::cout << "DrawMap: ";
    std::cout << "total: " << drawTotalTime << " msec ";
    std::cout << "min: " << drawMinTime << " msec ";
    std::cout << "avg: " << drawTotalTime/(xTileCount*yTileCount) << " msec ";
    std::cout << "max: " << drawMaxTime << " msec" << std::endl;
  }

  database.Close();

#if defined(HAVE_LIB_OSMSCOUTMAPCAIRO)
  if (driver=="cairo") {
    cairo_destroy(cairo);
    cairo_surface_destroy(surface);
  }
#endif
  return 0;
}
Exemple #3
0
int expand_meta(const char *name, struct storage_backend * store)
{
    int fd;
    int x, y, z;
    size_t pos = 0;
    void *buf;
    char path[PATH_MAX];
    struct stat_info tile_stat;

    if (path_to_xyz(name, &x, &y, &z)) return -1;

    int limit = (1 << z);
    limit = MIN(limit, METATILE);

    float fromlat = tiley2lat(y+8, z);
    float tolat = tiley2lat(y, z);
    float fromlon = tilex2long(x, z);
    float tolon = tilex2long(x+8, z);

    if (tolon < bbox[0] || fromlon > bbox[2] || tolat < bbox[1] || fromlat > bbox[3])
    {
        if (verbose) printf("z=%d x=%d y=%d is out of bbox\n", z, x, y);
        return -8;
    }

    fd = open(name, O_RDONLY);
    if (fd < 0)
    {
        fprintf(stderr, "Could not open metatile %s. Reason: %s\n", name, strerror(errno));
        return -1;
    }

    struct stat st;
    fstat(fd, &st);

    buf = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
    if (buf == MAP_FAILED)
    {
        fprintf(stderr, "Cannot mmap file %s for %ld bytes: %s\n", name, st.st_size, strerror(errno));
        close(fd);
        return -3;
    }
    struct meta_layout *m = (struct meta_layout *)buf;

    if (memcmp(m->magic, META_MAGIC, strlen(META_MAGIC)))
    {
        fprintf(stderr, "Meta file %s header magic mismatch\n", name);
        close(fd);
        return -4;
    }

    if (m->count != (METATILE * METATILE))
    {
        fprintf(stderr, "Meta file %s header bad count %d != %d\n", name, m->count, METATILE * METATILE);
        close(fd);
        return -5;
    }

    if (store == NULL)
    {
        sprintf(path, "%s/%d", target, z);
        if (mkdir(path, 0755) && (errno != EEXIST))
        {
            fprintf(stderr, "cannot create directory %s: %s\n", path, strerror(errno));
            close(fd);
            return -1;
        }
    }

    if (store != NULL) {
        if (!force) tile_stat = store->tile_stat(store, target, "options", x, y, z);
        if (force || (tile_stat.size < 0) || (tile_stat.expired)) {
            if (store->metatile_write(store, target, "options", x, y, z, buf, st.st_size) == -1) {
                close(fd);
                fprintf(stderr, "Failed to write data to Memcached %s/%d/%d/%d.png\n", target, x, y, z);
                return -1;
            }
            if (verbose) printf("Produced metatile: %s/%d/%d/%d.meta\n", target, x, y, z);
        }
    } else {
        for (int meta = 0; meta < METATILE*METATILE; meta++)
        {
            int tx = x + (meta / METATILE);
            int ty = y + (meta % METATILE);
            int output;

            if (ty==y)
            {
                sprintf(path, "%s/%d/%d", target, z, tx);
                if (mkdir(path, 0755) && (errno != EEXIST))
                {
                    fprintf(stderr, "cannot create directory %s: %s\n", path, strerror(errno));
                    close(fd);
                    return -1;
                }
            }

            sprintf(path, "%s/%d/%d/%d.png", target, z, tx, ty);
            output = open(path, O_WRONLY | O_TRUNC | O_CREAT, 0666);
            if (output == -1)
            {
                fprintf(stderr, "cannot open %s for writing: %s\n", path, strerror(errno));
                close(fd);
                return -1;
            }

            pos = 0;
            while (pos < m->index[meta].size)
            {
                size_t len = m->index[meta].size - pos;
                int written = write(output, buf + pos + m->index[meta].offset, len);

                if (written < 0)
                {
                    fprintf(stderr, "Failed to write data to file %s. Reason: %s\n", path, strerror(errno));
                    close(fd);
                    return -7;
                }
                else if (written > 0)
                {
                    pos += written;
                }
                else
                {
                    break;
                }
            }
            close(output);
            if (verbose) printf("Produced tile: %s\n", path);
        }
    }
    munmap(buf, st.st_size);
    close(fd);
    return pos;
}