diff options
author | tatiana-yan <tatiana.kondakova@gmail.com> | 2019-02-20 17:23:30 +0300 |
---|---|---|
committer | Arsentiy Milchakov <milcars@mapswithme.com> | 2019-02-21 16:37:52 +0300 |
commit | d3576782a0716364fdba40cf267e93acd64d3a64 (patch) | |
tree | cc9e31421419020df43eed61b8f2ab126a0e37de /editor | |
parent | be773015f6f829b840d229bb85cc0d8809aa36f6 (diff) |
[editor][indexer] Use EditableMapObject in editor instead of FeatureType.
Diffstat (limited to 'editor')
-rw-r--r-- | editor/editor_tests/osm_editor_test.cpp | 27 | ||||
-rw-r--r-- | editor/editor_tests/xml_feature_test.cpp | 10 | ||||
-rw-r--r-- | editor/osm_editor.cpp | 153 | ||||
-rw-r--r-- | editor/osm_editor.hpp | 11 | ||||
-rw-r--r-- | editor/xml_feature.cpp | 76 | ||||
-rw-r--r-- | editor/xml_feature.hpp | 11 |
6 files changed, 126 insertions, 162 deletions
diff --git a/editor/editor_tests/osm_editor_test.cpp b/editor/editor_tests/osm_editor_test.cpp index 4660e672aa..13195724ac 100644 --- a/editor/editor_tests/osm_editor_test.cpp +++ b/editor/editor_tests/osm_editor_test.cpp @@ -151,8 +151,6 @@ void GenerateUploadedFeature(MwmSet::MwmId const & mwmId, osm::EditableMapObject const & emo, pugi::xml_document & out) { - auto & editor = osm::Editor::Instance(); - pugi::xml_node root = out.append_child("mapsme"); root.append_attribute("format_version") = 1; @@ -161,11 +159,8 @@ void GenerateUploadedFeature(MwmSet::MwmId const & mwmId, mwmNode.append_attribute("version") = static_cast<long long>(mwmId.GetInfo()->GetVersion()); pugi::xml_node created = mwmNode.append_child("create"); - FeatureType ft; - editor.GetEditedFeature(emo.GetID().m_mwmId, emo.GetID().m_index, ft); - - editor::XMLFeature xf = editor::ToXML(ft, true); - xf.SetMWMFeatureIndex(ft.GetID().m_index); + editor::XMLFeature xf = editor::ToXML(emo, true); + xf.SetMWMFeatureIndex(emo.GetID().m_index); xf.SetModificationTime(time(nullptr)); xf.SetUploadTime(time(nullptr)); xf.SetUploadStatus("Uploaded"); @@ -244,7 +239,7 @@ void EditorTest::GetFeatureTypeInfoTest() auto const featuresAfter = editor.m_features.Get(); auto const fti = editor.GetFeatureTypeInfo(*featuresAfter, ft.GetID().m_mwmId, ft.GetID().m_index); TEST_NOT_EQUAL(fti, 0, ()); - TEST_EQUAL(fti->m_feature.GetID(), ft.GetID(), ()); + TEST_EQUAL(fti->m_object.GetID(), ft.GetID(), ()); }); } @@ -307,26 +302,24 @@ void EditorTest::SetIndexTest() osm::EditableMapObject emo; CreateCafeAtPoint({2.0, 2.0}, gbMwmId, emo); - ForEachCafeAtPoint(m_dataSource, m2::PointD(1.0, 1.0), [&editor](FeatureType & ft) - { - auto const firstPtr = editor.GetOriginalFeature(ft.GetID()); + ForEachCafeAtPoint(m_dataSource, m2::PointD(1.0, 1.0), [&editor](FeatureType & ft) { + auto const firstPtr = editor.GetOriginalMapObject(ft.GetID()); TEST(firstPtr, ()); SetBuildingLevelsToOne(ft); - auto const secondPtr = editor.GetOriginalFeature(ft.GetID()); + auto const secondPtr = editor.GetOriginalMapObject(ft.GetID()); TEST(secondPtr, ()); TEST_EQUAL(firstPtr->GetID(), secondPtr->GetID(), ()); }); - ForEachCafeAtPoint(m_dataSource, m2::PointD(1.0, 1.0), [&editor](FeatureType & ft) - { - TEST_EQUAL(editor.GetOriginalFeatureStreet(ft), "Test street", ()); + ForEachCafeAtPoint(m_dataSource, m2::PointD(1.0, 1.0), [&editor](FeatureType & ft) { + TEST_EQUAL(editor.GetOriginalFeatureStreet(ft.GetID()), "Test street", ()); EditFeature(ft, [](osm::EditableMapObject & emo) { osm::LocalizedStreet ls{"Some street", ""}; emo.SetStreet(ls); }); - TEST_EQUAL(editor.GetOriginalFeatureStreet(ft), "Test street", ()); + TEST_EQUAL(editor.GetOriginalFeatureStreet(ft.GetID()), "Test street", ()); }); uint32_t counter = 0; @@ -991,7 +984,7 @@ void EditorTest::LoadMapEditsTest() { for (auto const & index : mwm.second) { - loadedFeatures.emplace_back(index.second.m_feature.GetID()); + loadedFeatures.emplace_back(index.second.m_object.GetID()); } } }; diff --git a/editor/editor_tests/xml_feature_test.cpp b/editor/editor_tests/xml_feature_test.cpp index fed6d4b45b..ff0a91bd74 100644 --- a/editor/editor_tests/xml_feature_test.cpp +++ b/editor/editor_tests/xml_feature_test.cpp @@ -3,7 +3,7 @@ #include "editor/xml_feature.hpp" #include "indexer/classificator_loader.hpp" -#include "indexer/feature.hpp" +#include "indexer/editable_map_object.hpp" #include "geometry/mercator.hpp" @@ -368,13 +368,13 @@ UNIT_TEST(XMLFeature_FromXMLAndBackToXML) editor::XMLFeature xmlWithType = xmlNoType; xmlWithType.SetTagValue("amenity", "atm"); - FeatureType ft; - editor::FromXML(xmlWithType, ft); - auto fromFtWithType = editor::ToXML(ft, true); + osm::EditableMapObject emo; + editor::FromXML(xmlWithType, emo); + auto fromFtWithType = editor::ToXML(emo, true); fromFtWithType.SetAttribute("timestamp", kTimestamp); TEST_EQUAL(fromFtWithType, xmlWithType, ()); - auto fromFtWithoutType = editor::ToXML(ft, false); + auto fromFtWithoutType = editor::ToXML(emo, false); fromFtWithoutType.SetAttribute("timestamp", kTimestamp); TEST_EQUAL(fromFtWithoutType, xmlNoType, ()); } diff --git a/editor/osm_editor.cpp b/editor/osm_editor.cpp index 23db625a48..73898a97c6 100644 --- a/editor/osm_editor.cpp +++ b/editor/osm_editor.cpp @@ -119,37 +119,34 @@ bool NeedsUpload(string const & uploadStatus) } /// Compares editable fields connected with feature ignoring street. -bool AreFeaturesEqualButStreet(FeatureType & a, FeatureType & b) +bool AreObjectsEqualButStreet(osm::EditableMapObject const & lhs, + osm::EditableMapObject const & rhs) { - feature::TypesHolder const aTypes(a); - feature::TypesHolder const bTypes(b); + feature::TypesHolder const & lhsTypes = lhs.GetTypes(); + feature::TypesHolder const & rhsTypes = rhs.GetTypes(); - if (!aTypes.Equals(bTypes)) + if (!lhsTypes.Equals(rhsTypes)) return false; - if (a.GetHouseNumber() != b.GetHouseNumber()) + if (lhs.GetHouseNumber() != rhs.GetHouseNumber()) return false; - if (!a.GetMetadata().Equals(b.GetMetadata())) + if (!lhs.GetMetadata().Equals(rhs.GetMetadata())) return false; - if (a.GetNames() != b.GetNames()) + if (lhs.GetNameMultilang() != rhs.GetNameMultilang()) return false; return true; } -XMLFeature GetMatchingFeatureFromOSM(osm::ChangesetWrapper & cw, FeatureType & ft) +XMLFeature GetMatchingFeatureFromOSM(osm::ChangesetWrapper & cw, osm::EditableMapObject & o) { - ASSERT_NOT_EQUAL(ft.GetFeatureType(), feature::GEOM_LINE, - ("Line features are not supported yet.")); - if (ft.GetFeatureType() == feature::GEOM_POINT) - return cw.GetMatchingNodeFeatureFromOSM(ft.GetCenter()); + ASSERT_NOT_EQUAL(o.GetGeomType(), feature::GEOM_LINE, ("Line features are not supported yet.")); + if (o.GetGeomType() == feature::GEOM_POINT) + return cw.GetMatchingNodeFeatureFromOSM(o.GetMercator()); - // Warning: geometry is cached in FeatureType. So if it wasn't BEST_GEOMETRY, - // we can never have it. Features here came from editors loader and should - // have BEST_GEOMETRY geometry. - auto geometry = ft.GetTriangesAsPoints(FeatureType::BEST_GEOMETRY); + auto geometry = o.GetTriangesAsPoints(); ASSERT_GREATER_OR_EQUAL(geometry.size(), 3, ("Is it an area feature?")); @@ -257,13 +254,10 @@ bool Editor::Save(FeaturesContainer const & features) const for (auto & index : mwm.second) { FeatureTypeInfo const & fti = index.second; - // Temporary solution because of FeatureType does not have constant getters. - // TODO(a): Use constant reference instead of copy. - auto feature = fti.m_feature; // TODO: Do we really need to serialize deleted features in full details? Looks like mwm ID // and meta fields are enough. XMLFeature xf = - editor::ToXML(feature, true /*type serializing helps during migration*/); + editor::ToXML(fti.m_object, true /* type serializing helps during migration */); xf.SetMWMFeatureIndex(index.first); if (!fti.m_street.empty()) xf.SetTagValue(kAddrStreetTag, fti.m_street); @@ -415,15 +409,12 @@ Editor::SaveResult Editor::SaveEditedFeature(EditableMapObject const & emo) if (wasCreatedByUser) { fti.m_status = FeatureStatus::Created; - fti.m_feature.ReplaceBy(emo); + fti.m_object = emo; if (featureStatus == FeatureStatus::Created) { auto const & editedFeatureInfo = features->at(fid.m_mwmId).at(fid.m_index); - // Temporary solution because of FeatureType does not have constant getters. - // TODO(a): Use constant reference instead of copy. - auto feature = editedFeatureInfo.m_feature; - if (AreFeaturesEqualButStreet(fti.m_feature, feature) && + if (AreObjectsEqualButStreet(fti.m_object, editedFeatureInfo.m_object) && emo.GetStreet().m_defaultName == editedFeatureInfo.m_street) { return SaveResult::NothingWasChanged; @@ -432,30 +423,23 @@ Editor::SaveResult Editor::SaveEditedFeature(EditableMapObject const & emo) } else { - auto const originalFeaturePtr = GetOriginalFeature(fid); - if (!originalFeaturePtr) + auto const originalObjectPtr = GetOriginalMapObject(fid); + if (!originalObjectPtr) { LOG(LERROR, ("A feature with id", fid, "cannot be loaded.")); alohalytics::LogEvent("Editor_MissingFeature_Error"); return SaveResult::SavingError; } - - fti.m_feature = featureStatus == FeatureStatus::Untouched - ? *originalFeaturePtr - : features->at(fid.m_mwmId).at(fid.m_index).m_feature; - fti.m_feature.ReplaceBy(emo); + fti.m_object = emo; bool const sameAsInMWM = - AreFeaturesEqualButStreet(fti.m_feature, *originalFeaturePtr) && - emo.GetStreet().m_defaultName == GetOriginalFeatureStreet(fti.m_feature); + AreObjectsEqualButStreet(fti.m_object, *originalObjectPtr) && + emo.GetStreet().m_defaultName == GetOriginalFeatureStreet(fti.m_object.GetID()); if (featureStatus != FeatureStatus::Untouched) { // A feature was modified and equals to the one in editor. auto const & editedFeatureInfo = features->at(fid.m_mwmId).at(fid.m_index); - // Temporary solution because of FeatureType does not have constant getters. - // TODO(a): Use constant reference instead of copy. - auto feature = editedFeatureInfo.m_feature; - if (AreFeaturesEqualButStreet(fti.m_feature, feature) && + if (AreObjectsEqualButStreet(fti.m_object, editedFeatureInfo.m_object) && emo.GetStreet().m_defaultName == editedFeatureInfo.m_street) { return SaveResult::NothingWasChanged; @@ -527,10 +511,7 @@ void Editor::ForEachCreatedFeature(MwmSet::MwmId const & id, FeatureIndexFunctor FeatureTypeInfo const & ftInfo = index.second; if (ftInfo.m_status == FeatureStatus::Created) { - // Temporary solution because of FeatureType does not have constant getters. - // TODO(a): Use constant reference instead of copy. - auto feature = ftInfo.m_feature; - if (rect.IsPointInside(feature.GetCenter())) + if (rect.IsPointInside(ftInfo.m_object.GetMercator())) f(index.first); } } @@ -544,7 +525,7 @@ bool Editor::GetEditedFeature(MwmSet::MwmId const & mwmId, uint32_t index, if (featureInfo == nullptr) return false; - outFeature = featureInfo->m_feature; + outFeature = FeatureType::ConstructFromMapObject(featureInfo->m_object); return true; } @@ -601,15 +582,15 @@ EditableProperties Editor::GetEditableProperties(FeatureType & feature) const // Disable opening hours editing if opening hours cannot be parsed. if (featureStatus != FeatureStatus::Created) { - auto const originalFeaturePtr = GetOriginalFeature(fid); - if (!originalFeaturePtr) + auto const originalObjectPtr = GetOriginalMapObject(fid); + if (!originalObjectPtr) { LOG(LERROR, ("A feature with id", fid, "cannot be loaded.")); alohalytics::LogEvent("Editor_MissingFeature_Error"); return {}; } - auto const & metadata = originalFeaturePtr->GetMetadata(); + auto const & metadata = originalObjectPtr->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()) @@ -693,9 +674,6 @@ void Editor::UploadChanges(string const & key, string const & secret, ChangesetT // TODO(a): Use UploadInfo as part of FeatureTypeInfo. UploadInfo uploadInfo = {fti.m_uploadAttemptTimestamp, fti.m_uploadStatus, fti.m_uploadError}; - // Temporary solution because of FeatureType does not have constant getters. - // TODO(a): Use constant reference instead of copy. - auto featureData = fti.m_feature; string ourDebugFeatureString; try @@ -706,7 +684,7 @@ void Editor::UploadChanges(string const & key, string const & secret, ChangesetT case FeatureStatus::Obsolete: continue; // Obsolete features will be deleted by OSMers. case FeatureStatus::Created: { - XMLFeature feature = editor::ToXML(featureData, true); + XMLFeature feature = editor::ToXML(fti.m_object, true); if (!fti.m_street.empty()) feature.SetTagValue(kAddrStreetTag, fti.m_street); ourDebugFeatureString = DebugPrint(feature); @@ -715,7 +693,7 @@ void Editor::UploadChanges(string const & key, string const & secret, ChangesetT ("Linear and area features creation is not supported yet.")); try { - auto const center = featureData.GetCenter(); + auto const center = fti.m_object.GetMercator(); XMLFeature osmFeature = changeset.GetMatchingNodeFeatureFromOSM(center); // If we are here, it means that object already exists at the given point. @@ -757,24 +735,23 @@ void Editor::UploadChanges(string const & key, string const & secret, ChangesetT { // Do not serialize feature's type to avoid breaking OSM data. // TODO: Implement correct types matching when we support modifying existing feature types. - XMLFeature feature = editor::ToXML(featureData, false); + XMLFeature feature = editor::ToXML(fti.m_object, false); if (!fti.m_street.empty()) feature.SetTagValue(kAddrStreetTag, fti.m_street); ourDebugFeatureString = DebugPrint(feature); - auto const originalFeaturePtr = GetOriginalFeature(fti.m_feature.GetID()); - if (!originalFeaturePtr) + auto const originalObjectPtr = GetOriginalMapObject(fti.m_object.GetID()); + if (!originalObjectPtr) { - LOG(LERROR, ("A feature with id", fti.m_feature.GetID(), "cannot be loaded.")); + LOG(LERROR, ("A feature with id", fti.m_object.GetID(), "cannot be loaded.")); alohalytics::LogEvent("Editor_MissingFeature_Error"); - GetPlatform().RunTask(Platform::Thread::Gui, [this, fid = fti.m_feature.GetID()]() - { + GetPlatform().RunTask(Platform::Thread::Gui, [this, fid = fti.m_object.GetID()]() { RemoveFeatureIfExists(fid); }); continue; } - XMLFeature osmFeature = GetMatchingFeatureFromOSM(changeset, *originalFeaturePtr); + XMLFeature osmFeature = GetMatchingFeatureFromOSM(changeset, *originalObjectPtr); XMLFeature const osmFeatureCopy = osmFeature; osmFeature.ApplyPatch(feature); // Check to avoid uploading duplicates into OSM. @@ -793,18 +770,17 @@ void Editor::UploadChanges(string const & key, string const & secret, ChangesetT break; case FeatureStatus::Deleted: - auto const originalFeaturePtr = GetOriginalFeature(fti.m_feature.GetID()); - if (!originalFeaturePtr) + auto const originalObjectPtr = GetOriginalMapObject(fti.m_object.GetID()); + if (!originalObjectPtr) { - LOG(LERROR, ("A feature with id", fti.m_feature.GetID(), "cannot be loaded.")); + LOG(LERROR, ("A feature with id", fti.m_object.GetID(), "cannot be loaded.")); alohalytics::LogEvent("Editor_MissingFeature_Error"); - GetPlatform().RunTask(Platform::Thread::Gui, [this, fid = fti.m_feature.GetID()]() - { + GetPlatform().RunTask(Platform::Thread::Gui, [this, fid = fti.m_object.GetID()]() { RemoveFeatureIfExists(fid); }); continue; } - changeset.Delete(GetMatchingFeatureFromOSM(changeset, *originalFeaturePtr)); + changeset.Delete(GetMatchingFeatureFromOSM(changeset, *originalObjectPtr)); break; } uploadInfo.m_uploadStatus = kUploaded; @@ -837,22 +813,22 @@ void Editor::UploadChanges(string const & key, string const & secret, ChangesetT if (uploadInfo.m_uploadStatus != kUploaded) { - ms::LatLon const ll = MercatorBounds::ToLatLon(feature::GetCenter(featureData)); + ms::LatLon const ll = fti.m_object.GetLatLon(); alohalytics::LogEvent( "Editor_DataSync_error", {{"type", fti.m_uploadStatus}, {"details", fti.m_uploadError}, {"our", ourDebugFeatureString}, - {"mwm", fti.m_feature.GetID().GetMwmName()}, - {"mwm_version", strings::to_string(fti.m_feature.GetID().GetMwmVersion())}}, + {"mwm", fti.m_object.GetID().GetMwmName()}, + {"mwm_version", strings::to_string(fti.m_object.GetID().GetMwmVersion())}}, alohalytics::Location::FromLatLon(ll.lat, ll.lon)); } - GetPlatform().RunTask(Platform::Thread::Gui, [this, id = fti.m_feature.GetID(), uploadInfo]() - { - // Call Save every time we modify each feature's information. - SaveUploadedInformation(id, uploadInfo); - }); + GetPlatform().RunTask(Platform::Thread::Gui, + [this, id = fti.m_object.GetID(), uploadInfo]() { + // Call Save every time we modify each feature's information. + SaveUploadedInformation(id, uploadInfo); + }); } } @@ -915,23 +891,23 @@ bool Editor::FillFeatureInfo(FeatureStatus status, XMLFeature const & xml, Featu { if (status == FeatureStatus::Created) { - editor::FromXML(xml, fti.m_feature); + editor::FromXML(xml, fti.m_object); } else { - auto const originalFeaturePtr = GetOriginalFeature(fid); - if (!originalFeaturePtr) + auto const originalObjectPtr = GetOriginalMapObject(fid); + if (!originalObjectPtr) { LOG(LERROR, ("A feature with id", fid, "cannot be loaded.")); alohalytics::LogEvent("Editor_MissingFeature_Error"); return false; } - fti.m_feature = *originalFeaturePtr; - editor::ApplyPatch(xml, fti.m_feature); + fti.m_object = *originalObjectPtr; + editor::ApplyPatch(xml, fti.m_object); } - fti.m_feature.SetID(fid); + fti.m_object.SetID(fid); fti.m_street = xml.GetTagValue(kAddrStreetTag); fti.m_modificationTimestamp = xml.GetModificationTime(); @@ -1031,16 +1007,13 @@ Editor::Stats Editor::GetStats() const for (auto & index : id.second) { auto const & fti = index.second; - // Temporary solution because of FeatureType does not have constant getters. - // TODO(a): Use constant reference instead of copy. - auto feature = fti.m_feature; stats.m_edits.push_back(make_pair(FeatureID(id.first, index.first), fti.m_uploadStatus + " " + fti.m_uploadError)); LOG(LDEBUG, (fti.m_uploadAttemptTimestamp == base::INVALID_TIME_STAMP ? "NOT_UPLOADED_YET" : base::TimestampToString(fti.m_uploadAttemptTimestamp), - fti.m_uploadStatus, fti.m_uploadError, feature.GetFeatureType(), - feature::GetCenter(feature))); + fti.m_uploadStatus, fti.m_uploadError, fti.m_object.GetGeomType(), + fti.m_object.GetMercator())); if (fti.m_uploadStatus == kUploaded) { ++stats.m_uploadedCount; @@ -1161,16 +1134,16 @@ void Editor::MarkFeatureWithStatus(FeaturesContainer & editableFeatures, Feature auto & fti = editableFeatures[fid.m_mwmId][fid.m_index]; - auto const originalFeaturePtr = GetOriginalFeature(fid); + auto const originalObjectPtr = GetOriginalMapObject(fid); - if (!originalFeaturePtr) + if (!originalObjectPtr) { LOG(LERROR, ("A feature with id", fid, "cannot be loaded.")); alohalytics::LogEvent("Editor_MissingFeature_Error"); return; } - fti.m_feature = *originalFeaturePtr; + fti.m_object = *originalObjectPtr; fti.m_status = status; fti.m_modificationTimestamp = time(nullptr); } @@ -1185,24 +1158,24 @@ MwmSet::MwmId Editor::GetMwmIdByMapName(string const & name) return m_delegate->GetMwmIdByMapName(name); } -unique_ptr<FeatureType> Editor::GetOriginalFeature(FeatureID const & fid) const +unique_ptr<EditableMapObject> Editor::GetOriginalMapObject(FeatureID const & fid) const { if (!m_delegate) { LOG(LERROR, ("Can't get original feature by id:", fid, ", delegate is not set.")); return {}; } - return m_delegate->GetOriginalFeature(fid); + return m_delegate->GetOriginalMapObject(fid); } -string Editor::GetOriginalFeatureStreet(FeatureType & ft) const +string Editor::GetOriginalFeatureStreet(FeatureID const & fid) const { if (!m_delegate) { LOG(LERROR, ("Can't get feature street, delegate is not set.")); return {}; } - return m_delegate->GetOriginalFeatureStreet(ft); + return m_delegate->GetOriginalFeatureStreet(fid); } void Editor::ForEachFeatureAtPoint(FeatureTypeFn && fn, m2::PointD const & point) const diff --git a/editor/osm_editor.hpp b/editor/osm_editor.hpp index 7666d15d6c..d5a229857a 100644 --- a/editor/osm_editor.hpp +++ b/editor/osm_editor.hpp @@ -58,8 +58,8 @@ public: virtual ~Delegate() = default; virtual MwmSet::MwmId GetMwmIdByMapName(string const & name) const = 0; - virtual unique_ptr<FeatureType> GetOriginalFeature(FeatureID const & fid) const = 0; - virtual string GetOriginalFeatureStreet(FeatureType & ft) const = 0; + virtual unique_ptr<EditableMapObject> GetOriginalMapObject(FeatureID const & fid) const = 0; + virtual string GetOriginalFeatureStreet(FeatureID const & fid) const = 0; virtual void ForEachFeatureAtPoint(FeatureTypeFn && fn, m2::PointD const & point) const = 0; }; @@ -196,8 +196,7 @@ private: struct FeatureTypeInfo { FeatureStatus m_status; - // TODO(AlexZ): Integrate EditableMapObject class into an editor instead of FeatureType. - FeatureType m_feature; + EditableMapObject m_object; /// If not empty contains Feature's addr:street, edited by user. string m_street; time_t m_modificationTimestamp = base::INVALID_TIME_STAMP; @@ -236,8 +235,8 @@ private: // These methods are just checked wrappers around Delegate. MwmSet::MwmId GetMwmIdByMapName(string const & name); - unique_ptr<FeatureType> GetOriginalFeature(FeatureID const & fid) const; - string GetOriginalFeatureStreet(FeatureType & ft) const; + unique_ptr<EditableMapObject> GetOriginalMapObject(FeatureID const & fid) const; + string GetOriginalFeatureStreet(FeatureID const & fid) const; void ForEachFeatureAtPoint(FeatureTypeFn && fn, m2::PointD const & point) const; FeatureID GetFeatureIdByXmlFeature(FeaturesContainer const & features, editor::XMLFeature const & xml, MwmSet::MwmId const & mwmId, diff --git a/editor/xml_feature.cpp b/editor/xml_feature.cpp index 58e7c5a36e..e6e7d57484 100644 --- a/editor/xml_feature.cpp +++ b/editor/xml_feature.cpp @@ -1,15 +1,17 @@ #include "editor/xml_feature.hpp" #include "indexer/classificator.hpp" -#include "indexer/feature.hpp" +#include "indexer/editable_map_object.hpp" + +#include "coding/string_utf8_multilang.hpp" + +#include "geometry/latlon.hpp" #include "base/exception.hpp" #include "base/macros.hpp" #include "base/string_utils.hpp" #include "base/timer.hpp" -#include "geometry/latlon.hpp" - #include <array> #include <sstream> #include <string> @@ -381,52 +383,47 @@ XMLFeature::Type XMLFeature::StringToType(string const & type) return Type::Unknown; } -void ApplyPatch(XMLFeature const & xml, FeatureType & feature) +void ApplyPatch(XMLFeature const & xml, osm::EditableMapObject & object) { - xml.ForEachName([&feature](string const & lang, string const & name) { - feature.GetParams().name.AddString(lang, name); + xml.ForEachName([&object](string const & lang, string const & name) { + object.SetName(name, StringUtf8Multilang::GetLangIndex(lang)); }); string const house = xml.GetHouse(); if (!house.empty()) - feature.GetParams().house.Set(house); + object.SetHouseNumber(house); - xml.ForEachTag([&feature](string const & k, string const & v) { - if (!feature.UpdateMetadataValue(k, v)) + xml.ForEachTag([&object](string const & k, string const & v) { + if (!object.UpdateMetadataValue(k, v)) LOG(LWARNING, ("Patch feature has unknown tags", k, v)); }); - - // If types count are changed here, in ApplyPatch, new number of types should be passed - // instead of GetTypesCount(). - // So we call UpdateHeader for recalc header and update parsed parts. - feature.UpdateHeader(true /* commonParsed */, true /* metadataParsed */); } -XMLFeature ToXML(FeatureType & fromFeature, bool serializeType) +XMLFeature ToXML(osm::EditableMapObject const & object, bool serializeType) { - bool const isPoint = fromFeature.GetFeatureType() == feature::GEOM_POINT; + bool const isPoint = object.GetGeomType() == feature::GEOM_POINT; XMLFeature toFeature(isPoint ? XMLFeature::Type::Node : XMLFeature::Type::Way); if (isPoint) { - toFeature.SetCenter(fromFeature.GetCenter()); + toFeature.SetCenter(object.GetMercator()); } else { - auto const & triangles = fromFeature.GetTriangesAsPoints(FeatureType::BEST_GEOMETRY); + auto const & triangles = object.GetTriangesAsPoints(); toFeature.SetGeometry(begin(triangles), end(triangles)); } - fromFeature.ForEachName( + object.GetNameMultilang().ForEach( [&toFeature](uint8_t const & lang, string const & name) { toFeature.SetName(lang, name); }); - string const house = fromFeature.GetHouseNumber(); + string const house = object.GetHouseNumber(); if (!house.empty()) toFeature.SetHouse(house); if (serializeType) { - feature::TypesHolder th(fromFeature); + feature::TypesHolder th = object.GetTypes(); // TODO(mgsergio): Use correct sorting instead of SortBySpec based on the config. th.SortBySpec(); // TODO(mgsergio): Either improve "OSM"-compatible serialization for more complex types, @@ -455,31 +452,31 @@ XMLFeature ToXML(FeatureType & fromFeature, bool serializeType) } } - fromFeature.ForEachMetadataItem(true /* skipSponsored */, - [&toFeature](string const & tag, string const & value) { - toFeature.SetTagValue(tag, value); - }); + object.ForEachMetadataItem(true /* skipSponsored */, + [&toFeature](string const & tag, string const & value) { + toFeature.SetTagValue(tag, value); + }); return toFeature; } -bool FromXML(XMLFeature const & xml, FeatureType & feature) +bool FromXML(XMLFeature const & xml, osm::EditableMapObject & object) { ASSERT_EQUAL(XMLFeature::Type::Node, xml.GetType(), - ("At the moment only new nodes (points) can can be created.")); - feature.SetCenter(xml.GetMercatorCenter()); - xml.ForEachName([&feature](string const & lang, string const & name) { - feature.GetParams().name.AddString(lang, name); + ("At the moment only new nodes (points) can be created.")); + object.SetPointType(); + object.SetMercator(xml.GetMercatorCenter()); + xml.ForEachName([&object](string const & lang, string const & name) { + object.SetName(name, StringUtf8Multilang::GetLangIndex(lang)); }); string const house = xml.GetHouse(); if (!house.empty()) - feature.GetParams().house.Set(house); + object.SetHouseNumber(house); - uint32_t typesCount = 0; - array<uint32_t, feature::kMaxTypesCount> types; - xml.ForEachTag([&feature, &types, &typesCount](string const & k, string const & v) { - if (feature.UpdateMetadataValue(k, v)) + feature::TypesHolder types; + xml.ForEachTag([&object, &types](string const & k, string const & v) { + if (object.UpdateMetadataValue(k, v)) return; // Simple heuristics. It works if all our supported types for @@ -492,18 +489,17 @@ bool FromXML(XMLFeature const & xml, FeatureType & feature) if (type == 0) type = cl.GetTypeByPathSafe({"amenity", k}); // atm=yes, toilet=yes etc. - if (type && typesCount >= feature::kMaxTypesCount) + if (type && types.Size() >= feature::kMaxTypesCount) LOG(LERROR, ("Can't add type:", k, v, ". Types limit exceeded.")); else if (type) - types[typesCount++] = type; + types.Add(type); else LOG(LWARNING, ("Can't load/parse type:", k, v)); }); - feature.SetTypes(types, typesCount); - feature.UpdateHeader(true /* commonParsed */, true /* metadataParsed */); + object.SetTypes(types); - return typesCount > 0; + return types.Size() > 0; } string DebugPrint(XMLFeature const & feature) diff --git a/editor/xml_feature.hpp b/editor/xml_feature.hpp index ecc10e90bd..abbab0388d 100644 --- a/editor/xml_feature.hpp +++ b/editor/xml_feature.hpp @@ -13,7 +13,10 @@ #include "3party/pugixml/src/pugixml.hpp" -class FeatureType; +namespace osm +{ +class EditableMapObject; +} namespace editor { @@ -175,16 +178,16 @@ private: /// Rewrites all but geometry and types. /// Should be applied to existing features only (in mwm files). -void ApplyPatch(XMLFeature const & xml, FeatureType & feature); +void ApplyPatch(XMLFeature const & xml, osm::EditableMapObject & object); /// @param serializeType if false, types are not serialized. /// Useful for applying modifications to existing OSM features, to avoid issues when someone /// has changed a type in OSM, but our users uploaded invalid outdated type after modifying feature. -XMLFeature ToXML(FeatureType & feature, bool serializeType); +XMLFeature ToXML(osm::EditableMapObject const & object, bool serializeType); /// Creates new feature, including geometry and types. /// @Note: only nodes (points) are supported at the moment. -bool FromXML(XMLFeature const & xml, FeatureType & feature); +bool FromXML(XMLFeature const & xml, osm::EditableMapObject & object); string DebugPrint(XMLFeature const & feature); string DebugPrint(XMLFeature::Type const type); |