KMB import fix #6006

Merged
root merged 18 commits from kmb-import-fix into master 2023-10-02 22:39:32 +00:00
Member

The main problem with updated KMB format that version ID is not changed. KMB file is generated with version V8 while internal changes are incompatible with V8. Introduced new version V8MM for new KMB files format.

KBM v8MM files don't have compilations. I removed compilations from the code. Tracks data has extra 3 bytes with unknown purpose. Also timestamp is now stored as milliseconds instead of seconds.

Updated unit tests.

Changes in kml_to_kmb tool

kml_to_kmb now accepts optional version parameter. It can generate not only files in V9 (latest) format but with V8.
This was needed to generate test data in V8 format.

Fixes #5718

The main problem with updated KMB format that version ID is not changed. KMB file is generated with version `V8` while internal changes are incompatible with `V8`. Introduced new version `V8MM` for new KMB files format. KBM v8MM files don't have compilations. I removed compilations from the code. Tracks data has extra 3 bytes with unknown purpose. Also timestamp is now stored as milliseconds instead of seconds. Updated unit tests. ### Changes in `kml_to_kmb` tool `kml_to_kmb` now accepts optional version parameter. It can generate not only files in V9 (latest) format but with V8. This was needed to generate test data in V8 format. Fixes #5718
biodranik (Migrated from github.com) reviewed 2023-09-12 11:59:13 +00:00
biodranik (Migrated from github.com) left a comment

Is it possible to create a subtype for version81 and incorporate all fixes there?

Is it possible to create a subtype for version81 and incorporate all fixes there?
vng (Migrated from github.com) reviewed 2023-09-13 11:03:51 +00:00
vng (Migrated from github.com) commented 2023-09-13 11:03:36 +00:00

So the HasCompilationsSection() should be enough, no?
Why comment here? Let's keep as-is.

So the HasCompilationsSection() should be enough, no? Why comment here? Let's keep as-is.
vng (Migrated from github.com) commented 2023-09-13 11:03:30 +00:00

So the HasCompilationsSection() should be enough, no?
Why comment here? Let's keep as-is.

So the HasCompilationsSection() should be enough, no? Why comment here? Let's keep as-is.
strump reviewed 2023-09-13 11:45:20 +00:00
Author
Member

Not only compilations section is disabled but also Bookmark and Category fields list should be updated. If I enable back "compilations" field parsing would fail.

Not only compilations section is disabled but also Bookmark and Category fields list should be updated. If I enable back "compilations" field parsing would fail.
biodranik (Migrated from github.com) reviewed 2023-09-16 11:59:46 +00:00
biodranik (Migrated from github.com) left a comment

LGTM with minor comments.

LGTM with minor comments.
biodranik (Migrated from github.com) commented 2023-09-16 11:55:17 +00:00
    std::string const versionStr = argv[2];
```suggestion std::string const versionStr = argv[2]; ```
biodranik (Migrated from github.com) commented 2023-09-16 11:57:01 +00:00

Is it really needed?

  BookmarkDataV8() = default;
Is it really needed? ```suggestion BookmarkDataV8() = default; ```
biodranik (Migrated from github.com) commented 2023-09-16 11:57:16 +00:00
  BookmarkDataV8(BookmarkData const & src)
```suggestion BookmarkDataV8(BookmarkData const & src) ```
strump reviewed 2023-09-20 08:33:00 +00:00
@ -0,0 +18,4 @@
explicit SerializerKmlV8(FileData & data) : SerializerKml(data) {};
template <typename Sink>
void Serialize(Sink & sink)
Author
Member

This method is cop-n-paste of SerializerKml::Serialize(sink).
The only differences are that it writes version 0x08 as first byte and it calls SerializerKmlV8::SerializeBookmarks() instead of SerializerKml::SerializeBookmarks().
Is there a better way? Should I introduce virtual methods SerializerKml::SerializeVersion() and SerializerKml::SerializeBookmarks()?

