Git Product home page Git Product logo

gpx's People

Contributors

0b11001111 avatar a1ien avatar agateau avatar bors[bot] avatar brendanashworth avatar caspervg avatar cassaundra avatar cedeber avatar dhontecillas avatar ebcrowder avatar felgru avatar frewsxcv avatar hfiguiere avatar jasper-bosch avatar lingepumpe avatar lnicola avatar michaelkirk avatar mkroehnert avatar nathanhowell avatar ndrsg avatar nerdypepper avatar oherrala avatar pelmers avatar snoir avatar soruh avatar sosna avatar tehsmeely avatar urschrei avatar w-flo avatar wtchen avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gpx's Issues

Relax behavior for empty `<text>` tags

Hello

A friend sent me a .gpx file for a trip that we are planning. I tried to load the file with the following simple code:

use gpx;
use std::fs::File;
use std::io::BufReader;

fn main() {
    let file = File::open("traces/randonnee-37642110-3-beaulolais.gpx").unwrap();
    let reader = BufReader::new(file);
    let gpx = gpx::read(reader).unwrap();
    println!("{:?}", gpx);
}

I got this error:

thread 'main' panicked at 'called Result::unwrap() on an Err value: NoStringContent', src\main.rs:8:33

The metadata section of the .gpx file is as follow:

    <metadata>
        <name>3 BEAULOLAIS</name>
        <link href="">
            <text></text>
        </link>
    </metadata>

The application works properly if I remove <text></text> or add some text between the tags. This is coherent with the error, as the tag is empty (it has NoStringContent XD).

However, both Komoot and Garmin Connect load the file happily.

I believe the gpx library should have a more relaxed behavior when encountering an empty <text> tag and just ignore the tag, without raising any error.

discrepancy between gpx::read and GPX schema documentation

In src/parser/waypoint.rs the element "ageofgpsdata" gets parsed into the age filed of the Waypoint object. Comparing that with the GPX 1.1 shema, there is no "ageofgpsdata" in a waypoint element. Instead there exists an "ageofdgpsdata" element. That would also be somewhat consistent with the documentation of the age attribute of the Waypoint class, which speaks of seconds since the last DGPS update.

The Waypoint parser should probably be changed to be able to parse "ageofdgpsdata" elements into the age attribute.

I’m not sure what to do about "ageofgpsdata" elements (without d). Those are actually used in the example file tests/fixtures/with_accuracy.gpx. If there are non-conforming gpx files in the wild that have waypoints with an "ageofgpsdata" element, we should probably be able to read them.

Implementing serde (De)Serialize for GPX structs?

Hello all,
first of all I want to say thank you for your work on the GPX crate.

I am using this crate for a hobby project which allows recording GPS tracks via the webbrowser GPS API and exporting them as GPX. See https://gitlab.com/mkroehnert/trailcorder.

In addition to the existing XML export option, I am currently testing a feature for persisting the recorded data in local storage as JSON objects, which requires deriving serde (De)Serialize for the structs in this crate.

Since it is not easily possible to add serde #derive to structs that are not part of my own crate, I added the required changes in the following commit of my fork: https://github.com/mkroehnert/gpx/commit/26a0b8b1bd9c6348a86c9a30ccff2b963245a05f

Before putting more work into hiding the serde dependency behind a feature flag,
I wanted to ask if this is a contribution you would consider adding/merging,

API to update creator attribute (feature)

Strava uses the creator attribute in GPX files in a very special way. Not being able to set it when creating a GPX file will prevent Strava from using elevation data when uploading the GPX file there.

From the Strava API docs in https://developers.strava.com/docs/uploads/

Device type is detected in all file types from standard ‘creator’ tags. These tags are then matched to a list of known devices. In some cases the name of the device will be displayed along with the activity details on strava.com.

A generic “with barometer” device is provided to force the system to use the elevation data from TCX and GPX file types. One only needs to add “with barometer” to the end of the creator name.

I suggest having a way to programmatically change the creator attribute from "https://github.com/georust/gpx".

allow parsing of arbitrary third-party extensions

The GPX schema allows for some tags to include arbitrary XML data in the form of the extensions tag:

<...>
Allow any elements from a namespace other than this schema's namespace (lax validation). [0..*]
</...>

Currently rust-gpx has no functionality that allows this data to be parsed or stored in the resulting Gpx instance. This issue is a tracking issue for this feature.

