organicmaps / organicmaps

🍃 Organic Maps is a free Android & iOS offline maps app for travelers, tourists, hikers, and cyclists. It uses crowd-sourced OpenStreetMap data and is developed with love by MapsWithMe (MapsMe) founders and our community. No ads, no tracking, no data collection, no crapware. Please donate to support the development!
https://organicmaps.app
Apache License 2.0
9.65k stars 926 forks source link

Load and save optional timestamp for each track point #8314

Closed biodranik closed 3 weeks ago

biodranik commented 4 months ago

This is a pre-requisite to the track recorder feature #2147

Each recorded coordinate should have a timestamp for a valid recorded GPX or KML track. It will be used to calculate derived properties (speed) and display track statistics.

kml::MultiGeometry used in TrackData uses PointWithAltitude that stores (x, y, h) without timestamp.

See <time> element in GPX http://www.topografix.com/gpx/1/1/#type_wptType

and <when> for KML https://developers.google.com/kml/documentation/kmlreference#when

It would be great to store time in a compact way, and ideally only if necessary, to avoid unnecessary memory consumption.

CC @rtsisyk @kavikhalique @cyber-toad

rtsisyk commented 3 months ago

@kavikhalique is it on your radar? Do we need it for the basic track recorder?

kavikhalique commented 3 months ago

@kavikhalique is it on your radar? Do we need it for the basic track recorder?

Yes, i had done some research in past and found Kml itself do not have any functionality to use timestamp for each points for a track.

We can store only one time stamp.

If we want to use timestamp for each specific point in track then i found there were two ways.

  1. Store track as set of individual single points (placemark) and store timestamp for each (it is not space friendly and consume a huge amount of space and will take lots of time to load)

  2. We can use which is a part of google earth extensions to kml as stated on internet.

<gx:Track>
        <when>2023-06-21T12:00:00Z</when>
        <gx:coord>-122.0822035425683 37.42228990140251 0</gx:coord>
        <when>2023-06-21T12:01:00Z</when>
        <gx:coord>-122.085204635393 37.4223710139276 0</gx:coord>
        <when>2023-06-21T12:02:00Z</when>
        <gx:coord>-122.087204631393 37.422371004274 0</gx:coord>
 </gx:Track>
rtsisyk commented 3 months ago

Let's check that others app do. We don't need to reinvent the wheel in this topic.

biodranik commented 2 months ago

@rtsisyk It's not about other apps, it's about KML and GPX formats for tracks. A timestamp for each point is required to calculate any usable metrics.

@cyber-toad WDYT?

cyber-toad commented 2 months ago

@cyber-toad WDYT?

@biodranik looks good. Not sure how to implement compact storage (comparing to add int_32 to Point for timestamp) - do you mean some subclassing like PointWithAltitude / PointWithAltitudeAndTime and switch between them in when trackdata is created?

biodranik commented 2 months ago

@cyber-toad yes, using different vectors for example.

To improve loading speed, we can store a number of serialized track points in the beginning of the track/in the metadata, to pre-allocate the vector of the necessary size.

kirylkaveryn commented 1 month ago

@biodranik @rtsisyk @cyber-toad lets decide what format to store the track in OM we should use.

We store all the files in kml in the OM and gpx will only be used for the export.

As I see there is only 2 options to store the track in kml as @kavikhalique mentioned earlier:

  1. google extension (not compact - it duplicates the coordinates and altitudes)
  2. proprietary format (will be compact but not supported by the other apps)
biodranik commented 1 month ago

As was mentioned in the ticket above, there is only one choice to store track data with time stamps in KML, <gx:Track>: https://developers.google.com/kml/documentation/kmlreference#gxtrack

To store several tracks united as one track/route <gx:MultiTrack> can be used: https://developers.google.com/kml/documentation/kmlreference#gxmultitrack

There is already a test with this gx:Track and even gx:MultiTrack: UNIT_TEST(Kml_Ver_2_3)

Not sure which duplication you have in mind @kirylkaveryn ? KML scheme doesn't have any duplicate elements.

kirylkaveryn commented 1 month ago

@biodranik as I understand the <LineString><coordinates>... should be fully replaced with the <gx:Track>...? Some apps store both (GuruMaps).

I'm not familiar with the xmls parsing so apriciate any help @cyber-toad

biodranik commented 1 month ago

as I understand the ... should be fully replaced with the ...?

Correct. Some apps may store both for compatibility with older software that doesn't work with KML 2.3. We can decide if we need to duplicate the data in KML later if we get reports about such cases later. Now it would be better/safer to avoid it. Most devices expect GPX as an input, not KML, so it shouldn't be an issue.

AFAIU, KML parser already parses gx:track data, but ignores/drops <when> tags. So the parser should be minimally patched in void KmlParser::CharData(std::string & value) method. You can use the test file/the unit test mentioned above, and use a debugger in the method above to understand how the state machine is implemented and where the <when> tag should be extracted.

@cyber-toad any help is appreciated.

biodranik commented 1 month ago

Here is a bit more information about KML 2.2 and 2.3 difference + an example https://github.com/organicmaps/organicmaps/pull/9107#issuecomment-2309896315

biodranik commented 3 weeks ago

Timestamps serialization was implemented in https://github.com/organicmaps/organicmaps/pull/9175 , timestamps gpx export was implemented in https://github.com/organicmaps/organicmaps/pull/9216 thanks to @kirylkaveryn !