예제 #1
0
  /**
   * Return the parent tile.
   *
   * Note that the parent tile will cover a 4 times bigger region than the current tile.
   *
   * Note that for tiles with level 0 no parent tile will exist. The method will assert in this case!
   */
  TileId TileId::GetParent() const
  {
    Magnification zoomedOutMagnification;

    assert(magnification.GetLevel()>0);

    zoomedOutMagnification.SetLevel(magnification.GetLevel()-1);

    return TileId(zoomedOutMagnification,x/2,y/2);
  }
예제 #2
0
 /**
  * Ceate a new tile by passing magnification and tile coordinates
  */
 TileId::TileId(const Magnification& magnification,
                size_t x,
                size_t y)
 : magnification(magnification),
   x(x),
   y(y),
   boundingBox(GeoCoord(y*cellDimension[magnification.GetLevel()].height-90.0,
                        x*cellDimension[magnification.GetLevel()].width-180.0),
               GeoCoord((y+1)*cellDimension[magnification.GetLevel()].height-90.0,
                        (x+1)*cellDimension[magnification.GetLevel()].width-180.0))
 {
   // no code
 }
예제 #3
0
  bool TileProjection::Set(size_t tileX, size_t tileY,
                           const Magnification& magnification,
                           double dpi,
                           size_t width, size_t height)
  {
    if (valid &&
        this->tileX==tileY &&
        this->tileY==tileY &&
        this->magnification==magnification &&
        this->dpi==dpi &&
        this->width==width &&
        this->height==height) {
      return true;
    }

    valid=true;

    // Make a copy of the context information
    this->tileX=tileX;
    this->tileY=tileY;
    this->magnification=magnification;
    this->dpi=dpi;
    this->width=width;
    this->height=height;

    latMin=TileYToLat(tileY+1,
                      magnification);
    latMax=TileYToLat(tileY,
                      magnification);

    lonMin=TileXToLon(tileX,
                      magnification);
    lonMax=TileXToLon(tileX+1,
                      magnification);

    lat=(latMin+latMax)/2;
    lon=(lonMin+lonMax)/2;

    scale=width/(gradtorad*(lonMax-lonMin));
    scaleGradtorad = scale * gradtorad;

    lonOffset=lonMin*scaleGradtorad;
    latOffset=scale*atanh(sin(latMin*gradtorad));

    pixelSize=earthExtent/magnification.GetMagnification()/256;

#ifdef OSMSCOUT_HAVE_SSE2
    sse2LonOffset      = _mm_set1_pd(lonOffset);
    sse2LatOffset      = _mm_set1_pd(latOffset);
    sse2Scale          = _mm_set1_pd(scale);
    sse2ScaleGradtorad = _mm_set1_pd(scaleGradtorad);
    sse2Height         = _mm_set1_pd(height);
#endif

    return true;
  }
예제 #4
0
  bool WaterIndex::GetRegions(const GeoBox& boundingBox,
                              const Magnification& magnification,
                              std::list<GroundTile>& tiles) const
  {
    try {
      uint32_t cx1,cx2,cy1,cy2;
      uint32_t idx=magnification.GetLevel();

      tiles.clear();

      if (levels.empty()) {
        return true;
      }

      idx+=4;

      idx=std::max(waterIndexMinMag,idx);
      idx=std::min(waterIndexMaxMag,idx);

      idx-=waterIndexMinMag;

      cx1=(uint32_t)floor((boundingBox.GetMinLon()+180.0)/levels[idx].cellWidth);
      cx2=(uint32_t)floor((boundingBox.GetMaxLon()+180.0)/levels[idx].cellWidth);
      cy1=(uint32_t)floor((boundingBox.GetMinLat()+90.0)/levels[idx].cellHeight);
      cy2=(uint32_t)floor((boundingBox.GetMaxLat()+90.0)/levels[idx].cellHeight);

      const Level &level=levels[idx];

      if (level.hasCellData) {
        GetGroundTileFromData(level,
                              cx1,
                              cx2,
                              cy1,
                              cy2,
                              tiles);
      }
      else {
        GetGroundTileByDefault(level,
                               cx1,
                               cx2,
                               cy1,
                               cy2,
                               tiles);
      }
    }
    catch (IOException& e) {
      log.Error() << e.GetDescription();
      return false;
    }

    return true;
  }
예제 #5
0
  bool MagnificationConverter::Convert(const std::string& name,
                                       Magnification& magnification)
  {
    auto entry=stringToMagMap.find(name);

    if (entry==stringToMagMap.end()) {
      return false;
    }

    magnification.SetMagnification(entry->second);

    return true;
  }
