void OsmAnd::ObfRoutingSectionReader_P::readBorderLinePoints( const std::unique_ptr<ObfReader_P>& reader, QList< std::shared_ptr<const ObfRoutingBorderLinePoint> >* resultOut /*= nullptr*/, IQueryFilter* filter /*= nullptr*/, std::function<bool (const std::shared_ptr<const ObfRoutingBorderLinePoint>&)> visitor /*= nullptr*/ ) { auto cis = reader->_codedInputStream.get(); PointI location; gpb::uint64 id; for(;;) { auto tag = cis->ReadTag(); switch(gpb::internal::WireFormatLite::GetTagFieldNumber(tag)) { case 0: return; case OBF::OsmAndRoutingIndex_RouteBorderPointsBlock::kXFieldNumber: cis->ReadVarint32(reinterpret_cast<gpb::uint32*>(&location.x)); break; case OBF::OsmAndRoutingIndex_RouteBorderPointsBlock::kYFieldNumber: cis->ReadVarint32(reinterpret_cast<gpb::uint32*>(&location.y)); break; case OBF::OsmAndRoutingIndex_RouteBorderPointsBlock::kBaseIdFieldNumber: cis->ReadVarint64(&id); break; case OBF::OsmAndRoutingIndex_RouteBorderPointsBlock::kPointsFieldNumber: { gpb::uint32 length; cis->ReadVarint32(&length); auto oldLimit = cis->PushLimit(length); const std::shared_ptr<ObfRoutingBorderLinePoint> point(new ObfRoutingBorderLinePoint()); readBorderLinePoint(reader, point); cis->PopLimit(oldLimit); point->_id += id; point->_location += location; id = point->_id; location = point->_location; bool valid = true; if(filter) valid = filter->acceptsPoint(point->location); if(valid && visitor) valid = visitor(point); if(valid && resultOut) resultOut->push_back(qMove(point)); } break; default: ObfReaderUtilities::skipUnknownField(cis, tag); break; } } }
void OsmAnd::ObfAddressSectionReader_P::readStreet( const std::unique_ptr<ObfReader_P>& reader, const std::shared_ptr<const Model::StreetGroup>& group, const std::shared_ptr<Model::Street>& street) { auto cis = reader->_codedInputStream.get(); for(;;) { auto tag = cis->ReadTag(); switch(gpb::internal::WireFormatLite::GetTagFieldNumber(tag)) { case 0: if(street->_latinName.isEmpty()) street->_latinName = reader->transliterate(street->_name); return; case OBF::StreetIndex::kIdFieldNumber: cis->ReadVarint64(reinterpret_cast<gpb::uint64*>(&street->_id)); break; case OBF::StreetIndex::kNameEnFieldNumber: ObfReaderUtilities::readQString(cis, street->_latinName); break; case OBF::StreetIndex::kNameFieldNumber: ObfReaderUtilities::readQString(cis, street->_name); break; case OBF::StreetIndex::kXFieldNumber: { auto dx = ObfReaderUtilities::readSInt32(cis); street->_tile24.x = (Utilities::get31TileNumberX(group->_longitude) >> 7) + dx; } break; case OBF::StreetIndex::kYFieldNumber: { auto dy = ObfReaderUtilities::readSInt32(cis); street->_tile24.y = (Utilities::get31TileNumberY(group->_latitude) >> 7) + dy; } break; case OBF::StreetIndex::kIntersectionsFieldNumber: case OBF::StreetIndex::kBuildingsFieldNumber: { gpb::uint32 length; cis->ReadVarint32(&length); cis->Skip(length); } break; default: ObfReaderUtilities::skipUnknownField(cis, tag); break; } } }
void OsmAnd::ObfRoutingSectionReader_P::readBorderLinePoint( const std::unique_ptr<ObfReader_P>& reader, const std::shared_ptr<ObfRoutingBorderLinePoint>& point) { auto cis = reader->_codedInputStream.get(); for(;;) { auto tag = cis->ReadTag(); switch(gpb::internal::WireFormatLite::GetTagFieldNumber(tag)) { case 0: return; case OBF::OsmAndRoutingIndex_RouteBorderPoint::kDxFieldNumber: cis->ReadVarint32(reinterpret_cast<gpb::uint32*>(&point->_location.x)); break; case OBF::OsmAndRoutingIndex_RouteBorderPoint::kDyFieldNumber: cis->ReadVarint32(reinterpret_cast<gpb::uint32*>(&point->_location.y)); break; case OBF::OsmAndRoutingIndex_RouteBorderPoint::kRoadIdFieldNumber: cis->ReadVarint64(&point->_id); break; case OBF::OsmAndRoutingIndex_RouteBorderPoint::kDirectionFieldNumber: { gpb::uint32 value; cis->ReadVarint32(&value); //TODO:p.direction = codedIS.readBool(); } break; case OBF::OsmAndRoutingIndex_RouteBorderPoint::kTypesFieldNumber: { gpb::uint32 length; cis->ReadVarint32(&length); auto oldLimit = cis->PushLimit(length); while(cis->BytesUntilLimit() > 0) { gpb::uint32 value; cis->ReadVarint32(&value); point->_types.push_back(value); } cis->PopLimit(oldLimit); } break; default: ObfReaderUtilities::skipUnknownField(cis, tag); break; } } }
bool OsmAnd::ObfReader_P::readInfo(const ObfReader_P& reader, std::shared_ptr<const ObfInfo>& info_) { auto cis = reader._codedInputStream.get(); std::shared_ptr<ObfInfo> info(new ObfInfo()); bool loadedCorrectly = false; for(;;) { auto tag = cis->ReadTag(); switch(gpb::internal::WireFormatLite::GetTagFieldNumber(tag)) { case 0: if(loadedCorrectly) info_ = info; return loadedCorrectly; case OBF::OsmAndStructure::kVersionFieldNumber: cis->ReadVarint32(reinterpret_cast<gpb::uint32*>(&info->_version)); break; case OBF::OsmAndStructure::kDateCreatedFieldNumber: cis->ReadVarint64(reinterpret_cast<gpb::uint64*>(&info->_creationTimestamp)); break; case OBF::OsmAndStructure::kMapIndexFieldNumber: { const std::shared_ptr<ObfMapSectionInfo> section(new ObfMapSectionInfo(info)); section->_length = ObfReaderUtilities::readBigEndianInt(cis); section->_offset = cis->CurrentPosition(); auto oldLimit = cis->PushLimit(section->_length); ObfMapSectionReader_P::read(reader, section); info->_isBasemap = info->_isBasemap || section->isBasemap; cis->PopLimit(oldLimit); cis->Seek(section->_offset + section->_length); info->_mapSections.push_back(qMove(section)); } break; case OBF::OsmAndStructure::kAddressIndexFieldNumber: { const std::shared_ptr<ObfAddressSectionInfo> section(new ObfAddressSectionInfo(info)); section->_length = ObfReaderUtilities::readBigEndianInt(cis); section->_offset = cis->CurrentPosition(); auto oldLimit = cis->PushLimit(section->_length); ObfAddressSectionReader_P::read(reader, section); cis->PopLimit(oldLimit); cis->Seek(section->_offset + section->_length); info->_addressSections.push_back(qMove(section)); } break; case OBF::OsmAndStructure::kTransportIndexFieldNumber: { const std::shared_ptr<ObfTransportSectionInfo> section(new ObfTransportSectionInfo(info)); section->_length = ObfReaderUtilities::readBigEndianInt(cis); section->_offset = cis->CurrentPosition(); auto oldLimit = cis->PushLimit(section->_length); ObfTransportSectionReader_P::read(reader, section); cis->PopLimit(oldLimit); cis->Seek(section->_offset + section->_length); info->_transportSections.push_back(qMove(section)); } break; case OBF::OsmAndStructure::kRoutingIndexFieldNumber: { const std::shared_ptr<ObfRoutingSectionInfo> section(new ObfRoutingSectionInfo(info)); section->_length = ObfReaderUtilities::readBigEndianInt(cis); section->_offset = cis->CurrentPosition(); auto oldLimit = cis->PushLimit(section->_length); ObfRoutingSectionReader_P::read(reader, section); cis->PopLimit(oldLimit); cis->Seek(section->_offset + section->_length); info->_routingSections.push_back(qMove(section)); } break; case OBF::OsmAndStructure::kPoiIndexFieldNumber: { const std::shared_ptr<ObfPoiSectionInfo> section(new ObfPoiSectionInfo(info)); section->_length = ObfReaderUtilities::readBigEndianInt(cis); section->_offset = cis->CurrentPosition(); auto oldLimit = cis->PushLimit(section->_length); ObfPoiSectionReader_P::read(reader, section); cis->PopLimit(oldLimit); cis->Seek(section->_offset + section->_length); info->_poiSections.push_back(qMove(section)); } break; case OBF::OsmAndStructure::kVersionConfirmFieldNumber: { gpb::uint32 controlVersion; cis->ReadVarint32(&controlVersion); loadedCorrectly = (controlVersion == info->_version); if(!loadedCorrectly) break; } break; default: ObfReaderUtilities::skipUnknownField(cis, tag); break; } } return false; }
void OsmAnd::ObfMapSectionReader_P::readMapObjectsBlock( const ObfReader_P& reader, const std::shared_ptr<const ObfMapSectionInfo>& section, const std::shared_ptr<const ObfMapSectionLevelTreeNode>& tree, QList< std::shared_ptr<const OsmAnd::BinaryMapObject> >* resultOut, const AreaI* bbox31, const FilterReadingByIdFunction filterById, const VisitorFunction visitor, const std::shared_ptr<const IQueryController>& queryController, ObfMapSectionReader_Metrics::Metric_loadMapObjects* const metric) { const auto cis = reader.getCodedInputStream().get(); QList< std::shared_ptr<BinaryMapObject> > intermediateResult; QStringList mapObjectsCaptionsTable; gpb::uint64 baseId = 0; for (;;) { const auto tag = cis->ReadTag(); switch (gpb::internal::WireFormatLite::GetTagFieldNumber(tag)) { case 0: { if (!ObfReaderUtilities::reachedDataEnd(cis)) return; for (const auto& mapObject : constOf(intermediateResult)) { // Fill mapObject captions from string-table for (auto& caption : mapObject->captions) { const auto stringId = ObfReaderUtilities::decodeIntegerFromString(caption); if (stringId >= mapObjectsCaptionsTable.size()) { LogPrintf(LogSeverityLevel::Error, "Data mismatch: string #%d (map object %s not found in string table (size %d) in section '%s'", stringId, qPrintable(mapObject->id.toString()), mapObjectsCaptionsTable.size(), qPrintable(section->name)); caption = QString::fromLatin1("#%1 NOT FOUND").arg(stringId); continue; } caption = mapObjectsCaptionsTable[stringId]; } ////////////////////////////////////////////////////////////////////////// //if (mapObject->id.getOsmId() == 49048972u) //{ // int i = 5; //} ////////////////////////////////////////////////////////////////////////// if (!visitor || visitor(mapObject)) { if (resultOut) resultOut->push_back(qMove(mapObject)); } } return; } case OBF::MapDataBlock::kBaseIdFieldNumber: { cis->ReadVarint64(&baseId); ////////////////////////////////////////////////////////////////////////// //if (bbox31) // LogPrintf(LogSeverityLevel::Debug, "BBOX %d %d %d %d - MAP BLOCK %" PRIi64, bbox31->top, bbox31->left, bbox31->bottom, bbox31->right, baseId); ////////////////////////////////////////////////////////////////////////// break; } case OBF::MapDataBlock::kDataObjectsFieldNumber: { gpb::uint32 length; cis->ReadVarint32(&length); const auto offset = cis->CurrentPosition(); // Read map object content const Stopwatch readMapObjectStopwatch(metric != nullptr); std::shared_ptr<OsmAnd::BinaryMapObject> mapObject; auto oldLimit = cis->PushLimit(length); readMapObject(reader, section, baseId, tree, mapObject, bbox31, metric); ObfReaderUtilities::ensureAllDataWasRead(cis); cis->PopLimit(oldLimit); // Update metric if (metric) metric->visitedMapObjects++; // If map object was not read, skip it if (!mapObject) { if (metric) metric->elapsedTimeForOnlyVisitedMapObjects += readMapObjectStopwatch.elapsed(); break; } // Update metric if (metric) { metric->elapsedTimeForOnlyAcceptedMapObjects += readMapObjectStopwatch.elapsed(); metric->acceptedMapObjects++; } ////////////////////////////////////////////////////////////////////////// //if (mapObject->id.getOsmId() == 49048972u) //{ // int i = 5; //} ////////////////////////////////////////////////////////////////////////// // Check if map object is desired const auto shouldReject = filterById && !filterById( section, mapObject->id, mapObject->bbox31, mapObject->level->minZoom, mapObject->level->maxZoom); if (shouldReject) break; // Save object intermediateResult.push_back(qMove(mapObject)); break; } case OBF::MapDataBlock::kStringTableFieldNumber: { gpb::uint32 length; cis->ReadVarint32(&length); const auto offset = cis->CurrentPosition(); auto oldLimit = cis->PushLimit(length); if (intermediateResult.isEmpty()) { cis->Skip(cis->BytesUntilLimit()); cis->PopLimit(oldLimit); break; } ObfReaderUtilities::readStringTable(cis, mapObjectsCaptionsTable); ObfReaderUtilities::ensureAllDataWasRead(cis); cis->PopLimit(oldLimit); break; } default: ObfReaderUtilities::skipUnknownField(cis, tag); break; } } }
void OsmAnd::ObfAddressSectionReader_P::readBuilding( const std::unique_ptr<ObfReader_P>& reader, const std::shared_ptr<const Model::Street>& street, const std::shared_ptr<Model::Building>& building ) { auto cis = reader->_codedInputStream.get(); for(;;) { auto tag = cis->ReadTag(); switch(gpb::internal::WireFormatLite::GetTagFieldNumber(tag)) { case 0: if(building->_latinName.isEmpty()) building->_latinName = reader->transliterate(building->_name); if(building->_latinName2.isEmpty()) building->_latinName2 = reader->transliterate(building->_name2); return; case OBF::BuildingIndex::kIdFieldNumber: cis->ReadVarint64(reinterpret_cast<gpb::uint64*>(&building->_id)); break; case OBF::BuildingIndex::kNameEnFieldNumber: ObfReaderUtilities::readQString(cis, building->_latinName); break; case OBF::BuildingIndex::kNameFieldNumber: ObfReaderUtilities::readQString(cis, building->_name); break; case OBF::BuildingIndex::kNameEn2FieldNumber: ObfReaderUtilities::readQString(cis, building->_latinName2); break; case OBF::BuildingIndex::kName2FieldNumber: ObfReaderUtilities::readQString(cis, building->_name2); break; case OBF::BuildingIndex::kInterpolationFieldNumber: { auto value = ObfReaderUtilities::readSInt32(cis); if(value > 0) building->_interpolationInterval = value; else building->_interpolation = static_cast<Model::Building::Interpolation>(value); } break; case OBF::BuildingIndex::kXFieldNumber: { auto dx = ObfReaderUtilities::readSInt32(cis); building->_xTile24 = street->_tile24.x + dx; } break; case OBF::BuildingIndex::kX2FieldNumber: { auto dx2 = ObfReaderUtilities::readSInt32(cis); building->_x2Tile24 = street->_tile24.x + dx2; } break; case OBF::BuildingIndex::kYFieldNumber: { auto dy = ObfReaderUtilities::readSInt32(cis); building->_yTile24 = street->_tile24.y + dy; } break; case OBF::BuildingIndex::kY2FieldNumber: { auto dy2 = ObfReaderUtilities::readSInt32(cis); building->_y2Tile24 = street->_tile24.y + dy2; } break; case OBF::BuildingIndex::kPostcodeFieldNumber: ObfReaderUtilities::readQString(cis, building->_postcode); break; default: ObfReaderUtilities::skipUnknownField(cis, tag); break; } } }
void OsmAnd::ObfAddressSectionReader_P::readStreetGroupHeader( const std::unique_ptr<ObfReader_P>& reader, const std::shared_ptr<const ObfAddressBlocksSectionInfo>& section, unsigned int offset, std::shared_ptr<OsmAnd::Model::StreetGroup>& outStreetGroup ) { auto cis = reader->_codedInputStream.get(); std::shared_ptr<OsmAnd::Model::StreetGroup> streetGroup; // boolean englishNameMatched = false; for(;;) { auto tag = cis->ReadTag(); switch(gpb::internal::WireFormatLite::GetTagFieldNumber(tag)) { case 0: if(streetGroup->_latinName.isEmpty()) streetGroup->_latinName = reader->transliterate(streetGroup->_name); outStreetGroup = streetGroup; return; case OBF::CityIndex::kCityTypeFieldNumber: { gpb::uint32 type; cis->ReadVarint32(&type); streetGroup.reset(new Model::Settlement(/*TODO:type*/)); } break; case OBF::CityIndex::kIdFieldNumber: cis->ReadVarint64(reinterpret_cast<gpb::uint64*>(&streetGroup->_id)); /* TODO: if(nameMatcher != null && useEn && !englishNameMatched){ codedIS.skipRawBytes(codedIS.getBytesUntilLimit()); return null; } */ break; case OBF::CityIndex::kNameEnFieldNumber: { ObfReaderUtilities::readQString(cis, streetGroup->_latinName); /* TODO: if (nameMatcher != null && latinName.length() > 0 && nameMatcher.matches(latinName)) { englishNameMatched = true; } */ } break; case OBF::CityIndex::kNameFieldNumber: { QString name; ObfReaderUtilities::readQString(cis, name); /* if(nameMatcher != null){ if(!useEn){ if(!nameMatcher.matches(name)) { codedIS.skipRawBytes(codedIS.getBytesUntilLimit()); return null; } } else if(nameMatcher.matches(Junidecode.unidecode(name))){ englishNameMatched = true; } } */ if(!streetGroup) streetGroup.reset(new Model::PostcodeArea()); streetGroup->_name = name; } break; case OBF::CityIndex::kXFieldNumber: { gpb::uint32 x = 0; cis->ReadVarint32(&x); streetGroup->_longitude = Utilities::get31LongitudeX(x); } break; case OBF::CityIndex::kYFieldNumber: { gpb::uint32 y = 0; cis->ReadVarint32(&y); streetGroup->_latitude = Utilities::get31LatitudeY(y); } break; case OBF::CityIndex::kShiftToCityBlockIndexFieldNumber: streetGroup->_offset = ObfReaderUtilities::readBigEndianInt(cis) + offset; break; default: ObfReaderUtilities::skipUnknownField(cis, tag); break; } } }
void OsmAnd::ObfMapSectionReader_P::readMapObjectsBlock( const std::unique_ptr<ObfReader_P>& reader, const std::shared_ptr<const ObfMapSectionInfo>& section, const std::shared_ptr<ObfMapSectionLevelTreeNode>& tree, QList< std::shared_ptr<const OsmAnd::Model::MapObject> >* resultOut, const AreaI* bbox31, const FilterMapObjectsByIdSignature filterById, std::function<bool (const std::shared_ptr<const OsmAnd::Model::MapObject>&)> visitor, const IQueryController* const controller, ObfMapSectionReader_Metrics::Metric_loadMapObjects* const metric) { auto cis = reader->_codedInputStream.get(); QList< std::shared_ptr<Model::MapObject> > intermediateResult; QStringList mapObjectsNamesTable; gpb::uint64 baseId = 0; for(;;) { if(controller && controller->isAborted()) return; auto tag = cis->ReadTag(); switch(gpb::internal::WireFormatLite::GetTagFieldNumber(tag)) { case 0: for(const auto& mapObject : constOf(intermediateResult)) { // Fill mapObject names from stringtable for(auto& nameValue : mapObject->_names) { const auto stringId = ObfReaderUtilities::decodeIntegerFromString(nameValue); if(stringId >= mapObjectsNamesTable.size()) { LogPrintf(LogSeverityLevel::Error, "Data mismatch: string #%d (map object #%" PRIu64 " (%" PRIi64 ") not found in string table (size %d) in section '%s'", stringId, mapObject->id >> 1, static_cast<int64_t>(mapObject->id) / 2, mapObjectsNamesTable.size(), qPrintable(section->name)); nameValue = QString::fromLatin1("#%1 NOT FOUND").arg(stringId); continue; } nameValue = mapObjectsNamesTable[stringId]; } if(!visitor || visitor(mapObject)) { if(resultOut) resultOut->push_back(qMove(mapObject)); } } return; case OBF::MapDataBlock::kBaseIdFieldNumber: cis->ReadVarint64(&baseId); break; case OBF::MapDataBlock::kDataObjectsFieldNumber: { gpb::uint32 length; cis->ReadVarint32(&length); // Update metric std::chrono::high_resolution_clock::time_point readMapObject_begin; if(metric) readMapObject_begin = std::chrono::high_resolution_clock::now(); // Read map object content std::shared_ptr<OsmAnd::Model::MapObject> mapObject; { auto oldLimit = cis->PushLimit(length); readMapObject(reader, section, baseId, tree, mapObject, bbox31); assert(cis->BytesUntilLimit() == 0); // Update metric if(metric) metric->visitedMapObjects++; cis->PopLimit(oldLimit); } // If map object was not read, skip it if(!mapObject) { // Update metric if(metric) { const std::chrono::duration<float> readMapObject_elapsed = std::chrono::high_resolution_clock::now() - readMapObject_begin; metric->elapsedTimeForOnlyVisitedMapObjects += readMapObject_elapsed.count(); } break; } // Update metric if(metric) { const std::chrono::duration<float> readMapObject_elapsed = std::chrono::high_resolution_clock::now() - readMapObject_begin; metric->elapsedTimeForOnlyAcceptedMapObjects += readMapObject_elapsed.count(); metric->acceptedMapObjects++; } // Make unique map object identifier mapObject->_id = Model::MapObject::getUniqueId(mapObject->_id, section); // Check if map object is desired if(filterById && !filterById(section, mapObject->id, mapObject->bbox31, mapObject->level->minZoom, mapObject->level->maxZoom)) break; // Save object mapObject->_foundation = tree->_foundation; intermediateResult.push_back(qMove(mapObject)); } break; case OBF::MapDataBlock::kStringTableFieldNumber: { gpb::uint32 length; cis->ReadVarint32(&length); auto oldLimit = cis->PushLimit(length); if(intermediateResult.isEmpty()) { cis->Skip(cis->BytesUntilLimit()); cis->PopLimit(oldLimit); break; } ObfReaderUtilities::readStringTable(cis, mapObjectsNamesTable); assert(cis->BytesUntilLimit() == 0); cis->PopLimit(oldLimit); } break; default: ObfReaderUtilities::skipUnknownField(cis, tag); break; } }
void OsmAnd::ObfMapSectionReader_P::readMapObjectsBlock( const std::unique_ptr<ObfReader_P>& reader, const std::shared_ptr<const ObfMapSectionInfo>& section, const std::shared_ptr<ObfMapSectionLevelTreeNode>& tree, QList< std::shared_ptr<const OsmAnd::Model::MapObject> >* resultOut, const AreaI* bbox31, std::function<bool (const std::shared_ptr<const OsmAnd::Model::MapObject>&)> visitor, IQueryController* controller) { auto cis = reader->_codedInputStream.get(); QList< std::shared_ptr<OsmAnd::Model::MapObject> > intermediateResult; QStringList mapObjectsNamesTable; gpb::uint64 baseId = 0; for(;;) { if(controller && controller->isAborted()) return; auto tag = cis->ReadTag(); switch(gpb::internal::WireFormatLite::GetTagFieldNumber(tag)) { case 0: for(auto itEntry = intermediateResult.begin(); itEntry != intermediateResult.end(); ++itEntry) { const auto& entry = *itEntry; // Fill names of roads from stringtable for(auto itNameEntry = entry->_names.begin(); itNameEntry != entry->_names.end(); ++itNameEntry) { const auto& encodedId = itNameEntry.value(); uint32_t stringId = 0; stringId |= (encodedId.at(1 + 0).unicode() & 0xff) << 8*0; stringId |= (encodedId.at(1 + 1).unicode() & 0xff) << 8*1; stringId |= (encodedId.at(1 + 2).unicode() & 0xff) << 8*2; stringId |= (encodedId.at(1 + 3).unicode() & 0xff) << 8*3; if(stringId >= mapObjectsNamesTable.size()) { LogPrintf(LogSeverityLevel::Error, "Data mismatch: string #%d (map object #%" PRIu64 " (%" PRIi64 ") not found in string table(%d) in section '%s'", stringId, entry->id >> 1, static_cast<int64_t>(entry->id) / 2, mapObjectsNamesTable.size(), qPrintable(section->name)); itNameEntry.value() = QString::fromLatin1("#%1 NOT FOUND").arg(stringId); continue; } itNameEntry.value() = mapObjectsNamesTable[stringId]; } if(!visitor || visitor(entry)) { if(resultOut) resultOut->push_back(entry); } } return; case OBF::MapDataBlock::kBaseIdFieldNumber: cis->ReadVarint64(&baseId); break; case OBF::MapDataBlock::kDataObjectsFieldNumber: { gpb::uint32 length; cis->ReadVarint32(&length); auto oldLimit = cis->PushLimit(length); auto pos = cis->CurrentPosition(); std::shared_ptr<OsmAnd::Model::MapObject> mapObject; readMapObject(reader, section, tree, baseId, mapObject, bbox31); if(mapObject) { mapObject->_foundation = tree->_foundation; intermediateResult.push_back(mapObject); } cis->PopLimit(oldLimit); } break; case OBF::MapDataBlock::kStringTableFieldNumber: { gpb::uint32 length; cis->ReadVarint32(&length); auto oldLimit = cis->PushLimit(length); if(intermediateResult.isEmpty()) { cis->Skip(cis->BytesUntilLimit()); cis->PopLimit(oldLimit); break; } ObfReaderUtilities::readStringTable(cis, mapObjectsNamesTable); cis->PopLimit(oldLimit); } break; default: ObfReaderUtilities::skipUnknownField(cis, tag); break; } }