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)); }
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(); }
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; }