예제 #6
0
  /**
   * Return all tile necessary for covering the given boundingbox using the given magnification.
   */
  void DataTileCache::GetTilesForBoundingBox(const Magnification& magnification,
                                              const GeoBox& boundingBox,
                                              std::list<TileRef>& tiles) const
  {
    tiles.clear();

    //log.Debug() << "Creating tile data for level " << level << " and bounding box " << boundingBox.GetDisplayText();

    uint32_t level=magnification.GetLevel();

    uint32_t cx1=(uint32_t)floor((boundingBox.GetMinLon()+180.0)/cellDimension[level].width);
    uint32_t cy1=(uint32_t)floor((boundingBox.GetMinLat()+90.0)/cellDimension[level].height);

    uint32_t cx2=(uint32_t)floor((boundingBox.GetMaxLon()+180.0)/cellDimension[level].width);
    uint32_t cy2=(uint32_t)floor((boundingBox.GetMaxLat()+90.0)/cellDimension[level].height);

    //std::cout << "Tile bounding box: " << cx1 << "," << cy1 << " - "  << cx2 << "," << cy2 << std::endl;

    for (size_t y=cy1; y<=cy2; y++) {
      for (size_t x=cx1; x<=cx2; x++) {
        tiles.push_back(GetTile(TileId(magnification,x,y)));
      }
    }
  }
