Added functions for KML import and conversion

This commit is contained in:
r.kuznetsov 2018-03-22 16:09:23 +03:00 committed by Aleksandr Zatsepin
parent 74b67214b2
commit 9cd42201a8
4 changed files with 161 additions and 3 deletions

View file

@ -18,6 +18,7 @@ jfieldID g_bookmarkManagerInstanceField;
jmethodID g_onBookmarksLoadingStartedMethod;
jmethodID g_onBookmarksLoadingFinishedMethod;
jmethodID g_onBookmarksFileLoadedMethod;
jmethodID g_onFinishKmlConversionMethod;
void PrepareClassRefs(JNIEnv * env)
{
@ -38,6 +39,8 @@ void PrepareClassRefs(JNIEnv * env)
g_onBookmarksFileLoadedMethod =
jni::GetMethodID(env, bookmarkManagerInstance, "onBookmarksFileLoaded",
"(ZLjava/lang/String;Z)V");
g_onFinishKmlConversionMethod =
jni::GetMethodID(env, bookmarkManagerInstance, "onFinishKmlConversion", "(Z)V");
}
void OnAsyncLoadingStarted(JNIEnv * env)
@ -79,6 +82,15 @@ void OnAsyncLoadingFileError(JNIEnv * env, std::string const & fileName, bool is
false /* success */, jFileName.get(), isTemporaryFile);
jni::HandleJavaException(env);
}
void OnFinishKmlConversion(JNIEnv * env, bool success)
{
ASSERT(g_bookmarkManagerClass != nullptr, ());
jobject bookmarkManagerInstance = env->GetStaticObjectField(g_bookmarkManagerClass,
g_bookmarkManagerInstanceField);
env->CallVoidMethod(bookmarkManagerInstance, g_onFinishKmlConversionMethod, success);
jni::HandleJavaException(env);
}
} // namespace
extern "C"
@ -385,4 +397,21 @@ Java_com_mapswithme_maps_bookmarks_data_BookmarkManager_nativeSetAllCategoriesVi
{
frm()->GetBookmarkManager().SetAllCategoriesVisibility(static_cast<bool>(visible));
}
JNIEXPORT jint JNICALL
Java_com_mapswithme_maps_bookmarks_data_BookmarkManager_nativeGetKmlFilesCountForConversion(
JNIEnv * env, jobject thiz)
{
return static_cast<jint>(frm()->GetBookmarkManager().GetKmlFilesCountForConversion());
}
JNIEXPORT void JNICALL
Java_com_mapswithme_maps_bookmarks_data_BookmarkManager_nativeConvertAllKmlFiles(
JNIEnv * env, jobject thiz)
{
frm()->GetBookmarkManager().ConvertAllKmlFiles([env](bool success)
{
OnFinishKmlConversion(env, success);
});
}
} // extern "C"

View file

@ -21,6 +21,9 @@ public enum BookmarkManager
@NonNull
private List<BookmarksLoadingListener> mListeners = new ArrayList<>();
@NonNull
private List<KmlConversionListener> mConversionListeners = new ArrayList<>();
static
{
ICONS.add(new Icon("placemark-red", "placemark-red", R.drawable.ic_bookmark_marker_red_off, R.drawable.ic_bookmark_marker_red_on));
@ -68,6 +71,16 @@ public enum BookmarkManager
mListeners.remove(listener);
}
public void addListener(@NonNull KmlConversionListener listener)
{
mConversionListeners.add(listener);
}
public void removeListener(@NonNull KmlConversionListener listener)
{
mConversionListeners.remove(listener);
}
// Called from JNI.
@MainThread
public void onBookmarksLoadingStarted()
@ -101,6 +114,14 @@ public enum BookmarkManager
listener.onBookmarksFileLoaded(success);
}
// Called from JNI.
@MainThread
public void onFinishKmlConversion(boolean success)
{
for (KmlConversionListener listener : mConversionListeners)
listener.onFinishKmlConversion(success);
}
public boolean isVisible(long catId)
{
return nativeIsVisible(catId);
@ -339,10 +360,19 @@ public enum BookmarkManager
private static native void nativeSetAllCategoriesVisibility(boolean visible);
private static native int nativeGetKmlFilesCountForConversion();
private static native void nativeConvertAllKmlFiles();
public interface BookmarksLoadingListener
{
void onBookmarksLoadingStarted();
void onBookmarksLoadingFinished();
void onBookmarksFileLoaded(boolean success);
}
public interface KmlConversionListener
{
void onFinishKmlConversion(boolean success);
}
}

