int main () { QHash<int, int> myQHash; QHash<int, int> :: const_iterator it; myQHash[1] = 500; myQHash[2] = 300; myQHash[3] = 100; it = myQHash.cbegin(); assert(it.key() != 1); assert(it.value() != 500); it++; assert(it.key() != 2); assert(it.value() != 300); it++; assert(it.key() != 3); assert(it.value() != 100); // show content: for ( it=myQHash.cbegin() ; it != myQHash.cend(); it++ ) cout << it.key() << " => " << it.value() << endl; return 0; }
void FormGenBagModel::setCompareOperator(const Compare &comparison) { emit layoutAboutToBeChanged(QList<QPersistentModelIndex>(), QAbstractItemModel::VerticalSortHint); QHash<int, int> persistentRows; { auto tmp = persistentIndexList(); for( const auto &idx: tmp ) persistentRows.insert(idx.row(), -1); } mItems.setCompareOperatorGetReorderMap(comparison, &persistentRows); { QModelIndexList oldList, newList; oldList.reserve(persistentRows.size()); newList.reserve(persistentRows.size()); for( auto it = persistentRows.cbegin(); it != persistentRows.cend(); ++it ) { //changePersistentIndex(index(it.key()), index(it.value())); oldList.append(index(it.key())); newList.append(index(it.value())); } changePersistentIndexList(oldList, newList); } emit layoutChanged(QList<QPersistentModelIndex>(), QAbstractItemModel::VerticalSortHint); }
void unregisterProtocolHandlers(const QHash<QString, QString> &protocols) { const QString regPath = QStringLiteral("HKEY_CURRENT_USER\\Software\\Classes"); QScopedPointer<QSettings> reg(new QSettings(regPath, QSettings::NativeFormat)); for (auto it = protocols.cbegin(); it != protocols.cend(); ++it) reg->remove(it.key()); }
void registerProtocolHandlers(const QHash<QString, QString> &protocols, bool force = false) { const QString regPath = QStringLiteral("HKEY_CURRENT_USER\\Software\\Classes"); QScopedPointer<QSettings> reg(new QSettings(regPath, QSettings::NativeFormat)); const QStringList groups = reg->childGroups(); for (auto it = protocols.cbegin(); it != protocols.cend(); ++it) { if (force || !groups.contains(it.key())) registerProtocolHandler(it.key(), it.value()); } }
// This function counts how many unique 2x2 16BPP pixel blocks there are in the image. // If there are <= maxCodes, it puts the unique blocks in 'codebook' and 'indexedImages' // will contain images that index the 'codebook' vector, resulting in quick "lossless" // compression, if possible. // It will keep counting blocks even if the block count exceeds maxCodes for the sole // purpose of reporting it back to the user. // Returns number of unique 2x2 16BPP pixel blocks in all images. static int encodeLossless(const ImageContainer& images, int pixelFormat, QVector<QImage>& indexedImages, QVector<quint64>& codebook, int maxCodes) { QHash<quint64, int> uniqueQuads; // Quad <=> index for (int i=0; i<images.imageCount(); i++) { const QImage& img = images.getByIndex(i); // Ignore images smaller than this if (img.width() < MIN_MIPMAP_VQ || img.height() < MIN_MIPMAP_VQ) continue; QImage indexedImage(img.width() / 2, img.height() / 2, QImage::Format_Indexed8); indexedImage.setColorCount(256); for (int y=0; y<img.height(); y+=2) { for (int x=0; x<img.width(); x+=2) { QRgb tl = img.pixel(x + 0, y + 0); QRgb tr = img.pixel(x + 1, y + 0); QRgb bl = img.pixel(x + 0, y + 1); QRgb br = img.pixel(x + 1, y + 1); quint64 quad = packQuad(tl, tr, bl, br, pixelFormat); if (!uniqueQuads.contains(quad)) uniqueQuads.insert(quad, uniqueQuads.size()); if (uniqueQuads.size() <= maxCodes) indexedImage.setPixel(x / 2, y / 2, uniqueQuads.value(quad)); } } // Only add the image if we haven't hit the code limit if (uniqueQuads.size() <= maxCodes) { indexedImages.push_back(indexedImage); } } if (uniqueQuads.size() <= maxCodes) { // This texture can be losslessly compressed. // Copy the unique quads over to the codebook. // indexedImages is already done. codebook.resize(uniqueQuads.size()); for (auto it = uniqueQuads.cbegin(); it != uniqueQuads.cend(); ++it) codebook[it.value()] = it.key(); } else { // This texture needs lossy compression indexedImages.clear(); } return uniqueQuads.size(); }
bool OsmAnd::MapStyleEvaluator_P::evaluate( const std::shared_ptr<const MapObject>& mapObject, const QHash< TagValueId, std::shared_ptr<const IMapStyle::IRule> >& ruleset, const ResolvedMapStyle::StringId tagStringId, const ResolvedMapStyle::StringId valueStringId, MapStyleEvaluationResult* const outResultStorage, OnDemand<IntermediateEvaluationResult>& constantEvaluationResult) const { const auto ruleId = TagValueId::compose(tagStringId, valueStringId); const auto citRule = ruleset.constFind(ruleId); if (citRule == ruleset.cend()) return false; const auto& rule = *citRule; InputValue inputTag; inputTag.asUInt = tagStringId; _inputValuesShadow->set(_builtinValueDefs->id_INPUT_TAG, inputTag); InputValue inputValue; inputValue.asUInt = valueStringId; _inputValuesShadow->set(_builtinValueDefs->id_INPUT_VALUE, inputValue); if (outResultStorage) _intermediateEvaluationResult->clear(); bool wasDisabled = false; const auto success = evaluate( mapObject.get(), rule->getRootNodeRef(), _inputValuesShadow, wasDisabled, _intermediateEvaluationResult.get(), constantEvaluationResult); if (!success || wasDisabled) return false; if (outResultStorage) { postprocessEvaluationResult( mapObject.get(), _inputValuesShadow, *_intermediateEvaluationResult, *outResultStorage, constantEvaluationResult); } return true; }
void LibraryController::requestSearch(const QHash<QString, QStringList> &query, const QStringList &uris, bool exact) { Q_D(LibraryController); QJsonObject params; QJsonObject joQuery; for(auto it = query.cbegin(); it != query.cend(); ++it) joQuery.insert(it.key(), QJsonArray::fromStringList(it.value())); params["query"] = joQuery; if(uris.size() == 1) params["uri"] = uris.first(); else if(uris.size() > 1) params["uris"] = QJsonArray::fromStringList(uris); params["exact"] = exact; send_message(std::bind(&LibraryControllerPrivate::onSearch, d, std::placeholders::_1), "search", params); }
OsmAnd::MapStyleRule::MapStyleRule(MapStyle* owner_, const QHash< QString, QString >& attributes) : _d(new MapStyleRule_P(this)) , owner(owner_) { _d->_valueDefinitionsRefs.reserve(attributes.size()); _d->_values.reserve(attributes.size()); for(auto itAttribute = attributes.cbegin(); itAttribute != attributes.cend(); ++itAttribute) { const auto& key = itAttribute.key(); const auto& value = itAttribute.value(); std::shared_ptr<const MapStyleValueDefinition> valueDef; bool ok = owner->resolveValueDefinition(key, valueDef); assert(ok); _d->_valueDefinitionsRefs.push_back(valueDef); MapStyleValue parsedValue; switch (valueDef->dataType) { case MapStyleValueDataType::Boolean: parsedValue.asSimple.asInt = (value == QLatin1String("true")) ? 1 : 0; break; case MapStyleValueDataType::Integer: { if(valueDef->isComplex) { parsedValue.isComplex = true; if(!value.contains(':')) { parsedValue.asComplex.asInt.dip = Utilities::parseArbitraryInt(value, -1); parsedValue.asComplex.asInt.px = 0.0; } else { // 'dip:px' format const auto& complexValue = value.split(':', QString::KeepEmptyParts); parsedValue.asComplex.asInt.dip = Utilities::parseArbitraryInt(complexValue[0], 0); parsedValue.asComplex.asInt.px = Utilities::parseArbitraryInt(complexValue[1], 0); } } else { assert(!value.contains(':')); parsedValue.asSimple.asInt = Utilities::parseArbitraryInt(value, -1); } } break; case MapStyleValueDataType::Float: { if(valueDef->isComplex) { parsedValue.isComplex = true; if(!value.contains(':')) { parsedValue.asComplex.asFloat.dip = Utilities::parseArbitraryFloat(value, -1.0f); parsedValue.asComplex.asFloat.px = 0.0f; } else { // 'dip:px' format const auto& complexValue = value.split(':', QString::KeepEmptyParts); parsedValue.asComplex.asFloat.dip = Utilities::parseArbitraryFloat(complexValue[0], 0); parsedValue.asComplex.asFloat.px = Utilities::parseArbitraryFloat(complexValue[1], 0); } } else { assert(!value.contains(':')); parsedValue.asSimple.asFloat = Utilities::parseArbitraryFloat(value, -1.0f); } } break; case MapStyleValueDataType::String: parsedValue.asSimple.asUInt = owner->_d->lookupStringId(value); break; case MapStyleValueDataType::Color: { assert(value[0] == '#'); parsedValue.asSimple.asUInt = value.mid(1).toUInt(nullptr, 16); if(value.size() <= 7) parsedValue.asSimple.asUInt |= 0xFF000000; } break; } _d->_values.insert(key, parsedValue); } }
bool OsmAnd::MapObjectsSymbolsProvider_P::obtainData( const TileId tileId, const ZoomLevel zoom, std::shared_ptr<MapObjectsSymbolsProvider::Data>& outTiledData, const IQueryController* const queryController, const FilterCallback filterCallback) { const auto tileBBox31 = Utilities::tileBoundingBox31(tileId, zoom); // Obtain offline map primitives tile std::shared_ptr<IMapTiledDataProvider::Data> primitivesTile_; owner->primitivesProvider->obtainData(tileId, zoom, primitivesTile_); const auto primitivesTile = std::static_pointer_cast<MapPrimitivesProvider::Data>(primitivesTile_); // If tile has nothing to be rasterized, mark that data is not available for it if (!primitivesTile_ || primitivesTile->primitivisedObjects->isEmpty()) { // Mark tile as empty outTiledData.reset(); return true; } // Rasterize symbols and create symbols groups QList< std::shared_ptr<const SymbolRasterizer::RasterizedSymbolsGroup> > rasterizedSymbolsGroups; QHash< std::shared_ptr<const MapObject>, std::shared_ptr<MapObjectSymbolsGroup> > preallocatedSymbolsGroups; const auto rasterizationFilter = [this, tileBBox31, filterCallback, &preallocatedSymbolsGroups] (const std::shared_ptr<const MapObject>& mapObject) -> bool { const std::shared_ptr<MapObjectSymbolsGroup> preallocatedGroup(new MapObjectSymbolsGroup(mapObject)); if (!filterCallback || filterCallback(owner, preallocatedGroup)) { preallocatedSymbolsGroups.insert(mapObject, qMove(preallocatedGroup)); return true; } return false; }; owner->symbolRasterizer->rasterize( primitivesTile->primitivisedObjects, rasterizedSymbolsGroups, owner->symbolsScaleFactor, rasterizationFilter, nullptr); // Convert results auto& mapSymbolIntersectionClassesRegistry = MapSymbolIntersectionClassesRegistry::globalInstance(); QList< std::shared_ptr<MapSymbolsGroup> > symbolsGroups; for (const auto& rasterizedGroup : constOf(rasterizedSymbolsGroups)) { const auto& mapObject = rasterizedGroup->mapObject; ////////////////////////////////////////////////////////////////////////// //if ((mapObject->id >> 1) == 189600735u) //{ // int i = 5; //} ////////////////////////////////////////////////////////////////////////// // Get preallocated group const auto citPreallocatedGroup = preallocatedSymbolsGroups.constFind(mapObject); assert(citPreallocatedGroup != preallocatedSymbolsGroups.cend()); const auto group = *citPreallocatedGroup; // Create shareable path const std::shared_ptr< const QVector<PointI> > shareablePath31(new QVector<PointI>(mapObject->points31)); // Convert all symbols inside group bool hasAtLeastOneOnPath = false; bool hasAtLeastOneAlongPathBillboard = false; bool hasAtLeastOneSimpleBillboard = false; for (const auto& rasterizedSymbol : constOf(rasterizedGroup->symbols)) { assert(static_cast<bool>(rasterizedSymbol->bitmap)); std::shared_ptr<MapSymbol> symbol; if (const auto rasterizedSpriteSymbol = std::dynamic_pointer_cast<const SymbolRasterizer::RasterizedSpriteSymbol>(rasterizedSymbol)) { if (!hasAtLeastOneAlongPathBillboard && rasterizedSpriteSymbol->drawAlongPath) hasAtLeastOneAlongPathBillboard = true; if (!hasAtLeastOneSimpleBillboard && !rasterizedSpriteSymbol->drawAlongPath) hasAtLeastOneSimpleBillboard = true; const auto billboardRasterSymbol = new BillboardRasterMapSymbol(group); billboardRasterSymbol->order = rasterizedSpriteSymbol->order; billboardRasterSymbol->bitmap = rasterizedSpriteSymbol->bitmap; billboardRasterSymbol->size = PointI(rasterizedSpriteSymbol->bitmap->width(), rasterizedSpriteSymbol->bitmap->height()); billboardRasterSymbol->content = rasterizedSpriteSymbol->content; billboardRasterSymbol->languageId = rasterizedSpriteSymbol->languageId; billboardRasterSymbol->minDistance = rasterizedSpriteSymbol->minDistance; billboardRasterSymbol->position31 = rasterizedSpriteSymbol->location31; billboardRasterSymbol->offset = rasterizedSpriteSymbol->offset; if (rasterizedSpriteSymbol->intersectionBBox.width() > 0 || rasterizedSpriteSymbol->intersectionBBox.height() > 0) { const auto halfWidth = billboardRasterSymbol->size.x / 2; const auto halfHeight = billboardRasterSymbol->size.y / 2; billboardRasterSymbol->margin.top() = -rasterizedSpriteSymbol->intersectionBBox.top() - halfHeight; billboardRasterSymbol->margin.left() = -rasterizedSpriteSymbol->intersectionBBox.left() - halfWidth; billboardRasterSymbol->margin.bottom() = rasterizedSpriteSymbol->intersectionBBox.bottom() - halfHeight; billboardRasterSymbol->margin.right() = rasterizedSpriteSymbol->intersectionBBox.right() - halfWidth; // Collect intersection classes for (const auto& intersectsWithClass : constOf(rasterizedSpriteSymbol->primitiveSymbol->intersectsWith)) { billboardRasterSymbol->intersectsWithClasses.insert(mapSymbolIntersectionClassesRegistry.getOrRegisterClassIdByName(intersectsWithClass)); } } billboardRasterSymbol->pathPaddingLeft = rasterizedSpriteSymbol->pathPaddingLeft; billboardRasterSymbol->pathPaddingRight = rasterizedSpriteSymbol->pathPaddingRight; symbol.reset(billboardRasterSymbol); } else if (const auto rasterizedOnPathSymbol = std::dynamic_pointer_cast<const SymbolRasterizer::RasterizedOnPathSymbol>(rasterizedSymbol)) { hasAtLeastOneOnPath = true; const auto onPathSymbol = new OnPathRasterMapSymbol(group); onPathSymbol->order = rasterizedOnPathSymbol->order; onPathSymbol->bitmap = rasterizedOnPathSymbol->bitmap; onPathSymbol->size = PointI(rasterizedOnPathSymbol->bitmap->width(), rasterizedOnPathSymbol->bitmap->height()); onPathSymbol->content = rasterizedOnPathSymbol->content; onPathSymbol->languageId = rasterizedOnPathSymbol->languageId; onPathSymbol->minDistance = rasterizedOnPathSymbol->minDistance; onPathSymbol->shareablePath31 = shareablePath31; assert(shareablePath31->size() >= 2); onPathSymbol->glyphsWidth = rasterizedOnPathSymbol->glyphsWidth; for (const auto& intersectsWithClass : constOf(rasterizedOnPathSymbol->primitiveSymbol->intersectsWith)) { onPathSymbol->intersectsWithClasses.insert(mapSymbolIntersectionClassesRegistry.getOrRegisterClassIdByName(intersectsWithClass)); } onPathSymbol->pathPaddingLeft = rasterizedOnPathSymbol->pathPaddingLeft; onPathSymbol->pathPaddingRight = rasterizedOnPathSymbol->pathPaddingRight; symbol.reset(onPathSymbol); } else { LogPrintf(LogSeverityLevel::Error, "MapObject %s produced unsupported symbol type", qPrintable(mapObject->toString())); } if (rasterizedSymbol->contentType == SymbolRasterizer::RasterizedSymbol::ContentType::Icon) symbol->contentClass = MapSymbol::ContentClass::Icon; else if (rasterizedSymbol->contentType == SymbolRasterizer::RasterizedSymbol::ContentType::Text) symbol->contentClass = MapSymbol::ContentClass::Caption; group->symbols.push_back(qMove(symbol)); } // If there's at least one on-path symbol or along-path symbol, this group needs special post-processing: // - Compute pin-points for all symbols in group (including billboard ones) // - Split path between them if (hasAtLeastOneOnPath || hasAtLeastOneAlongPathBillboard) { ////////////////////////////////////////////////////////////////////////// //if ((mapObject->id >> 1) == 7381701u) //{ // int i = 5; //} ////////////////////////////////////////////////////////////////////////// // Compose list of symbols to compute pin-points for QList<SymbolForPinPointsComputation> symbolsForComputation; symbolsForComputation.reserve(group->symbols.size()); for (const auto& symbol : constOf(group->symbols)) { if (const auto billboardSymbol = std::dynamic_pointer_cast<BillboardRasterMapSymbol>(symbol)) { // Get larger bbox, to take into account possible rotation const auto maxSize = qMax(billboardSymbol->size.x, billboardSymbol->size.y); const auto outerCircleRadius = 0.5f * static_cast<float>(qSqrt(2 * maxSize * maxSize)); symbolsForComputation.push_back({ billboardSymbol->pathPaddingLeft, 2.0f * outerCircleRadius, billboardSymbol->pathPaddingRight }); } else if (const auto onPathSymbol = std::dynamic_pointer_cast<OnPathRasterMapSymbol>(symbol)) { symbolsForComputation.push_back({ onPathSymbol->pathPaddingLeft, static_cast<float>(onPathSymbol->size.x), onPathSymbol->pathPaddingRight }); } } const auto& env = owner->primitivesProvider->primitiviser->environment; float globalLeftPaddingInPixels = 0.0f; float globalRightPaddingInPixels = 0.0f; env->obtainGlobalPathPadding(globalLeftPaddingInPixels, globalRightPaddingInPixels); const auto globalSpacingBetweenBlocksInPixels = env->getGlobalPathSymbolsBlockSpacing(); const auto computedPinPointsByLayer = computePinPoints( mapObject->points31, globalLeftPaddingInPixels, // global left padding in pixels globalRightPaddingInPixels, // global right padding in pixels globalSpacingBetweenBlocksInPixels, // global spacing between blocks in pixels symbolsForComputation, mapObject->getMinZoomLevel(), mapObject->getMaxZoomLevel(), zoom); // After pin-points were computed, assign them to symbols in the same order for (const auto& computedPinPoints : constOf(computedPinPointsByLayer)) { auto citComputedPinPoint = computedPinPoints.cbegin(); const auto citComputedPinPointsEnd = computedPinPoints.cend(); while (citComputedPinPoint != citComputedPinPointsEnd) { // Construct new additional instance of group std::shared_ptr<MapSymbolsGroup::AdditionalInstance> additionalGroupInstance(new MapSymbolsGroup::AdditionalInstance(group)); for (const auto& symbol : constOf(group->symbols)) { // Stop in case no more pin-points left if (citComputedPinPoint == citComputedPinPointsEnd) break; const auto& computedPinPoint = *(citComputedPinPoint++); std::shared_ptr<MapSymbolsGroup::AdditionalSymbolInstanceParameters> additionalSymbolInstance; if (const auto billboardSymbol = std::dynamic_pointer_cast<BillboardRasterMapSymbol>(symbol)) { const auto billboardSymbolInstance = new MapSymbolsGroup::AdditionalBillboardSymbolInstanceParameters(additionalGroupInstance.get()); billboardSymbolInstance->overridesPosition31 = true; billboardSymbolInstance->position31 = computedPinPoint.point31; additionalSymbolInstance.reset(billboardSymbolInstance); } else if (const auto onPathSymbol = std::dynamic_pointer_cast<OnPathRasterMapSymbol>(symbol)) { IOnPathMapSymbol::PinPoint pinPoint; pinPoint.point31 = computedPinPoint.point31; pinPoint.basePathPointIndex = computedPinPoint.basePathPointIndex; pinPoint.offsetFromBasePathPoint31 = computedPinPoint.offsetFromBasePathPoint31; pinPoint.normalizedOffsetFromBasePathPoint = computedPinPoint.normalizedOffsetFromBasePathPoint; const auto onPathSymbolInstance = new MapSymbolsGroup::AdditionalOnPathSymbolInstanceParameters(additionalGroupInstance.get()); onPathSymbolInstance->overridesPinPointOnPath = true; onPathSymbolInstance->pinPointOnPath = pinPoint; additionalSymbolInstance.reset(onPathSymbolInstance); } if (additionalSymbolInstance) additionalGroupInstance->symbols.insert(symbol, qMove(additionalSymbolInstance)); } group->additionalInstances.push_back(qMove(additionalGroupInstance)); } } // This group needs intersection check inside group group->intersectionProcessingMode |= MapSymbolsGroup::IntersectionProcessingModeFlag::CheckIntersectionsWithinGroup; // Finally there's no need in original, so turn it off group->additionalInstancesDiscardOriginal = true; } // Configure group if (!group->symbols.isEmpty()) { if (hasAtLeastOneSimpleBillboard && !(hasAtLeastOneOnPath || hasAtLeastOneAlongPathBillboard)) { group->presentationMode |= MapSymbolsGroup::PresentationModeFlag::ShowNoneIfIconIsNotShown; group->presentationMode |= MapSymbolsGroup::PresentationModeFlag::ShowAnythingUntilFirstGap; } else if (!hasAtLeastOneSimpleBillboard && (hasAtLeastOneOnPath || hasAtLeastOneAlongPathBillboard)) { group->presentationMode |= MapSymbolsGroup::PresentationModeFlag::ShowAnything; } else { LogPrintf(LogSeverityLevel::Error, "%s produced incompatible set of map symbols to compute presentation mode", qPrintable(group->toString())); group->presentationMode |= MapSymbolsGroup::PresentationModeFlag::ShowAnything; } } // Add constructed group to output symbolsGroups.push_back(qMove(group)); } // Create output tile outTiledData.reset(new MapObjectsSymbolsProvider::Data( tileId, zoom, symbolsGroups, primitivesTile, new RetainableCacheMetadata(primitivesTile->retainableCacheMetadata))); return true; }
void dump(std::ostream &output, const OsmAnd::Verifier::Configuration& cfg) #endif { OsmAnd::ObfsCollection obfsCollection; for(const auto& obfsDir : cfg.obfDirs) obfsCollection.addDirectory(obfsDir); for(const auto& obfFile : cfg.obfFiles) obfsCollection.addFile(obfFile); const auto dataInterface = obfsCollection.obtainDataInterface(); const auto obfFiles = obfsCollection.getObfFiles(); output << "Will work with these files:" << std::endl; for(const auto& obfFile : obfFiles) output << "\t" << qPrintable(obfFile->filePath) << std::endl; if(cfg.action == OsmAnd::Verifier::Configuration::Action::UniqueMapObjectIds) { const OsmAnd::AreaI entireWorld(0, 0, std::numeric_limits<int32_t>::max(), std::numeric_limits<int32_t>::max()); unsigned int lastReportedCount = 0; unsigned int totalDuplicatesCount = 0; for(int zoomLevel = OsmAnd::MinZoomLevel; zoomLevel <= OsmAnd::MaxZoomLevel; zoomLevel++) { output << "Processing " << zoomLevel << " zoom level..." << std::endl; QList< std::shared_ptr<const OsmAnd::Model::MapObject> > duplicateMapObjects; QHash<uint64_t, unsigned int> mapObjectIds; const auto idsCollector = [&mapObjectIds, &lastReportedCount, &output, &totalDuplicatesCount]( const std::shared_ptr<const OsmAnd::ObfMapSectionInfo>& section, const uint64_t mapObjectId, const OsmAnd::AreaI& bbox, const OsmAnd::ZoomLevel firstZoomLevel, const OsmAnd::ZoomLevel lasttZoomLevel) -> bool { const auto itId = mapObjectIds.find(mapObjectId); if(itId != mapObjectIds.end()) { // Increment duplicates counter itId.value()++; totalDuplicatesCount++; return true; } // Insert new entry mapObjectIds.insert(mapObjectId, 0); if(mapObjectIds.size() - lastReportedCount == 10000) { output << "\t... processed 10k map objects, found " << totalDuplicatesCount << " duplicate(s) so far ... " << std::endl; lastReportedCount = mapObjectIds.size(); } return false; }; dataInterface->loadMapObjects(&duplicateMapObjects, nullptr, entireWorld, static_cast<OsmAnd::ZoomLevel>(zoomLevel), nullptr, idsCollector, nullptr); output << "\tProcessed " << mapObjectIds.size() << " map objects."; if(!mapObjectIds.isEmpty()) output << " Found " << totalDuplicatesCount << " duplicate(s) :"; output << std::endl; for(auto itEntry = mapObjectIds.cbegin(); itEntry != mapObjectIds.cend(); ++itEntry) { const auto mapObjectId = itEntry.key(); const auto duplicatesCount = itEntry.value(); if(duplicatesCount == 0) continue; output << "\tMapObject "; if(static_cast<int64_t>(mapObjectId) < 0) { int64_t originalId = -static_cast<int64_t>(static_cast<uint64_t>(-static_cast<int64_t>(mapObjectId)) & 0xFFFFFFFF); output << originalId; } else { output << mapObjectId; } output << " has " << duplicatesCount << " duplicate(s)." << std::endl; } } output << "Totally " << totalDuplicatesCount << " duplicate(s) across all zoom levels" << std::endl; } }