/*! * \brief GetPointForTurn returns ingoingPoint or outgoingPoint for turns. * These points belongs to the route but they often are not neighbor of junctionPoint. * To calculate the resulting point the function implements the following steps: * - going from junctionPoint along feature ft according to the direction which is set in GetPointIndex(). * - until one of following conditions is fulfilled: * - the end of ft is reached; (returns the last feature point) * - more than kMaxPointsCount points are passed; (returns the kMaxPointsCount-th point) * - the length of passed parts of segment exceeds kMinDistMeters; (returns the next point after the event) * \param segment is a ingoing or outgoing feature segment. * \param ft is a ingoing or outgoing feature. * \param junctionPoint is a junction point. * \param maxPointsCount returned poit could't be more than maxPointsCount poins away from junctionPoint * \param minDistMeters returned point should be minDistMeters away from junctionPoint if ft is long and consists of short segments * \param GetPointIndex is a function for getting points by index. * It defines a direction of following along a feature. So it differs for ingoing and outgoing cases. * It has following parameters: * - start is an index of the start point of a feature segment. For example, FtSeg::m_pointStart. * - end is an index of the end point of a feature segment. For example, FtSeg::m_pointEnd. * - shift is a number of points which shall be added to end or start index. After that * the sum reflects an index of a feature segment point which will be used for a turn calculation. * The sum shall belongs to a range [min(start, end), max(start, end)]. * shift belongs to a range [0, abs(end - start)]. * \return an ingoing or outgoing point for a turn calculation. */ m2::PointD GetPointForTurn(OsrmMappingTypes::FtSeg const & segment, FeatureType const & ft, m2::PointD const & junctionPoint, size_t const maxPointsCount, double const minDistMeters, size_t (*GetPointIndex)(const size_t start, const size_t end, const size_t shift)) { double curDistanceMeters = 0.; m2::PointD point = junctionPoint; m2::PointD nextPoint; size_t const numSegPoints = abs(segment.m_pointEnd - segment.m_pointStart); ASSERT_GREATER(numSegPoints, 0, ()); ASSERT_LESS(numSegPoints, ft.GetPointsCount(), ()); size_t const usedFtPntNum = min(maxPointsCount, numSegPoints); for (size_t i = 1; i <= usedFtPntNum; ++i) { nextPoint = ft.GetPoint(GetPointIndex(segment.m_pointStart, segment.m_pointEnd, i)); curDistanceMeters += MercatorBounds::DistanceOnEarth(point, nextPoint); if (curDistanceMeters > minDistMeters) return nextPoint; point = nextPoint; } return nextPoint; }
/*! * \brief GetPointForTurn returns ingoingPoint or outgoingPoint for turns. * These points belongs to the route but they often are not neighbor of junctionPoint. * To calculate the resulting point the function implements the following steps: * - going from junctionPoint along feature ft according to the direction which is set in GetPointIndex(). * - until one of following conditions is fulfilled: * - the end of ft is reached; (returns the last feature point) * - more than kMaxPointsCount points are passed; (returns the kMaxPointsCount-th point) * - the length of passed parts of segment exceeds kMinDistMeters; (returns the next point after the event) * \param segment is a ingoing or outgoing feature segment. * \param ft is a ingoing or outgoing feature. * \param junctionPoint is a junction point. * \param GetPointIndex is a function for getting points by index. * It defines a direction of following along a feature. So it differs for ingoing and outgoing cases. * It has following parameters: * - start is an index of the start point of a feature segment. For example, FtSeg::m_pointStart. * - end is an index of the end point of a feature segment. For example, FtSeg::m_pointEnd. * - shift is a number of points which shall be added to end or start index. After that * the sum reflects an index of a point of a feature segment which will be used for turn calculation. * The sum shall belongs to a range [min(start, end), max(start, end)]. * shift belongs to a range [0, abs(end - start)]. * \return an ingoing or outgoing point for turn calculation. */ m2::PointD GetPointForTurn(OsrmMappingTypes::FtSeg const & segment, FeatureType const & ft, m2::PointD const & junctionPoint, size_t (*GetPointIndex)(const size_t start, const size_t end, const size_t shift)) { // An ingoing and outgoing point could be farther then kMaxPointsCount points from the junctionPoint size_t const kMaxPointsCount = 7; // If ft feature is long enough and consist of short segments // the point for turn generation is taken as the next point the route after kMinDistMeters. double const kMinDistMeters = 300.; double curDistanceMeters = 0.; m2::PointD point = junctionPoint; m2::PointD nextPoint; size_t const numSegPoints = abs(segment.m_pointEnd - segment.m_pointStart); ASSERT_GREATER(numSegPoints, 0, ()); ASSERT_LESS(numSegPoints, ft.GetPointsCount(), ()); size_t const usedFtPntNum = min(kMaxPointsCount, numSegPoints); for (size_t i = 1; i <= usedFtPntNum; ++i) { nextPoint = ft.GetPoint(GetPointIndex(segment.m_pointStart, segment.m_pointEnd, i)); curDistanceMeters += MercatorBounds::DistanceOnEarth(point, nextPoint); if (curDistanceMeters > kMinDistMeters) return nextPoint; point = nextPoint; } return nextPoint; }
void RuleDrawer::operator()(FeatureType const & f) { if (CheckCancelled()) return; Stylist s; m_callback(f, s); if (s.IsEmpty()) return; int const zoomLevel = m_context->GetTileKey().m_zoomLevel; if (s.IsCoastLine() && zoomLevel > scales::GetUpperWorldScale() && f.GetID().m_mwmId.GetInfo()->GetType() == MwmInfo::COASTS) { string name; if (f.GetName(StringUtf8Multilang::kDefaultCode, name)) { ASSERT(!name.empty(), ()); strings::SimpleTokenizer iter(name, ";"); while (iter) { if (m_isLoadedFn(*iter)) return; ++iter; } }
void operator()(FeatureType const & ft) { static CarModel const carModel; if (ft.GetFeatureType() != feature::GEOM_LINE || !carModel.IsRoad(ft)) return; uint32_t const featureId = ft.GetID().m_index; for (auto const n : m_routingMapping.m_segMapping.GetNodeIdByFid(featureId)) n_nodeIds.push_back(n); }
void MapObject::SetFromFeatureType(FeatureType const & ft) { m_mercator = feature::GetCenter(ft); m_name = ft.GetNames(); m_types = feature::TypesHolder(ft); m_metadata = ft.GetMetadata(); m_featureID = ft.GetID(); ASSERT(m_featureID.IsValid(), ()); m_geomType = ft.GetFeatureType(); }
// LocalityScorer::Delegate overrides: void GetNames(uint32_t featureId, vector<string> & names) const override { FeatureType ft; if (!m_context.GetFeature(featureId, ft)) return; for (auto const & lang : m_params.m_langs) { string name; if (ft.GetName(lang, name)) names.push_back(name); } }
void GetIntersection(FeatureType & f, FeatureIntersector<DEPTH_LEVELS> & fIsect) { // We need to cover feature for the best geometry, because it's indexed once for the // first top level scale. Do reset current cached geometry first. f.ResetGeometry(); int const scale = FeatureType::BEST_GEOMETRY; f.ForEachPoint(fIsect, scale); f.ForEachTriangle(fIsect, scale); CHECK(!(fIsect.m_trg.empty() && fIsect.m_polyline.empty()) && f.GetLimitRect(scale).IsValid(), (f.DebugString(scale))); }
void FeaturesVector::GetByIndex(uint32_t index, FeatureType & ft) const { uint32_t offset = 0, size = 0; auto const ftOffset = m_table ? m_table->GetFeatureOffset(index) : index; m_RecordReader.ReadRecord(ftOffset, m_buffer, offset, size); ft.Deserialize(m_LoadInfo.GetLoader(), &m_buffer[offset]); }
void Editor::DeleteFeature(FeatureType const & feature) { FeatureID const & fid = feature.GetID(); auto const mwm = m_features.find(fid.m_mwmId); if (mwm != m_features.end()) { auto const f = mwm->second.find(fid.m_index); // Created feature is deleted by removing all traces of it. if (f != mwm->second.end() && f->second.m_status == FeatureStatus::Created) { mwm->second.erase(f); return; } } FeatureTypeInfo & fti = m_features[fid.m_mwmId][fid.m_index]; fti.m_status = FeatureStatus::Deleted; // TODO: What if local client time is absolutely wrong? fti.m_modificationTimestamp = time(nullptr); // TODO: We don't really need to serialize whole feature. Improve this code in the future. fti.m_feature = feature; // TODO(AlexZ): Synchronize Save call/make it on a separate thread. Save(GetEditorFilePath()); Invalidate(); }
void Point2Node::operator()(FeatureType const & ft) { if (!CarModel::Instance().IsRoad(ft)) return; uint32_t const featureId = ft.GetID().m_index; for (auto const & n : m_routingMapping.m_segMapping.GetNodeIdByFid(featureId)) m_nodeIds.push_back(n); }
uint32_t FeaturesLayerMatcher::GetMatchingStreetImpl(uint32_t houseId, FeatureType & houseFeature) { // Check if this feature is modified - the logic will be different. string streetName; bool const edited = osm::Editor::Instance().GetEditedFeatureStreet(houseFeature.GetID(), streetName); // Check the cached result value. auto entry = m_matchingStreetsCache.Get(houseId); if (!edited && !entry.second) return entry.first; // Load feature if needed. if (!houseFeature.GetID().IsValid()) GetByIndex(houseId, houseFeature); // Get nearby streets and calculate the resulting index. auto const & streets = GetNearbyStreets(houseId, houseFeature); uint32_t & result = entry.first; result = kInvalidId; if (edited) { auto const ret = find_if(streets.begin(), streets.end(), [&streetName](TStreet const & st) { return st.m_name == streetName; }); if (ret != streets.end()) result = ret->m_id.m_index; } else { uint32_t index; if (m_context->GetStreetIndex(houseId, index) && index < streets.size()) result = streets[index].m_id.m_index; } // If there is no saved street for feature, assume that it's a nearest street if it's too close. if (result == kInvalidId && !streets.empty() && streets[0].m_distanceMeters < kMaxApproxStreetDistanceM) { result = streets[0].m_id.m_index; } return result; }
EditableProperties Editor::GetEditableProperties(FeatureType const & feature) const { // Disable editor for old data. if (!version::IsSingleMwm(feature.GetID().m_mwmId.GetInfo()->m_version.GetVersion())) return {}; // TODO(mgsergio): Check if feature is in the area where editing is disabled in the config. return GetEditablePropertiesForTypes(feature::TypesHolder(feature)); }
bool BannerSet::HasBannerForFeature(FeatureType const & ft) const { bool result = false; ft.ForEachType([this, &result](uint32_t type) { if (!result && HasBannerForType(type)) result = true; }); return result; }
void operator()(FeatureType & f, uint32_t) { ++m_totalCount; string s1, s2; f.GetPreferredNames(s1, s2); if (!s1.empty()) ++m_namesCount; m_currFeatureTypes.clear(); f.ForEachType([this](uint32_t type) { m_currFeatureTypes.push_back(type); }); CHECK(!m_currFeatureTypes.empty(), ("Feature without any type???")); auto found = m_stats.insert(make_pair(m_currFeatureTypes, 1)); if (!found.second) found.first->second++; }
bool Matches(Context & context, Sample::Result const & golden, search::Result const & actual) { static double constexpr kToleranceMeters = 50; if (actual.GetResultType() != Result::RESULT_FEATURE) return false; FeatureType ft; if (!context.GetFeature(actual.GetFeatureID(), ft)) return false; string name; if (!ft.GetName(FeatureType::DEFAULT_LANG, name)) name.clear(); auto const houseNumber = ft.GetHouseNumber(); auto const center = feature::GetCenter(ft); return golden.m_name == strings::MakeUniString(name) && golden.m_houseNumber == houseNumber && MercatorBounds::DistanceOnEarth(golden.m_pos, center) < kToleranceMeters; }
bool RuleDrawer::CheckCoastlines(FeatureType & f, Stylist const & s) { int const zoomLevel = m_context->GetTileKey().m_zoomLevel; if (s.IsCoastLine() && zoomLevel > scales::GetUpperWorldScale() && f.GetID().m_mwmId.GetInfo()->GetType() == MwmInfo::COASTS) { string name; if (f.GetName(StringUtf8Multilang::kDefaultCode, name)) { ASSERT(!name.empty(), ()); strings::SimpleTokenizer iter(name, ";"); while (iter) { if (m_isLoadedFn(*iter)) return false; ++iter; } }
void CaptionDescription::Init(FeatureType & f, int8_t deviceLang, int const zoomLevel, feature::EGeomType const type, drule::text_type_t const mainTextType, bool const auxCaptionExists) { if (auxCaptionExists || type == feature::GEOM_LINE) f.GetPreferredNames(true /* allowTranslit */, deviceLang, m_mainText, m_auxText); else f.GetReadableName(true /* allowTranslit */, deviceLang, m_mainText); // Set max text size to avoid VB/IB overflow in rendering. size_t constexpr kMaxTextSize = 200; if (m_mainText.size() > kMaxTextSize) m_mainText = m_mainText.substr(0, kMaxTextSize) + "..."; m_roadNumber = f.GetRoadNumber(); m_houseNumber = f.GetHouseNumber(); ProcessZoomLevel(zoomLevel); ProcessMainTextType(mainTextType); }
void StreetVicinityLoader::LoadStreet(uint32_t featureId, Street & street) { FeatureType feature; if (!m_context->GetFeature(featureId, feature)) return; if (feature.GetFeatureType() != feature::GEOM_LINE) return; vector<m2::PointD> points; feature.ForEachPoint(MakeBackInsertFunctor(points), FeatureType::BEST_GEOMETRY); ASSERT(!points.empty(), ()); for (auto const & point : points) street.m_rect.Add(MercatorBounds::RectByCenterXYAndSizeInMeters(point, m_offsetMeters)); covering::CoveringGetter coveringGetter(street.m_rect, covering::ViewportWithLowLevels); auto const & intervals = coveringGetter.Get(m_scale); m_context->ForEachIndex(intervals, m_scale, MakeBackInsertFunctor(street.m_features)); street.m_calculator = make_unique<ProjectionOnStreetCalculator>(points); }
void operator() (FeatureType const & f) { feature::TypesHolder types(f); if (!types.Has(m_coastType) && NeedProcess(types)) { double const d = f.GetDistance(m_pt, m_scale); ASSERT_GREATER_OR_EQUAL(d, 0.0, ()); if (IsInclude(d, types)) { string name; f.GetReadableName(name); string house = f.GetHouseNumber(); // if geom type is not GEOM_POINT, result center point doesn't matter in future use m2::PointD const pt = (types.GetGeoType() == feature::GEOM_POINT) ? f.GetCenter() : m2::PointD(); // name, house are assigned like move semantics m_cont.push_back(FeatureInfoT(GetResultDistance(d, types), types, name, house, pt)); } }
EditableProperties Editor::GetEditableProperties(FeatureType const & feature) const { ASSERT(version::IsSingleMwm(feature.GetID().m_mwmId.GetInfo()->m_version.GetVersion()), ("Edit mode should be available only on new data")); ASSERT(GetFeatureStatus(feature.GetID()) != FeatureStatus::Obsolete, ("Edit mode should not be available on obsolete features")); // TODO(mgsergio): Check if feature is in the area where editing is disabled in the config. auto editableProperties = GetEditablePropertiesForTypes(feature::TypesHolder(feature)); // Disable opening hours editing if opening hours cannot be parsed. if (GetFeatureStatus(feature.GetID()) != FeatureStatus::Created) { auto const originalFeaturePtr = GetOriginalFeature(feature.GetID()); if (!originalFeaturePtr) { LOG(LERROR, ("A feature with id", feature.GetID(), "cannot be loaded.")); alohalytics::LogEvent("Editor_MissingFeature_Error"); return {}; } auto const & metadata = originalFeaturePtr->GetMetadata(); auto const & featureOpeningHours = metadata.Get(feature::Metadata::FMD_OPEN_HOURS); // Note: empty string is parsed as a valid opening hours rule. if (!osmoh::OpeningHours(featureOpeningHours).IsValid()) { auto & meta = editableProperties.m_metadata; auto const toBeRemoved = remove(begin(meta), end(meta), feature::Metadata::FMD_OPEN_HOURS); if (toBeRemoved != end(meta)) meta.erase(toBeRemoved); } } return editableProperties; }
uint32_t GetPopulation(FeatureType const & ft) { uint32_t population = ft.GetPopulation(); if (population < 10) { switch (IsLocalityChecker::Instance().GetType(ft)) { case CITY: case TOWN: population = 10000; break; case VILLAGE: population = 100; break; default: population = 0; } } return population; }
void Point2PhantomNode::MakeResult(vector<FeatureGraphNode> & res, size_t maxCount) { vector<OsrmMappingTypes::FtSeg> segments; sort(m_candidates.begin(), m_candidates.end(), [](Candidate const & r1, Candidate const & r2) { return (r1.m_dist < r2.m_dist); }); size_t const n = min(m_candidates.size(), maxCount); segments.resize(n); for (size_t j = 0; j < n; ++j) { OsrmMappingTypes::FtSeg & seg = segments[j]; Candidate const & c = m_candidates[j]; seg.m_fid = c.m_fid; seg.m_pointStart = c.m_segIdx; seg.m_pointEnd = c.m_segIdx + 1; } OsrmFtSegMapping::OsrmNodesT nodes; m_routingMapping.m_segMapping.GetOsrmNodes(segments, nodes); res.clear(); res.resize(maxCount); for (size_t j = 0; j < maxCount; ++j) { if (!segments[j].IsValid()) continue; auto it = nodes.find(segments[j].Store()); if (it == nodes.cend()) continue; FeatureGraphNode & node = res[j]; if (!m_direction.IsAlmostZero()) { // Filter income nodes by direction mode OsrmMappingTypes::FtSeg const & node_seg = segments[j]; FeatureType feature; Index::FeaturesLoaderGuard loader(m_index, m_routingMapping.GetMwmId()); loader.GetFeatureByIndex(node_seg.m_fid, feature); feature.ParseGeometry(FeatureType::BEST_GEOMETRY); m2::PointD const featureDirection = feature.GetPoint(node_seg.m_pointEnd) - feature.GetPoint(node_seg.m_pointStart); bool const sameDirection = (m2::DotProduct(featureDirection, m_direction) > 0); if (sameDirection) { node.node.forward_node_id = it->second.first; node.node.reverse_node_id = INVALID_NODE_ID; } else { node.node.forward_node_id = INVALID_NODE_ID; node.node.reverse_node_id = it->second.second; } } else { node.node.forward_node_id = it->second.first; node.node.reverse_node_id = it->second.second; } node.segment = segments[j]; node.segmentPoint = m_candidates[j].m_point; node.mwmId = m_routingMapping.GetMwmId(); CalculateWeights(node); } res.erase(remove_if(res.begin(), res.end(), [](FeatureGraphNode const & f) { return !f.mwmId.IsAlive(); }), res.end()); }
string DebugPrint(FeatureType const & ft) { return ft.DebugString(FeatureType::BEST_GEOMETRY); }
ExitCodes main_(int, const char**) { //------------------------------------------------------------- // parameter handling //------------------------------------------------------------- //input file names String in = getStringOption_("in"); //input file type FileHandler fh; FileTypes::Type in_type = FileTypes::nameToType(getStringOption_("in_type")); if (in_type == FileTypes::UNKNOWN) { in_type = fh.getType(in); writeDebug_(String("Input file type: ") + FileTypes::typeToName(in_type), 2); } if (in_type == FileTypes::UNKNOWN) { writeLog_("Error: Could not determine input file type!"); return PARSE_ERROR; } //output file names and types String out = getStringOption_("out"); FileTypes::Type out_type = FileTypes::nameToType(getStringOption_("out_type")); if (out_type == FileTypes::UNKNOWN) { out_type = fh.getTypeByFileName(out); } if (out_type == FileTypes::UNKNOWN) { writeLog_("Error: Could not determine output file type!"); return PARSE_ERROR; } bool TIC_DTA2D = getFlag_("TIC_DTA2D"); writeDebug_(String("Output file type: ") + FileTypes::typeToName(out_type), 1); //------------------------------------------------------------- // reading input //------------------------------------------------------------- typedef MSExperiment<Peak1D> MSExperimentType; MSExperimentType exp; typedef MSExperimentType::SpectrumType SpectrumType; typedef FeatureMap<> FeatureMapType; FeatureMapType fm; ConsensusMap cm; writeDebug_(String("Loading input file"), 1); if (in_type == FileTypes::CONSENSUSXML) { ConsensusXMLFile().load(in, cm); cm.sortByPosition(); if ((out_type != FileTypes::FEATUREXML) && (out_type != FileTypes::CONSENSUSXML)) { // You you will lose information and waste memory. Enough reasons to issue a warning! writeLog_("Warning: Converting consensus features to peaks. You will lose information!"); exp.set2DData(cm); } } else if (in_type == FileTypes::EDTA) { EDTAFile().load(in, cm); cm.sortByPosition(); if ((out_type != FileTypes::FEATUREXML) && (out_type != FileTypes::CONSENSUSXML)) { // You you will lose information and waste memory. Enough reasons to issue a warning! writeLog_("Warning: Converting consensus features to peaks. You will lose information!"); exp.set2DData(cm); } } else if (in_type == FileTypes::FEATUREXML || in_type == FileTypes::TSV || in_type == FileTypes::PEPLIST || in_type == FileTypes::KROENIK) { fh.loadFeatures(in, fm, in_type); fm.sortByPosition(); if ((out_type != FileTypes::FEATUREXML) && (out_type != FileTypes::CONSENSUSXML)) { // You will lose information and waste memory. Enough reasons to issue a warning! writeLog_("Warning: Converting features to peaks. You will lose information! Mass traces are added, if present as 'num_of_masstraces' and 'masstrace_intensity_<X>' (X>=0) meta values."); exp.set2DData<true>(fm); } } else { fh.loadExperiment(in, exp, in_type, log_type_); } //------------------------------------------------------------- // writing output //------------------------------------------------------------- writeDebug_(String("Writing output file"), 1); if (out_type == FileTypes::MZML) { //add data processing entry addDataProcessing_(exp, getProcessingInfo_(DataProcessing:: CONVERSION_MZML)); MzMLFile f; f.setLogType(log_type_); ChromatogramTools().convertSpectraToChromatograms(exp, true); f.store(out, exp); } else if (out_type == FileTypes::MZDATA) { //annotate output with data processing info addDataProcessing_(exp, getProcessingInfo_(DataProcessing:: CONVERSION_MZDATA)); MzDataFile f; f.setLogType(log_type_); ChromatogramTools().convertChromatogramsToSpectra<MSExperimentType>(exp); f.store(out, exp); } else if (out_type == FileTypes::MZXML) { //annotate output with data processing info addDataProcessing_(exp, getProcessingInfo_(DataProcessing:: CONVERSION_MZXML)); MzXMLFile f; f.setLogType(log_type_); ChromatogramTools().convertChromatogramsToSpectra<MSExperimentType>(exp); f.store(out, exp); } else if (out_type == FileTypes::DTA2D) { //add data processing entry addDataProcessing_(exp, getProcessingInfo_(DataProcessing:: FORMAT_CONVERSION)); DTA2DFile f; f.setLogType(log_type_); ChromatogramTools().convertChromatogramsToSpectra<MSExperimentType>(exp); if (TIC_DTA2D) { // store the total ion chromatogram (TIC) f.storeTIC(out, exp); } else { // store entire experiment f.store(out, exp); } } else if (out_type == FileTypes::MGF) { //add data processing entry addDataProcessing_(exp, getProcessingInfo_(DataProcessing:: FORMAT_CONVERSION)); MascotGenericFile f; f.setLogType(log_type_); f.store(out, exp); } else if (out_type == FileTypes::FEATUREXML) { if ((in_type == FileTypes::FEATUREXML) || (in_type == FileTypes::TSV) || (in_type == FileTypes::PEPLIST) || (in_type == FileTypes::KROENIK)) { fm.applyMemberFunction(&UniqueIdInterface::setUniqueId); } else if (in_type == FileTypes::CONSENSUSXML || in_type == FileTypes::EDTA) { ConsensusMap::convert(cm, true, fm); } else // not loaded as feature map or consensus map { // The feature specific information is only defaulted. Enough reasons to issue a warning! writeLog_("Warning: Converting peaks to features will lead to incomplete features!"); fm.clear(); fm.reserve(exp.getSize()); typedef FeatureMapType::FeatureType FeatureType; FeatureType feature; feature.setQuality(0, 1); // override default feature.setQuality(1, 1); // override default feature.setOverallQuality(1); // override default for (MSExperimentType::ConstIterator spec_iter = exp.begin(); spec_iter != exp.end(); ++spec_iter ) { feature.setRT(spec_iter->getRT()); for (SpectrumType::ConstIterator peak1_iter = spec_iter->begin(); peak1_iter != spec_iter->end(); ++peak1_iter ) { feature.setMZ(peak1_iter->getMZ()); feature.setIntensity(peak1_iter->getIntensity()); feature.setUniqueId(); fm.push_back(feature); } } fm.updateRanges(); } addDataProcessing_(fm, getProcessingInfo_(DataProcessing:: FORMAT_CONVERSION)); FeatureXMLFile().store(out, fm); } else if (out_type == FileTypes::CONSENSUSXML) { if ((in_type == FileTypes::FEATUREXML) || (in_type == FileTypes::TSV) || (in_type == FileTypes::PEPLIST) || (in_type == FileTypes::KROENIK)) { fm.applyMemberFunction(&UniqueIdInterface::setUniqueId); ConsensusMap::convert(0, fm, cm); } // nothing to do for consensus input else if (in_type == FileTypes::CONSENSUSXML || in_type == FileTypes::EDTA) { } else // experimental data { ConsensusMap::convert(0, exp, cm, exp.size()); } addDataProcessing_(cm, getProcessingInfo_(DataProcessing:: FORMAT_CONVERSION)); ConsensusXMLFile().store(out, cm); } else if (out_type == FileTypes::EDTA) { if (fm.size() > 0 && cm.size() > 0) { LOG_ERROR << "Internal error: cannot decide on container (Consensus or Feature)! This is a bug. Please report it!"; return INTERNAL_ERROR; } if (fm.size() > 0) EDTAFile().store(out, fm); else if (cm.size() > 0) EDTAFile().store(out, cm); } else { writeLog_("Unknown output file type given. Aborting!"); printUsage_(); return ILLEGAL_PARAMETERS; } return EXECUTION_OK; }
void Index::FeaturesLoaderGuard::GetOriginalFeatureByIndex(uint32_t index, FeatureType & ft) const { m_vector.GetByIndex(index, ft); ft.SetID(FeatureID(m_handle.GetId(), index)); }
void operator()(FeatureType & f, uint32_t) { f.ForEachName(*this); }
int main(int argc, char * argv[]) { google::SetUsageMessage("SRTM coverage checker."); google::ParseCommandLineFlags(&argc, &argv, true); Platform & platform = GetPlatform(); if (!FLAGS_mwm_path.empty()) platform.SetWritableDirForTests(FLAGS_mwm_path); if (FLAGS_srtm_path.empty()) { LOG(LERROR, ("SRTM files directory is not specified.")); return -1; } LOG(LINFO, ("writable dir =", platform.WritableDir())); LOG(LINFO, ("srtm dir =", FLAGS_srtm_path)); vector<platform::LocalCountryFile> localFiles; platform::FindAllLocalMapsAndCleanup(numeric_limits<int64_t>::max() /* latestVersion */, localFiles); auto fetcher = integration::CreateFeaturesFetcher(localFiles); generator::SrtmTileManager manager(FLAGS_srtm_path); for (auto & file : localFiles) { file.SyncWithDisk(); if (file.GetFiles() != MapOptions::MapWithCarRouting) { LOG(LINFO, ("Warning! Routing file not found for:", file.GetCountryName())); continue; } FilesMappingContainer container(file.GetPath(MapOptions::CarRouting)); if (!container.IsExist(ROUTING_FTSEG_FILE_TAG)) { LOG(LINFO, ("Warning! Mwm file has not routing ftseg section:", file.GetCountryName())); continue; } routing::TDataFacade dataFacade; dataFacade.Load(container); OsrmFtSegMapping segMapping; segMapping.Load(container, file); segMapping.Map(container); size_t all = 0; size_t good = 0; for (size_t i = 0; i < dataFacade.GetNumberOfNodes(); ++i) { buffer_vector<OsrmMappingTypes::FtSeg, 8> buffer; segMapping.ForEachFtSeg(i, MakeBackInsertFunctor(buffer)); vector<m2::PointD> path; for (size_t k = 0; k < buffer.size(); ++k) { auto const & segment = buffer[k]; if (!segment.IsValid()) continue; // Load data from drive. FeatureType ft; Index::FeaturesLoaderGuard loader( fetcher->GetIndex(), fetcher->GetIndex().GetMwmIdByCountryFile(file.GetCountryFile())); loader.GetFeatureByIndex(segment.m_fid, ft); ft.ParseGeometry(FeatureType::BEST_GEOMETRY); // Get points in proper direction. auto const startIdx = segment.m_pointStart; auto const endIdx = segment.m_pointEnd; for (auto idx = min(startIdx, endIdx); idx <= max(startIdx, endIdx); ++idx) path.push_back(ft.GetPoint(idx)); all += path.size(); for (auto const & point : path) { auto const height = manager.GetHeight(MercatorBounds::ToLatLon(point)); if (height != generator::SrtmTile::kInvalidHeight) good++; } } } auto const bad = all - good; auto const percent = all == 0 ? 0.0 : bad * 100.0 / all; if (percent > 10.0) { LOG(LINFO, ("Huge error rate in:", file.GetCountryName(), "good:", good, "bad:", bad, "all:", all, "%:", percent)); } } return 0; }
bool ExactMatchingRule::Matches(FeatureType & feature) const { if (m_mwmId != feature.GetID().m_mwmId) return false; return m_feature.Matches(feature); }
void Point2PhantomNode::CalculateWeight(OsrmMappingTypes::FtSeg const & seg, m2::PointD const & segPt, NodeID const & nodeId, bool calcFromRight, int & weight, int & offset) const { // nodeId can be INVALID_NODE_ID when reverse node is absent. This node has no weight. if (nodeId == INVALID_NODE_ID) { offset = 0; weight = 0; return; } Index::FeaturesLoaderGuard loader(m_index, m_routingMapping.GetMwmId()); // Offset is measured in milliseconds. We don't know about speed restrictions on the road. // So we find it by a whole edge weight. // Distance from the node border to the projection point is in meters. double distanceM = 0.; // Whole node distance in meters. double fullDistanceM = 0.; // Minimal OSRM edge weight in milliseconds. EdgeWeight minWeight = 0; auto const range = m_routingMapping.m_segMapping.GetSegmentsRange(nodeId); OsrmMappingTypes::FtSeg segment; size_t const startIndex = calcFromRight ? range.second - 1 : range.first; size_t const endIndex = calcFromRight ? range.first - 1 : range.second; int const indexIncrement = calcFromRight ? -1 : 1; bool foundSeg = false; m2::PointD lastPoint; for (size_t segmentIndex = startIndex; segmentIndex != endIndex; segmentIndex += indexIncrement) { m_routingMapping.m_segMapping.GetSegmentByIndex(segmentIndex, segment); if (!segment.IsValid()) continue; FeatureType ft; loader.GetFeatureByIndex(segment.m_fid, ft); ft.ParseGeometry(FeatureType::BEST_GEOMETRY); // Find whole edge weight by node outgoing point. if (segmentIndex == range.second - 1) minWeight = GetMinNodeWeight(nodeId, ft.GetPoint(segment.m_pointEnd)); // Calculate distances. double distance = CalculateDistance(ft, segment.m_pointStart, segment.m_pointEnd); fullDistanceM += distance; if (foundSeg) continue; if (segment.m_fid == seg.m_fid && OsrmMappingTypes::IsInside(segment, seg)) { auto const splittedSegment = OsrmMappingTypes::SplitSegment(segment, seg, !calcFromRight); distanceM += CalculateDistance(ft, splittedSegment.m_pointStart, splittedSegment.m_pointEnd); // node.m_seg always forward ordered (m_pointStart < m_pointEnd) distanceM -= MercatorBounds::DistanceOnEarth( ft.GetPoint(calcFromRight ? seg.m_pointStart : seg.m_pointEnd), segPt); foundSeg = true; } else { distanceM += distance; } } ASSERT_GREATER(fullDistanceM, 0, ("No valid segments on the edge.")); double const ratio = (fullDistanceM == 0) ? 0 : distanceM / fullDistanceM; ASSERT_LESS_OR_EQUAL(ratio, 1., ()); // OSRM calculates edge weight form start to user point how offset + weight. // But it doesn't place info about start and end edge result weight into result structure. // So we store whole edge weight into offset and calculates this weights at a postprocessing step. offset = minWeight; weight = max(static_cast<int>(minWeight * ratio), 0) - minWeight; }
// Functions --------------------------------------------------------------------------------------- void ProcessMetadata(FeatureType & ft, Result::Metadata & meta) { if (meta.m_isInitialized) return; feature::Metadata const & src = ft.GetMetadata(); auto const cuisinesMeta = src.Get(feature::Metadata::FMD_CUISINE); if (cuisinesMeta.empty()) { meta.m_cuisine = ""; } else { vector<string> cuisines; osm::Cuisines::Instance().ParseAndLocalize(cuisinesMeta, cuisines); meta.m_cuisine = strings::JoinStrings(cuisines, " • "); } meta.m_airportIata = src.Get(feature::Metadata::FMD_AIRPORT_IATA); meta.m_brand = src.Get(feature::Metadata::FMD_BRAND); string const openHours = src.Get(feature::Metadata::FMD_OPEN_HOURS); if (!openHours.empty()) { osmoh::OpeningHours const oh(openHours); // TODO: We should check closed/open time for specific feature's timezone. time_t const now = time(nullptr); if (oh.IsValid() && !oh.IsUnknown(now)) meta.m_isOpenNow = oh.IsOpen(now) ? osm::Yes : osm::No; // In else case value us osm::Unknown, it's set in preview's constructor. } if (strings::to_int(src.Get(feature::Metadata::FMD_STARS), meta.m_stars)) meta.m_stars = base::clamp(meta.m_stars, 0, 5); else meta.m_stars = 0; bool const isSponsoredHotel = ftypes::IsBookingChecker::Instance()(ft); meta.m_isSponsoredHotel = isSponsoredHotel; meta.m_isHotel = ftypes::IsHotelChecker::Instance()(ft); if (isSponsoredHotel) { auto const r = src.Get(feature::Metadata::FMD_RATING); if (!r.empty()) { float raw; if (strings::to_float(r.c_str(), raw)) meta.m_hotelRating = raw; } int pricing; if (!strings::to_int(src.Get(feature::Metadata::FMD_PRICE_RATE), pricing)) pricing = 0; string pricingStr; CHECK_GREATER_OR_EQUAL(pricing, 0, ("Pricing must be positive!")); for (auto i = 0; i < pricing; i++) pricingStr.append(kPricingSymbol); meta.m_hotelPricing = pricing; meta.m_hotelApproximatePricing = pricingStr; } meta.m_isInitialized = true; }