Пример #1
0
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);
}
Пример #3
0
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());
}
Пример #4
0
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());
    }
}
Пример #5
0
// 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;
}
Пример #7
0
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);
}
Пример #8
0
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;
}
Пример #10
0
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;
    }
}