void rasterize(std::ostream &output, const OsmAnd::EyePiece::Configuration& cfg)
#endif
{
    // Obtain and configure rasterization style context
    OsmAnd::MapStyles stylesCollection;
    for(auto itStyleFile = cfg.styleFiles.begin(); itStyleFile != cfg.styleFiles.end(); ++itStyleFile)
    {
        const auto& styleFile = *itStyleFile;

        if(!stylesCollection.registerStyle(styleFile.absoluteFilePath()))
            output << xT("Failed to parse metadata of '") << QStringToStlString(styleFile.fileName()) << xT("' or duplicate style") << std::endl;
    }
    std::shared_ptr<const OsmAnd::MapStyle> style;
    if(!stylesCollection.obtainStyle(cfg.styleName, style))
    {
        output << xT("Failed to resolve style '") << QStringToStlString(cfg.styleName) << xT("'") << std::endl;
        return;
    }
    if(cfg.dumpRules)
        style->dump();
    
    OsmAnd::ObfsCollection obfsCollection;
    obfsCollection.watchDirectory(cfg.obfsDir);

    // Collect all map objects (this should be replaced by something like RasterizerViewport/RasterizerContext)
    QList< std::shared_ptr<const OsmAnd::Model::MapObject> > mapObjects;
    OsmAnd::AreaI bbox31(
            OsmAnd::Utilities::get31TileNumberY(cfg.bbox.top),
            OsmAnd::Utilities::get31TileNumberX(cfg.bbox.left),
            OsmAnd::Utilities::get31TileNumberY(cfg.bbox.bottom),
            OsmAnd::Utilities::get31TileNumberX(cfg.bbox.right)
        );
    const auto& obfDI = obfsCollection.obtainDataInterface();
    OsmAnd::MapFoundationType mapFoundation;
    obfDI->obtainMapObjects(&mapObjects, &mapFoundation, bbox31, cfg.zoom, nullptr);
    bool basemapAvailable;
    obfDI->obtainBasemapPresenceFlag(basemapAvailable);
    
    // Calculate output size in pixels
    const auto tileWidth = OsmAnd::Utilities::getTileNumberX(cfg.zoom, cfg.bbox.right) - OsmAnd::Utilities::getTileNumberX(cfg.zoom, cfg.bbox.left);
    const auto tileHeight = OsmAnd::Utilities::getTileNumberY(cfg.zoom, cfg.bbox.bottom) - OsmAnd::Utilities::getTileNumberY(cfg.zoom, cfg.bbox.top);
    const auto pixelWidth = qCeil(tileWidth * cfg.tileSide);
    const auto pixelHeight = qCeil(tileHeight * cfg.tileSide);
    output << xT("Will rasterize ") << mapObjects.count() << xT(" objects onto ") << pixelWidth << xT("x") << pixelHeight << xT(" bitmap") << std::endl;

    // Allocate render target
    SkBitmap renderSurface;
    renderSurface.setConfig(cfg.is32bit ? SkBitmap::kARGB_8888_Config : SkBitmap::kRGB_565_Config, pixelWidth, pixelHeight);
    if(!renderSurface.allocPixels())
    {
        output << xT("Failed to allocated render target ") << pixelWidth << xT("x") << pixelHeight;
        return;
    }
    SkDevice renderTarget(renderSurface);

    // Create render canvas
    SkCanvas canvas(&renderTarget);

    // Perform actual rendering
    OsmAnd::RasterizerEnvironment rasterizerEnv(style, basemapAvailable);
    OsmAnd::RasterizerContext rasterizerContext;
    OsmAnd::Rasterizer::prepareContext(rasterizerEnv, rasterizerContext, bbox31, cfg.zoom, cfg.tileSide, cfg.densityFactor, mapFoundation, mapObjects, OsmAnd::PointF(), nullptr);
    if(cfg.drawMap)
        OsmAnd::Rasterizer::rasterizeMap(rasterizerEnv, rasterizerContext, true, canvas, nullptr);
    /*if(cfg.drawText)
        OsmAnd::Rasterizer::rasterizeText(rasterizerContext, !cfg.drawMap, canvas, nullptr);*/

    // Save rendered area
    if(!cfg.output.isEmpty())
    {
        std::unique_ptr<SkImageEncoder> encoder(CreatePNGImageEncoder());
        std::unique_ptr<SkImageEncoder> outputStream(CreatePNGImageEncoder());
        encoder->encodeFile(cfg.output.toLocal8Bit(), renderSurface, 100);
    }

    return;
}
Exemple #2
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;
    }
}