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 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)); }
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(); }
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; }
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; } }
bool ExactMatchingRule::Matches(FeatureType & feature) const { if (m_mwmId != feature.GetID().m_mwmId) return false; return m_feature.Matches(feature); }