This method is cop-n-paste of `SerializerKml::Serialize(sink)`. The only differences are that it writes version 0x08 as first byte and it calls `SerializerKmlV8::SerializeBookmarks()` instead of `SerializerKml::SerializeBookmarks()`. Is there a better way? Should I introduce virtual methods `SerializerKml::SerializeVersion()` and `SerializerKml::SerializeBookmarks()`?
strump reviewed 2023-09-21 07:55:41 +00:00
Author
Member

Compiler shows warning: all paths through this function will call itself because types Timestamp and TimestampMillis could be converted to one another. Is there any way to force use DebugPrint(Timestamp) function from base/internal/message.hpp ?

Compiler shows warning: `all paths through this function will call itself` because types `Timestamp` and `TimestampMillis` could be converted to one another. Is there any way to force use `DebugPrint(Timestamp)` function from `base/internal/message.hpp` ?
Author
Member

Fixed

Fixed
Author
Member

Fixed.
We need default constructor to initialize std::vector<BookmarkDataV8> m_bookmarksData; field in FileDataV8

Fixed. We need default constructor to initialize `std::vector<BookmarkDataV8> m_bookmarksData;` field in FileDataV8
biodranik (Migrated from github.com) reviewed 2023-09-22 13:11:57 +00:00
@ -0,0 +18,4 @@
explicit SerializerKmlV8(FileData & data) : SerializerKml(data) {};
template <typename Sink>
void Serialize(Sink & sink)
biodranik (Migrated from github.com) commented 2023-09-22 13:11:57 +00:00

That's ok.

That's ok.
strump reviewed 2023-09-26 08:59:19 +00:00
Author
Member

Appeared that V8MM format doesn't have m_type field. Because of that we had m_visibility = false. Using default m_type for all V8MM.

Appeared that V8MM format doesn't have `m_type` field. Because of that we had `m_visibility = false`. Using default `m_type` for all V8MM.
@ -1873,3 +1874,3 @@
kmlData = LoadKmlFile(fileSavePath, KmlFileType::Text);
else if (ext == ".gpx")
else if (ext == kGpxExtension)
kmlData = LoadKmlFile(fileSavePath, KmlFileType::Gpx);
Author
Member

When you import KMB file it is converted to KML first in GetKMLPath(...) function and then KML is imported.
In such case filePath = "some_file.kmb and fileSavePath = "some_file.kmb2.kml". Because we parse fileSavePath we should get extension correctly here.

When you import KMB file it is converted to KML first in `GetKMLPath(...)` function and then KML is imported. In such case `filePath = "some_file.kmb` and `fileSavePath = "some_file.kmb2.kml"`. Because we parse `fileSavePath` we should get extension correctly here.
Author
Member

In my cases there was a problem with fileSavePath parsing. And temp files were not cleaned up.

In my cases there was a problem with `fileSavePath` parsing. And temp files were not cleaned up.
biodranik (Migrated from github.com) reviewed 2023-09-28 23:15:13 +00:00
@ -1873,3 +1874,3 @@
kmlData = LoadKmlFile(fileSavePath, KmlFileType::Text);
else if (ext == ".gpx")
else if (ext == kGpxExtension)
kmlData = LoadKmlFile(fileSavePath, KmlFileType::Gpx);
biodranik (Migrated from github.com) commented 2023-09-28 23:15:13 +00:00

It would be even better to see these comments in the code instead of the PR ;-)

It would be even better to see these comments in the code instead of the PR ;-)
biodranik (Migrated from github.com) reviewed 2023-09-28 23:16:08 +00:00
biodranik (Migrated from github.com) commented 2023-09-28 23:16:08 +00:00

Let's mention it in the code.

Let's mention it in the code.
biodranik (Migrated from github.com) reviewed 2023-09-28 23:19:36 +00:00
biodranik (Migrated from github.com) commented 2023-09-28 23:19:35 +00:00

Both if and else branches have this line. Put it before the if.

Both if and else branches have this line. Put it before the if.
biodranik (Migrated from github.com) reviewed 2023-09-28 23:20:11 +00:00
biodranik (Migrated from github.com) commented 2023-09-28 23:20:11 +00:00