How to access the time of a waypoint?

Hello,

Thanks a lot for the crate! This makes handling of gpx files really easy.

I have one question though: How can I, as a consumer, properly work with the time of a waypoint? Maybe I'm missing it, but although with the newest commit, the Time struct is exported, I can only format it directly to a string. I would like to have it as a chrono DateTime to further do some calculations on it.

Currently it seems that I have to format it as a String (involving an allocation), just to have it again parsed again by chrono.

What about a chrono feature of the crate, which could transform the Time as a chrono DateTime?

Allow continuing on unimportant errors

I have a GPX file, which has a malformed <time> node:

<time>2022-04-13T11:49:33.749</time>

The rest of the file is fine, but gpx::read fails because of that. Could there be an option to "continue on unimportant errors" for parsing? Thanks.

Add write example to README

There's a small example on docs.rs, but it's a bit barebones and doesn't cover a potential use case. We should add a more useful example, and feature it on the README. For example, construct a new Gpx object from scratch and save it to a file.

gpx Point out of sync with geo crate's Point

I ran into an issue where traits implemented on Point in the geo crate didn't apply to the Point objects returned from gpx file parsing.

Looks like the latest geo crate uses newer geo_types version than this crate, so the trait impls don't apply to those types.

For now it's easy to workaround it by converting with something like Point::new(val.lng(), val.lat()), but it would be even better if this weren't necessary.

crates publishing team

👋 Hi @frewsxcv,

Following up on georust/meta#21, I created a new gpx-publishers team for publishing to crates.io with you as a maintainer (actually since @frewsxcv is an organization owner, GH won't let me mark him as a maintainer, but it'd be redundant permissions anyway 🤷).

Could you please update the crate owners? Specifically:


You two are the only "user owners" of that crate, so only you two can edit that crate's owners:

cd gpx
# 💥 remove large publishing group
cargo owner --remove github:georust:core
# 🔐 add small publishing group
cargo owner --add github:georust:gpx-publishers

# make sure everything looks good 👀 
cargo owner --list

And if there's anyone else you'd like to be able to publish the crates, feel free to add them to your publishing team, or as a user-owner. Consider that user-owners, as opposed to owners-via-team, can themselves edit the crate's owners, which could be desirable, or not, depending.

In particular, @brendanashworth, @Lingepumpe, and @oherrala have been active in this repo in the past. Are any of them interested in being added as publishers?

Let me know if you have any questions, or you can review georust/meta#21.

Time Parsing

Hello everybody,

first of all thanks for providing this great package!

I stumbled over a GPX file that contains the following time stamp <time>2021-10-10T09:55:20.952</time> which causes an Rfc3339Error during parsing. The file, however, validates against the GPX 1.1 schema

$ xmllint --schema http://www.topografix.com/GPX/1/1/gpx.xsd /tmp/test.gpx --noout
/tmp/test.gpx validates

Both, GPX 1.0 and GPX 1.1 define time stamps as xsd:dateTime which is neither RFC 3339 nor ISO 8601 by definition, although the latter strongly inspired it. See this great visualization for comparison of the standards 😎.

I suggest to assume ISO 8601 by default. Since the world isn't perfect, I also suggest to implement an fall back on RFC 3339 in error cases or, even better, allow for user defined error handlers. In my case, for instance, I don't really care about the time stamp and would pass a callback that simply ignores the "malformed" input.

If you're interested, I can start working on a PR 🙃

gpx crate can produce invalid XML

It's possible to write out gpx which cannot be read back in with gpx crate itself. In this example case we have string ?> in Route's name which is not correctly escaped to produce a valid XML output.

Consider the following example program:

use std::io::Cursor;
use gpx;

fn main() {
    let g = gpx::Gpx {
        version: gpx::GpxVersion::Gpx11,
        route: gpx::Route {
            name: Some("?>".into()),
            .. gpx::Route::default()
        },
        .. gpx::Gpx::default()
    };

    let mut buf = Vec::new();
    gpx::write(&g, &mut buf).unwrap();
    println!("{}", String::from_utf8_lossy(&buf));
    let cursor = Cursor::new(&buf);
    let _ = gpx::read(cursor).unwrap();
}

and when executed:

$ cargo run -q --example invalid-xml
<?xml version="1.0" encoding="utf-8"?>
<gpx version="1.1" creator="https://github.com/georust/gpx">
  <rte>
    <name>?></name>
  </rte>