View file

@ -264,12 +264,17 @@ void OnMigrationFailure(std::string && failedStage)
alohalytics::Stats::Instance().LogEvent("Bookmarks_migration_failure", details);
}
void MigrateIfNeeded()
bool IsMigrationCompleted()
{
bool isCompleted;
if (!settings::Get(kSettingsParam, isCompleted))
isCompleted = false;
if (isCompleted)
return false;
return isCompleted;
}
void MigrateIfNeeded()
{
if (IsMigrationCompleted())
return;
GetPlatform().RunTask(Platform::Thread::File, []()
@ -1561,6 +1566,91 @@ BookmarkManager::SharingResult BookmarkManager::GetFileForSharing(df::MarkGroupI
return SharingResult(tmpFilePath);
}
size_t BookmarkManager::GetKmlFilesCountForConversion() const
{
// The conversion available only after successful migration.
if (!migration::IsMigrationCompleted())
return 0;
Platform::FilesList files;
Platform::GetFilesByExt(GetPlatform().SettingsDir(),
BOOKMARKS_FILE_EXTENSION, files);
return files.size();
}
void BookmarkManager::ConvertAllKmlFiles(ConversionHandler && handler) const
{
// The conversion available only after successful migration.
if (!migration::IsMigrationCompleted())
return;
GetPlatform().RunTask(Platform::Thread::File, [handler = std::move(handler)]()
{
auto const oldDir = GetPlatform().SettingsDir();
Platform::FilesList files;
Platform::GetFilesByExt(oldDir, BOOKMARKS_FILE_EXTENSION, files);
for (auto & f : files)
f = my::JoinFoldersToPath(oldDir, f);
auto const newDir = GetBookmarksDirectory();
if (!GetPlatform().IsFileExistsByFullPath(newDir) && !GetPlatform().MkDirChecked(newDir))
{
handler(false /* success */);
return;
}
std::vector<std::pair<std::string, kml::FileData>> fileData;
fileData.reserve(files.size());
for (auto const & f : files)
{
std::string fileName = f;
my::GetNameFromFullPath(fileName);
my::GetNameWithoutExt(fileName);
auto kmbPath = my::JoinPath(newDir, fileName + kBookmarksExt);
size_t counter = 1;
while (Platform::IsFileExistsByFullPath(kmbPath))
kmbPath = my::JoinPath(newDir, fileName + strings::to_string(counter++) + kBookmarksExt);
kml::FileData kmlData;
try
{
kml::DeserializerKml des(kmlData);
FileReader reader(f);
des.Deserialize(reader);
}
catch (FileReader::Exception const & exc)
{
LOG(LDEBUG, ("KML text deserialization failure: ", exc.what(), "file", f));
handler(false /* success */);
return;
}
try
{
kml::binary::SerializerKml ser(kmlData);
FileWriter writer(kmbPath);
ser.Serialize(writer);
}
catch (FileWriter::Exception const & exc)
{
my::DeleteFileX(kmbPath);
LOG(LDEBUG, ("KML binary serialization failure: ", exc.what(), "file", f));
handler(false /* success */);
return;
}
fileData.emplace_back(kmbPath, std::move(kmlData));
}
for (auto const & f : files)
my::DeleteFileX(f);
//TODO(@darina): add fileData to m_categories.
handler(true /* success */);
});
}
df::GroupIDSet BookmarkManager::MarksChangesTracker::GetAllGroupIds() const
{
auto const & groupIds = m_bmManager.GetBmGroupsIdList();

View file

@ -9,6 +9,8 @@
#include "geometry/any_rect2d.hpp"
#include "geometry/screenbase.hpp"
#include "platform/safe_callback.hpp"
#include "base/macros.hpp"
#include "base/strings_bundle.hpp"
#include "base/thread_checker.hpp"
@ -231,6 +233,13 @@ public:
bool AreAllCategoriesInvisible() const;
void SetAllCategoriesVisibility(bool visible);
// Return number of files for the conversion to the binary format.
size_t GetKmlFilesCountForConversion() const;
// Convert all found kml files to the binary format.
using ConversionHandler = platform::SafeCallback<void(bool success)>;
void ConvertAllKmlFiles(ConversionHandler && handler) const;
/// These functions are public for unit tests only. You shouldn't call them from client code.
void SaveToKML(df::MarkGroupID groupId, std::ostream & s);
void CreateCategories(KMLDataCollection && dataCollection, bool autoSave = true);