What kind of problem did you have with parsing? Should it be fixed/handled properly?

What kind of problem did you have with parsing? Should it be fixed/handled properly?
biodranik (Migrated from github.com) reviewed 2023-09-29 09:28:51 +00:00
biodranik (Migrated from github.com) commented 2023-09-29 09:27:20 +00:00

nit: remove unnecessary newline

nit: remove unnecessary newline
biodranik (Migrated from github.com) commented 2023-09-29 09:27:24 +00:00

nit: remove unnecessary newline

nit: remove unnecessary newline
biodranik (Migrated from github.com) commented 2023-09-29 09:27:48 +00:00

namespace kml::binary

namespace kml::binary
biodranik (Migrated from github.com) commented 2023-09-29 09:28:47 +00:00
// BookmarkDataV8MM contains the same fields as BookmarkDataV8 but without compilations.

nit: Have dots at the end of sentences.

```suggestion // BookmarkDataV8MM contains the same fields as BookmarkDataV8 but without compilations. ``` nit: Have dots at the end of sentences.
strump reviewed 2023-09-30 14:47:24 +00:00
@ -1873,3 +1874,3 @@
kmlData = LoadKmlFile(fileSavePath, KmlFileType::Text);
else if (ext == ".gpx")
else if (ext == kGpxExtension)
kmlData = LoadKmlFile(fileSavePath, KmlFileType::Gpx);
Author
Member

Reviewed this part of code because ext is always "kml".

Reviewed this part of code because `ext` is always `"kml"`.
strump reviewed 2023-09-30 14:49:11 +00:00
Author
Member

If input KML/KMZ file has invalid format we get kmlData == nullptr.

If input KML/KMZ file has invalid format we get `kmlData == nullptr`.
strump reviewed 2023-09-30 14:49:52 +00:00
Author
Member

Removed this field completly. Added comment.

Removed this field completly. Added comment.
strump reviewed 2023-09-30 14:50:03 +00:00
Author
Member

Fixed.

Fixed.
strump reviewed 2023-09-30 14:50:10 +00:00
Author
Member

Fixed.

Fixed.
strump reviewed 2023-09-30 14:50:15 +00:00
Author
Member

Fixed

Fixed
strump reviewed 2023-09-30 14:50:34 +00:00
Author
Member

Fixed.

Fixed.
biodranik (Migrated from github.com) reviewed 2023-09-30 18:39:36 +00:00
@ -1873,3 +1874,3 @@
kmlData = LoadKmlFile(fileSavePath, KmlFileType::Text);
else if (ext == ".gpx")
else if (ext == kGpxExtension)
kmlData = LoadKmlFile(fileSavePath, KmlFileType::Gpx);
biodranik (Migrated from github.com) commented 2023-09-30 18:39:36 +00:00

Did you add a comment in the code? Btw, why is it always kml there?

Did you add a comment in the code? Btw, why is it always kml there?
biodranik (Migrated from github.com) reviewed 2023-09-30 20:33:45 +00:00
@ -1873,2 +1873,3 @@
if (ext == kKmlExtension)
kmlData = LoadKmlFile(fileSavePath, KmlFileType::Text);
else if (ext == ".gpx")
else if (ext == kGpxExtension)
biodranik (Migrated from github.com) commented 2023-09-30 20:33:45 +00:00

Are you 100% sure that this code should be removed? Did you test it with other file types? Is it guaranteed that this code is called only for kml/kmz files?

Are you 100% sure that this code should be removed? Did you test it with other file types? Is it guaranteed that this code is called only for kml/kmz files?
strump reviewed 2023-10-01 11:22:16 +00:00
@ -1873,2 +1873,3 @@
if (ext == kKmlExtension)
kmlData = LoadKmlFile(fileSavePath, KmlFileType::Text);
else if (ext == ".gpx")
else if (ext == kGpxExtension)
Author
Member

I tested with KML, KMZ, KMB, and GPX files.
Found an issue with GPX and fixed. Current implementation imports all formats successfully.