예제 #7
0
  bool WaterIndex::GetRegions(double minlon,
                              double minlat,
                              double maxlon,
                              double maxlat,
                              const Magnification& magnification,
                              std::list<GroundTile>& tiles) const
  {
    uint32_t cx1,cx2,cy1,cy2;
    uint32_t idx=magnification.GetLevel();

    if (levels.empty()) {
      return true;
    }

    idx+=4;

    idx=std::max(waterIndexMinMag,idx);
    idx=std::min(waterIndexMaxMag,idx);

    idx-=waterIndexMinMag;

    tiles.clear();

    if (!scanner.IsOpen()) {
      if (!scanner.Open(datafilename,FileScanner::LowMemRandom,true)) {
        log.Error() << "Error while opening " << scanner.GetFilename() << " for reading!";
        return false;
      }
    }

    cx1=(uint32_t)floor((minlon+180.0)/levels[idx].cellWidth);
    cx2=(uint32_t)floor((maxlon+180.0)/levels[idx].cellWidth);
    cy1=(uint32_t)floor((minlat+90.0)/levels[idx].cellHeight);
    cy2=(uint32_t)floor((maxlat+90.0)/levels[idx].cellHeight);

    GroundTile tile;

    tile.coords.reserve(5);
    tile.cellWidth=levels[idx].cellWidth;
    tile.cellHeight=levels[idx].cellHeight;

    for (uint32_t y=cy1; y<=cy2; y++) {
      for (uint32_t x=cx1; x<=cx2; x++) {
        tile.xAbs=x;
        tile.yAbs=y;

        if (x>=levels[idx].cellXStart &&
            y>=levels[idx].cellYStart) {
          tile.xRel=x-levels[idx].cellXStart;
          tile.yRel=y-levels[idx].cellYStart;
        }
        else {
          tile.xRel=0;
          tile.yRel=0;
        }

        if (x<levels[idx].cellXStart ||
            x>levels[idx].cellXEnd ||
            y<levels[idx].cellYStart ||
            y>levels[idx].cellYEnd) {
          tile.type=GroundTile::unknown;
          tile.coords.clear();

          tiles.push_back(tile);
        }
        else {
          uint32_t   cellId=(y-levels[idx].cellYStart)*levels[idx].cellXCount+x-levels[idx].cellXStart;
          uint32_t   index=cellId*8;
          FileOffset cell;

          scanner.SetPos(levels[idx].offset+index);

          if (!scanner.Read(cell)) {
            log.Error() << "Error while reading from file '" << scanner.GetFilename() << "'";
            return false;
          }

          if (cell==(FileOffset)GroundTile::land ||
              cell==(FileOffset)GroundTile::water ||
              cell==(FileOffset)GroundTile::coast ||
              cell==(FileOffset)GroundTile::unknown) {
            tile.type=(GroundTile::Type)cell;
            tile.coords.clear();

            tiles.push_back(tile);
          }
          else {
            uint32_t tileCount;

            tile.type=GroundTile::coast;
            tile.coords.clear();

            tiles.push_back(tile);

            scanner.SetPos(cell);
            scanner.ReadNumber(tileCount);

            for (size_t t=1; t<=tileCount; t++) {
              uint8_t    tileType;
              uint32_t   coordCount;

              scanner.Read(tileType);

              tile.type=(GroundTile::Type)tileType;

              scanner.ReadNumber(coordCount);

              tile.coords.resize(coordCount);

              for (size_t n=0; n<coordCount; n++) {
                uint16_t x;
                uint16_t y;

                scanner.Read(x);
                scanner.Read(y);

                tile.coords[n].Set(x & ~(1 << 15),
                                   y,
                                   x & (1 << 15));
              }

              tiles.push_back(tile);
            }
          }
        }
      }
    }

    return true;
  }
  bool OptimizeAreasLowZoomGenerator::HandleAreas(const ImportParameter& parameter,
                                                  Progress& progress,
                                                  const TypeConfig& typeConfig,
                                                  FileWriter& writer,
                                                  const TypeInfoSet& types,
                                                  std::list<TypeData>& typesData)
  {
    FileScanner scanner;
    // Everything smaller than 2mm should get dropped. Width, height and DPI come from the Nexus 4
    double dpi=320.0;
    double pixel=2.0/* mm */ * dpi / 25.4 /* inch */;

    progress.Info("Minimum visible size in pixel: "+NumberToString((unsigned long)pixel));

    try {
      scanner.Open(AppendFileToDir(parameter.GetDestinationDirectory(),
                                   AreaDataFile::AREAS_DAT),
                   FileScanner::Sequential,
                   parameter.GetWayDataMemoryMaped());

      TypeInfoSet                      typesToProcess(types);
      std::vector<std::list<AreaRef> > allAreas(typeConfig.GetTypeCount());

      while (true) {
        //
        // Load type data
        //

        TypeInfoSet loadedTypes;

        if (!GetAreas(typeConfig,
                      parameter,
                      progress,
                      scanner,
                      typesToProcess,
                      allAreas,
                      loadedTypes)) {
          return false;
        }

        typesToProcess.Remove(loadedTypes);

        for (const auto& type : loadedTypes) {
          progress.SetAction("Optimizing type "+ type->GetName());

          for (uint32_t level=parameter.GetOptimizationMinMag();
               level<=parameter.GetOptimizationMaxMag();
               level++) {
            Magnification      magnification; // Magnification, we optimize for
            std::list<AreaRef> optimizedAreas;

            magnification.SetLevel(level);

            OptimizeAreas(allAreas[type->GetIndex()],
                          optimizedAreas,
                          1280,768,
                          dpi,
                          pixel,
                          magnification,
                          parameter.GetOptimizationWayMethod());

            if (optimizedAreas.empty()) {
              progress.Debug("Empty optimization result for level "+NumberToString(level)+", no index generated");

              TypeData typeData;

              typeData.type=type;
              typeData.optLevel=level;

              typesData.push_back(typeData);

              continue;
            }

            progress.Info("Optimized from "+NumberToString(allAreas[type->GetIndex()].size())+" to "+NumberToString(optimizedAreas.size())+" areas");

            /*
            size_t optAreas=optimizedAreas.size();
            size_t optRoles=0;
            size_t optNodes=0;

            for (std::list<AreaRef>::const_iterator a=optimizedAreas.begin();
                a!=optimizedAreas.end();
                ++a) {
              AreaRef area=*a;

              optRoles+=area->rings.size();

              for (size_t r=0; r<area->rings.size(); r++) {
                optNodes+=area->rings[r].nodes.size();
              }
            }*/

            /*
            std::cout << "Areas: " << origAreas << " => " << optAreas << std::endl;
            std::cout << "Roles: " << origRoles << " => " << optRoles << std::endl;
            std::cout << "Nodes: " << origNodes << " => " << optNodes << std::endl;*/

            TypeData typeData;

            typeData.type=type;
            typeData.optLevel=level;

            GetAreaIndexLevel(parameter,
                              optimizedAreas,
                              typeData);

            //std::cout << "Resulting index level: " << typeData.indexLevel << ", " << typeData.indexCells << ", " << typeData.indexEntries << std::endl;

            FileOffsetFileOffsetMap offsets;

            WriteAreas(typeConfig,
                       writer,
                       optimizedAreas,
                       offsets);

            if (!WriteAreaBitmap(progress,
                                 writer,
                                 optimizedAreas,
                                 offsets,
                                 typeData)) {
              return false;
            }

            typesData.push_back(typeData);
          }

          allAreas[type->GetIndex()].clear();
        }

        if (typesToProcess.Empty()) {
          break;
        }
      }

      scanner.Close();
    }
    catch (IOException& e) {
      progress.Error(e.GetDescription());
      return false;
    }

    return true;
  }