/** * 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); }
/** * 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 }
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; }
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; }
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; }
/** * 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))); } } }
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; }