bool OptimizeAreaWayIdsGenerator::ScanAreaIds(const ImportParameter& parameter, Progress& progress, const TypeConfig& typeConfig, NodeUseMap& nodeUseMap) { FileScanner scanner; uint32_t dataCount=0; progress.SetAction("Scanning ids from 'areas2.tmp'"); if (!scanner.Open(AppendFileToDir(parameter.GetDestinationDirectory(), "areas2.tmp"), FileScanner::Sequential, parameter.GetAreaDataMemoryMaped())) { progress.Error(std::string("Cannot open '")+scanner.GetFilename()+"'"); return false; } if (!scanner.Read(dataCount)) { progress.Error("Error while reading number of data entries in file"); return false; } for (uint32_t current=1; current<=dataCount; current++) { uint8_t type; Id id; Area data; progress.SetProgress(current,dataCount); if (!scanner.Read(type) || !scanner.Read(id) || !data.ReadImport(typeConfig, scanner)) { progress.Error(std::string("Error while reading data entry ")+ NumberToString(current)+" of "+ NumberToString(dataCount)+ " in file '"+ scanner.GetFilename()+"'"); return false; } for (const auto& ring: data.rings) { std::unordered_set<Id> nodeIds; if (!ring.GetType()->CanRoute()) { continue; } for (const auto id: ring.ids) { if (nodeIds.find(id)==nodeIds.end()) { nodeUseMap.SetNodeUsed(id); nodeIds.insert(id); } } } } if (!scanner.Close()) { progress.Error(std::string("Error while closing file '")+ scanner.GetFilename()+"'"); return false; } return true; }
/** * Scans all areas. If an areas is of one of the given merge types, index all node ids * into the given NodeUseMap for all outer rings of the given area. */ bool MergeAreasGenerator::ScanAreaNodeIds(Progress& progress, const TypeConfig& typeConfig, FileScanner& scanner, const TypeInfoSet& mergeTypes, std::unordered_set<Id>& nodeUseMap) { uint32_t areaCount=0; progress.SetAction("Scanning for nodes joining areas from '"+scanner.GetFilename()+"'"); scanner.GotoBegin(); scanner.Read(areaCount); uint8_t type; Id id; Area data; std::unordered_set<Id> usedOnceSet; for (uint32_t current=1; current<=areaCount; current++) { progress.SetProgress(current,areaCount); scanner.Read(type); scanner.Read(id); data.ReadImport(typeConfig, scanner); if (!mergeTypes.IsSet(data.GetType())) { continue; } // We insert every node id only once per area, because we want to // find nodes that are shared by *different* areas. std::unordered_set<Id> nodeIds; for (const auto& ring: data.rings) { if (!ring.IsOuterRing()) { continue; } for (const auto node : ring.nodes) { Id id=node.GetId(); if (nodeIds.find(id)==nodeIds.end()) { auto entry=usedOnceSet.find(id); if (entry!=usedOnceSet.end()) { nodeUseMap.insert(id); } else { usedOnceSet.insert(id); } nodeIds.insert(id); } } } } return true; }
bool OptimizeAreaWayIdsGenerator::CopyAreas(const ImportParameter& parameter, Progress& progress, const TypeConfig& typeConfig, NodeUseMap& nodeUseMap) { FileScanner scanner; FileWriter writer; uint32_t areaCount=0; if (!writer.Open(AppendFileToDir(parameter.GetDestinationDirectory(), "areas3.tmp"))) { progress.Error(std::string("Cannot create '")+writer.GetFilename()+"'"); return false; } writer.Write(areaCount); progress.SetAction("Copy data from 'areas2.tmp' to 'areas3.tmp'"); if (!scanner.Open(AppendFileToDir(parameter.GetDestinationDirectory(), "areas2.tmp"), FileScanner::Sequential, parameter.GetAreaDataMemoryMaped())) { progress.Error(std::string("Cannot open '")+scanner.GetFilename()+"'"); return false; } if (!scanner.Read(areaCount)) { progress.Error("Error while reading number of data entries in file"); return false; } for (uint32_t current=1; current<=areaCount; current++) { uint8_t type; Id id; Area data; progress.SetProgress(current,areaCount); if (!scanner.Read(type) || !scanner.Read(id) || !data.ReadImport(typeConfig, scanner)) { progress.Error(std::string("Error while reading data entry ")+ NumberToString(current)+" of "+ NumberToString(areaCount)+ " in file '"+ scanner.GetFilename()+"'"); return false; } for (auto& ring : data.rings) { std::unordered_set<Id> nodeIds; for (auto& id : ring.ids) { if (!nodeUseMap.IsNodeUsedAtLeastTwice(id)) { id=0; } } } if (!writer.Write(type) || !writer.Write(id) || !data.Write(typeConfig, writer)) { progress.Error(std::string("Error while writing data entry to file '")+ writer.GetFilename()+"'"); return false; } } if (!scanner.Close()) { progress.Error(std::string("Error while closing file '")+ scanner.GetFilename()+"'"); return false; } if (!writer.SetPos(0)) { return false; } if (!writer.Write(areaCount)) { return false; } if (!writer.Close()) { progress.Error(std::string("Error while closing file '")+ writer.GetFilename()+"'"); return false; } return true; }