std::shared_ptr<OsmAnd::ObfDataInterface> OsmAnd::ObfsCollection_P::obtainDataInterface() const
{
    // Check if sources were invalidated
    if (_collectedSourcesInvalidated.loadAcquire() > 0)
        collectSources();

    // Create ObfReaders from collected sources
    QList< std::shared_ptr<const ObfReader> > obfReaders;
    {
        QReadLocker scopedLocker(&_collectedSourcesLock);

        for(const auto& collectedSources : constOf(_collectedSources))
        {
            obfReaders.reserve(obfReaders.size() + collectedSources.size());
            for(const auto& obfFile : constOf(collectedSources))
            {
                std::shared_ptr<const ObfReader> obfReader(new ObfReader(obfFile));
                if (!obfReader->isOpened() || !obfReader->obtainInfo())
                    continue;
                obfReaders.push_back(qMove(obfReader));
            }
        }
    }

    return std::shared_ptr<ObfDataInterface>(new ObfDataInterface(obfReaders));
}
Exemple #2
0
void dump(std::ostream &output, const QString& filePath, const OsmAnd::Inspector::Configuration& cfg)
#endif
{
    std::shared_ptr<QFile> file(new QFile(filePath));
    if(!file->exists())
    {
        output << xT("OBF '") << QStringToStlString(filePath) << xT("' does not exist.") << std::endl;
        return;
    }

    if(!file->open(QIODevice::ReadOnly))
    {
        output << xT("Failed to open OBF '") << QStringToStlString(file->fileName()) << xT("'") << std::endl;
        return;
    }

    std::shared_ptr<OsmAnd::ObfReader> obfReader(new OsmAnd::ObfReader(file));
    const auto& obfInfo = obfReader->obtainInfo();

    output << xT("OBF '") << QStringToStlString(file->fileName()) << xT("' version = ") << obfInfo->version << std::endl;
    int idx = 1;
    for(auto itSection = obfInfo->mapSections.cbegin(); itSection != obfInfo->mapSections.cend(); ++itSection, idx++)
    {
        const auto& section = *itSection;

        output << idx << xT(". Map data '") << QStringToStlString(section->name) << xT("' - ") << section->length << xT(" bytes") << std::endl;
        int levelIdx = 1;
        for(auto itLevel = section->levels.cbegin(); itLevel != section->levels.cend(); ++itLevel, levelIdx++)
        {
            auto level = (*itLevel);
            output << xT("\t") << idx << xT(".") << levelIdx << xT(" Map level minZoom = ") << level->minZoom << xT(", maxZoom = ") << level->maxZoom << std::endl;
            output << xT("\t\tBounds ") << formatBounds(level->area31.left, level->area31.right, level->area31.top, level->area31.bottom) << std::endl;
        }

        if(cfg.verboseMap)
            printMapDetailInfo(output, cfg, obfReader, section);
    }
    for(auto itSection = obfInfo->transportSections.cbegin(); itSection != obfInfo->transportSections.cend(); ++itSection, idx++)
    {
        const auto& section = *itSection;

        output << idx << xT(". Transport data '") << QStringToStlString(section->name) << xT("' - ") << section->length << xT(" bytes") << std::endl;
        output << "\tBounds " << formatBounds(section->area24.left << (31 - 24), section->area24.right << (31 - 24), section->area24.top << (31 - 24), section->area24.bottom << (31 - 24)) << std::endl;
    }
    for(auto itSection = obfInfo->routingSections.cbegin(); itSection != obfInfo->routingSections.cend(); ++itSection, idx++)
    {
        const auto& section = *itSection;

        output << idx << xT(". Routing data '") << QStringToStlString(section->name) << xT("' - ") << section->length << xT(" bytes") << std::endl;
        double lonLeft = 180;
        double lonRight = -180;
        double latTop = -90;
        double latBottom = 90;
        for(auto itSubsection = section->subsections.cbegin(); itSubsection != section->subsections.cend(); ++itSubsection)
        {
            auto subsection = itSubsection->get();

            lonLeft = std::min(lonLeft, OsmAnd::Utilities::get31LongitudeX(subsection->area31.left));
            lonRight = std::max(lonRight, OsmAnd::Utilities::get31LongitudeX(subsection->area31.right));
            latTop = std::max(latTop, OsmAnd::Utilities::get31LatitudeY(subsection->area31.top));
            latBottom = std::min(latBottom, OsmAnd::Utilities::get31LatitudeY(subsection->area31.bottom));
        }
        output << xT("\tBounds ") << formatGeoBounds(lonLeft, lonRight, latTop, latBottom) << std::endl;
    }
    for(auto itSection = obfInfo->poiSections.cbegin(); itSection != obfInfo->poiSections.cend(); ++itSection, idx++)
    {
        const auto& section = *itSection;

        output << idx << xT(". POI data '") << QStringToStlString(section->name) << xT("' - ") << section->length << xT(" bytes") << std::endl;
        if(cfg.verbosePoi)
            printPOIDetailInfo(output, cfg, obfReader, section);
    }
    for(auto itSection = obfInfo->addressSections.cbegin(); itSection != obfInfo->addressSections.cend(); ++itSection, idx++)
    {
        const auto& section = *itSection;

        output << idx << xT(". Address data '") << QStringToStlString(section->name) << xT("' - ") << section->length << xT(" bytes") << std::endl;
        printAddressDetailedInfo(output, cfg, obfReader, section);
    }

    file->close();
}
Exemple #3
0
void performJourney(std::ostream &output, const OsmAnd::Voyager::Configuration& cfg)
#endif
{
    if(cfg.generateXml)
    {
#if defined(_UNICODE) || defined(UNICODE)
        output << xT("<?xml version=\"1.0\" encoding=\"UTF-16\"?>") << std::endl;
#else
        output << xT("<?xml version=\"1.0\" encoding=\"UTF-8\"?>") << std::endl;
#endif
    }

    QList< std::shared_ptr<OsmAnd::ObfReader> > obfData;
    for(auto itObf = cfg.obfs.begin(); itObf != cfg.obfs.end(); ++itObf)
    {
        const auto& obf = *itObf;
        std::shared_ptr<OsmAnd::ObfReader> obfReader(new OsmAnd::ObfReader(std::shared_ptr<QIODevice>(new QFile(obf.absoluteFilePath()))));
        obfData.push_back(obfReader);
    }

    OsmAnd::RoutePlannerContext plannerContext(obfData, cfg.routingConfig, cfg.vehicle, false);
    std::shared_ptr<OsmAnd::Model::Road> startRoad;
    if(!OsmAnd::RoutePlanner::findClosestRoadPoint(&plannerContext, cfg.startLatitude, cfg.startLongitude, &startRoad))
    {
        if(cfg.generateXml)
            output << xT("<!--");
        output << xT("Failed to find road near start point");
        if(cfg.generateXml)
            output << xT("-->");
        output << std::endl;
        return;
    }
    std::shared_ptr<OsmAnd::Model::Road> endRoad;
    if(!OsmAnd::RoutePlanner::findClosestRoadPoint(&plannerContext, cfg.endLatitude, cfg.endLongitude, &endRoad))
    {
        if(cfg.generateXml)
            output << xT("<!--");
        output << xT("Failed to find road near end point");
        if(cfg.generateXml)
            output << xT("-->");
        output << std::endl;
        return;
    }

    if(cfg.verbose)
    {
        if(cfg.generateXml)
            output << xT("<!--");
        output << xT("Start point (LAT ") << cfg.startLatitude << xT("; LON ") << cfg.startLongitude << xT("):");
        if(cfg.generateXml)
            output << xT("-->");
        output << std::endl;
        if(cfg.generateXml)
            output << xT("<!--");
        output << xT("\tRoad name(s): ");
        if(startRoad->names.size() == 0)
        {
            output << xT("\t[none] (") << startRoad->id << xT(")");
            if(cfg.generateXml)
                output << xT("-->");
            output << std::endl;
        }
        else
        {
            for(auto itName = startRoad->names.begin(); itName != startRoad->names.end(); ++itName)
                output << QStringToStlString(itName.value()) << xT("; ");
            output << xT(" (") << startRoad->id << xT(")");
            if(cfg.generateXml)
                output << xT("-->");
            output << std::endl;
        }
        output << std::endl;
    
        if(cfg.generateXml)
            output << xT("<!--");
        output << xT("End point (LAT ") << cfg.endLatitude << xT("; LON ") << cfg.endLongitude << xT("):");
        if(cfg.generateXml)
            output << xT("-->");
        output << std::endl;
        if(cfg.generateXml)
            output << xT("<!--");
        output << xT("\tRoad name(s): ");
        if(endRoad->names.size() == 0)
        {
            output << xT("\t[none] (") << endRoad->id << xT(")");
            if(cfg.generateXml)
                output << xT("-->");
            output << std::endl;
        }
        else
        {
            for(auto itName = endRoad->names.begin(); itName != endRoad->names.end(); ++itName)
                output << QStringToStlString(itName.value()) << xT("; ");
            output << xT(" (") << endRoad->id << xT(")");
            if(cfg.generateXml)
                output << xT("-->");
            output << std::endl;
        }
        output << std::endl;
    }

    QList< std::pair<double, double> > points;
    points.push_back(std::pair<double, double>(cfg.startLatitude, cfg.startLongitude));
    for(auto itIntermediatePoint = cfg.waypoints.begin(); itIntermediatePoint != cfg.waypoints.end(); ++itIntermediatePoint)
        points.push_back(*itIntermediatePoint);
    points.push_back(std::pair<double, double>(cfg.endLatitude, cfg.endLongitude));

    QList< std::shared_ptr<OsmAnd::RouteSegment> > route;
    auto routeCalculationStart = std::chrono::steady_clock::now();
    if(cfg.verbose)
    {
        if(cfg.generateXml)
            output << xT("<!--");
        output << xT("Started route calculation ") << QStringToStlString(QTime::currentTime().toString());
        if(cfg.generateXml)
            output << xT("-->");
        output << std::endl;
    }
    OsmAnd::RouteCalculationResult routeFound =
            OsmAnd::RoutePlanner::calculateRoute(&plannerContext, points, cfg.leftSide, nullptr);
    route = routeFound.list;
    auto routeCalculationFinish = std::chrono::steady_clock::now();
    if(cfg.verbose)
    {
        if(cfg.generateXml)
            output << xT("<!--");
        output << xT("Finished route calculation ") << QStringToStlString(QTime::currentTime().toString()) << xT(", took ") << std::chrono::duration<double, std::milli> (routeCalculationFinish - routeCalculationStart).count() << xT(" ms");
        if(cfg.generateXml)
            output << xT("-->");
        output << std::endl;
    }
    if(cfg.doRecalculate)
    {
        auto routeRecalculationStart = std::chrono::steady_clock::now();
        if(cfg.verbose)
        {
            if(cfg.generateXml)
                output << xT("<!--");
            output << xT("Started route recalculation ") << QStringToStlString(QTime::currentTime().toString());
            if(cfg.generateXml)
                output << xT("-->");
            output << std::endl;
        }
        routeFound = OsmAnd::RoutePlanner::calculateRoute(&plannerContext, points, cfg.leftSide, nullptr);
        route = routeFound.list;
        auto routeRecalculationFinish = std::chrono::steady_clock::now();
        if(cfg.verbose)
        {
            if(cfg.generateXml)
                output << xT("<!--");
            output << xT("Finished route recalculation ") << QStringToStlString(QTime::currentTime().toString()) << xT(", took ") << std::chrono::duration<double, std::milli> (routeRecalculationFinish - routeRecalculationStart).count() << xT(" ms");
            if(cfg.generateXml)
                output << xT("-->");
            output << std::endl;
        }
    }
    if(routeFound.warnMessage == "")
    {
        if(cfg.generateXml)
            output << xT("<!--");
        output << xT("FAILED TO FIND ROUTE!") << QStringToStlString(routeFound.warnMessage);
        if(cfg.generateXml)
            output << xT("-->");
        output << std::endl;
    }

    float totalTime = 0.0f;
    float totalDistance = 0.0f;
    for(auto itSegment = route.begin(); itSegment != route.end(); ++itSegment)
    {
        auto segment = *itSegment;

        totalTime += segment->time;
        totalDistance += segment->distance;
    }

    if(cfg.generateXml)
        output << xT("<test") << std::endl;
    else
        output << xT("ROUTE:") << std::endl;

    output << xT("\tregions=\"\"") << std::endl;
    output << xT("\tdescription=\"\"") << std::endl;
    output << xT("\tbest_percent=\"\"") << std::endl;
    output << xT("\tvehicle=\"") << QStringToStlString(cfg.vehicle) << xT("\"") << std::endl;
    output << xT("\tstart_lat=\"") << cfg.startLatitude << xT("\"") << std::endl;
    output << xT("\tstart_lon=\"") << cfg.startLongitude << xT("\"") << std::endl;
    output << xT("\ttarget_lat=\"") << cfg.endLatitude << xT("\"") << std::endl;
    output << xT("\ttarget_lon=\"") << cfg.endLongitude << xT("\"") << std::endl;
    output << xT("\tloadedTiles=\"") << 0 << xT("\"") << std::endl;
    output << xT("\tvisitedSegments=\"") << 0 << xT("\"") << std::endl;
    output << xT("\tcomplete_distance=\"") << totalDistance << xT("\"") << std::endl;
    output << xT("\tcomplete_time=\"") << totalTime << xT("\"") << std::endl;
    output << xT("\trouting_time=\"") << 0 << xT("\"") << std::endl;

    if(cfg.generateXml)
        output << xT(">") << std::endl;
    else
        output << std::endl;

    std::unique_ptr<QFile> gpxFile;
    std::unique_ptr<QTextStream> gpxStream;
    if(!cfg.gpxPath.isEmpty())
    {
        gpxFile.reset(new QFile(cfg.gpxPath));
        gpxFile->open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text);
        gpxStream.reset(new QTextStream(gpxFile.get()));
    }
    if(gpxFile && gpxFile->isOpen())
    {
        *(gpxStream.get()) << "<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>\n";
        *(gpxStream.get()) << "<gpx version=\"1.0\" creator=\"OsmAnd Voyager tool\" xmlns=\"http://www.topografix.com/GPX/1/1\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd\">\n";
        *(gpxStream.get()) << "\t<trk>\n";
        *(gpxStream.get()) << "\t\t<trkseg>\n";
    }
    for(auto itSegment = route.begin(); itSegment != route.end(); ++itSegment)
    {
        auto segment = *itSegment;

        if(cfg.generateXml)
            output << xT("\t<segment") << std::endl;
        else
            output << xT("\tSEGMENT:") << std::endl;

        output << xT("\t\tid=\"") << segment->road->id << xT("\"") << std::endl;
        output << xT("\t\tstart=\"") << segment->startPointIndex << xT("\"") << std::endl;
        output << xT("\t\tend=\"") << segment->endPointIndex << xT("\"") << std::endl;

        QString name;
        if(!segment->road->names.isEmpty())
            name += segment->road->names.begin().value();
        /*String ref = res.getObject().getRef();
        if (ref != null) {
            name += " (" + ref + ") ";
        }*/
        output << xT("\t\tname=\"") << QStringToStlString(name) << xT("\"") << std::endl;

        output << xT("\t\ttime=\"") << segment->time << xT("\"") << std::endl;
        output << xT("\t\tdistance=\"") << segment->distance << xT("\"") << std::endl;
        /*float ms = res.getObject().getMaximumSpeed();
        if(ms > 0) {
            additional.append("maxspeed = \"").append(ms * 3.6f).append("\" ").append(res.getObject().getHighway()).append(" ");
        }*/
        /*
        if (res.getTurnType() != null) {
            additional.append("turn = \"").append(res.getTurnType()).append("\" ");
            additional.append("turn_angle = \"").append(res.getTurnType().getTurnAngle()).append("\" ");
            if (res.getTurnType().getLanes() != null) {
                additional.append("lanes = \"").append(Arrays.toString(res.getTurnType().getLanes())).append("\" ");
            }
        }*/
        output << xT("\t\tstart_bearing=\"") << segment->getBearingBegin() << xT("\"") << std::endl;
        output << xT("\t\tend_bearing=\"") << segment->getBearingEnd() << xT("\"") << std::endl;
        //additional.append("description = \"").append(res.getDescription()).append("\" ");
        
        if(cfg.generateXml)
            output << xT("\t/>") << std::endl;
        else
            output << std::endl;

        if(gpxFile && gpxFile->isOpen())
        {
            output << xT("\t\tstart=\"") << segment->startPointIndex << xT("\"") << std::endl;
            output << xT("\t\tend=\"") << segment->endPointIndex << xT("\"") << std::endl;
            for(auto pointIdx = segment->startPointIndex; pointIdx < segment->endPointIndex; pointIdx++)
            {
                const auto& point = segment->road->points[pointIdx];

                *(gpxStream.get()) << "\t\t\t<trkpt lon=\"" << OsmAnd::Utilities::get31LongitudeX(point.x) << "\" lat=\"" << OsmAnd::Utilities::get31LatitudeY(point.y) << "\"/>\n";
            }
        }
    }

    if(gpxFile && gpxFile->isOpen())
    {
        *(gpxStream.get()) << "\t\t</trkseg>\n";
        *(gpxStream.get()) << "\t</trk>\n";
        *(gpxStream.get()) << "</gpx>\n";
        gpxStream->flush();
        gpxFile->close();
    }

    if(cfg.generateXml)
        output << xT("</test>") << std::endl;
}