One questionable part: KMB is first converted to temp KML and then KML is converted to final KML. Maybe we can skip temporary step.

Nice to have: unit tests 🙂

I tested with KML, KMZ, KMB, and GPX files. Found an issue with GPX and fixed. Current implementation imports all formats successfully. One questionable part: KMB is first converted to temp KML and then KML is converted to final KML. Maybe we can skip temporary step. Nice to have: unit tests 🙂
biodranik (Migrated from github.com) reviewed 2023-10-01 20:52:32 +00:00
@ -1873,2 +1873,3 @@
if (ext == kKmlExtension)
kmlData = LoadKmlFile(fileSavePath, KmlFileType::Text);
else if (ext == ".gpx")
else if (ext == kGpxExtension)
biodranik (Migrated from github.com) commented 2023-10-01 20:52:32 +00:00

Converting kml to kml doesn't look necessary ) Is it easy to fix?

Converting kml to kml doesn't look necessary ) Is it easy to fix?
biodranik (Migrated from github.com) reviewed 2023-10-01 20:56:50 +00:00
@ -358,6 +376,7 @@ std::string GetKMLPath(std::string const & filePath)
}
else if (fileExt == kKmzExtension)
{
// Extract KML file from KMZ archive and save to temp KML with unique name.
biodranik (Migrated from github.com) commented 2023-10-01 20:56:50 +00:00

Why is this copying necessary?

Why is this copying necessary?
strump reviewed 2023-10-02 09:00:46 +00:00
Author
Member

collection has type std::vector<std::pair<std::string, std::unique_ptr<kml::FileData>>>
I converted std::optional<kml::FileData> to std::unique_ptr<kml::FileData> here.
Should we change collection type?

`collection` has type `std::vector<std::pair<std::string, std::unique_ptr<kml::FileData>>>` I converted `std::optional<kml::FileData>` to `std::unique_ptr<kml::FileData>` here. Should we change `collection` type?
biodranik (Migrated from github.com) reviewed 2023-10-02 09:13:22 +00:00
biodranik (Migrated from github.com) commented 2023-10-02 09:13:22 +00:00

Good question, likely yes, if the collection is not moved often. Moving unique_ptr is cheaper than moving FileData.

Otherwise:

    collection->emplace_back(filePath, std::make_unique<kml::FileData>(std::move(kmlData)));
Good question, likely yes, if the collection is not moved often. Moving unique_ptr is cheaper than moving FileData. Otherwise: ```suggestion collection->emplace_back(filePath, std::make_unique<kml::FileData>(std::move(kmlData))); ```
strump reviewed 2023-10-02 09:52:06 +00:00
Author
Member

Your suggested code doesn't work. Compilation error:
error: no matching constructor for initialization of 'kml::FileData'

Replaced with:
std::make_unique<kml::FileData>(std::move(kmlData.value()))

Your suggested code doesn't work. Compilation error: `error: no matching constructor for initialization of 'kml::FileData'` Replaced with: `std::make_unique<kml::FileData>(std::move(kmlData.value()))`
vng (Migrated from github.com) reviewed 2023-10-02 12:25:22 +00:00
vng (Migrated from github.com) left a comment

So you what was the reason to modify existing code with optional?
And then writing "nice":

std::make_unique<kml::FileData>(std::move(kmlData.value())))
So you what was the reason to modify existing code with optional? And then writing "nice": ``` std::make_unique<kml::FileData>(std::move(kmlData.value()))) ```
@ -19,0 +20,4 @@
public:
TimestampMillis() = default;
explicit TimestampMillis(Timestamp const & ts) : Timestamp{ts} {}
TimestampMillis & operator=(Timestamp const & ts)
vng (Migrated from github.com) commented 2023-10-02 12:19:42 +00:00

I suspect it is not needed.

