bool Editor::CreatePoint(uint32_t type, m2::PointD const & mercator, MwmSet::MwmId const & id, EditableMapObject & outFeature) { ASSERT(id.IsAlive(), ("Please check that feature is created in valid MWM file before calling this method.")); outFeature.SetMercator(mercator); outFeature.SetID(GenerateNewFeatureId(id)); outFeature.SetType(type); outFeature.SetEditableProperties(GetEditablePropertiesForTypes(outFeature.GetTypes())); // Only point type features can be created at the moment. outFeature.SetPointType(); return true; }
bool Editor::CreatePoint(uint32_t type, m2::PointD const & mercator, MwmSet::MwmId const & id, EditableMapObject & outFeature) { ASSERT(id.IsAlive(), ("Please check that feature is created in valid MWM file before calling this method.")); if (!id.GetInfo()->m_limitRect.IsPointInside(mercator)) { LOG(LERROR, ("Attempt to create a feature outside of the MWM's bounding box.")); return false; } outFeature.SetMercator(mercator); outFeature.SetID(GenerateNewFeatureId(id)); outFeature.SetType(type); outFeature.SetEditableProperties(GetEditablePropertiesForTypes(outFeature.GetTypes())); // Only point type features can be created at the moment. outFeature.SetPointType(); return true; }
/// Several cases should be handled while saving changes: /// 1) a feature is not in editor's cache /// I. a feature was created /// save it and mark as `Created' /// II. a feature was modified /// save it and mark as `Modified' /// 2) a feature is in editor's cache /// I. a feature was created /// save it and mark as `Created' /// II. a feature was modified and equals to the one in cache /// ignore it /// III. a feature was modified and equals to the one in mwm /// either delete it or save and mark as `Modified' depending on upload status Editor::SaveResult Editor::SaveEditedFeature(EditableMapObject const & emo) { FeatureID const & fid = emo.GetID(); FeatureTypeInfo fti; auto const featureStatus = GetFeatureStatus(fid.m_mwmId, fid.m_index); ASSERT_NOT_EQUAL(featureStatus, FeatureStatus::Obsolete, ("Obsolete feature cannot be modified.")); ASSERT_NOT_EQUAL(featureStatus, FeatureStatus::Deleted, ("Unexpected feature status.")); bool const wasCreatedByUser = IsCreatedFeature(fid); if (wasCreatedByUser) { fti.m_status = FeatureStatus::Created; fti.m_feature.ReplaceBy(emo); if (featureStatus == FeatureStatus::Created) { auto const & editedFeatureInfo = m_features[fid.m_mwmId][fid.m_index]; if (AreFeaturesEqualButStreet(fti.m_feature, editedFeatureInfo.m_feature) && emo.GetStreet().m_defaultName == editedFeatureInfo.m_street) { return NothingWasChanged; } } } else { auto const originalFeaturePtr = GetOriginalFeature(fid); if (!originalFeaturePtr) { 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 : m_features[fid.m_mwmId][fid.m_index].m_feature; fti.m_feature.ReplaceBy(emo); bool const sameAsInMWM = AreFeaturesEqualButStreet(fti.m_feature, *originalFeaturePtr) && emo.GetStreet().m_defaultName == GetOriginalFeatureStreet(fti.m_feature); if (featureStatus != FeatureStatus::Untouched) { // A feature was modified and equals to the one in editor. auto const & editedFeatureInfo = m_features[fid.m_mwmId][fid.m_index]; if (AreFeaturesEqualButStreet(fti.m_feature, editedFeatureInfo.m_feature) && emo.GetStreet().m_defaultName == editedFeatureInfo.m_street) { return NothingWasChanged; } // A feature was modified and equals to the one in mwm (changes are rolled back). if (sameAsInMWM) { // Feature was not yet uploaded. Since it's equal to one mwm we can remove changes. if (editedFeatureInfo.m_uploadStatus != kUploaded) { RemoveFeatureFromStorageIfExists(fid.m_mwmId, fid.m_index); // TODO(AlexZ): Synchronize Save call/make it on a separate thread. Save(); Invalidate(); return SavedSuccessfully; } } // If a feature is not the same as in mwm or it was uploaded // we must save it and mark for upload. } // A feature was NOT edited before and current changes are useless. else if (sameAsInMWM) { return NothingWasChanged; } fti.m_status = FeatureStatus::Modified; } // TODO: What if local client time is absolutely wrong? fti.m_modificationTimestamp = time(nullptr); fti.m_street = emo.GetStreet().m_defaultName; // Reset upload status so already uploaded features can be uploaded again after modification. fti.m_uploadStatus = {}; m_features[fid.m_mwmId][fid.m_index] = move(fti); // TODO(AlexZ): Synchronize Save call/make it on a separate thread. bool const savedSuccessfully = Save(); Invalidate(); return savedSuccessfully ? SavedSuccessfully : NoFreeSpaceError; }