</gpx>
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error(Msg("error while parsing XML"), State { next_error: Some(Error { pos: 4:11, kind: Syntax("Unexpected token: ?>") }), backtrace: InternalBacktrace { backtrace: None } })', examples/invalid-xml.rs:18:13
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Waypoint name can be an empty string

Hello.

I found out that I have a GPX file with a waypoint name which is empty:

<wpt lat="47.940954" lon="7.158881">
  <ele>0</ele>
  <name><![CDATA[]]></name>
  <desc><![CDATA[]]></desc>
  <sym>3</sym>
</wpt>

Looking at the GPX spec: http://www.topografix.com/GPX/1/1/#type_wptType this seems to be valid.

GPX does not place restrictions on the length of this field or the characters contained in it.

But this crate makes it mandatory (allow_empty: false here):

"name" => waypoint.name = Some(string::consume(context, "name", false)?),

I believe we should allow it empty, don't you think?
Thanks

please upgrade geo and geo-types dependency

Hi, I'm using gpx crate in a program together with geo and geo-types. When compiling I get:

error[E0308]: mismatched types
   --> src/context.rs:166:37
    |
166 |                         coords.push(f.point());
    |                                     ^^^^^^^^^ expected struct `geo::Point`, found struct `geo_types::point::Point`
    |
    = note: expected struct `geo::Point<f64>`
               found struct `geo_types::point::Point<f64>`
    = note: perhaps two different versions of crate `geo_types` are being used?

error[E0599]: no method named `geodesic_distance` found for struct `geo_types::point::Point<f64>` in the current scope
   --> src/context.rs:174:36
    |
174 |                         let d = p1.geodesic_distance(&p2);
    |                                    ^^^^^^^^^^^^^^^^^ method not found in `geo_types::point::Point<f64>`

I can solve this updating geo and geo-types dependency on a local gpx crate. How should this work on Rust? Should gpx always be in sync with latest geo release? Should gpx re-export geo crate? Sorry but I'm not a Rust expert!

Cannot parse <copyright> tag in metadata

The GPX 1.1 spec defines a copyright type which may be in the metadata tag. In gpx v0.8 parsing such a file returns Error(InvalidChildElement("copyright", "metadata"), ...).

Metadata:

<copyright> copyrightType </copyright> [0..1]

copyrightType:

<copyright
  author="xsd:string [1] ?">
    <year> xsd:gYear </year> [0..1] ?
    <license> xsd:anyURI </license> [0..1] ?
</copyright>

For my purposes I wouldn't mind if the parser just skips this element and ignores it as long as the file can be parsed.

Support writing to files

I know this is mentioned in the readme but I though opening an issue would be good so people can subscribe to the status of the issue.

Behavior for empty `<name/>` tags

Hi there,

My GPS tracker app (Sports Tracker) produces gpx files that contain empty name tags:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<gpx xmlns="http://www.topografix.com/GPX/1/1" xmlns:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" creator="Sports Tracker" version="1.1" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd http://www.garmin.com/xmlschemas/TrackPointExtension/v1 http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd">
<metadata>
    <name/>
    <desc/>
    <author><name>Jasper</name></author>
</metadata>
<trk>
    <name/>
    <trkseg>
    <trkpt...

That empty name tag in the metadata results in a NoStringContent error.

I created a pull request (#97) that fixes this by allowing the name tag to be empty.

If you need any further information or if you'd like me to add a test then please let me know.

garmin gpx track logs could not be read

Reason are track extensions like:

<trk> <name>2017-05-17 06:47:34 Tag</name> <extensions> <gpxx:TrackExtension> 
<gpxx:DisplayColor>Cyan</gpxx:DisplayColor> </gpxx:TrackExtension> 
</extensions> <trkseg> 

Should be fixed by adding an extensions event to consume at tracks.rs:

    "extensions" => {
                    extensions::consume(context)?;
                }

Panic for tracks with empty name

When opening a file with this format:

<gpx>
    <!--- metadata --->
    <trk>
        <name></name>
        <!--- rest of track data --->
    </trk>
</gpx>

gpx panics with the message: no content inside string.

Is there a reason string::consume is called with allow_empty=false here?
Is this construct just invalid and the App I used has generated an invalid gpx file?
If that is the case, since all other gpx applications I tested don't have a problem with this, would it make sense to accept this anyways?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.