I suspect it is not needed.
rtsisyk reviewed 2023-10-02 12:46:18 +00:00
@ -1525,1 +1525,4 @@
};
// kBinKmlV8 contains the same bookmarks and tracks as kBinKmlV7
std::vector<uint8_t> const kBinKmlV8 = {

Is it possible to push an ordinary file into the repository instead of this?

Is it possible to push an ordinary file into the repository instead of this?
biodranik (Migrated from github.com) reviewed 2023-10-02 13:37:31 +00:00
biodranik (Migrated from github.com) commented 2023-10-02 13:37:31 +00:00

Neither external variable nor !kmlData checks are necessary.

Neither external variable nor !kmlData checks are necessary.
biodranik (Migrated from github.com) reviewed 2023-10-02 13:40:21 +00:00
biodranik (Migrated from github.com) commented 2023-10-02 13:40:21 +00:00
  TEST(kmlData, ());
```suggestion TEST(kmlData, ()); ```
biodranik (Migrated from github.com) reviewed 2023-10-02 13:40:32 +00:00
biodranik (Migrated from github.com) commented 2023-10-02 13:40:32 +00:00
  TEST(!kmlData, ());
```suggestion TEST(!kmlData, ()); ```
vng (Migrated from github.com) approved these changes 2023-10-02 15:00:03 +00:00
biodranik (Migrated from github.com) approved these changes 2023-10-02 22:39:25 +00:00
biodranik (Migrated from github.com) left a comment

@strump let's make a follow-up issue with KML tasks/improvements mentioned in this PR.

@strump let's make a follow-up issue with KML tasks/improvements mentioned in this PR.
This repo is archived. You cannot comment on pull requests.
No reviewers
No labels
Accessibility
Accessibility
Address
Address
Android
Android
Android Auto
Android Auto
Android Automotive (AAOS)
Android Automotive (AAOS)
API
API
AppGallery
AppGallery
AppStore
AppStore
Battery and Performance
Battery and Performance
Blocker
Blocker
Bookmarks and Tracks
Bookmarks and Tracks
Borders
Borders
Bug
Bug
Build
Build
CarPlay
CarPlay
Classificator
Classificator
Community
Community
Core
Core
CrashReports
CrashReports
Cycling
Cycling
Desktop
Desktop
DevEx
DevEx
DevOps
DevOps
dev_sandbox
dev_sandbox
Directions
Directions
Documentation
Documentation
Downloader
Downloader
Drape
Drape
Driving
Driving
Duplicate
Duplicate
Editor
Editor
Elevation
Elevation
Enhancement
Enhancement
Epic
Epic
External Map Datasets
External Map Datasets
F-Droid
F-Droid
Fonts
Fonts
Frequently User Reported
Frequently User Reported
Fund
Fund
Generator
Generator
Good first issue
Good first issue
Google Play
Google Play
GPS
GPS
GSoC
GSoC
iCloud
iCloud
Icons
Icons
iOS
iOS
Legal
Legal
Linux Desktop
Linux Desktop
Linux packaging
Linux packaging
Linux Phone
Linux Phone
Mac OS
Mac OS
Map Data
Map Data
Metro
Metro
Navigation
Navigation
Need Feedback
Need Feedback
Night Mode
Night Mode
NLnet 2024-06-281
NLnet 2024-06-281
No Feature Parity
No Feature Parity
Opening Hours
Opening Hours
Outdoors
Outdoors
POI Info
POI Info
Privacy
Privacy
Public Transport
Public Transport
Raw Idea
Raw Idea
Refactoring
Refactoring
Regional
Regional
Regression
Regression
Releases
Releases
RoboTest
RoboTest
Route Planning
Route Planning
Routing
Routing
Ruler
Ruler
Search
Search
Security
Security
Styles
Styles
Tests
Tests
Track Recording
Track Recording
Translations
Translations
TTS
TTS
UI
UI
UX
UX
Walk Navigation
Walk Navigation
Watches
Watches
Web
Web
Wikipedia
Wikipedia
Windows
Windows
Won't fix
Won't fix
World Map
World Map
No milestone
No project
No assignees
3 participants
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: organicmaps/organicmaps-tmp#6006
No description provided.