TypeId TypeManager::registerType( std::type_info const& typeId, TypeInfo info ) { const TypeId id = info.GetId(); assert( id <= impl_->nextTypeId_ ); // no funny business! can't make up your own ids! // grow list if( impl_->infos_.size() <= static_cast<size_t>( id ) ) impl_->infos_.resize( id + 1, TypeInfo( INVALID_TYPE ) ); impl_->infos_[id] = info; impl_->allTypes_[ typeId ] = id; assert( impl_->typeNames_.find( info.GetName() ) == impl_->typeNames_.end() \ && "Re-registering type not supported" ); impl_->typeNames_[info.GetName()] = id; return info.GetId(); }
bool AreaWayIndexGenerator::FitsIndexCriteria(const ImportParameter& parameter, Progress& progress, const TypeInfo& typeInfo, const TypeData& typeData, const CoordCountMap& cellFillCount) { if (typeData.indexCells==0) { return true; } size_t entryCount=0; size_t max=0; for (CoordCountMap::const_iterator cell=cellFillCount.begin(); cell!=cellFillCount.end(); ++cell) { entryCount+=cell->second; max=std::max(max,cell->second); } // Average number of entries per tile cell double average=entryCount*1.0/cellFillCount.size(); // If the fill rate of the index is too low, we use this index level anyway if (typeData.indexCells/(1.0*typeData.cellXCount*typeData.cellYCount)<= parameter.GetAreaWayIndexMinFillRate()) { progress.Warning(typeInfo.GetName()+" ("+NumberToString(typeInfo.GetId())+") is not well distributed"); return true; } // If average fill size and max fill size for tile cells // is within limits, store it now. if (max<=parameter.GetAreaWayIndexCellSizeMax() && average<=parameter.GetAreaWayIndexCellSizeAverage()) { return true; } return false; }
bool AreaWayIndexGenerator::WriteBitmap(Progress& progress, FileWriter& writer, const TypeInfo& typeInfo, const TypeData& typeData, const CoordOffsetsMap& typeCellOffsets) { size_t indexEntries=0; size_t dataSize=0; char buffer[10]; for (CoordOffsetsMap::const_iterator cell=typeCellOffsets.begin(); cell!=typeCellOffsets.end(); ++cell) { indexEntries+=cell->second.size(); dataSize+=EncodeNumber(cell->second.size(),buffer); FileOffset previousOffset=0; for (std::list<FileOffset>::const_iterator offset=cell->second.begin(); offset!=cell->second.end(); ++offset) { FileOffset data=*offset-previousOffset; dataSize+=EncodeNumber(data,buffer); previousOffset=*offset; } } // "+1" because we add +1 to every offset, to generate offset > 0 uint8_t dataOffsetBytes=BytesNeededToAddressFileData(dataSize+1); progress.Info("Writing map for "+ typeInfo.GetName()+" , "+ ByteSizeToString(1.0*dataOffsetBytes*typeData.cellXCount*typeData.cellYCount+dataSize)); FileOffset bitmapOffset; if (!writer.GetPos(bitmapOffset)) { progress.Error("Cannot get type index start position in file"); return false; } assert(typeData.indexOffset!=0); if (!writer.SetPos(typeData.indexOffset)) { progress.Error("Cannot go to type index offset in file"); return false; } writer.WriteFileOffset(bitmapOffset); writer.Write(dataOffsetBytes); if (!writer.SetPos(bitmapOffset)) { progress.Error("Cannot go to type index start position in file"); return false; } // Write the bitmap with offsets for each cell // We prefill with zero and only overwrite cells that have data // So zero means "no data for this cell" for (size_t i=0; i<typeData.cellXCount*typeData.cellYCount; i++) { writer.WriteFileOffset(0, dataOffsetBytes); } FileOffset dataStartOffset; if (!writer.GetPos(dataStartOffset)) { progress.Error("Cannot get start of data section after bitmap"); return false; } // Now write the list of offsets of objects for every cell with content for (CoordOffsetsMap::const_iterator cell=typeCellOffsets.begin(); cell!=typeCellOffsets.end(); ++cell) { FileOffset bitmapCellOffset=bitmapOffset+ ((cell->first.y-typeData.cellYStart)*typeData.cellXCount+ cell->first.x-typeData.cellXStart)*(FileOffset)dataOffsetBytes; FileOffset previousOffset=0; FileOffset cellOffset; assert(bitmapCellOffset>=bitmapOffset); if (!writer.GetPos(cellOffset)) { progress.Error("Cannot get cell start position in file"); return false; } if (!writer.SetPos(bitmapCellOffset)) { progress.Error("Cannot go to cell start position in file"); return false; } assert(cellOffset>bitmapCellOffset); // We add +1 to make sure, that we can differentiate between "0" as "no entry" and "0" as first data entry. writer.WriteFileOffset(cellOffset-dataStartOffset+1,dataOffsetBytes); if (!writer.SetPos(cellOffset)) { progress.Error("Cannot go back to cell start position in file"); return false; } writer.WriteNumber((uint32_t)cell->second.size()); // FileOffsets are already in increasing order, since // File is scanned from start to end for (std::list<FileOffset>::const_iterator offset=cell->second.begin(); offset!=cell->second.end(); ++offset) { writer.WriteNumber((FileOffset)(*offset-previousOffset)); previousOffset=*offset; } } return true; }
bool AreaWayIndexGenerator::FitsIndexCriteria(const ImportParameter& /*parameter*/, Progress& progress, const TypeInfo& typeInfo, const TypeData& typeData, const CoordCountMap& cellFillCount) const { if (typeData.indexCells==0) { return true; } size_t overallCount=0; size_t maxCellCount=0; for (const auto& cell : cellFillCount) { overallCount+=cell.second; maxCellCount=std::max(maxCellCount,cell.second); } // Average number of entries per tile cell double average=overallCount*1.0/cellFillCount.size(); size_t emptyCount=0; size_t toLowCount=0; size_t toHighCount=0; size_t inCount=0; size_t allCount=0; for (const auto& cell : cellFillCount) { if (cell.second==0) { emptyCount++; } else if (cell.second<0.4*average) { toLowCount++; } else if (cell.second>128){ toHighCount++; } else { inCount++; } allCount++; } if (toHighCount*1.0/allCount>=0.05) { return false; } if (toLowCount*1.0/allCount>=0.2) { progress.Warning(typeInfo.GetName()+" has more than 20% cells with <40% of average filling ("+NumberToString(toLowCount)+"/"+NumberToString(allCount)+")"); } /* // If the fill rate of the index is too low, we use this index level anyway if (fillRate<parameter.GetAreaWayIndexMinFillRate()) { progress.Warning(typeInfo.GetName()+" is not well distributed"); return true; } // If average fill size and max fill size for tile cells // is within limits, store it now. if (maxCellCount<=parameter.GetAreaWayIndexCellSizeMax() && average<=parameter.GetAreaWayIndexCellSizeAverage()) { return true; }*/ return true; }